Bläddra i källkod

DateTimePicker: fix incorrect date on time pick (#11474)

* date-time-picker: fix incorrect date on time pick

* date-time-picker: fix incorrect date on confirm
Jiewei Qian 7 år sedan
förälder
incheckning
ecec908da8

+ 3 - 3
packages/date-picker/src/panel/date-range.vue

@@ -190,7 +190,7 @@
     isDate,
     modifyDate,
     modifyTime,
-    modifyWithDefaultTime,
+    modifyWithTimeString,
     prevYear,
     nextYear,
     prevMonth,
@@ -498,8 +498,8 @@
 
       handleRangePick(val, close = true) {
         const defaultTime = this.defaultTime || [];
-        const minDate = modifyWithDefaultTime(val.minDate, defaultTime[0]);
-        const maxDate = modifyWithDefaultTime(val.maxDate, defaultTime[1]);
+        const minDate = modifyWithTimeString(val.minDate, defaultTime[0]);
+        const maxDate = modifyWithTimeString(val.maxDate, defaultTime[1]);
 
         if (this.maxDate === maxDate && this.minDate === minDate) {
           return;

+ 23 - 8
packages/date-picker/src/panel/date.vue

@@ -150,7 +150,7 @@
     isDate,
     modifyDate,
     modifyTime,
-    modifyWithDefaultTime,
+    modifyWithTimeString,
     clearMilliseconds,
     clearTime,
     prevYear,
@@ -192,7 +192,7 @@
         if (isDate(val)) {
           this.date = new Date(val);
         } else {
-          this.date = this.defaultValue ? new Date(this.defaultValue) : new Date();
+          this.date = this.getDefaultValue();
         }
       },
 
@@ -233,7 +233,7 @@
       },
 
       handleClear() {
-        this.date = this.defaultValue ? new Date(this.defaultValue) : new Date();
+        this.date = this.getDefaultValue();
         this.$emit('pick', null);
       },
 
@@ -303,7 +303,9 @@
 
       handleTimePick(value, visible, first) {
         if (isDate(value)) {
-          const newDate = this.value ? modifyTime(this.date, value.getHours(), value.getMinutes(), value.getSeconds()) : modifyWithDefaultTime(value, this.defaultTime);
+          const newDate = this.value
+            ? modifyTime(this.value, value.getHours(), value.getMinutes(), value.getSeconds())
+            : modifyWithTimeString(this.getDefaultValue(), this.defaultTime);
           this.date = newDate;
           this.emit(this.date, true);
         } else {
@@ -334,7 +336,9 @@
 
       handleDatePick(value) {
         if (this.selectionMode === 'day') {
-          this.date = this.value ? modifyDate(this.date, value.getFullYear(), value.getMonth(), value.getDate()) : modifyWithDefaultTime(value, this.defaultTime);
+          this.date = this.value
+            ? modifyDate(this.value, value.getFullYear(), value.getMonth(), value.getDate())
+            : modifyWithTimeString(value, this.defaultTime);
           this.emit(this.date, this.showTime);
         } else if (this.selectionMode === 'week') {
           this.emit(value.date);
@@ -366,8 +370,13 @@
         if (this.selectionMode === 'dates') {
           this.emit(this.selectedDate);
         } else {
-          const date = this.value ? this.date : modifyWithDefaultTime(this.date, this.defaultTime);
-          this.emit(date);
+          // value were emitted in handle{Date,Time}Pick, nothing to update here
+          // deal with the scenario where: user opens the picker, then confirm without doing anything
+          const value = this.value
+            ? this.value
+            : modifyWithTimeString(this.getDefaultValue(), this.defaultTime);
+          this.date = new Date(value); // refresh date
+          this.emit(value);
         }
       },
 
@@ -466,6 +475,12 @@
             ? !this.disabledDate(value)
             : true
         );
+      },
+
+      getDefaultValue() {
+        // if default-value is set, return it
+        // otherwise, return now (the moment this method gets called)
+        return this.defaultValue ? new Date(this.defaultValue) : new Date();
       }
     },
 
@@ -478,7 +493,7 @@
         popperClass: '',
         date: new Date(),
         value: '',
-        defaultValue: null,
+        defaultValue: null, // use getDefaultValue() for time computation
         defaultTime: null,
         showTime: false,
         selectionMode: 'day',

+ 1 - 1
packages/date-picker/src/util/index.js

@@ -144,7 +144,7 @@ export const modifyTime = function(date, h, m, s) {
   return new Date(date.getFullYear(), date.getMonth(), date.getDate(), h, m, s, date.getMilliseconds());
 };
 
-export const modifyWithDefaultTime = (date, time) => {
+export const modifyWithTimeString = (date, time) => {
   if (date == null || !time) {
     return date;
   }

+ 65 - 0
test/unit/specs/date-picker.spec.js

@@ -1329,6 +1329,71 @@ describe('DatePicker', () => {
         }, DELAY);
       }, DELAY);
     });
+
+    it('select time honors picked date', done => {
+      vm = createVue({
+        template: '<el-date-picker type="datetime" v-model="value" ref="compo" />',
+        data() {
+          return {
+            value: new Date(2000, 9, 1, 12, 0, 0) // 2010-10-01 12:00:00
+          };
+        }
+      }, true);
+      vm.$refs.compo.$el.querySelector('input').focus();
+      setTimeout(_ => {
+        // changed month / year should not effect picked time
+        vm.$refs.compo.picker.$el.querySelector('.el-date-picker__header .el-icon-arrow-right').click();
+        setTimeout(_ => {
+          vm.$refs.compo.picker.$el.querySelector('.el-date-picker__header .el-icon-d-arrow-right').click();
+          setTimeout(_ => {
+            // simulate time selection
+            // handleTimePick takes Date object, but it's non-time fields are ignored
+            vm.$refs.compo.picker.handleTimePick(new Date(2001, 10, 10, 13, 14, 15), false, false);
+            setTimeout(_ => {
+              expect(vm.value.getFullYear()).to.equal(2000);
+              expect(vm.value.getMonth()).to.equal(9);
+              expect(vm.value.getDate()).to.equal(1);
+              expect(vm.value.getHours()).to.equal(13);
+              expect(vm.value.getMinutes()).to.equal(14);
+              expect(vm.value.getSeconds()).to.equal(15);
+              done();
+            }, DELAY);
+          }, DELAY);
+        }, DELAY);
+      }, DELAY);
+    });
+
+    it('confirm button honors picked date', done => {
+      vm = createVue({
+        template: '<el-date-picker type="datetime" v-model="value" ref="compo" />',
+        data() {
+          return {
+            value: new Date(2000, 9, 1, 12, 0, 0) // 2010-10-01 12:00:00
+          };
+        }
+      }, true);
+      vm.$refs.compo.$el.querySelector('input').focus();
+      setTimeout(_ => {
+        // changed month / year should not effect picked time
+        vm.$refs.compo.picker.$el.querySelector('.el-date-picker__header .el-icon-arrow-right').click();
+        setTimeout(_ => {
+          vm.$refs.compo.picker.$el.querySelector('.el-date-picker__header .el-icon-d-arrow-right').click();
+          setTimeout(_ => {
+            // click confirm button
+            vm.$refs.compo.picker.$el.querySelector('.el-picker-panel__footer .el-button--default').click();
+            setTimeout(_ => {
+              expect(vm.value.getFullYear()).to.equal(2000);
+              expect(vm.value.getMonth()).to.equal(9);
+              expect(vm.value.getDate()).to.equal(1);
+              expect(vm.value.getHours()).to.equal(12);
+              expect(vm.value.getMinutes()).to.equal(0);
+              expect(vm.value.getSeconds()).to.equal(0);
+              done();
+            }, DELAY);
+          }, DELAY);
+        }, DELAY);
+      }, DELAY);
+    });
   });
 
   describe('type:week', () => {