Skip to content

Commit 45a1e89

Browse files
committed
fix(directive): get the current value from a component's model when available
When the directive is used on a custom component that has its own model, but that model is not been bound back to the input's value property, the directive is not getting the proper value as part of the update hook. Such is the case with vuetify's v-text-input. This can be resolved by checking the vnode to see if a model is defined, if so get the value for masking from the model rather than from the input.value. fixes #10, fixes #11, resolves vuetifyjs/vuetify#10890
1 parent ce8135b commit 45a1e89

File tree

2 files changed

+15
-12
lines changed

2 files changed

+15
-12
lines changed

src/core.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export function inputHandler(event) {
6868
const originalPosition = target.selectionEnd
6969
const { oldValue } = target[CONFIG_KEY]
7070

71-
updateValue(target, { emit: false }, event)
71+
updateValue(target, null, { emit: false }, event)
7272
updateCursor(event, originalValue, originalPosition)
7373

7474
if (oldValue !== target.value) {
@@ -133,11 +133,12 @@ export function updateCursor(event, originalValue, originalPosition) {
133133
* @param {Boolean} options.force Forces the update even if the old value and the new value are the same
134134
* @param {Event} [event] The event that triggered this this update, null if not triggered by an input event
135135
*/
136-
export function updateValue(el, { emit = true, force = false } = {}, event) {
136+
export function updateValue(el, vnode, { emit = true, force = false } = {}, event) {
137137
const { config, oldValue } = el[CONFIG_KEY]
138+
const currentValue = vnode && vnode.data.model ? vnode.data.model.value : el.value
138139

139-
if (force || oldValue !== el.value) {
140-
let newValue = masker(el.value, config)
140+
if (force || oldValue !== currentValue) {
141+
let newValue = masker(currentValue, config)
141142

142143
if (event && typeof config.formatter === 'function') {
143144
const formattedValue = config.formatter(newValue, event)
@@ -151,11 +152,13 @@ export function updateValue(el, { emit = true, force = false } = {}, event) {
151152
}
152153

153154
el[CONFIG_KEY].oldValue = newValue.masked
154-
// fixes safari issue where setting the value also resets cursor to end of input
155+
el.unmaskedValue = newValue.unmasked
156+
157+
// safari makes the cursor jump to the end if el.value gets assign even if to the same value
158+
// additionally, vuetify is trigering directive.update twice at init, this check ensures we only emit once
155159
if (el.value !== newValue.masked) {
156160
el.value = newValue.masked
161+
emit && el.dispatchEvent(FacadeInputEvent())
157162
}
158-
el.unmaskedValue = newValue.unmasked
159-
emit && el.dispatchEvent(FacadeInputEvent())
160163
}
161164
}

src/directive.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as core from './core'
22
const CONFIG_KEY = core.CONFIG_KEY
33

44
export default {
5-
bind: function(el, binding) {
5+
bind: (el, binding, vnode) => {
66
el = core.getInputElement(el)
77
el.addEventListener('input', core.inputHandler, true)
88

@@ -11,17 +11,17 @@ export default {
1111
}
1212

1313
// set initial value
14-
core.updateValue(el)
14+
core.updateValue(el, vnode)
1515
},
1616

17-
update: (el, { value, oldValue }) => {
17+
update: (el, { value, oldValue }, vnode) => {
1818
el = core.getInputElement(el)
1919

2020
if (value !== oldValue) {
2121
el[CONFIG_KEY].config = core.normalizeConfig(value)
22-
core.updateValue(el, { force: true })
22+
core.updateValue(el, vnode, { force: true })
2323
} else {
24-
core.updateValue(el)
24+
core.updateValue(el, vnode)
2525
}
2626
},
2727

0 commit comments

Comments
 (0)