DatePicker: extract time and date format from format prop (#10174)

pull/10267/head
remizovvv 2018-03-20 10:04:44 +04:00 committed by 杨奕
parent d7c4fd2632
commit bfa44e8b4f
6 changed files with 137 additions and 23 deletions

View File

@ -278,7 +278,7 @@ DateTimePicker is derived from DatePicker and TimePicker. For a more detailed ex
| end-placeholder | placeholder for the end date in range mode | string | — | — |
| time-arrow-control | whether to pick time using arrow buttons | boolean | — | false |
| type | type of the picker | string | year/month/date/datetime/ week/datetimerange/daterange | date |
| format | format of the displayed value in the input box | string | see [date formats](#/en-US/component/date-picker#date-formats) | yyyy-MM-dd |
| format | format of the displayed value in the input box | string | see [date formats](#/en-US/component/date-picker#date-formats) | yyyy-MM-dd HH:mm:ss |
| align | alignment | left/center/right | left |
| popper-class | custom class name for DateTimePicker's dropdown | string | — | — |
| picker-options | additional options, check the table below | object | — | {} |

View File

@ -193,7 +193,9 @@
prevYear,
nextYear,
prevMonth,
nextMonth
nextMonth,
extractDateFormat,
extractTimeFormat
} from '../util';
import Clickoutside from 'element-ui/src/utils/clickoutside';
import Locale from 'element-ui/src/mixins/locale';
@ -272,37 +274,37 @@
},
minVisibleDate() {
return this.minDate ? formatDate(this.minDate) : '';
return this.minDate ? formatDate(this.minDate, this.dateFormat) : '';
},
maxVisibleDate() {
return (this.maxDate || this.minDate) ? formatDate(this.maxDate || this.minDate) : '';
return (this.maxDate || this.minDate) ? formatDate(this.maxDate || this.minDate, this.dateFormat) : '';
},
minVisibleTime() {
return this.minDate ? formatDate(this.minDate, 'HH:mm:ss') : '';
return this.minDate ? formatDate(this.minDate, this.timeFormat) : '';
},
maxVisibleTime() {
return (this.maxDate || this.minDate) ? formatDate(this.maxDate || this.minDate, 'HH:mm:ss') : '';
return (this.maxDate || this.minDate) ? formatDate(this.maxDate || this.minDate, this.timeFormat) : '';
},
timeFormat() {
if (this.format) {
return extractTimeFormat(this.format);
} else {
return 'HH:mm:ss';
}
},
dateFormat() {
if (this.format) {
return this.format.replace('HH:mm', '').replace(':ss', '').trim();
return extractDateFormat(this.format);
} else {
return 'yyyy-MM-dd';
}
},
timeFormat() {
if (this.format && this.format.indexOf('ss') === -1) {
return 'HH:mm';
} else {
return 'HH:mm:ss';
}
},
enableMonthArrow() {
const nextMonth = (this.leftMonth + 1) % 12;
const yearOffset = this.leftMonth + 1 >= 12 ? 1 : 0;

View File

@ -153,7 +153,9 @@
nextYear,
prevMonth,
nextMonth,
changeYearMonthAndClampDate
changeYearMonthAndClampDate,
extractDateFormat,
extractTimeFormat
} from '../util';
import Clickoutside from 'element-ui/src/utils/clickoutside';
import Locale from 'element-ui/src/mixins/locale';
@ -215,7 +217,6 @@
const value = value => {this.$refs.timepicker.value = value;};
const date = date => {this.$refs.timepicker.date = date;};
this.$watch('format', format);
this.$watch('value', value);
this.$watch('date', date);
@ -523,8 +524,8 @@
},
timeFormat() {
if (this.format && this.format.indexOf('ss') === -1) {
return 'HH:mm';
if (this.format) {
return extractTimeFormat(this.format);
} else {
return 'HH:mm:ss';
}
@ -532,7 +533,7 @@
dateFormat() {
if (this.format) {
return this.format.replace('HH', '').replace(/[^a-zA-Z]*mm/, '').replace(/[^a-zA-Z]*ss/, '').trim();
return extractDateFormat(this.format);
} else {
return 'yyyy-MM-dd';
}

View File

@ -747,9 +747,9 @@ export default {
this.picker.selectionMode = this.selectionMode;
this.picker.unlinkPanels = this.unlinkPanels;
this.picker.arrowControl = this.arrowControl || this.timeArrowControl || false;
if (this.format) {
this.picker.format = this.format;
}
this.$watch('format', (format) => {
this.picker.format = format;
});
const updateOptions = () => {
const options = this.pickerOptions;
@ -770,6 +770,11 @@ export default {
this.picker[option] = options[option];
}
}
// main format must prevail over undocumented pickerOptions.format
if (this.format) {
this.picker.format = this.format;
}
};
updateOptions();
this.unwatchPickerOptions = this.$watch('pickerOptions', () => updateOptions(), { deep: true });

View File

@ -215,3 +215,16 @@ export const nextYear = function(date, amount = 1) {
const month = date.getMonth();
return changeYearMonthAndClampDate(date, year + amount, month);
};
export const extractDateFormat = function(format) {
return format
.replace(/\W?m{1,2}|\W?ZZ/g, '')
.replace(/\W?h{1,2}|\W?s{1,3}|\W?a/gi, '')
.trim();
};
export const extractTimeFormat = function(format) {
return format
.replace(/\W?D{1,2}|\W?Do|\W?d{1,4}|\W?M{1,4}|\W?y{2,4}/g, '')
.trim();
};

View File

@ -967,6 +967,49 @@ describe('DatePicker', () => {
expect(vm.picker.$el.querySelector('.el-time-panel')).to.ok;
});
it('both picker show correct formated value (extract date-format and time-format from format property)', done => {
vm = createVue({
template: '<el-date-picker type="datetime" v-model="value" :format="format" :pickerOptions="pickerOptions" ref="compo" />',
data() {
return {
value: new Date(2018, 2, 5, 10, 15, 24),
format: 'yyyy/MM/dd hh:mm A',
pickerOptions: null
};
}
}, true);
const input = vm.$refs.compo.$el.querySelector('input');
input.blur();
input.focus();
setTimeout(_ => {
const datePanel = vm.$refs.compo.picker;
const dateInput = datePanel.$el.querySelector('.el-date-picker__time-header > span:nth-child(1) input');
const timeInput = datePanel.$el.querySelector('.el-date-picker__time-header > span:nth-child(2) input');
timeInput.focus();
setTimeout(_ => {
// both input shows correct value
expect(dateInput.value).to.equal('2018/03/05');
expect(timeInput.value).to.equal('10:15 AM');
// change main format
vm.format = 'd-M-yy hh a';
setTimeout(_ => {
expect(dateInput.value).to.equal('5-3-18');
expect(timeInput.value).to.equal('10 am');
// change not documented pickerOptions.format mustn't change picker format
vm.pickerOptions = { format: 'yyyy-MM-dd HH:mm:ss'};
setTimeout(_ => {
expect(dateInput.value).to.equal('5-3-18');
expect(timeInput.value).to.equal('10 am');
done();
}, DELAY);
}, DELAY);
}, DELAY);
}, DELAY);
});
it('both picker show correct value', done => {
vm = createVue({
template: '<el-date-picker type="datetime" v-model="value" ref="compo" />',
@ -1634,6 +1677,56 @@ describe('DatePicker', () => {
}, DELAY);
});
it('both picker show correct formated value (extract date-format and time-format from format property)', done => {
destroyVM(vm); // nuke beforeEach's vm before creating our own
vm = createVue({
template: `
<el-date-picker ref="compo" type="datetimerange" v-model="value" :format="format"></el-date-picker>
`,
data() {
return {
value: [new Date(2018, 8, 5, 10, 20, 30), new Date(2018, 8, 15, 15, 35, 45)],
format: 'yyyy/MM/dd hh:mm A'
};
}
}, true);
setTimeout(_ => {
const compo = vm.$refs.compo;
compo.$el.click();
setTimeout(_ => {
const pickers = compo.picker.$el.querySelectorAll('.el-date-range-picker__time-header .el-date-range-picker__editors-wrap');
const left = {
dateInput: pickers[0].querySelector('.el-date-range-picker__time-picker-wrap:nth-child(1) input'),
timeInput: pickers[0].querySelector('.el-date-range-picker__time-picker-wrap:nth-child(2) input')
};
const right = {
dateInput: pickers[1].querySelector('.el-date-range-picker__time-picker-wrap:nth-child(1) input'),
timeInput: pickers[1].querySelector('.el-date-range-picker__time-picker-wrap:nth-child(2) input')
};
left.timeInput.focus();
right.timeInput.focus();
// all inputs shows correct value
expect(left.dateInput.value).to.equal('2018/09/05');
expect(left.timeInput.value).to.equal('10:20 AM');
expect(right.dateInput.value).to.equal('2018/09/15');
expect(right.timeInput.value).to.equal('03:35 PM');
vm.format = 'd-M-yy HH:mm:ss';
setTimeout(_ => {
expect(left.dateInput.value).to.equal('5-9-18');
expect(left.timeInput.value).to.equal('10:20:30');
expect(right.dateInput.value).to.equal('15-9-18');
expect(right.timeInput.value).to.equal('15:35:45');
done();
}, DELAY);
}, DELAY);
}, DELAY);
});
it('select daterange with defaultTime min & max', done => {
destroyVM(vm); // nuke beforeEach's vm before creating our own
vm = createVue({