Bladeren bron

DatePicker: Optimize the input, fixed #484 (#543)

cinwell.li 8 jaren geleden
bovenliggende
commit
e96ba3d26b

+ 3 - 0
CHANGELOG.md

@@ -17,6 +17,9 @@
 - TableColumn[type="selection"] 增加 selectable 属性
 - 修复 Input textarea 在动态赋值时 autosize 没有触发的问题
 - 修复 Input Number min max 属性设置后点击加减出现的崩溃的bug
+- 优化 TimePicker/DatePicker 输入日期行为
+- 修复 DatePicker 输入禁用状态的日期却生效的问题 #484
+
 
 #### 非兼容性更新
 

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

@@ -331,7 +331,12 @@
       handleDateInput(event, type) {
         const value = event.target.value;
         const parsedValue = parseDate(value, 'yyyy-MM-dd');
+
         if (parsedValue) {
+          if (typeof this.disabledDate === 'function' &&
+            this.disabledDate(new Date(parsedValue))) {
+            return;
+          }
           const target = new Date(type === 'min' ? this.minDate : this.maxDate);
           if (target) {
             target.setFullYear(parsedValue.getFullYear());

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

@@ -137,10 +137,16 @@
       },
 
       value(newVal) {
-        if (this.selectionMode === 'day' && newVal instanceof Date) {
+        if (newVal instanceof Date) {
+
+          if (typeof this.disabledDate === 'function' &&
+            this.disabledDate(new Date(newVal))) {
+            return;
+          }
           this.date = newVal;
           this.year = newVal.getFullYear();
           this.month = newVal.getMonth();
+          this.$emit('pick', newVal, true);
         }
       },
 
@@ -377,6 +383,8 @@
               date.setMonth(this.date.getMonth());
               date.setDate(this.date.getDate());
               this.date = date;
+              this.$refs.timepicker.value = date;
+              this.timePickerVisible = false;
             }
           }
         }
@@ -394,6 +402,7 @@
             date.setMinutes(this.date.getMinutes());
             date.setSeconds(this.date.getSeconds());
             this.date = date;
+            this.resetView();
           }
         }
       },

+ 38 - 15
packages/date-picker/src/panel/time-range.vue

@@ -61,6 +61,15 @@
 
     return minValue > maxValue;
   };
+  const clacTime = function(time) {
+    time = Array.isArray(time) ? time : [time];
+    const minTime = time[0] || new Date();
+    const date = new Date();
+    date.setHours(date.getHours() + 1);
+    const maxTime = time[1] || date;
+
+    return { minTime, maxTime };
+  };
 
   export default {
     components: {
@@ -73,24 +82,38 @@
       }
     },
 
+    props: ['value'],
+
+    watch: {
+      value(val) {
+        const time = clacTime(val);
+
+        this.handleMinChange({
+          hours: time.minTime.getHours(),
+          minutes: time.minTime.getMinutes(),
+          seconds: time.minTime.getSeconds()
+        });
+        this.handleMaxChange({
+          hours: time.maxTime.getHours(),
+          minutes: time.maxTime.getMinutes(),
+          seconds: time.maxTime.getSeconds()
+        });
+      }
+    },
+
     data() {
-      let defaultValue = this.$options.defaultValue;
-      defaultValue = Array.isArray(defaultValue) ? defaultValue : [defaultValue];
-      const minTime = defaultValue[0] || new Date();
-      const date = new Date();
-      date.setHours(date.getHours() + 1);
-      const maxTime = defaultValue[1] || date;
+      const time = clacTime(this.$options.defaultValue);
 
       return {
-        minTime: minTime,
-        maxTime: maxTime,
-        btnDisabled: isDisabled(minTime, maxTime),
-        maxHours: maxTime.getHours(),
-        maxMinutes: maxTime.getMinutes(),
-        maxSeconds: maxTime.getSeconds(),
-        minHours: minTime.getHours(),
-        minMinutes: minTime.getMinutes(),
-        minSeconds: minTime.getSeconds(),
+        minTime: time.minTime,
+        maxTime: time.maxTime,
+        btnDisabled: isDisabled(time.minTime, time.maxTime),
+        maxHours: time.maxTime.getHours(),
+        maxMinutes: time.maxTime.getMinutes(),
+        maxSeconds: time.maxTime.getSeconds(),
+        minHours: time.minTime.getHours(),
+        minMinutes: time.minTime.getMinutes(),
+        minSeconds: time.minTime.getSeconds(),
         format: 'HH:mm:ss',
         visible: false,
         width: 0

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

@@ -72,6 +72,14 @@
         if (this.value && val && compareTime(this.value, val) === -1) {
           this.$emit('pick');
         }
+      },
+
+      value(val, old) {
+        if (val && this.items.some(i => i.value === val && !i.disabled)) {
+          this.$emit('pick', val, true);
+        } else {
+          this.$emit('pick', old, true);
+        }
       }
     },
 

+ 6 - 6
packages/date-picker/src/panel/time.vue

@@ -19,7 +19,7 @@
         <button
           type="button"
           class="el-time-panel__btn cancel"
-          @click="handleCancel()">{{ $t('datepicker.cancel') }}</button>
+          @click="handleCancel">{{ $t('datepicker.cancel') }}</button>
         <button
           type="button"
           class="el-time-panel__btn confirm"
@@ -66,10 +66,11 @@
           date = new Date();
         }
 
-        this.hours = date.getHours();
-        this.minutes = date.getMinutes();
-        this.seconds = date.getSeconds();
-        this.handleConfirm(true);
+        this.handleChange({
+          hours: date.getHours(),
+          minutes: date.getMinutes(),
+          seconds: date.getSeconds()
+        });
       },
 
       selectableRange(val) {
@@ -129,7 +130,6 @@
 
       handleConfirm(visible = false, first) {
         const date = new Date(limitRange(this.currentDate, this.selectableRange));
-
         this.$emit('pick', date, visible, first);
       },
 

+ 21 - 68
packages/date-picker/src/picker.vue

@@ -16,12 +16,11 @@
       @focus="handleFocus"
       @blur="handleBlur"
       @keydown="handleKeydown"
-      @keyup="handleKeyup"
       ref="reference"
       v-model.lazy="visualValue" />
 
     <span
-      @click="togglePicker()"
+      @click="togglePicker"
       class="el-date-editor__trigger el-icon"
       :class="[triggerClass]"
       v-if="haveTrigger">
@@ -47,7 +46,7 @@ const newPopper = {
   beforeDestroy: Popper.beforeDestroy
 };
 
-const FUNCTION_KEYS = [13, 16, 17, 18, 19, 20, 27, 33, 34, 35, 36, 37, 38, 39, 40];
+// const FUNCTION_KEYS = [13, 16, 17, 18, 19, 20, 27, 33, 34, 35, 36, 37, 38, 39, 40];
 const RANGE_SEPARATOR = ' - ';
 const DEFAULT_FORMATS = {
   date: 'yyyy-MM-dd',
@@ -210,9 +209,7 @@ export default {
     pickerOptions: {}
   },
 
-  directives: {
-    Clickoutside
-  },
+  directives: { Clickoutside },
 
   data() {
     return {
@@ -279,11 +276,11 @@ export default {
           const parsedValue = parser(value, this.format || DEFAULT_FORMATS[type]);
 
           if (parsedValue) {
-            this.$emit('input', parsedValue);
+            this.picker.value = parsedValue;
           }
           return;
         }
-        this.$emit('input', value);
+        this.picker.value = value;
       }
     }
   },
@@ -318,89 +315,45 @@ export default {
 
     handleKeydown(event) {
       const keyCode = event.keyCode;
-      let selectionStart = event.target.selectionStart;
-      let selectionEnd = event.target.selectionEnd;
-      let length = event.target.value.length;
+      const target = event.target;
+      let selectionStart = target.selectionStart;
+      let selectionEnd = target.selectionEnd;
+      let length = target.value.length;
 
       // tab
       if (keyCode === 9) {
         this.pickerVisible = false;
-      } else if (keyCode === 27) {
+      // enter
+      } else if (keyCode === 13) {
         this.pickerVisible = this.picker.visible = false;
+        this.visualValue = target.value;
+        target.blur();
       // left
       } else if (keyCode === 37) {
         event.preventDefault();
 
         if (selectionEnd === length && selectionStart === length) {
-          event.target.selectionStart = length - 2;
+          target.selectionStart = length - 2;
         } else if (selectionStart >= 3) {
-          event.target.selectionStart -= 3;
+          target.selectionStart -= 3;
         } else {
-          event.target.selectionStart = 0;
+          target.selectionStart = 0;
         }
-        event.target.selectionEnd = event.target.selectionStart + 2;
+        target.selectionEnd = target.selectionStart + 2;
       // right
       } else if (keyCode === 39) {
         event.preventDefault();
         if (selectionEnd === 0 && selectionStart === 0) {
-          event.target.selectionEnd = 2;
+          target.selectionEnd = 2;
         } else if (selectionEnd <= length - 3) {
-          event.target.selectionEnd += 3;
+          target.selectionEnd += 3;
         } else {
-          event.target.selectionEnd = length;
+          target.selectionEnd = length;
         }
-        event.target.selectionStart = event.target.selectionEnd - 2;
+        target.selectionStart = target.selectionEnd - 2;
       }
     },
 
-    handleKeyup(event) {
-      const keyCode = event.keyCode;
-      if (FUNCTION_KEYS.indexOf(keyCode) > -1) return;
-      if (!(this.picker && this.pickerVisible)) return;
-      const selectionStart = event.target.selectionStart;
-      const value = event.target.value;
-      const type = this.type;
-      const parser = (
-        TYPE_VALUE_RESOLVER_MAP[type] ||
-        TYPE_VALUE_RESOLVER_MAP['default']
-      ).parser;
-      const parsedValue = parser(value, this.format || DEFAULT_FORMATS[type]);
-
-      if (!parsedValue) return;
-      this.picker.value = parsedValue;
-      this.$emit('input', parsedValue);
-
-      if (this.type.indexOf('date') > -1) return;
-
-      setTimeout(_ => {
-        let start = selectionStart;
-        let end = selectionStart;
-        const offset = 2;
-
-        if (selectionStart === 9) {
-          start += offset;
-        }
-        if (selectionStart >= 12) {
-          if (selectionStart % 3 === 0) {
-            start += 1;
-            end = start;
-          } else if (selectionStart % 3 === 2) {
-            end = start + offset;
-          }
-        } else {
-          if (selectionStart % 3 === 1) {
-            start += 1;
-            end = start;
-          } else if (selectionStart % 3 === 0) {
-            end = start + offset;
-          }
-        }
-
-        event.target.selectionStart = start;
-        event.target.selectionEnd = end;
-      }, 0);
-    },
-
     togglePicker() {
       !this.pickerVisible ? this.showPicker() : this.hidePicker();
     },

+ 0 - 27
packages/date-picker/src/util/dropdown.js

@@ -1,27 +0,0 @@
-var dropdowns = [];
-
-document.addEventListener('click', function(event) {
-  dropdowns.forEach(function(dropdown) {
-    var target = event.target;
-    if (!dropdown || !dropdown.$el) return;
-    if (target === dropdown.$el || dropdown.$el.contains(target)) {
-      return;
-    }
-    dropdown.onDocumentClick && dropdown.onDocumentClick(event);
-  });
-});
-
-export default {
-  open(instance) {
-    if (instance) {
-      dropdowns.push(instance);
-    }
-  },
-
-  close(instance) {
-    var index = dropdowns.indexOf(instance);
-    if (index !== -1) {
-      dropdowns.splice(instance, 1);
-    }
-  }
-};