|
2 | 2 | import VueDatePicker from "@vuepic/vue-datepicker";
|
3 | 3 | import { ref, useTemplateRef, watch } from "vue";
|
4 | 4 |
|
| 5 | +type DateRange = [Date, Date]; |
| 6 | +
|
5 | 7 | const model = defineModel<Date[]>({ required: true });
|
6 | 8 | const internalModel = ref<Date[]>([]);
|
7 | 9 | const displayDataRange = ref<string>("No dates");
|
8 | 10 | const datePicker = useTemplateRef<typeof VueDatePicker>("datePicker");
|
9 | 11 |
|
10 | 12 | watch(internalModel, () => {
|
11 |
| - model.value = internalModel.value; |
12 |
| - if (internalModel.value.length === 2) { |
13 |
| - const from = internalModel.value[0]; |
14 |
| - const to = internalModel.value[1]; |
15 |
| - displayDataRange.value = `${from.toLocaleDateString()} ${from.toLocaleTimeString()} - ${to.toLocaleDateString()} ${to.toLocaleTimeString()}`; |
16 |
| - } else { |
17 |
| - displayDataRange.value = "No dates"; |
18 |
| - } |
| 13 | + if (isValidRange(internalModel.value as DateRange)) { |
| 14 | + model.value = internalModel.value; |
| 15 | + displayDataRange.value = formatDate(internalModel.value as DateRange); |
| 16 | + } else internalModel.value = model.value; |
19 | 17 | });
|
20 | 18 |
|
21 | 19 | watch(model, () => {
|
22 | 20 | internalModel.value = model.value;
|
23 | 21 | });
|
24 | 22 |
|
| 23 | +function isValidRange([fromDate, toDate]: DateRange) { |
| 24 | + return (!fromDate && !toDate) || (toDate && toDate <= new Date()); |
| 25 | +} |
| 26 | +
|
25 | 27 | function clearCurrentDate() {
|
26 | 28 | internalModel.value = [];
|
27 | 29 | datePicker.value?.closeMenu();
|
28 | 30 | }
|
| 31 | +
|
| 32 | +function formatDate([fromDate, toDate]: DateRange) { |
| 33 | + if (toDate && toDate > new Date()) return "Date cannot be in the future"; |
| 34 | + if (fromDate && toDate) return `${fromDate.toLocaleString()} - ${toDate.toLocaleString()}`; |
| 35 | + if (fromDate) return fromDate.toLocaleString(); |
| 36 | + return "No dates"; |
| 37 | +} |
29 | 38 | </script>
|
30 | 39 |
|
31 | 40 | <template>
|
32 |
| - <VueDatePicker ref="datePicker" v-model="internalModel" :range="{ partialRange: false }" :enable-seconds="true" :max-date="new Date()" :action-row="{ showNow: false, showCancel: false, showSelect: true }"> |
| 41 | + <VueDatePicker ref="datePicker" v-model="internalModel" :format="formatDate" :range="{ partialRange: false }" :enable-seconds="true" :action-row="{ showNow: false, showCancel: false, showSelect: true }"> |
33 | 42 | <template #trigger>
|
34 | 43 | <button type="button" class="btn btn-dropdown dropdown-toggle">
|
35 | 44 | {{ displayDataRange }}
|
36 | 45 | </button>
|
37 | 46 | </template>
|
38 | 47 | <template #action-extra>
|
39 |
| - <button v-if="internalModel.length === 2" class="dp__action_button dp__action_cancel" @click="clearCurrentDate()">Clear range</button> |
| 48 | + <button v-if="internalModel.length === 2" class="dp__action_button dp__action_cancel" @click="clearCurrentDate()">Clear Range</button> |
40 | 49 | </template>
|
41 | 50 | </VueDatePicker>
|
42 | 51 | </template>
|
0 commit comments