diff --git a/src/index.js b/src/index.js index 084ddfae..ee3fad7f 100644 --- a/src/index.js +++ b/src/index.js @@ -1,43 +1,20 @@ import format from './format.js'; +import { trigger } from './utils' /** * Event handler - * @param {HTMLInputElement} target - */ -function handler ({target}) { - let {previousValue, mask} = target.dataset; - - // do nothing if mask is not specified - if(!mask) return; - - if (typeof previousValue === 'string' && previousValue.length < target.value.length) { - target.value = format(target.value, mask); - } - - target.dataset.previousValue = target.value; -} - -/** - * Fires on bind handler * @param {HTMLInputElement} el - * @param {String} mask + * @param {Boolean} force */ -function bindHandler(el, mask) { - el.dataset.mask = mask; - - //add event listener - el.addEventListener('input', handler, false); +function updateValue (el, force = false) { + let {value, dataset: {previousValue, mask } } = el; - // run format function right after bind - handler({target: el}) -} + if(force || (value && value !== previousValue && value.length > previousValue.length)) { + el.value = format(value, mask); + trigger(el, 'input') + } -/** - * Fires on unbind handler - * @param {HTMLInputElement} el - */ -function unbindHandler(el) { - el.removeEventListener('input', handler, false); + el.dataset.previousValue = value; } /** @@ -45,12 +22,9 @@ function unbindHandler(el) { * @param {HTMLInputElement} el * @param {String} mask */ -function updateHandler(el, mask){ +function updateMask(el, mask) { // change format el.dataset.mask = mask; - - // run format function with new mask - el.value = format(el.value, mask); } @@ -69,14 +43,10 @@ export default function (Vue) { * @param {?String} value */ bind (el, {value}) { - bindHandler(el, value); + updateMask(el, value); + updateValue(el); }, - /** - * Called only once, when the directive is unbound from the element. - */ - unbind: unbindHandler, - /** * Called after the containing component has updated, * but possibly before its children have updated. @@ -88,11 +58,17 @@ export default function (Vue) { * @param {?String} value * @param {?String} oldValue */ - update(el, {value, oldValue}){ - // if mask was not changed - do nothing - if (value === oldValue) return; + componentUpdated(el, {value, oldValue}){ + + let isMaskChanged = value !== oldValue; + + // update mask first if changed + if(isMaskChanged){ + updateMask(el, value); + } - updateHandler(el, value) + // update value + updateValue(el, isMaskChanged); } }); }; diff --git a/src/utils/index.js b/src/utils/index.js new file mode 100644 index 00000000..68c638a3 --- /dev/null +++ b/src/utils/index.js @@ -0,0 +1,12 @@ +/** + * Notifies Vue about internal value change + * @see https://github.com/vuejs/Discussion/issues/157#issuecomment-273301588 + * + * @param {HTMLInputElement} el + * @param {String} type + */ +export const trigger = (el, type) => { + const e = document.createEvent('HTMLEvents'); + e.initEvent(type, true, true); + el.dispatchEvent(e) +};