mirror of
https://github.com/tenrok/maska.git
synced 2026-06-20 20:00:34 +03:00
Make directive change async for correct eager mode
Fix #133 where eager mask used with v-model
This commit is contained in:
+7
-14
@@ -6,13 +6,11 @@ type MaskaDirective = Directive<HTMLElement, MaskaDetail | undefined>
|
|||||||
const masks = new WeakMap<HTMLInputElement, MaskInput>()
|
const masks = new WeakMap<HTMLInputElement, MaskInput>()
|
||||||
|
|
||||||
const checkValue = (input: HTMLInputElement): void => {
|
const checkValue = (input: HTMLInputElement): void => {
|
||||||
const value = input.dataset.maskaValue
|
setTimeout(() => {
|
||||||
if (
|
if (masks.get(input)?.needUpdateValue(input) === true) {
|
||||||
(value == null && input.value !== '') ||
|
input.dispatchEvent(new CustomEvent('input'))
|
||||||
(value != null && value !== input.value)
|
}
|
||||||
) {
|
})
|
||||||
input.dispatchEvent(new CustomEvent('input'))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const vMaska: MaskaDirective = (el, binding) => {
|
export const vMaska: MaskaDirective = (el, binding) => {
|
||||||
@@ -21,10 +19,10 @@ export const vMaska: MaskaDirective = (el, binding) => {
|
|||||||
|
|
||||||
if (input == null) return
|
if (input == null) return
|
||||||
|
|
||||||
|
checkValue(input)
|
||||||
|
|
||||||
const existed = masks.get(input)
|
const existed = masks.get(input)
|
||||||
if (existed != null) {
|
if (existed != null) {
|
||||||
checkValue(input)
|
|
||||||
|
|
||||||
if (!existed.needUpdateOptions(input, opts)) {
|
if (!existed.needUpdateOptions(input, opts)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -49,9 +47,4 @@ export const vMaska: MaskaDirective = (el, binding) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
masks.set(input, new MaskInput(input, opts))
|
masks.set(input, new MaskInput(input, opts))
|
||||||
|
|
||||||
// timeout to process initial v-model value
|
|
||||||
setTimeout(() => {
|
|
||||||
checkValue(input)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-1
@@ -50,6 +50,15 @@ export class MaskInput {
|
|||||||
return JSON.stringify(mask.opts) !== JSON.stringify(maskNew.opts)
|
return JSON.stringify(mask.opts) !== JSON.stringify(maskNew.opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
needUpdateValue (input: HTMLInputElement): boolean {
|
||||||
|
const value = input.dataset.maskaValue
|
||||||
|
|
||||||
|
return (
|
||||||
|
(value == null && input.value !== '') ||
|
||||||
|
(value != null && value !== input.value)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private getMaskOpts (options: MaskInputOptions): MaskOptions {
|
private getMaskOpts (options: MaskInputOptions): MaskOptions {
|
||||||
const { onMaska, preProcess, postProcess, ...opts } = options
|
const { onMaska, preProcess, postProcess, ...opts } = options
|
||||||
|
|
||||||
@@ -98,7 +107,6 @@ export class MaskInput {
|
|||||||
|
|
||||||
const input = e.target as HTMLInputElement
|
const input = e.target as HTMLInputElement
|
||||||
const mask = this.items.get(input) as Mask
|
const mask = this.items.get(input) as Mask
|
||||||
|
|
||||||
const valueOld = input.value
|
const valueOld = input.value
|
||||||
const ss = input.selectionStart
|
const ss = input.selectionStart
|
||||||
const se = input.selectionEnd
|
const se = input.selectionEnd
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { vMaska } from '../../src'
|
import { vMaska } from '../../src'
|
||||||
|
|
||||||
const data = ref('123')
|
const data = ref('1234')
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<input v-maska data-maska="#-#" v-model="data" />
|
<input v-maska data-maska="##-#" v-model="data" data-maska-eager />
|
||||||
<button @click="data = '345'">Set</button>
|
<button @click="data = '5678'">Set</button>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -138,17 +138,20 @@ test('custom component', async () => {
|
|||||||
expect(wrapper.get('div').element.textContent).toBe('1-2')
|
expect(wrapper.get('div').element.textContent).toBe('1-2')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// TODO: find a way to test keyboard input, like backspace after input '567'
|
||||||
test('change value', async () => {
|
test('change value', async () => {
|
||||||
const wrapper = mount(ChangeValue)
|
const wrapper = mount(ChangeValue)
|
||||||
const input = wrapper.get('input')
|
const input = wrapper.get('input')
|
||||||
|
|
||||||
await new Promise((r) => setTimeout(r))
|
await new Promise((r) => setTimeout(r))
|
||||||
|
|
||||||
expect(input.element.value).toBe('1-2')
|
expect(input.element.value).toBe('12-3')
|
||||||
|
|
||||||
await wrapper.get('button').trigger('click')
|
await wrapper.get('button').trigger('click')
|
||||||
|
|
||||||
expect(input.element.value).toBe('3-4')
|
await new Promise((r) => setTimeout(r))
|
||||||
|
|
||||||
|
expect(input.element.value).toBe('56-7')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('multiple inputs', async () => {
|
test('multiple inputs', async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user