Skip to content

Commit 478786e

Browse files
committed
[Fix] Reverse Fill Issue
1 parent c3386c0 commit 478786e

File tree

4 files changed

+50
-35
lines changed

4 files changed

+50
-35
lines changed

docs/.vuepress/components/PlayGround.vue

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,7 @@ export default {
149149
suffix: '',
150150
precision: 2,
151151
nullValue: '',
152-
masked: false,
153-
reverseFill: false
152+
masked: false
154153
}
155154
}
156155
},

src/core.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -101,21 +101,22 @@ export function updateCursor(el: HTMLInputElement, position: number) {
101101
*/
102102
export function updateValue(el: CustomInputElement, vnode: VNode | null, { emit = true, force = false, clean = false } = {}) {
103103
const { options, oldValue } = el
104+
const { reverseFill, max, min } = options
104105
const currentValue = vnode && vnode.data && vnode.data.domProps ? vnode.data.domProps.value : el.value
105106

106107
if (force || oldValue !== currentValue) {
107-
const number = new NumberFormat(options).clean(clean && !options.reverseFill)
108+
const number = new NumberFormat(options).clean(clean && !reverseFill)
108109
let masked = number.format(currentValue)
109-
let unmasked = number.clean(options && !options.reverseFill).unformat(currentValue)
110+
let unmasked = number.clean(!reverseFill).unformat(currentValue)
110111

111112
// check value with in range max and min value
112113
if (clean) {
113-
if (Number(options.max) === options.max && Number(unmasked) > options.max) {
114-
masked = number.format(options.max)
115-
unmasked = number.unformat(options.max)
116-
} else if (Number(options.min) === options.min && Number(unmasked) < options.min) {
117-
masked = number.format(options.min)
118-
unmasked = number.unformat(options.min)
114+
if (Number(max) === max && Number(unmasked) > max) {
115+
masked = number.format(max)
116+
unmasked = number.unformat(max)
117+
} else if (Number(min) === min && Number(unmasked) < min) {
118+
masked = number.format(min)
119+
unmasked = number.unformat(min)
119120
}
120121
}
121122

@@ -184,9 +185,9 @@ export function blurHandler(event: Event) {
184185
return false
185186
}
186187

187-
const { oldValue, masked, options } = target
188+
const { oldValue, masked } = target
188189

189-
updateValue(target, null, { force: true, emit: false, clean: options && !options.reverseFill })
190+
updateValue(target, null, { force: true, emit: false, clean: true })
190191

191192
if (oldValue !== target.value) {
192193
target.oldValue = masked

src/directive.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,22 @@ import { VNode } from 'vue'
22
import { DirectiveBinding } from 'vue/types/options'
33
import * as core from './core'
44
import defaultOptions from './options'
5+
import NumberFormat from './number-format'
56

67
export default {
78
bind: (el: core.CustomInputElement, { value, modifiers }: DirectiveBinding, vnode: VNode) => {
89
el = core.getInputElement(el)
910
const options = Object.assign(core.cloneDeep(defaultOptions), value, modifiers)
11+
const { reverseFill, precision } = options
1012
el.options = options
13+
if (reverseFill && el.value) {
14+
el.value = parseFloat(new NumberFormat({ ...options, reverseFill: false }).unformat(el.value)).toFixed(precision)
15+
if (vnode && vnode.data && vnode.data.domProps) {
16+
vnode.data.domProps.value = el.value
17+
}
18+
}
1119
// set initial value
12-
core.updateValue(el, vnode, { force: options.prefill, clean: true, emit: false })
20+
core.updateValue(el, vnode, { force: options.prefill, clean: false, emit: false })
1321
},
1422

1523
inserted: (el: core.CustomInputElement) => {

src/number-format.ts

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,11 @@ export default class NumberFormat {
4040

4141
constructor(config?: Options) {
4242
this.options = Object.assign(defaultOptions, config)
43+
const { prefix, suffix, decimal, reverseFill } = this.options
4344

4445
this.input = ''
4546
this.number = ''
46-
this.isClean = true
47-
48-
const { prefix, suffix, decimal } = this.options
47+
this.isClean = !reverseFill
4948

5049
this.preSurRegExp = new RegExp(`${prefix}|${suffix}`, 'g')
5150
this.numberRegExp = new RegExp(`[^0-9\\${decimal}]+`, 'gi')
@@ -95,23 +94,28 @@ export default class NumberFormat {
9594
}
9695

9796
numbers() {
98-
if (this.options.reverseFill) {
99-
this.number = this.toFixed().replace('.', this.options.decimal)
97+
const { reverseFill, decimal } = this.options
98+
if (reverseFill) {
99+
this.number = this.toFixed().replace('.', decimal)
100100
} else if (typeof this.input === 'number') {
101-
this.number = this.parts(this.input.toString().replace('-', ''), '.').join(this.options.decimal)
101+
this.number = this.parts(this.input.toString().replace('-', ''), '.').join(decimal)
102102
} else {
103-
this.number = this.parts(this.numberOnly()).join(this.options.decimal)
103+
this.number = this.parts(this.numberOnly()).join(decimal)
104104
}
105105
return this.number
106106
}
107107

108+
unformatNumber(): string {
109+
return this.numbers().toString().replace(this.options.decimal, '.')
110+
}
111+
108112
realNumber(): number {
109-
return parseFloat(this.numbers().toString().replace(this.options.decimal, '.'))
113+
return parseFloat(this.unformatNumber())
110114
}
111115

112116
parts(num: Input, separator?: string) {
113-
const decimal = separator || this.options.decimal
114-
let parts: Input[] = num.toString().split(decimal)
117+
const { precision, minimumFractionDigits, decimal } = this.options
118+
let parts: Input[] = num.toString().split(separator || decimal)
115119

116120
if (parts.length > 1) {
117121
parts[0] = this.toNumber(parts[0]) || 0
@@ -120,10 +124,10 @@ export default class NumberFormat {
120124
}
121125

122126
if (this.isClean) {
123-
const newNumber = this.toNumber(parts.join('.')).toFixed(this.options.precision)
127+
const newNumber = this.toNumber(parts.join('.')).toFixed(precision)
124128
const cleanNumber = this.toNumber(newNumber)
125-
const minimumDigits = cleanNumber.toFixed(this.options.minimumFractionDigits)
126-
const hasMinFraction = this.options.minimumFractionDigits >= 0 && cleanNumber.toString().length < minimumDigits.length
129+
const minimumDigits = cleanNumber.toFixed(minimumFractionDigits)
130+
const hasMinFraction = minimumFractionDigits >= 0 && cleanNumber.toString().length < minimumDigits.length
127131

128132
if (hasMinFraction) {
129133
parts = minimumDigits.toString().split('.')
@@ -136,9 +140,10 @@ export default class NumberFormat {
136140
}
137141

138142
addSeparator() {
139-
const parts: Input[] = this.numbers().split(this.options.decimal)
140-
parts[0] = parts[0].toString().replace(/(\d)(?=(?:\d{3})+\b)/gm, `$1${this.options.separator}`)
141-
return parts.join(this.options.decimal)
143+
const { decimal, separator } = this.options
144+
const parts: Input[] = this.numbers().split(decimal)
145+
parts[0] = parts[0].toString().replace(/(\d)(?=(?:\d{3})+\b)/gm, `$1${separator}`)
146+
return parts.join(decimal)
142147
}
143148

144149
/**
@@ -148,10 +153,11 @@ export default class NumberFormat {
148153
*/
149154
format(input: Input): string {
150155
this.input = input
151-
if (this.isNull() && !this.options.reverseFill) {
152-
return this.options.nullValue
156+
const { reverseFill, nullValue, prefix, suffix } = this.options
157+
if (this.isNull() && !reverseFill) {
158+
return nullValue
153159
}
154-
return this.sign() + this.options.prefix + this.addSeparator() + this.options.suffix
160+
return this.sign() + prefix + this.addSeparator() + suffix
155161
}
156162

157163
/**
@@ -161,11 +167,12 @@ export default class NumberFormat {
161167
*/
162168
unformat(input: Input): string {
163169
this.input = input
170+
const { reverseFill, nullValue } = this.options
164171
if (this.isNull()) {
165-
return this.options.nullValue
172+
return nullValue
166173
}
167-
if (this.options.reverseFill && this.realNumber() === 0) {
168-
return this.options.nullValue
174+
if (reverseFill && this.realNumber() === 0) {
175+
return nullValue
169176
}
170177
return this.sign() + this.realNumber()
171178
}

0 commit comments

Comments
 (0)