(function(root, factory) { if (typeof define === 'function' && define.amd) { define(factory); } else if (typeof exports === 'object') { module.exports = factory(); } else { root.VMasker = factory(); } }(this, function() { var DIGIT = "9", ALPHA = "A", ALPHANUM = "S", BY_PASS_KEYS = [9, 16, 17, 18, 36, 37, 38, 39, 40, 91, 92, 93], isAllowedKeyCode = function(keyCode) { for (var i = 0, len = BY_PASS_KEYS.length; i < len; i++) { if (keyCode == BY_PASS_KEYS[i]) { return false; } } return true; }, mergeMoneyOptions = function(opts) { opts = opts || {}; opts = { precision: opts.hasOwnProperty("precision") ? opts.precision : 2, separator: opts.separator || ",", delimiter: opts.delimiter || ".", unit: opts.unit && (opts.unit.replace(/[\s]/g,'') + " ") || "", suffixUnit: opts.suffixUnit && (" " + opts.suffixUnit.replace(/[\s]/g,'')) || "", zeroCents: opts.zeroCents, lastOutput: opts.lastOutput }; opts.moneyPrecision = opts.zeroCents ? 0 : opts.precision; return opts; }, // Fill wildcards past index in output with placeholder addPlaceholdersToOutput = function(output, index, placeholder) { for (; index < output.length; index++) { if(output[index] === DIGIT || output[index] === ALPHA || output[index] === ALPHANUM) { output[index] = placeholder; } } return output; } ; var VanillaMasker = function(elements) { this.elements = elements; }; VanillaMasker.prototype.unbindElementToMask = function() { for (var i = 0, len = this.elements.length; i < len; i++) { this.elements[i].lastOutput = ""; this.elements[i].onkeyup = false; this.elements[i].onkeydown = false; if (this.elements[i].value.length) { this.elements[i].value = this.elements[i].value.replace(/\D/g, ''); } } }; VanillaMasker.prototype.bindElementToMask = function(maskFunction) { var that = this, onType = function(e) { e = e || window.event; var source = e.target || e.srcElement; if (isAllowedKeyCode(e.keyCode)) { setTimeout(function() { that.opts.lastOutput = source.lastOutput; source.value = VMasker[maskFunction](source.value, that.opts); source.lastOutput = source.value; if (source.setSelectionRange && that.opts.suffixUnit) { source.setSelectionRange(source.value.length, (source.value.length - that.opts.suffixUnit.length)); } }, 0); } } ; for (var i = 0, len = this.elements.length; i < len; i++) { this.elements[i].lastOutput = ""; this.elements[i].onkeyup = onType; if (this.elements[i].value.length) { this.elements[i].value = VMasker[maskFunction](this.elements[i].value, this.opts); } } }; VanillaMasker.prototype.maskMoney = function(opts) { this.opts = mergeMoneyOptions(opts); this.bindElementToMask("toMoney"); }; VanillaMasker.prototype.maskNumber = function() { this.opts = {}; this.bindElementToMask("toNumber"); }; VanillaMasker.prototype.maskAlphaNum = function() { this.opts = {}; this.bindElementToMask("toAlphaNumeric"); }; VanillaMasker.prototype.maskPattern = function(pattern) { this.opts = {pattern: pattern}; this.bindElementToMask("toPattern"); }; VanillaMasker.prototype.unMask = function() { this.unbindElementToMask(); }; var VMasker = function(el) { if (!el) { throw new Error("VanillaMasker: There is no element to bind."); } var elements = ("length" in el) ? (el.length ? el : []) : [el]; return new VanillaMasker(elements); }; VMasker.toMoney = function(value, opts) { opts = mergeMoneyOptions(opts); if (opts.zeroCents) { opts.lastOutput = opts.lastOutput || ""; var zeroMatcher = ("("+ opts.separator +"[0]{0,"+ opts.precision +"})"), zeroRegExp = new RegExp(zeroMatcher, "g"), digitsLength = value.toString().replace(/[\D]/g, "").length || 0, lastDigitLength = opts.lastOutput.toString().replace(/[\D]/g, "").length || 0 ; value = value.toString().replace(zeroRegExp, ""); if (digitsLength < lastDigitLength) { value = value.slice(0, value.length - 1); } } var number = value.toString().replace(/[\D]/g, ""), clearDelimiter = new RegExp("^(0|\\"+ opts.delimiter +")"), clearSeparator = new RegExp("(\\"+ opts.separator +")$"), money = number.substr(0, number.length - opts.moneyPrecision), masked = money.substr(0, money.length % 3), cents = new Array(opts.precision + 1).join("0") ; money = money.substr(money.length % 3, money.length); for (var i = 0, len = money.length; i < len; i++) { if (i % 3 === 0) { masked += opts.delimiter; } masked += money[i]; } masked = masked.replace(clearDelimiter, ""); masked = masked.length ? masked : "0"; if (!opts.zeroCents) { var beginCents = number.length - opts.precision, centsValue = number.substr(beginCents, opts.precision), centsLength = centsValue.length, centsSliced = (opts.precision > centsLength) ? opts.precision : centsLength ; cents = (cents + centsValue).slice(-centsSliced); } var output = opts.unit + masked + opts.separator + cents + opts.suffixUnit; return output.replace(clearSeparator, ""); }; VMasker.toPattern = function(value, opts) { var pattern = (typeof opts === 'object' ? opts.pattern : opts), patternChars = pattern.replace(/\W/g, ''), output = pattern.split(""), values = value.toString().replace(/\W/g, ""), charsValues = values.replace(/\W/g, ''), index = 0, i, outputLength = output.length, placeholder = (typeof opts === 'object' ? opts.placeholder : undefined) ; for (i = 0; i < outputLength; i++) { // Reached the end of input if (index >= values.length) { if (patternChars.length == charsValues.length) { return output.join(""); } else if ((placeholder !== undefined) && (patternChars.length > charsValues.length)) { return addPlaceholdersToOutput(output, i, placeholder).join(""); } else { break; } } // Remaining chars in input else{ if ((output[i] === DIGIT && values[index].match(/[0-9]/)) || (output[i] === ALPHA && values[index].match(/[a-zA-Z]/)) || (output[i] === ALPHANUM && values[index].match(/[0-9a-zA-Z]/))) { output[i] = values[index++]; } else if (output[i] === DIGIT || output[i] === ALPHA || output[i] === ALPHANUM) { if(placeholder !== undefined){ return addPlaceholdersToOutput(output, i, placeholder).join(""); } else{ return output.slice(0, i).join(""); } } } } return output.join("").substr(0, i); }; VMasker.toNumber = function(value) { return value.toString().replace(/(?!^-)[^0-9]/g, ""); }; VMasker.toAlphaNumeric = function(value) { return value.toString().replace(/[^a-z0-9 ]+/i, ""); }; return VMasker; }));