feat(input-number): validator

This commit is contained in:
07akioni 2019-10-30 18:10:11 +08:00
parent 95b6ce1c52
commit 26bc4952c3
6 changed files with 98 additions and 55 deletions

View File

@ -3,6 +3,7 @@
<n-input-number
v-model="value"
@change="handleChange"
@blur="handleBlur"
/>
```
```js
@ -15,7 +16,10 @@ export default {
methods: {
handleChange (newValue) {
this.$NMessage.info(`value: ${newValue}`)
}
},
handleBlur (e, v) {
this.$NMessage.info(`blur: ` + v)
},
}
}
```

View File

@ -6,4 +6,5 @@ event
min-max
size
step
validator
```

View File

@ -15,7 +15,7 @@
export default {
data () {
return {
value: 0
value: null
}
}
}

View File

@ -0,0 +1,17 @@
# Validator
```html
<n-input-number
v-model="value"
:validator="validator"
/>
```
```js
export default {
data () {
return {
value: null,
validator: x => x > 0
}
}
}
```

View File

@ -12,7 +12,7 @@
type="button"
class="n-input-number__minus-button"
:class="{
[`n-input-number__minus-button--disabled`]: value !== null && safeMin !== null && value <= safeMin
[`n-input-number__minus-button--disabled`]: !minusable
}"
@mousedown="handleMouseDown"
@click="minus"
@ -25,8 +25,8 @@
type="text"
:value="value"
:disabled="disabled ? 'disabled' : false"
@focus="handleFocus"
@blur="handleBlur"
@input="handleInput"
@keyup.enter="handleEnter"
>
<button
@ -34,7 +34,7 @@
type="button"
class="n-input-number__add-button"
:class="{
[`n-input-number__add-button--disabled`]: value !== null && safeMax !== null && value >= safeMax
[`n-input-number__add-button--disabled`]: !addable
}"
@mousedown="handleMouseDown"
@click="add"
@ -107,6 +107,10 @@ export default {
disabled: {
type: Boolean,
default: false
},
validator: {
type: Function,
default: null
}
},
computed: {
@ -120,12 +124,29 @@ export default {
if (parsedNumber !== null) return parsedNumber
else return null
},
minusable () {
if (this.validator) {
if (this.value !== null) return this.validator(this.value - this.step)
else return false
} else {
return !(this.value !== null && this.safeMin !== null && this.value <= this.safeMin)
}
},
addable () {
if (this.validator) {
if (this.value !== null) return this.validator(this.value + this.step)
else return false
} else {
return !(this.value !== null && this.safeMax !== null && this.value >= this.safeMax)
}
},
safeMax () {
const parsedNumber = parseNumber(this.max)
if (parsedNumber !== null) return parsedNumber
else return null
},
aValidValue () {
if (this.validator) return null
if (this.safeMin !== null) {
return Math.max(0, this.safeMin)
} else if (this.safeMax !== null) {
@ -137,29 +158,12 @@ export default {
},
watch: {
value (newValue, oldValue) {
if (newValue !== null) {
if (this.safeMax !== null && newValue > this.safeMax) {
newValue = this.safeMax
}
if (this.safeMin !== null && newValue < this.safeMin) {
newValue = this.safeMin
}
}
this.$emit('change', newValue, oldValue)
this.formBlur('change', newValue)
/**
* newValue === oldValue won't trigger watcher!
* so the call stack won't fall in loop
*/
this.$emit('input', newValue)
}
},
created () {
if (this.value !== null) {
if (this.safeMax !== null && this.value > this.safeMax) {
this.$emit('input', this.safeMax)
} else if (this.safeMin !== null && this.value < this.safeMin) {
this.$emit('input', this.safeMin)
const adjustedValue = this.adjustValue(newValue)
if (adjustedValue === newValue) {
this.$emit('change', newValue, oldValue)
this.formBlur('change', newValue)
} else {
this.$emit('input', adjustedValue)
}
}
},
@ -175,44 +179,62 @@ export default {
this.dispatch('NFormItem', 'on-form-' + type, val)
}
},
handleFocus (e) {
this.$emit('focus', e, this.value)
},
add () {
if (!this.addable) return
if (this.value === null) {
this.$emit('input', this.aValidValue)
} else {
const valueAfterChange = this.value + this.safeStep
const valueAfterChange = this.adjustValue(this.value + this.safeStep)
this.$emit('input', valueAfterChange)
}
},
minus () {
console.log('minus', this.minusable)
if (!this.minusable) return
if (this.value === null) {
this.$emit('input', this.aValidValue)
} else {
const valueAfterChange = this.value - this.safeStep
const valueAfterChange = this.adjustValue(this.value - this.safeStep)
this.$emit('input', valueAfterChange)
}
},
handleInput (e) {
},
handleEnter (e) {
this.$refs.input.blur()
const value = this.adjustValue(this.$refs.input.value)
this.$refs.input.value = value
this.$emit('input', value)
},
adjustValue (value) {
value = String(value).trim() || ''
if (value.trim() === '') {
value = null
} else if (Number.isNaN(Number(value))) {
value = this.value
} else {
value = Number(value)
}
if (value === null) {
return null
} if (this.validator) {
if (this.validator(value)) {
return value
} else {
return null
}
} else {
if (this.safeMin !== null && value < this.safeMin) value = this.safeMin
else if (this.safeMax !== null && value > this.safeMax) value = this.safeMax
}
return value
},
handleBlur (e) {
const value = e.target.value
if (value === '') {
this.$emit('input', null)
this.formBlur('blur', value)
return
}
const parsedNumber = Number(value)
if (Number.isNaN(parsedNumber)) {
e.target.value = String(this.value)
} else {
const valueAfterChange = parsedNumber
e.target.value = String(parsedNumber)
this.$emit('input', valueAfterChange)
}
this.formBlur('blur', parsedNumber)
const value = this.adjustValue(e.target.value)
e.target.value = value
this.$emit('input', value)
this.$emit('blur', e, value)
this.formBlur('blur', value)
}
}
}

View File

@ -25,7 +25,7 @@
// background: map-get($--input-number-background-color, 'disabled');
@include e(minus-button, add-button) {
background: map-get($--input-number-button-background-color, 'disabled');
color: map-get($--input-number-button-text-color, 'disabled');
fill: map-get($--input-number-button-text-color, 'disabled');
pointer-events: none;
}
@include e(input) {
@ -61,11 +61,9 @@
display: flex;
align-items: center;
justify-content: center;
path {
fill: map-get($--input-number-button-text-color, 'default');
}
fill: map-get($--input-number-button-text-color, 'default');
font-size: 14px;
transition: color .3s $default-cubic-bezier, background-color .3s $default-cubic-bezier, box-shadow .3s $default-cubic-bezier;
transition: fill .3s $default-cubic-bezier, background-color .3s $default-cubic-bezier, box-shadow .3s $default-cubic-bezier;
box-shadow: inset 0 0 0px 1px map-get($--input-number-border-color, 'default');
&:hover ~ {
@include e(border-layer) {
@ -81,8 +79,9 @@
background-color: map-get($--input-number-button-background-color, 'active')
}
@include m(disabled) {
cursor: not-allowed;
background-color: map-get($--input-number-button-background-color, 'disabled');
color: map-get($--input-number-button-text-color, 'disabled');
fill: map-get($--input-number-button-text-color, 'disabled');
}
}
@include e(minus-button) {