Ver Fonte

Улучшение NumInput

Book Pauk há 2 anos atrás
pai
commit
4b2e63bb5b
1 ficheiros alterados com 94 adições e 24 exclusões
  1. 94 24
      client/components/share/NumInput.vue

+ 94 - 24
client/components/share/NumInput.vue

@@ -6,15 +6,26 @@
         class="no-mp"
         :class="(error ? 'error' : '')"
         :disable="disable"
+        :mask="mask"
     >
         <slot></slot>
         <template #prepend>
+            <q-icon
+                v-show="mmButtons"
+                v-ripple="modelValue != min" 
+                style="font-size: 100%"
+                :class="(modelValue != min ? '' : 'disable')" 
+                name="la la-angle-double-left" 
+                class="button" 
+                @click="toMin"
+            />
+
             <q-icon
                 v-ripple="validate(modelValue - step)" 
                 :class="(validate(modelValue - step) ? '' : 'disable')" 
-                name="la la-minus-circle" 
+                :name="minusIcon" 
                 class="button" 
-                @click="minus"
+                @click="onClick('minus')"
                 @mousedown.prevent.stop="onMouseDown($event, 'minus')"
                 @mouseup.prevent.stop="onMouseUp"
                 @mouseout.prevent.stop="onMouseUp"
@@ -27,9 +38,9 @@
             <q-icon
                 v-ripple="validate(modelValue + step)"
                 :class="(validate(modelValue + step) ? '' : 'disable')"
-                name="la la-plus-circle"
+                :name="plusIcon"
                 class="button"
-                @click="plus"
+                @click="onClick('plus')"
                 @mousedown.prevent.stop="onMouseDown($event, 'plus')"
                 @mouseup.prevent.stop="onMouseUp"
                 @mouseout.prevent.stop="onMouseUp"
@@ -37,6 +48,16 @@
                 @touchend.stop="onTouchEnd"
                 @touchcancel.prevent.stop="onTouchEnd"
             />
+
+            <q-icon
+                v-show="mmButtons"
+                v-ripple="modelValue != max" 
+                style="font-size: 100%"
+                :class="(modelValue != max ? '' : 'disable')" 
+                name="la la-angle-double-right" 
+                class="button" 
+                @click="toMax"
+            />
         </template>
     </q-input>
 </template>
@@ -49,17 +70,18 @@ import * as utils from '../../share/utils';
 
 const componentOptions = {
     watch: {
-        filteredValue: function(newValue) {
-            if (this.validate(newValue)) {
-                this.error = false;
-                this.$emit('update:modelValue', this.string2number(newValue));
-            } else {
-                this.error = true;
-            }
+        filteredValue() {
+            this.checkErrorAndEmit(true);
         },
-        modelValue: function(newValue) {
+        modelValue(newValue) {
             this.filteredValue = newValue;
         },
+        min() {
+            this.checkErrorAndEmit();
+        },
+        max() {
+            this.checkErrorAndEmit();
+        }
     }
 };
 class NumInput {
@@ -70,7 +92,11 @@ class NumInput {
         max: { type: Number, default: Number.MAX_VALUE },
         step: { type: Number, default: 1 },
         digits: { type: Number, default: 0 },
-        disable: Boolean
+        disable: Boolean,
+        minusIcon: {type: String, default: 'la la-minus-circle'},
+        plusIcon: {type: String, default: 'la la-plus-circle'},
+        mmButtons: Boolean,
+        mask: String,
     };
 
     filteredValue = 0;
@@ -95,6 +121,16 @@ class NumInput {
         return true;
     }
 
+    checkErrorAndEmit(emit = false) {
+        if (this.validate(this.filteredValue)) {
+            this.error = false;
+            if (emit)
+                this.$emit('update:modelValue', this.string2number(this.filteredValue));
+        } else {
+            this.error = true;
+        }
+    }
+
     plus() {
         const newValue = this.modelValue + this.step;
         if (this.validate(newValue))
@@ -107,23 +143,42 @@ class NumInput {
             this.filteredValue = newValue;
     }
 
+    onClick(way) {
+        if (this.clickRepeat)
+            return;
+
+        if (way == 'plus') {
+            this.plus();
+        } else {
+            this.minus();
+        }
+    }
+
     onMouseDown(event, way) {
         this.startClickRepeat = true;
         this.clickRepeat = false;
 
         if (event.button == 0) {
             (async() => {
-                await utils.sleep(300);
-                if (this.startClickRepeat) {
-                    this.clickRepeat = true;
-                    while (this.clickRepeat) {
-                        if (way == 'plus') {
-                            this.plus();
-                        } else {
-                            this.minus();
+                if (this.inRepeatFunc)
+                    return;
+
+                this.inRepeatFunc = true;
+                try {
+                    await utils.sleep(300);
+                    if (this.startClickRepeat) {
+                        this.clickRepeat = true;
+                        while (this.clickRepeat) {
+                            if (way == 'plus') {
+                                this.plus();
+                            } else {
+                                this.minus();
+                            }
+                            await utils.sleep(100);
                         }
-                        await utils.sleep(50);
                     }
+                } finally {
+                    this.inRepeatFunc = false;
                 }
             })();
         }
@@ -133,7 +188,12 @@ class NumInput {
         if (this.inTouch)
             return;
         this.startClickRepeat = false;
-        this.clickRepeat = false;
+        if (this.clickRepeat) {
+            (async() => {
+                await utils.sleep(50);
+                this.clickRepeat = false;
+            })();
+        }
     }
 
     onTouchStart(event, way) {
@@ -151,6 +211,14 @@ class NumInput {
         this.inTouch = false;
         this.onMouseUp();
     }
+
+    toMin() {
+        this.filteredValue = this.min;
+    }
+
+    toMax() {
+        this.filteredValue = this.max;
+    }
 }
 
 export default vueComponent(NumInput);
@@ -165,7 +233,9 @@ export default vueComponent(NumInput);
 
 .button {
     font-size: 130%;
-    border-radius: 20px;
+    border-radius: 15px;
+    width: 30px;
+    height: 30px;
     color: #bbb;
     cursor: pointer;
 }