mirror of
https://github.com/tenrok/vue2-datepicker.git
synced 2026-06-23 19:00:36 +03:00
feat: add prop partial-update
Determine whether update date when select year of month. The default value is false.
This commit is contained in:
@@ -121,6 +121,7 @@ You can also override some of the default locale by `lang`.
|
|||||||
| popup-class | popup classes | | — |
|
| popup-class | popup classes | | — |
|
||||||
| shortcuts | set shortcuts to select | `Array<{text, onClick}>` | - |
|
| shortcuts | set shortcuts to select | `Array<{text, onClick}>` | - |
|
||||||
| title-format | format of the tooltip in calendar cell | [token](#token) | 'YYYY-MM-DD' |
|
| title-format | format of the tooltip in calendar cell | [token](#token) | 'YYYY-MM-DD' |
|
||||||
|
| partial-update | whether update date when select year or month | `boolean` | false |
|
||||||
| range-separator | text of range separator | `string` | ' ~ ' |
|
| range-separator | text of range separator | `string` | ' ~ ' |
|
||||||
| show-week-number | determine whether show week number | `boolean` | false |
|
| show-week-number | determine whether show week number | `boolean` | false |
|
||||||
| hour-step | interval between hours in time picker | 1 - 60 | 1 |
|
| hour-step | interval between hours in time picker | 1 - 60 | 1 |
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ import 'vue2-datepicker/locale/zh-cn';
|
|||||||
| popup-class | 弹出层的类 | | — |
|
| popup-class | 弹出层的类 | | — |
|
||||||
| shortcuts | 设置快捷选择 | `Array<{text, onClick}>` | - |
|
| shortcuts | 设置快捷选择 | `Array<{text, onClick}>` | - |
|
||||||
| title-format | 日历单元格的 tooltip | [token](#token) | 'YYYY-MM-DD' |
|
| title-format | 日历单元格的 tooltip | [token](#token) | 'YYYY-MM-DD' |
|
||||||
|
| partial-update | 是否更新日期当选择年或月的时候 | `boolean` | false |
|
||||||
| range-separator | 范围分隔符 | `string` | ' ~ ' |
|
| range-separator | 范围分隔符 | `string` | ' ~ ' |
|
||||||
| show-week-number | 是否显示星期数字 | `boolean` | false |
|
| show-week-number | 是否显示星期数字 | `boolean` | false |
|
||||||
| hour-step | 小时列的间隔 | 1 - 60 | 1 |
|
| hour-step | 小时列的间隔 | 1 - 60 | 1 |
|
||||||
|
|||||||
@@ -64,43 +64,6 @@ describe('CalendarPanel', () => {
|
|||||||
expect(td.classes()).toContain('active');
|
expect(td.classes()).toContain('active');
|
||||||
});
|
});
|
||||||
|
|
||||||
const renderType = type => {
|
|
||||||
it(`prop: type=${type}`, () => {
|
|
||||||
wrapper = shallowMount(CalendarPanel, {
|
|
||||||
propsData: {
|
|
||||||
type,
|
|
||||||
value: new Date(2019, 9, 1, 10),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(wrapper.element).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
['date', 'month', 'year'].forEach(renderType);
|
|
||||||
|
|
||||||
it('prop: disabledDate', () => {
|
|
||||||
const disabledDate = date => {
|
|
||||||
return date < new Date(2019, 9, 1) || date > new Date(2019, 9, 20);
|
|
||||||
};
|
|
||||||
wrapper = mount(CalendarPanel, {
|
|
||||||
propsData: {
|
|
||||||
value: new Date(2019, 9, 4),
|
|
||||||
disabledDate,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const tds = wrapper.findAll('.mx-table-date td');
|
|
||||||
for (let i = 0; i < 42; i++) {
|
|
||||||
const td = tds.at(i);
|
|
||||||
const classes = td.classes();
|
|
||||||
if (i < 2 || i > 21) {
|
|
||||||
expect(classes).toContain('disabled');
|
|
||||||
} else {
|
|
||||||
expect(classes).not.toContain('disabled');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tds.at(1).trigger('click');
|
|
||||||
expect(wrapper.emitted().select).toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('feat: click prev/next month', () => {
|
it('feat: click prev/next month', () => {
|
||||||
wrapper = shallowMount(CalendarPanel);
|
wrapper = shallowMount(CalendarPanel);
|
||||||
|
|
||||||
@@ -167,4 +130,61 @@ describe('CalendarPanel', () => {
|
|||||||
lastBtn.trigger('click');
|
lastBtn.trigger('click');
|
||||||
expect(vm.calendarDecade).toBe(2000);
|
expect(vm.calendarDecade).toBe(2000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const renderType = type => {
|
||||||
|
it(`prop: type=${type}`, () => {
|
||||||
|
wrapper = shallowMount(CalendarPanel, {
|
||||||
|
propsData: {
|
||||||
|
type,
|
||||||
|
value: new Date(2019, 9, 1, 10),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(wrapper.element).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
['date', 'month', 'year'].forEach(renderType);
|
||||||
|
|
||||||
|
it('prop: disabledDate', () => {
|
||||||
|
const disabledDate = date => {
|
||||||
|
return date < new Date(2019, 9, 1) || date > new Date(2019, 9, 20);
|
||||||
|
};
|
||||||
|
wrapper = mount(CalendarPanel, {
|
||||||
|
propsData: {
|
||||||
|
value: new Date(2019, 9, 4),
|
||||||
|
disabledDate,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const tds = wrapper.findAll('.mx-table-date td');
|
||||||
|
for (let i = 0; i < 42; i++) {
|
||||||
|
const td = tds.at(i);
|
||||||
|
const classes = td.classes();
|
||||||
|
if (i < 2 || i > 21) {
|
||||||
|
expect(classes).toContain('disabled');
|
||||||
|
} else {
|
||||||
|
expect(classes).not.toContain('disabled');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tds.at(1).trigger('click');
|
||||||
|
expect(wrapper.emitted().select).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('prop: partialUpdate', () => {
|
||||||
|
wrapper = mount(CalendarPanel, {
|
||||||
|
propsData: {
|
||||||
|
value: new Date(2019, 9, 4),
|
||||||
|
partialUpdate: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
wrapper
|
||||||
|
.findAll('.mx-table-year td > div')
|
||||||
|
.at(0)
|
||||||
|
.trigger('click');
|
||||||
|
expect(wrapper.emitted().select[0][0]).toEqual(new Date(2010, 9, 4));
|
||||||
|
wrapper.setProps({ value: new Date(2010, 9, 4) });
|
||||||
|
wrapper
|
||||||
|
.findAll('.mx-table-month td > div')
|
||||||
|
.at(0)
|
||||||
|
.trigger('click');
|
||||||
|
expect(wrapper.emitted().select[1][0]).toEqual(new Date(2010, 0, 4));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -63,4 +63,17 @@ describe('CalendarRange', () => {
|
|||||||
await flushPromises();
|
await flushPromises();
|
||||||
expect(wrapper.vm.calendars).toEqual([new Date(2019, 6, 1), new Date(2019, 7, 1)]);
|
expect(wrapper.vm.calendars).toEqual([new Date(2019, 6, 1), new Date(2019, 7, 1)]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('partialUpdate should be false', () => {
|
||||||
|
wrapper = mount(CalendarRange, {
|
||||||
|
propsData: {
|
||||||
|
partialUpdate: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const panels = wrapper.findAll(CalendarPanel);
|
||||||
|
const startPanel = panels.at(0);
|
||||||
|
const endPanel = panels.at(1);
|
||||||
|
expect(startPanel.vm.partialUpdate).toBe(false);
|
||||||
|
expect(endPanel.vm.partialUpdate).toBe(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ describe('DatetimePanel', () => {
|
|||||||
it('feat: click date', () => {
|
it('feat: click date', () => {
|
||||||
wrapper = mount(DatetimePanel, {
|
wrapper = mount(DatetimePanel, {
|
||||||
propsData: {
|
propsData: {
|
||||||
|
type: 'datetime',
|
||||||
defaultValue: new Date(2019, 9, 1, 12),
|
defaultValue: new Date(2019, 9, 1, 12),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ describe('DatetimeRange', () => {
|
|||||||
wrapper = mount(DatetimeRange, {
|
wrapper = mount(DatetimeRange, {
|
||||||
sync: false,
|
sync: false,
|
||||||
propsData: {
|
propsData: {
|
||||||
|
type: 'datetime',
|
||||||
value: [new Date(2019, 9, 4, 18), new Date(2019, 9, 6, 12)],
|
value: [new Date(2019, 9, 4, 18), new Date(2019, 9, 6, 12)],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -146,6 +146,11 @@ export default {
|
|||||||
default: 'YYYY-MM-DD',
|
default: 'YYYY-MM-DD',
|
||||||
},
|
},
|
||||||
calendar: Date,
|
calendar: Date,
|
||||||
|
// update date when select year or month
|
||||||
|
partialUpdate: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
const panels = ['date', 'year', 'month'];
|
const panels = ['date', 'year', 'month'];
|
||||||
@@ -252,6 +257,10 @@ export default {
|
|||||||
const nextCalendar = setYear(this.innerCalendar, year);
|
const nextCalendar = setYear(this.innerCalendar, year);
|
||||||
this.updateCalendar(nextCalendar);
|
this.updateCalendar(nextCalendar);
|
||||||
this.handelPanelChange('month');
|
this.handelPanelChange('month');
|
||||||
|
if (this.partialUpdate && this.innerValue[0]) {
|
||||||
|
const date = setYear(this.innerValue[0], year);
|
||||||
|
this.emitDate(date, 'year');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleSelectMonth(month) {
|
handleSelectMonth(month) {
|
||||||
@@ -262,6 +271,10 @@ export default {
|
|||||||
const nextCalendar = setMonth(this.innerCalendar, month);
|
const nextCalendar = setMonth(this.innerCalendar, month);
|
||||||
this.updateCalendar(nextCalendar);
|
this.updateCalendar(nextCalendar);
|
||||||
this.handelPanelChange('date');
|
this.handelPanelChange('date');
|
||||||
|
if (this.partialUpdate && this.innerValue[0]) {
|
||||||
|
const date = setMonth(setYear(this.innerValue[0], this.calendarYear), month);
|
||||||
|
this.emitDate(date, 'month');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleSelectDate(day) {
|
handleSelectDate(day) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import CalendarPanel from './calendar-panel';
|
|||||||
import { getValidDate, isValidDate, isValidRangeDate } from '../util/date';
|
import { getValidDate, isValidDate, isValidRangeDate } from '../util/date';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
name: 'CalendarRange',
|
||||||
components: { CalendarPanel },
|
components: { CalendarPanel },
|
||||||
props: {
|
props: {
|
||||||
...CalendarPanel.props,
|
...CalendarPanel.props,
|
||||||
@@ -107,6 +108,8 @@ export default {
|
|||||||
calendar,
|
calendar,
|
||||||
value: this.innerValue,
|
value: this.innerValue,
|
||||||
getClasses: this.getRangeClasses,
|
getClasses: this.getRangeClasses,
|
||||||
|
// don't update when range is true
|
||||||
|
partialUpdate: false,
|
||||||
};
|
};
|
||||||
const on = {
|
const on = {
|
||||||
select: this.handleSelect,
|
select: this.handleSelect,
|
||||||
|
|||||||
@@ -42,16 +42,14 @@ export default {
|
|||||||
handleSelect(date, type) {
|
handleSelect(date, type) {
|
||||||
if (type === 'date') {
|
if (type === 'date') {
|
||||||
this.openTimePanel();
|
this.openTimePanel();
|
||||||
const time = isValidDate(this.value) ? this.value : new Date(this.defaultValue);
|
}
|
||||||
const datetime = new Date(date);
|
const time = isValidDate(this.value) ? this.value : new Date(this.defaultValue);
|
||||||
datetime.setHours(time.getHours(), time.getMinutes(), time.getSeconds());
|
const datetime = new Date(date);
|
||||||
if (this.disabledTime(new Date(datetime))) {
|
datetime.setHours(time.getHours(), time.getMinutes(), time.getSeconds());
|
||||||
this.currentValue = date;
|
if (this.disabledTime(new Date(datetime))) {
|
||||||
} else {
|
this.currentValue = date;
|
||||||
this.emitDate(datetime, type);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
this.emitDate(date, type);
|
this.emitDate(datetime, type);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -59,6 +57,7 @@ export default {
|
|||||||
const calendarProps = {
|
const calendarProps = {
|
||||||
props: {
|
props: {
|
||||||
...pick(this, Object.keys(CalendarPanel.props)),
|
...pick(this, Object.keys(CalendarPanel.props)),
|
||||||
|
type: 'date',
|
||||||
value: this.currentValue,
|
value: this.currentValue,
|
||||||
},
|
},
|
||||||
on: {
|
on: {
|
||||||
@@ -72,7 +71,7 @@ export default {
|
|||||||
value: this.currentValue,
|
value: this.currentValue,
|
||||||
},
|
},
|
||||||
on: {
|
on: {
|
||||||
select: this.handleSelect,
|
select: this.emitDate,
|
||||||
'title-click': this.closeTimePanel,
|
'title-click': this.closeTimePanel,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -42,22 +42,20 @@ export default {
|
|||||||
handleSelect(dates, type) {
|
handleSelect(dates, type) {
|
||||||
if (type === 'date') {
|
if (type === 'date') {
|
||||||
this.openTimePanel();
|
this.openTimePanel();
|
||||||
let datetimes = dates.map((v, i) => {
|
}
|
||||||
const datetime = new Date(v);
|
let datetimes = dates.map((v, i) => {
|
||||||
const time = isValidRangeDate(this.value) ? this.value[i] : new Date(this.defaultValue);
|
const datetime = new Date(v);
|
||||||
datetime.setHours(time.getHours(), time.getMinutes(), time.getSeconds());
|
const time = isValidRangeDate(this.value) ? this.value[i] : new Date(this.defaultValue);
|
||||||
return datetime;
|
datetime.setHours(time.getHours(), time.getMinutes(), time.getSeconds());
|
||||||
});
|
return datetime;
|
||||||
if (datetimes[1].getTime() < datetimes[0].getTime()) {
|
});
|
||||||
datetimes = [datetimes[0], datetimes[0]];
|
if (datetimes[1].getTime() < datetimes[0].getTime()) {
|
||||||
}
|
datetimes = [datetimes[0], datetimes[0]];
|
||||||
if (datetimes.some(this.disabledTime)) {
|
}
|
||||||
this.currentValue = dates;
|
if (datetimes.some(this.disabledTime)) {
|
||||||
} else {
|
this.currentValue = dates;
|
||||||
this.emitDate(datetimes, type);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
this.emitDate(dates, type);
|
this.emitDate(datetimes, type);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -65,6 +63,7 @@ export default {
|
|||||||
const calendarProps = {
|
const calendarProps = {
|
||||||
props: {
|
props: {
|
||||||
...pick(this, Object.keys(CalendarRange.props)),
|
...pick(this, Object.keys(CalendarRange.props)),
|
||||||
|
type: 'date',
|
||||||
value: this.currentValue,
|
value: this.currentValue,
|
||||||
},
|
},
|
||||||
on: {
|
on: {
|
||||||
@@ -78,7 +77,7 @@ export default {
|
|||||||
showTimeHeader: true,
|
showTimeHeader: true,
|
||||||
},
|
},
|
||||||
on: {
|
on: {
|
||||||
select: this.handleSelect,
|
select: this.emitDate,
|
||||||
'title-click': this.closeTimePanel,
|
'title-click': this.closeTimePanel,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user