Description
Describe the bug
I'm trying to limit date range dynamically on the fly, to visualize user real range limit.
I'm don't want block user selection via RangeConfig::maxRange
In this case user select first date and can't click on date more than maxRange
.
Instead this I move start date closer to end date in calendar on the fly.
When user select any range I check range in @internal-model-change
and patch start date.
User at same time can see in calendar this limit.
To Reproduce
On clean setup use this code example:
Link to test stackblitz
<template>
<div>
<Datepicker
v-model="date"
ref="datePicker"
:ui="{ input: 'formControl' }"
hide-input-icon
:multi-calendars="datePickerMultiCalendar"
@update:model-value="checkDateRange"
@internal-model-change="limitDateRange"
tabindex="0"
auto-position="bottom"
month-name-format="long"
:month-change-on-arrows="false"
:model-auto="true"
:range="{ partialRange: true }"
locale="en"
format="dd.MM.yyyy"
:min-date="minDate"
:clearable="false"
:enable-time-picker="false"
:month-change-on-scroll="false"
:config="{
noSwipe: true,
onClickOutside: () => false,
mobileBreakpoint: 600,
}"
/>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import { subDays } from 'date-fns';
import Datepicker from '@vuepic/vue-datepicker';
import '@vuepic/vue-datepicker/dist/main.css';
const datePicker = ref(null);
const date = ref();
const datePickerMultiCalendar = ref(2);
// 1 calendar in mobile view, 2 for Desktop
function handleDatePickerSize() {
datePickerMultiCalendar.value = !window
? 2
: window.innerWidth > 600
? 2
: false;
}
handleDatePickerSize();
onMounted(() => {
window.addEventListener('resize', handleDatePickerSize, { passive: true });
});
onBeforeUnmount(() => {
window.removeEventListener('resize', handleDatePickerSize);
});
function checkDateRange() {
if (!date.value?.length) {
date.value = [date.value, date.value];
}
}
// Limit user range no more 7 days can select. Visualize it on calendar at same time on select.
// RangeConfig::maxRange is not user friendly
// :model-auto="true" must be set, beacuse we allow user to select one date and convert to range later
// date = [date, date]
const limitDateRange = (date) => {
// Do something
if (!date?.length || date.length === 1) {
return;
}
let startDate = date[0];
const endDate = date[1];
const limitDays = 7;
const testDateStart = subDays(endDate, limitDays - 1);
if (startDate < testDateStart) {
date[0] = testDateStart;
}
};
// See problem in code
// O = () => a.value[1] ? X() : oe(Ne(a.value[0])), K = () => (a.value || []).map((l) => oe(l)), fe = (l = false) => (l || S(), t.modelAuto ? O() : y.value.enabled ? K() : Array.isArray(a.value) ? ra(() => X(), u.value.enabled) : oe(Ne(a.value))), me = (l) => !l || Array.isArray(l) && !l.length ? null : t.timePicker ? k(Ne(l)) : t.monthPicker ? z(Ne(l)) : t.yearPicker ? f(Ne(l)) : y.value.enabled ? q(Ne(l)) : t.weekPicker ? ee(Ne(l)) : x(Ne(l)), v = (l) => {
// const D = me(l);
// za(Ne(D)) ? (a.value = Ne(D), W()) : (a.value = null, _.value = "");
//}
// When @internal-model-change trying to get "Second parameter is internal model-value in v-model format"
// watch(
// a,
// () => {
// typeof t.onInternalModelChange == "function" && e("internal-model-change", a.value, R(true) <--- HERE);
// },
// { deep: true }
//)
</script>
Expected behavior
Calendar can dynamically visualize new range applied in @internal-model-change="limitDateRange"
The feature @internal-model-change
working as declared in docs
The second parameter vModel
is resolving in module correctly
@internal-model-change="(internalModel, vModel) => console.log('internal-model-change', internalModel, vModel)"
Desktop & mobile (please complete the following information):
- Browser - any browser
- Library version >= v8.0.0