diff --git a/src/datetime-picker/DatePicker.js b/src/datetime-picker/DatePicker.js index a2d174426..690e2e31c 100644 --- a/src/datetime-picker/DatePicker.js +++ b/src/datetime-picker/DatePicker.js @@ -132,8 +132,49 @@ export default createComponent({ return null; } - value = Math.max(value, this.minDate.getTime()); - value = Math.min(value, this.maxDate.getTime()); + let minDate = new Date(this.minDate); + let maxDate = new Date(this.maxDate); + const dateMethods = { + year: 'getFullYear', + month: 'getMonth', + day: 'getDate', + hour: 'getHours', + minute: 'getMinutes', + }; + if (this.originColumns) { + const dateColumns = this.originColumns.map(({ type, values }, index) => { + const { range } = this.ranges[index]; + const minDateVal = minDate[dateMethods[type]](); + const maxDateVal = maxDate[dateMethods[type]](); + const min = type === 'month' ? +values[0] - 1 : +values[0]; + const max = + type === 'month' + ? +values[values.length - 1] - 1 + : +values[values.length - 1]; + + return { + type, + values: [ + minDateVal < range[0] ? Math.max(minDateVal, min) : min || minDateVal, + maxDateVal > range[1] ? Math.min(maxDateVal, max) : max || maxDateVal, + ] + }; + }); + + if (this.type === 'month-day') { + const year = (this.innerValue || this.minDate).getFullYear(); + dateColumns.unshift({ type: 'year', values: [year, year] }); + } + + const dates = Object.keys(dateMethods).map((type) => + dateColumns.filter(item => item.type === type)[0]?.values + ).filter((item) => item); + minDate = new Date(...dates.map((val) => getTrueValue(val[0]))); + maxDate = new Date(...dates.map((val) => getTrueValue(val[1]))); + } + + value = Math.max(value, minDate.getTime()); + value = Math.min(value, maxDate.getTime()); return new Date(value); }, @@ -193,7 +234,7 @@ export default createComponent({ let month; let day; if (type === 'month-day') { - year = (this.innerValue ? this.innerValue : this.minDate).getFullYear(); + year = (this.innerValue || this.minDate).getFullYear(); month = getValue('month'); day = getValue('day'); } else { diff --git a/src/datetime-picker/test/date-picker.spec.js b/src/datetime-picker/test/date-picker.spec.js index 360e23085..fe6e1f80d 100644 --- a/src/datetime-picker/test/date-picker.spec.js +++ b/src/datetime-picker/test/date-picker.spec.js @@ -226,7 +226,7 @@ test('v-model', async () => { data() { return { date: null, - minDate: new Date(2030, 0, 0, 0, 3) + minDate: new Date(2030, 0, 0, 0, 3), }; }, }); @@ -263,7 +263,7 @@ test('dynamic set min-date then emit correct value', async () => { return { date: defaultValue, minDate: new Date(2010, 0, 1, 10, 30), - } + }; }, mounted() { this.minDate = defaultValue; @@ -331,3 +331,86 @@ test('dynamic set max-date then emit correct value', async () => { new Date(2019, 10, 10, 10, 10) ); }); + +test('should value correctly when using filter and select over min date', async () => { + const minDate = new Date(2010, 0, 1, 0, 21); + const maxDate = new Date(2020, 0, 1, 20, 42); + + const wrapper = mount({ + template: ` + + `, + + data() { + return { + value: new Date(minDate), + minDate, + maxDate, + }; + }, + + methods: { + filter(type, values) { + if (type === 'minute') { + return values.filter((value) => value % 10 === 0); + } + + return values; + }, + }, + }); + + const confirm = wrapper.find('.van-picker__confirm'); + await later(); + confirm.trigger('click'); + expect(wrapper.emitted('confirm')[0][0]).toEqual(new Date(2010, 0, 1, 0, 30)); + + await later(); + triggerDrag(wrapper.findAll('.van-picker-column').at(3), 0, -300); + wrapper.findAll('.van-picker-column ul').at(3).trigger('transitionend'); + await later(); + triggerDrag(wrapper.findAll('.van-picker-column').at(4), 0, 300); + wrapper.findAll('.van-picker-column ul').at(3).trigger('transitionend'); + await later(); + confirm.trigger('click'); + expect(wrapper.emitted('confirm')[1][0]).toEqual(new Date(2010, 0, 1, 23, 0)); + + await later(); + triggerDrag(wrapper.findAll('.van-picker-column').at(3), 0, 300); + wrapper.findAll('.van-picker-column ul').at(3).trigger('transitionend'); + await later(); + confirm.trigger('click'); + expect(wrapper.emitted('confirm')[2][0]).toEqual(new Date(2010, 0, 1, 0, 30)); + + await later(); + wrapper.setData({ value: maxDate }); + confirm.trigger('click'); + expect(wrapper.emitted('confirm')[3][0]).toEqual( + new Date(2020, 0, 1, 20, 40) + ); + + await later(); + triggerDrag(wrapper.findAll('.van-picker-column').at(3), 0, 300); + wrapper.findAll('.van-picker-column ul').at(3).trigger('transitionend'); + await later(); + triggerDrag(wrapper.findAll('.van-picker-column').at(4), 0, -300); + wrapper.findAll('.van-picker-column ul').at(3).trigger('transitionend'); + await later(); + confirm.trigger('click'); + expect(wrapper.emitted('confirm')[4][0]).toEqual(new Date(2020, 0, 1, 0, 50)); + + await later(); + triggerDrag(wrapper.findAll('.van-picker-column').at(3), 0, -300); + wrapper.findAll('.van-picker-column ul').at(3).trigger('transitionend'); + await later(); + confirm.trigger('click'); + expect(wrapper.emitted('confirm')[5][0]).toEqual( + new Date(2020, 0, 1, 20, 40) + ); +});