浏览代码

DatePicker: add clear value, closed #759 (#1026)

cinwell.li 8 年之前
父节点
当前提交
1208ef520c

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

@@ -273,16 +273,16 @@
           this.minDate = null;
           this.maxDate = null;
         } else if (Array.isArray(newVal)) {
-          this.minDate = toDate(newVal[0]);
-          this.maxDate = toDate(newVal[1]);
+          this.minDate = newVal[0] ? toDate(newVal[0]) : null;
+          this.maxDate = newVal[1] ? toDate(newVal[1]) : null;
         }
       }
     },
 
     methods: {
       handleClear() {
-        this.minDate = '';
-        this.maxDate = '';
+        this.minDate = null;
+        this.maxDate = null;
         this.handleConfirm();
       },
 

+ 1 - 0
packages/date-picker/src/panel/date.vue

@@ -183,6 +183,7 @@
     methods: {
       handleClear() {
         this.date = new Date();
+        this.$emit('pick');
       },
 
       resetDate() {

+ 4 - 0
packages/date-picker/src/panel/time-range.vue

@@ -127,6 +127,10 @@
     },
 
     methods: {
+      handleClear() {
+        this.handleCancel();
+      },
+
       handleCancel() {
         this.$emit('pick');
       },

+ 4 - 0
packages/date-picker/src/panel/time-select.vue

@@ -81,6 +81,10 @@
         if (!item.disabled) {
           this.$emit('pick', item.value);
         }
+      },
+
+      handleClear() {
+        this.$emit('pick');
       }
     },
 

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

@@ -100,8 +100,12 @@
     },
 
     methods: {
+      handleClear() {
+        this.handleCancel();
+      },
+
       handleCancel() {
-        this.$emit('pick', null);
+        this.$emit('pick');
       },
 
       handleChange(date) {

+ 51 - 14
packages/date-picker/src/picker.vue

@@ -5,7 +5,7 @@
     :class="{
       'is-have-trigger': haveTrigger,
       'is-active': pickerVisible,
-      'is-filled': !!this.value
+      'is-filled': !!this.internalValue
     }">
 
     <input
@@ -22,9 +22,11 @@
       v-model.lazy="visualValue" />
 
     <span
-      @click="pickerVisible = !pickerVisible"
+      @click.stop="handleClickIcon"
       class="el-date-editor__trigger el-icon"
-      :class="[triggerClass]"
+      :class="[showClose ? 'el-icon-close' : triggerClass]"
+      @mouseenter="handleMouseEnterIcon"
+      @mouseleave="showClose = false"
       v-if="haveTrigger">
     </span>
   </span>
@@ -219,7 +221,9 @@ export default {
 
   data() {
     return {
-      pickerVisible: false
+      pickerVisible: false,
+      showClose: false,
+      internalValue: ''
     };
   },
 
@@ -228,15 +232,37 @@ export default {
       if (this.readonly || this.disabled) return;
       val ? this.showPicker() : this.hidePicker();
     },
-    value(val) {
+    internalValue(val) {
       if (!val && this.picker && typeof this.picker.handleClear === 'function') {
         this.picker.handleClear();
       }
       this.dispatch('form-item', 'el.form.change');
+    },
+    value: {
+      immediate: true,
+      handler(val) {
+        this.internalValue = val;
+      }
     }
   },
 
   computed: {
+    valueIsEmpty() {
+      const val = this.internalValue;
+      if (Array.isArray(val)) {
+        for (let i = 0, j = val.length; i < j; i++) {
+          if (val[i]) {
+            return false;
+          }
+        }
+      } else {
+        if (val) {
+          return false;
+        }
+      }
+      return true;
+    },
+
     triggerClass() {
       return this.type.indexOf('time') !== -1 ? 'el-icon-time' : 'el-icon-date';
     },
@@ -262,7 +288,7 @@ export default {
 
     visualValue: {
       get() {
-        const value = this.value;
+        const value = this.internalValue;
         const formatter = (
           TYPE_VALUE_RESOLVER_MAP[this.type] ||
           TYPE_VALUE_RESOLVER_MAP['default']
@@ -301,6 +327,20 @@ export default {
   },
 
   methods: {
+    handleMouseEnterIcon() {
+      if (!this.valueIsEmpty) {
+        this.showClose = true;
+      }
+    },
+
+    handleClickIcon() {
+      if (this.valueIsEmpty) {
+        this.pickerVisible = !this.pickerVisible;
+      } else {
+        this.internalValue = '';
+      }
+    },
+
     handleClose() {
       this.pickerVisible = false;
     },
@@ -370,7 +410,7 @@ export default {
 
     showPicker() {
       if (!this.picker) {
-        this.panel.defaultValue = this.value;
+        this.panel.defaultValue = this.internalValue;
         this.picker = new Vue(this.panel).$mount(document.createElement('div'));
         this.popperElm = this.picker.$el;
         this.picker.width = this.$refs.reference.getBoundingClientRect().width;
@@ -412,10 +452,7 @@ export default {
         this.picker.$on('dodestroy', this.doDestroy);
         this.picker.$on('pick', (date, visible = false) => {
           this.$emit('input', date);
-
-          if (!visible) {
-            this.pickerVisible = this.picker.visible = !this.picker.visible;
-          }
+          this.pickerVisible = this.picker.visible = visible;
           this.picker.resetView && this.picker.resetView();
         });
 
@@ -431,11 +468,11 @@ export default {
 
       this.updatePopper();
 
-      if (this.value instanceof Date) {
-        this.picker.date = new Date(this.value.getTime());
+      if (this.internalValue instanceof Date) {
+        this.picker.date = new Date(this.internalValue.getTime());
         this.picker.resetView && this.picker.resetView();
       } else {
-        this.picker.value = this.value;
+        this.picker.value = this.internalValue;
       }
 
       this.$nextTick(() => {

+ 29 - 7
test/unit/specs/date-picker.spec.js

@@ -66,6 +66,31 @@ describe('DatePicker', () => {
     }, DELAY);
   });
 
+  it('clear value', done => {
+    vm = createVue({
+      template: `
+        <el-date-picker v-model="value" ref="compo"></el-date-picker>
+      `,
+      data() {
+        return { value: '' };
+      }
+    }, true);
+    const input = vm.$el.querySelector('input');
+
+    input.focus();
+    setTimeout(_ => {
+      const $el = vm.$refs.compo.picker.$el;
+      $el.querySelector('td.available').click();
+      vm.$nextTick(_ => {
+        vm.$el.querySelector('.el-date-editor__trigger').click();
+        setTimeout(_ => {
+          expect(vm.value).to.empty;
+          done();
+        }, DELAY);
+      });
+    }, DELAY);
+  });
+
   it('reset', done => {
     vm = createVue({
       template: `
@@ -218,7 +243,6 @@ describe('DatePicker', () => {
     it('click now button', done => {
       const date = new Date(1999, 10, 10, 10, 10);
 
-      vm.picker.date = new Date(date);
       vm.picker.$el.querySelector('.el-picker-panel__link-btn').click();
       setTimeout(_ => {
         expect(vm.picker.date > date).to.true;
@@ -228,14 +252,12 @@ describe('DatePicker', () => {
 
     it('click timepicker', done => {
       const input = vm.picker.$el.querySelectorAll('.el-date-picker__editor-wrap input')[1];
-      input.blur();
-      input.focus();
-      input.blur();
+      triggerEvent(input, 'focus');
 
       setTimeout(_ => {
         expect(vm.picker.$el.querySelector('.el-time-panel')).to.have.deep.property('style.display').to.equal('');
         done();
-      }, 400);
+      }, DELAY);
     });
 
     it('input timepicker', done => {
@@ -391,7 +413,7 @@ describe('DatePicker', () => {
       setTimeout(_ => {
         expect(vm.picker.$el.querySelector('.el-date-range-picker__time-picker-wrap .el-time-panel')).to.have.deep.property('style.display').to.equal('');
         done();
-      }, 400);
+      }, DELAY);
     });
 
     it('click timepicker in right', done => {
@@ -403,7 +425,7 @@ describe('DatePicker', () => {
       setTimeout(_ => {
         expect(vm.picker.$el.querySelectorAll('.el-date-range-picker__time-picker-wrap .el-time-panel')[1]).to.have.deep.property('style.display').to.equal('');
         done();
-      }, 400);
+      }, DELAY);
     });
 
     it('input timepicker', done => {