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