1<template> 2 <b-row class="mb-2"> 3 <b-col class="d-sm-flex"> 4 <b-form-group 5 :label="$t('global.table.fromDate')" 6 label-for="input-from-date" 7 class="mr-3 my-0 w-100" 8 > 9 <b-input-group> 10 <b-form-input 11 id="input-from-date" 12 v-model="fromDate" 13 placeholder="YYYY-MM-DD" 14 :state="getValidationState(v$.fromDate)" 15 class="form-control-with-button mb-3 mb-md-0" 16 @blur="v$.fromDate.$touch()" 17 /> 18 <b-form-invalid-feedback role="alert"> 19 <template v-if="v$.fromDate.pattern.$invalid"> 20 {{ $t('global.form.invalidFormat') }} 21 </template> 22 <template v-if="v$.fromDate.maxDate.$invalid"> 23 {{ $t('global.form.dateMustBeBefore', { date: toDate }) }} 24 </template> 25 </b-form-invalid-feedback> 26 <b-form-datepicker 27 v-model="fromDate" 28 class="btn-datepicker btn-icon-only" 29 button-only 30 right 31 :max="toDate" 32 :hide-header="true" 33 :locale="locale" 34 :label-help=" 35 $t('global.calendar.useCursorKeysToNavigateCalendarDates') 36 " 37 :title="$t('global.calendar.selectDate')" 38 button-variant="link" 39 aria-controls="input-from-date" 40 > 41 <template #button-content> 42 <icon-calendar /> 43 <span class="sr-only"> 44 {{ $t('global.calendar.selectDate') }} 45 </span> 46 </template> 47 </b-form-datepicker> 48 </b-input-group> 49 </b-form-group> 50 <b-form-group 51 :label="$t('global.table.toDate')" 52 label-for="input-to-date" 53 class="my-0 w-100" 54 > 55 <b-input-group> 56 <b-form-input 57 id="input-to-date" 58 v-model="toDate" 59 placeholder="YYYY-MM-DD" 60 :state="getValidationState(v$.toDate)" 61 class="form-control-with-button" 62 @blur="v$.toDate.$touch()" 63 /> 64 <b-form-invalid-feedback role="alert"> 65 <template v-if="v$.toDate.pattern.$invalid"> 66 {{ $t('global.form.invalidFormat') }} 67 </template> 68 <template v-if="v$.toDate.minDate.$invalid"> 69 {{ $t('global.form.dateMustBeAfter', { date: fromDate }) }} 70 </template> 71 </b-form-invalid-feedback> 72 <b-form-datepicker 73 v-model="toDate" 74 class="btn-datepicker btn-icon-only" 75 button-only 76 right 77 :min="fromDate" 78 :hide-header="true" 79 :locale="locale" 80 :label-help=" 81 $t('global.calendar.useCursorKeysToNavigateCalendarDates') 82 " 83 :title="$t('global.calendar.selectDate')" 84 button-variant="link" 85 aria-controls="input-to-date" 86 > 87 <template #button-content> 88 <icon-calendar /> 89 <span class="sr-only"> 90 {{ $t('global.calendar.selectDate') }} 91 </span> 92 </template> 93 </b-form-datepicker> 94 </b-input-group> 95 </b-form-group> 96 </b-col> 97 </b-row> 98</template> 99 100<script> 101import IconCalendar from '@carbon/icons-vue/es/calendar/20'; 102import { helpers } from 'vuelidate/lib/validators'; 103import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js'; 104import { useVuelidate } from '@vuelidate/core'; 105import { useI18n } from 'vue-i18n'; 106 107const isoDateRegex = /([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))/; 108 109export default { 110 components: { IconCalendar }, 111 mixins: [VuelidateMixin], 112 setup() { 113 return { 114 v$: useVuelidate(), 115 }; 116 }, 117 data() { 118 return { 119 $t: useI18n().t, 120 fromDate: '', 121 toDate: '', 122 offsetToDate: '', 123 locale: this.$store.getters['global/languagePreference'], 124 }; 125 }, 126 validations() { 127 return { 128 fromDate: { 129 pattern: helpers.regex('pattern', isoDateRegex), 130 maxDate: (value) => { 131 if (!this.toDate) return true; 132 const date = new Date(value); 133 const maxDate = new Date(this.toDate); 134 if (date.getTime() > maxDate.getTime()) return false; 135 return true; 136 }, 137 }, 138 toDate: { 139 pattern: helpers.regex('pattern', isoDateRegex), 140 minDate: (value) => { 141 if (!this.fromDate) return true; 142 const date = new Date(value); 143 const minDate = new Date(this.fromDate); 144 if (date.getTime() < minDate.getTime()) return false; 145 return true; 146 }, 147 }, 148 }; 149 }, 150 watch: { 151 fromDate() { 152 this.emitChange(); 153 }, 154 toDate(newVal) { 155 // Offset the end date to end of day to make sure all 156 // entries from selected end date are included in filter 157 this.offsetToDate = new Date(newVal).setUTCHours(23, 59, 59, 999); 158 this.emitChange(); 159 }, 160 }, 161 methods: { 162 emitChange() { 163 if (this.v$.$invalid) return; 164 this.v$.$reset(); //reset to re-validate on blur 165 this.$emit('change', { 166 fromDate: this.fromDate ? new Date(this.fromDate) : null, 167 toDate: this.toDate ? new Date(this.offsetToDate) : null, 168 }); 169 }, 170 }, 171}; 172</script> 173