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"> 20 {{ $t('global.form.invalidFormat') }} 21 </template> 22 <template v-if="!$v.fromDate.maxDate"> 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"> 66 {{ $t('global.form.invalidFormat') }} 67 </template> 68 <template v-if="!$v.toDate.minDate"> 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'; 103 104import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js'; 105 106const isoDateRegex = /([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))/; 107 108export default { 109 components: { IconCalendar }, 110 mixins: [VuelidateMixin], 111 data() { 112 return { 113 fromDate: '', 114 toDate: '', 115 offsetToDate: '', 116 locale: this.$store.getters['global/languagePreference'], 117 }; 118 }, 119 validations() { 120 return { 121 fromDate: { 122 pattern: helpers.regex('pattern', isoDateRegex), 123 maxDate: (value) => { 124 if (!this.toDate) return true; 125 const date = new Date(value); 126 const maxDate = new Date(this.toDate); 127 if (date.getTime() > maxDate.getTime()) return false; 128 return true; 129 }, 130 }, 131 toDate: { 132 pattern: helpers.regex('pattern', isoDateRegex), 133 minDate: (value) => { 134 if (!this.fromDate) return true; 135 const date = new Date(value); 136 const minDate = new Date(this.fromDate); 137 if (date.getTime() < minDate.getTime()) return false; 138 return true; 139 }, 140 }, 141 }; 142 }, 143 watch: { 144 fromDate() { 145 this.emitChange(); 146 }, 147 toDate(newVal) { 148 // Offset the end date to end of day to make sure all 149 // entries from selected end date are included in filter 150 this.offsetToDate = new Date(newVal).setUTCHours(23, 59, 59, 999); 151 this.emitChange(); 152 }, 153 }, 154 methods: { 155 emitChange() { 156 if (this.$v.$invalid) return; 157 this.$v.$reset(); //reset to re-validate on blur 158 this.$emit('change', { 159 fromDate: this.fromDate ? new Date(this.fromDate) : null, 160 toDate: this.toDate ? new Date(this.offsetToDate) : null, 161 }); 162 }, 163 }, 164}; 165</script> 166