File: D:/web/matomo.circ/plugins/CoreHome/vue/src/DateRangePicker/DateRangePicker.vue
<!--
Matomo - free/libre analytics platform
@link https://matomo.org
@license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
-->
<template>
<div class="dateRangePicker">
<div id="calendarRangeFrom">
<h6>
{{ translate('General_DateRangeFrom') }}
<input
type="text"
id="inputCalendarFrom"
name="inputCalendarFrom"
class="browser-default"
v-model="startDateText"
@keydown="onRangeInputChanged('from', $event)"
@keyup="handleEnterPress($event)"
/>
</h6>
<DatePicker
id="calendarFrom"
:view-date="startDate"
:selected-date-start="fromPickerSelectedDates[0]"
:selected-date-end="fromPickerSelectedDates[1]"
:highlighted-date-start="fromPickerHighlightedDates[0]"
:highlighted-date-end="fromPickerHighlightedDates[1]"
@date-select="setStartRangeDate($event.date)"
@cell-hover="fromPickerHighlightedDates = getNewHighlightedDates($event.date, $event.$cell)"
@cell-hover-leave="fromPickerHighlightedDates = [null, null]"
>
</DatePicker>
</div>
<div id="calendarRangeTo">
<h6>
{{ translate('General_DateRangeTo') }}
<input
type="text"
id="inputCalendarTo"
name="inputCalendarTo"
class="browser-default"
v-model="endDateText"
@keydown="onRangeInputChanged('to', $event)"
@keyup="handleEnterPress($event)"
/>
</h6>
<DatePicker
id="calendarTo"
:view-date="endDate"
:selected-date-start="toPickerSelectedDates[0]"
:selected-date-end="toPickerSelectedDates[1]"
:highlighted-date-start="toPickerHighlightedDates[0]"
:highlighted-date-end="toPickerHighlightedDates[1]"
@date-select="setEndRangeDate($event.date)"
@cell-hover="toPickerHighlightedDates = getNewHighlightedDates($event.date, $event.$cell)"
@cell-hover-leave="toPickerHighlightedDates = [null, null]"
>
</DatePicker>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import DatePicker from '../DatePicker/DatePicker.vue';
import { parseDate, format } from '../Periods/utilities';
import ChangeEvent = JQuery.ChangeEvent;
const DATE_FORMAT = 'YYYY-MM-DD';
interface DateRangePickerState {
fromPickerSelectedDates: (Date|null)[];
toPickerSelectedDates: (Date|null)[];
fromPickerHighlightedDates: (Date|null)[];
toPickerHighlightedDates: (Date|null)[];
startDateText?: string;
endDateText?: string;
startDateInvalid: boolean;
endDateInvalid: boolean;
}
export default defineComponent({
props: {
startDate: String,
endDate: String,
},
components: {
DatePicker,
},
data(): DateRangePickerState {
let startDate = null;
try {
if (this.startDate) {
startDate = parseDate(this.startDate);
}
} catch (e) {
// ignore
}
let endDate = null;
try {
if (this.endDate) {
endDate = parseDate(this.endDate);
}
} catch (e) {
// ignore
}
return {
fromPickerSelectedDates: [startDate, startDate],
toPickerSelectedDates: [endDate, endDate],
fromPickerHighlightedDates: [null, null],
toPickerHighlightedDates: [null, null],
startDateText: this.startDate,
endDateText: this.endDate,
startDateInvalid: false,
endDateInvalid: false,
};
},
emits: ['rangeChange', 'submit'],
watch: {
startDate() {
this.startDateText = this.startDate;
this.setStartRangeDateFromStr(this.startDate);
},
endDate() {
this.endDateText = this.endDate;
this.setEndRangeDateFromStr(this.endDate);
},
},
mounted() {
this.rangeChanged(); // emit with initial range pair
},
methods: {
setStartRangeDate(date: Date) {
this.fromPickerSelectedDates = [date, date];
this.rangeChanged();
},
setEndRangeDate(date: Date) {
this.toPickerSelectedDates = [date, date];
this.rangeChanged();
},
onRangeInputChanged(source: string, event: ChangeEvent) {
setTimeout(() => {
if (source === 'from') {
this.setStartRangeDateFromStr(event.target.value);
} else {
this.setEndRangeDateFromStr(event.target.value);
}
});
},
getNewHighlightedDates(date: Date, $cell: JQuery) {
if ($cell.hasClass('ui-datepicker-unselectable')) {
return null;
}
return [date, date];
},
handleEnterPress($event: KeyboardEvent) {
if ($event.keyCode !== 13) {
return;
}
this.$emit('submit', {
start: this.startDate,
end: this.endDate,
});
},
setStartRangeDateFromStr(dateStr?: string) {
this.startDateInvalid = true;
let startDateParsed: Date|null = null;
try {
if (dateStr && dateStr.length === DATE_FORMAT.length) {
startDateParsed = parseDate(dateStr);
}
} catch (e) {
// ignore
}
if (startDateParsed) {
this.fromPickerSelectedDates = [startDateParsed, startDateParsed];
this.startDateInvalid = false;
this.rangeChanged();
}
},
setEndRangeDateFromStr(dateStr?: string) {
this.endDateInvalid = true;
let endDateParsed: Date|null = null;
try {
if (dateStr && dateStr.length === DATE_FORMAT.length) {
endDateParsed = parseDate(dateStr);
}
} catch (e) {
// ignore
}
if (endDateParsed) {
this.toPickerSelectedDates = [endDateParsed, endDateParsed];
this.endDateInvalid = false;
this.rangeChanged();
}
},
rangeChanged() {
this.$emit('rangeChange', {
start: this.fromPickerSelectedDates[0] ? format(this.fromPickerSelectedDates[0]) : null,
end: this.toPickerSelectedDates[0] ? format(this.toPickerSelectedDates[0]) : null,
});
},
},
});
</script>