From d57c3958ffe3eea2d83b02d28fb2082959d03610 Mon Sep 17 00:00:00 2001 From: luckyCao Date: Tue, 23 Apr 2019 11:28:02 +0800 Subject: [PATCH] InputNumber: add step-strictly attribute (#15050) --- examples/docs/en-US/input-number.md | 21 +++++++++++++++ examples/docs/es/input-number.md | 21 +++++++++++++++ examples/docs/fr-FR/input-number.md | 21 +++++++++++++++ examples/docs/zh-CN/input-number.md | 21 +++++++++++++++ packages/input-number/src/input-number.vue | 31 ++++++++++++++++++---- test/unit/specs/input-number.spec.js | 25 ++++++++++++++++- types/input-number.d.ts | 5 +++- 7 files changed, 138 insertions(+), 7 deletions(-) diff --git a/examples/docs/en-US/input-number.md b/examples/docs/en-US/input-number.md index ad59523a67..9670fd297f 100644 --- a/examples/docs/en-US/input-number.md +++ b/examples/docs/en-US/input-number.md @@ -69,6 +69,26 @@ Allows you to define incremental steps. ``` ::: +### Step strictly + +:::demo The `step-strictly` attribute accepts a `boolean`. if this attribute is `true`, input value can only be multiple of step. + +```html + + +``` +::: + ### Precision :::demo Add `precision` attribute to set the precision of input value. @@ -154,6 +174,7 @@ Use attribute `size` to set additional sizes with `medium`, `small` or `mini`. |min | the minimum allowed value | number | — | `-Infinity` | |max | the maximum allowed value | number | — | `Infinity` | |step | incremental step | number | — | 1 | +|step-strictly | whether input value can only be multiple of step | number | — | false | |precision | precision of input value | number | — | — | |size | size of the component | string | large/small| — | |disabled| whether the component is disabled | boolean | — | false | diff --git a/examples/docs/es/input-number.md b/examples/docs/es/input-number.md index 362f8db21b..b880635f13 100644 --- a/examples/docs/es/input-number.md +++ b/examples/docs/es/input-number.md @@ -69,6 +69,26 @@ Le permite definir el nivel de incremento de los saltos. ``` ::: +### Step strictly + +:::demo The `step-strictly` attribute accepts a `boolean`. if this attribute is `true`, input value can only be multiple of step. + +```html + + +``` +::: + ### Precision :::demo Add `precision` attribute to set the precision of input value. @@ -155,6 +175,7 @@ Utilice el atributo `size` para establecer tamaños adicionales con `medium`, `s | min | el valor mínimo permitido | number | — | `-Infinity` | | max | el valor maximo permitido | number | — | `Infinity` | | step | incremento (salto) | number | — | 1 | +| step-strictly | whether input value can can only be multiple of step | number | — | false | | precision | precisión del valor del input | number | — | — | | size | tamaño del componente | string | large/small | — | | disabled | si el componente esta deshabilitado | boolean | — | false | diff --git a/examples/docs/fr-FR/input-number.md b/examples/docs/fr-FR/input-number.md index 76016ed0a8..7a6eeba073 100644 --- a/examples/docs/fr-FR/input-number.md +++ b/examples/docs/fr-FR/input-number.md @@ -69,6 +69,26 @@ Vous pouvez déterminer un pas pour le champs. ``` ::: +### Step strictly + +:::demo The `step-strictly` attribute accepts a `boolean`. if this attribute is `true`, input value can only be multiple of step. + +```html + + +``` +::: + ### Précision :::demo Ajoutez l'attribut `precision` pour régler la précision du champs. @@ -154,6 +174,7 @@ Utilisez l'attribut `size` pour régler la taille avec `medium`, `small` ou `min | min | La valeur minimale autorisée. | number | — | `-Infinity` | | max | La valeur maximale autorisée. | number | — | `Infinity` | | step | Le pas pour l'incrémentation. | number | — | 1 | +| step-strictly | whether input value can only be multiple of step | number | — | false | | precision | La précision de la valeur. | number | — | — | | size | La taille du composant. | string | large/small| — | | disabled| Si le composant est désactivé. | boolean | — | false | diff --git a/examples/docs/zh-CN/input-number.md b/examples/docs/zh-CN/input-number.md index 3961be6a1f..e578368150 100644 --- a/examples/docs/zh-CN/input-number.md +++ b/examples/docs/zh-CN/input-number.md @@ -68,6 +68,26 @@ ``` ::: +### 严格步数 + +:::demo `step-strictly`属性接受一个`Boolean`。如果这个属性被设置为`true`,则只能输入步数的倍数。 + +```html + + +``` +::: + ### 精度 :::demo 设置 `precision` 属性可以控制数值精度,接收一个 `Number`。 @@ -152,6 +172,7 @@ | min | 设置计数器允许的最小值 | number | — | -Infinity | | max | 设置计数器允许的最大值 | number | — | Infinity | | step | 计数器步长 | number | — | 1 | +| step-strictly | 是否只能输入 step 的倍数 | number | — | false | | precision| 数值精度 | number | — | — | | size | 计数器尺寸 | string | large, small | — | | disabled | 是否禁用计数器 | boolean | — | false | diff --git a/packages/input-number/src/input-number.vue b/packages/input-number/src/input-number.vue index 70bf26c728..364ebdc60f 100644 --- a/packages/input-number/src/input-number.vue +++ b/packages/input-number/src/input-number.vue @@ -72,6 +72,10 @@ type: Number, default: 1 }, + stepStrictly: { + type: Boolean, + default: false + }, max: { type: Number, default: Infinity @@ -116,6 +120,13 @@ if (isNaN(newVal)) { return; } + + if (this.stepStrictly) { + const stepPrecision = this.getPrecision(this.step); + const precisionFactor = Math.pow(10, stepPrecision); + newVal = Math.round(newVal / this.step) * precisionFactor * this.step / precisionFactor; + } + if (this.precision !== undefined) { newVal = this.toPrecision(newVal, this.precision); } @@ -163,12 +174,22 @@ if (this.userInput !== null) { return this.userInput; } - const currentValue = this.currentValue; - if (typeof currentValue === 'number' && this.precision !== undefined) { - return currentValue.toFixed(this.precision); - } else { - return currentValue; + + let currentValue = this.currentValue; + + if (typeof currentValue === 'number') { + if (this.stepStrictly) { + const stepPrecision = this.getPrecision(this.step); + const precisionFactor = Math.pow(10, stepPrecision); + currentValue = Math.round(currentValue / this.step) * precisionFactor * this.step / precisionFactor; + } + + if (this.precision !== undefined) { + currentValue = currentValue.toFixed(this.precision); + } } + + return currentValue; } }, methods: { diff --git a/test/unit/specs/input-number.spec.js b/test/unit/specs/input-number.spec.js index 34a28db16f..dbff288b65 100644 --- a/test/unit/specs/input-number.spec.js +++ b/test/unit/specs/input-number.spec.js @@ -1,4 +1,4 @@ -import { createVue, triggerEvent, triggerClick, destroyVM } from '../util'; +import {createVue, triggerEvent, triggerClick, destroyVM, waitImmediate} from '../util'; const DELAY = 1; @@ -142,6 +142,29 @@ describe('InputNumber', () => { }); }); }); + it('step strictly', async() => { + vm = createVue({ + template: ` + + + `, + data() { + return { + value: 5 + }; + } + }, true); + + let input = vm.$el.querySelector('input'); + await waitImmediate(); + expect(vm.value).to.be.equal(4.8); + expect(input.value).to.be.equal('4.8'); + vm.value = '8'; + + await waitImmediate(); + expect(vm.value).to.be.equal(8.4); + expect(input.value).to.be.equal('8.4'); + }); it('min', done => { vm = createVue({ template: ` diff --git a/types/input-number.d.ts b/types/input-number.d.ts index deec6f59bc..76288ffc30 100644 --- a/types/input-number.d.ts +++ b/types/input-number.d.ts @@ -35,7 +35,10 @@ export declare class ElInputNumber extends ElementUIComponent { name: string /** Precision of input value */ - precision: Number + precision: number + + /** whether input value can only be multiple of step */ + stepStrictly: boolean /** * Focus the Input component