Эх сурвалжийг харах

DatePicker: fix date time picker cancel (#7442)

* date-time-picker: fix cancel button

* test: add date-time-picker tests
Jiewei Qian 7 жил өмнө
parent
commit
83245f846d

+ 22 - 11
packages/date-picker/src/panel/date.vue

@@ -35,11 +35,10 @@
                 @change.native="handleVisibleTimeChange" />
               <time-picker
                 ref="timepicker"
-                :date="date"
                 :time-arrow-control="arrowControl"
                 @pick="handleTimePick"
                 :visible="timePickerVisible"
-                @mounted="$refs.timepicker.format=timeFormat">
+                @mounted="proxyTimePickerDataProperties">
               </time-picker>
             </span>
           </div>
@@ -200,6 +199,20 @@
     },
 
     methods: {
+      proxyTimePickerDataProperties() {
+        const format = timeFormat => {this.$refs.timepicker.format = timeFormat;};
+        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);
+
+        format(this.timeFormat);
+        value(this.value);
+        date(this.date);
+      },
+
       handleClear() {
         this.date = this.defaultValue ? new Date(this.defaultValue) : new Date();
         this.$emit('pick');
@@ -207,7 +220,7 @@
 
       emit(value, ...args) {
         if (!value) {
-          this.emit('pick', value, ...args);
+          this.$emit('pick', value, ...args);
           return;
         }
         if (this.showTime) {
@@ -269,15 +282,13 @@
       },
 
       handleTimePick(value, visible, first) {
-        const newDate = modifyTime(this.date, value.getHours(), value.getMinutes(), value.getSeconds());
-        if (typeof this.disabledDate === 'function' && this.disabledDate(newDate)) {
-          this.$refs.timepicker.disabled = true;
-          return;
+        if (isDate(value)) {
+          const newDate = modifyTime(this.date, value.getHours(), value.getMinutes(), value.getSeconds());
+          this.date = newDate;
+          this.emit(this.date, true);
+        } else {
+          this.emit(value, true);
         }
-        this.$refs.timepicker.disabled = false;
-        this.date = newDate;
-        this.emit(this.date, true);
-
         if (!first) {
           this.timePickerVisible = visible;
         }

+ 8 - 5
packages/date-picker/src/panel/time.vue

@@ -105,14 +105,17 @@
 
     methods: {
       handleCancel() {
-        this.$emit('pick', this.oldValue);
+        this.$emit('pick', this.oldValue, false);
       },
 
       handleChange(date) {
-        this.date = clearMilliseconds(date);
-        // if date is out of range, do not emit
-        if (this.isValidValue(this.date)) {
-          this.$emit('pick', this.date, true);
+        // this.visible avoids edge cases, when use scrolls during panel closing animation
+        if (this.visible) {
+          this.date = clearMilliseconds(date);
+          // if date is out of range, do not emit
+          if (this.isValidValue(this.date)) {
+            this.$emit('pick', this.date, true);
+          }
         }
       },
 

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

@@ -779,6 +779,51 @@ describe('DatePicker', () => {
       expect(vm.picker.$el.querySelector('.el-time-panel')).to.ok;
     });
 
+    it('both picker show correct value', done => {
+      vm = createVue({
+        template: '<el-date-picker type="datetime" v-model="value" ref="compo" />',
+        data() {
+          return {
+            value: new Date(2000, 9, 1, 10, 0, 1)
+          };
+        }
+      }, 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(_ => {
+          const timePanel = datePanel.$refs.timepicker;
+          // both input shows correct value
+          expect(dateInput.value).to.equal('2000-10-01');
+          expect(timeInput.value).to.equal('10:00:01');
+          // time spinner highlight is correct
+          const [hours, minutes, seconds] = timePanel.$el.querySelectorAll('.el-time-spinner ul li.active');
+          expect(hours.textContent).to.include('10');
+          expect(minutes.textContent).to.include('00');
+          expect(seconds.textContent).to.include('01');
+          // sets value updates displayed value
+          vm.value = new Date(2001, 10, 2, 11, 1, 2);
+          setTimeout(_ => {
+            expect(dateInput.value).to.equal('2001-11-02');
+            expect(timeInput.value).to.equal('11:01:02');
+            const [hours, minutes, seconds] = timePanel.$el.querySelectorAll('.el-time-spinner ul li.active');
+            expect(hours.textContent).to.include('11');
+            expect(minutes.textContent).to.include('01');
+            expect(seconds.textContent).to.include('02');
+            expect(datePanel.visible).to.true;
+            expect(timePanel.visible).to.true;
+            done();
+          }, DELAY);
+        }, DELAY);
+      }, DELAY);
+    });
+
     it('click now button', done => {
       const date = new Date(1999, 10, 10, 10, 10);
 
@@ -842,6 +887,72 @@ describe('DatePicker', () => {
       }, DELAY);
     });
 
+    describe('cancel time', () => {
+      it('cancel to empty', done => {
+        vm = createVue({
+          template: '<el-date-picker type="datetime" v-model="value" ref="compo" />',
+          data() {
+            return {
+              value: ''
+            };
+          }
+        }, true);
+
+        const input = vm.$refs.compo.$el.querySelector('input');
+        input.blur();
+        input.focus();
+
+        setTimeout(_ => {
+          const timeInput = vm.$refs.compo.picker.$el.querySelector('.el-date-picker__time-header > span:nth-child(2) input');
+          timeInput.focus();
+          setTimeout(_ => {
+            const cancel = vm.$refs.compo.picker.$refs.timepicker.$el.querySelector('button.cancel');
+            cancel.click();
+            setTimeout(_ => {
+              expect(vm.value).to.equal('');
+              expect(vm.$refs.compo.pickerVisible).to.true;
+              done();
+            }, DELAY);
+          }, DELAY);
+        }, DELAY);
+      });
+
+      it('cancel to old value', done => {
+        vm = createVue({
+          template: '<el-date-picker type="datetime" v-model="value" ref="compo" />',
+          data() {
+            return {
+              value: new Date(2000, 9, 1, 10, 0, 0)
+            };
+          }
+        }, true);
+
+        const input = vm.$refs.compo.$el.querySelector('input');
+        input.blur();
+        input.focus();
+
+        const oldValue = vm.value.toISOString();
+
+        setTimeout(_ => {
+          const timeInput = vm.$refs.compo.picker.$el.querySelector('.el-date-picker__time-header > span:nth-child(2) input');
+          timeInput.focus();
+          setTimeout(_ => {
+            const nextTime = vm.$refs.compo.picker.$refs.timepicker.$el.querySelector('.active + *');
+            nextTime.click();
+            setTimeout(_ => {
+              const cancel = vm.$refs.compo.picker.$refs.timepicker.$el.querySelector('button.cancel');
+              cancel.click();
+              setTimeout(_ => {
+                expect(vm.value.toISOString()).to.equal(oldValue);
+                expect(vm.$refs.compo.pickerVisible).to.true;
+                done();
+              }, DELAY);
+            }, DELAY);
+          }, DELAY);
+        }, DELAY);
+      });
+    });
+
     describe('default value', () => {
       it('single', done => {
         let defaultValue = '2000-10-01';