2
0
mirror of https://github.com/tenrok/vue2-datepicker.git synced 2026-06-06 16:12:26 +03:00

Merge branch 'origin/dev' into dev

This commit is contained in:
mengxiong10
2020-06-07 11:23:05 +08:00
7 changed files with 98 additions and 14 deletions
+2
View File
@@ -124,6 +124,7 @@ You can also override some of the default locale by `lang`.
| clearable | if false, don't show the clear icon | `boolean` | true |
| confirm | if true, need click the button to change value | `boolean` | false |
| confirm-text | the text of confirm button | `string` | 'OK' |
| multiple | if true, multi-select date | `boolean` | false |
| disabled | disable the component | `boolean` | false |
| disabled-date | specify the date that cannot be selected | `(date) => boolean` | - |
| disabled-time | specify the time that cannot be selected | `(date) => boolean` | - |
@@ -132,6 +133,7 @@ You can also override some of the default locale by `lang`.
| input-class | input classname | `string` | 'mx-input' |
| input-attr | input attrs(eg: { name: 'date', id: 'foo'}) | `object` | — |
| open | open state of picker | `boolean` | - |
| default-panel | default panel of the picker | year\|month | - |
| popup-style | popup style | `object` | — |
| popup-class | popup classes | | — |
| shortcuts | set shortcuts to select | `Array<{text, onClick}>` | - |
+2
View File
@@ -122,6 +122,7 @@ import 'vue2-datepicker/locale/zh-cn';
| clearable | 是否显示清除按钮 | `boolean` | true |
| confirm | 是否需要确认 | `boolean` | false |
| confirm-text | 确认按钮的文字 | `string` | 'OK' |
| multiple | 如果是 true, 可以选择多个日期 | `boolean` | false |
| disabled | 禁用组件 | `boolean` | false |
| disabled-date | 禁止选择的日期 | `(date) => boolean` | - |
| disabled-time | 禁止选择的时间 | `(date) => boolean` | - |
@@ -130,6 +131,7 @@ import 'vue2-datepicker/locale/zh-cn';
| input-class | 输入框的类 | `string` | 'mx-input' |
| input-attr | 输入框的其他属性(eg: { name: 'date', id: 'foo'}) | `object` | — |
| open | 控制弹出层的显示 | `boolean` | - |
| default-panel | 控制打开的面板 | year\|month | - |
| popup-style | 弹出层的样式 | `object` | — |
| popup-class | 弹出层的类 | | — |
| shortcuts | 设置快捷选择 | `Array<{text, onClick}>` | - |
+31
View File
@@ -387,4 +387,35 @@ describe('DatePicker', () => {
input.trigger('change');
expect(wrapper.emitted().input).toEqual([[[text, text]], [[text, text]], [[text, text]]]);
});
it('prop: multiple', () => {
const value = [new Date(2020, 5, 6), new Date(2020, 6, 7)];
wrapper = mount(DatePicker, {
propsData: {
multiple: true,
open: true,
value,
},
});
wrapper.find('.mx-date-row .active').trigger('click');
expect(wrapper.emitted().input[0][0]).toEqual(value.slice(0, 1));
wrapper.find('[title="2020-07-15"]').trigger('click');
expect(wrapper.emitted().input[1][0]).toEqual(value.concat(new Date(2020, 6, 15)));
});
it('prop: invalid multiple', () => {
wrapper = shallowMount(DatePicker, {
propsData: {
multiple: true,
range: true,
},
});
const { vm } = wrapper;
expect(vm.validMultipleType).toBe(false);
wrapper.setProps({
range: false,
type: 'datetime',
});
expect(vm.validMultipleType).toBe(false);
});
});
-2
View File
@@ -38,10 +38,8 @@ export default {
data() {
return {
value1: new Date(),
value2: new Date(),
value3: '',
value4: '',
value5: '',
};
},
methods: {
+5 -4
View File
@@ -240,7 +240,8 @@ export default {
initCalendar() {
let calendarDate = this.calendar;
if (!isValidDate(calendarDate)) {
calendarDate = getValidDate(this.innerValue[0], this.defaultValue);
const { length } = this.innerValue;
calendarDate = getValidDate(length > 0 ? this.innerValue[length - 1] : this.defaultValue);
}
this.innerCalendar = calendarDate;
},
@@ -249,7 +250,7 @@ export default {
},
emitDate(date, type) {
if (!this.isDisabled(date)) {
this.$emit('select', date, type);
this.$emit('select', date, type, this.innerValue);
// someone need get the first selected date to set range value. (#429)
this.dispatch('DatePicker', 'pick', date, type);
}
@@ -287,7 +288,7 @@ export default {
const nextCalendar = setYear(this.innerCalendar, year);
this.updateCalendar(nextCalendar, 'year');
this.handelPanelChange('month');
if (this.partialUpdate && this.innerValue[0]) {
if (this.partialUpdate && this.innerValue.length === 1) {
const date = setYear(this.innerValue[0], year);
this.emitDate(date, 'year');
}
@@ -301,7 +302,7 @@ export default {
const nextCalendar = setMonth(this.innerCalendar, month);
this.updateCalendar(nextCalendar, 'month');
this.handelPanelChange('date');
if (this.partialUpdate && this.innerValue[0]) {
if (this.partialUpdate && this.innerValue.length === 1) {
const date = setMonth(setYear(this.innerValue[0], this.calendarYear), month);
this.emitDate(date, 'month');
}
+47 -7
View File
@@ -90,7 +90,7 @@
<script>
import { parse, format, getWeek } from 'date-format-parse';
import { isValidDate, isValidRangeDate } from './util/date';
import { isValidDate, isValidRangeDate, isValidDates } from './util/date';
import { pick, isObject, mergeDeep } from './util/base';
import { getLocale, getLocaleFieldValue } from './locale';
import Popup from './popup';
@@ -157,9 +157,15 @@ export default {
type: Boolean,
default: false,
},
multiple: {
type: Boolean,
default: false,
},
rangeSeparator: {
type: String,
default: ' ~ ',
default() {
return this.multiple ? ',' : ' ~ ';
},
},
lang: {
type: [String, Object],
@@ -222,6 +228,9 @@ export default {
type: String,
default: 'OK',
},
renderInputText: {
type: Function,
},
shortcuts: {
type: Array,
validator(value) {
@@ -262,6 +271,10 @@ export default {
},
innerValue() {
let { value } = this;
if (this.validMultipleType) {
value = Array.isArray(value) ? value : [];
return value.map(this.value2date);
}
if (this.range) {
value = Array.isArray(value) ? value.slice(0, 2) : [null, null];
return value.map(this.value2date);
@@ -272,6 +285,9 @@ export default {
if (this.userInput !== null) {
return this.userInput;
}
if (typeof this.renderInputText === 'function') {
return this.renderInputText(this.innerValue);
}
if (!this.isValidValue(this.innerValue)) {
return '';
}
@@ -290,6 +306,10 @@ export default {
}
return getLocale(this.lang);
},
validMultipleType() {
const types = ['date', 'month', 'year'];
return this.multiple && !this.range && types.indexOf(this.type) !== -1;
},
},
watch: {
innerValue: {
@@ -368,14 +388,30 @@ export default {
}
},
isValidValue(value) {
const validate = this.range ? isValidRangeDate : isValidDate;
return validate(value);
if (this.validMultipleType) {
return isValidDates(value);
}
if (this.range) {
return isValidRangeDate(value);
}
return isValidDate(value);
},
handleSelectDate(val, type) {
handleMultipleDates(date, dates) {
if (this.validMultipleType && dates) {
const nextDates = dates.filter(v => v.getTime() !== date.getTime());
if (nextDates.length === dates.length) {
nextDates.push(date);
}
return nextDates;
}
return date;
},
handleSelectDate(val, type, dates) {
val = this.handleMultipleDates(val, dates);
if (this.confirm) {
this.currentValue = val;
} else {
this.emitValue(val, type);
this.emitValue(val, this.validMultipleType ? `multiple-${type}` : type);
}
},
handleClear() {
@@ -421,9 +457,13 @@ export default {
return;
}
let date;
if (this.range) {
if (this.validMultipleType) {
date = text.split(this.rangeSeparator).map(v => this.parseDate(v.trim(), this.format));
} else if (this.range) {
let arr = text.split(this.rangeSeparator);
if (arr.length !== 2) {
// Maybe the separator during the day is the same as the separator for the date
// eg: 2019-10-09-2020-01-02
arr = text.split(this.rangeSeparator.trim());
}
date = arr.map(v => this.parseDate(v.trim(), this.format));
+11 -1
View File
@@ -15,9 +15,19 @@ export function isValidRangeDate(date) {
return Array.isArray(date) && date.length === 2 && date.every(isValidDate) && date[0] <= date[1];
}
export function isValidDates(dates) {
return Array.isArray(dates) && dates.every(isValidDate);
}
export function getValidDate(value, ...backup) {
const date = new Date(value);
return isValidDate(date) ? date : getValidDate(...backup);
if (isValidDate(date)) {
return date;
}
if (backup.length) {
return getValidDate(...backup);
}
return new Date();
}
export function assignTime(target, source) {