mirror of
https://github.com/itflow-org/itflow
synced 2026-03-09 23:34:50 +00:00
added input masks
This commit is contained in:
374
vendor/Inputmask/lib/inputmask.js
vendored
Normal file
374
vendor/Inputmask/lib/inputmask.js
vendored
Normal file
@@ -0,0 +1,374 @@
|
||||
/*
|
||||
* Input Mask Core
|
||||
* http://github.com/RobinHerbots/jquery.inputmask
|
||||
* Copyright (c) Robin Herbots
|
||||
* Licensed under the MIT license
|
||||
*/
|
||||
var $ = require("./dependencyLibs/inputmask.dependencyLib"), window = require("./global/window"),
|
||||
document = window.document,
|
||||
generateMaskSet = require("./maskset").generateMaskSet,
|
||||
analyseMask = require("./maskset").analyseMask,
|
||||
maskScope = require("./maskScope");
|
||||
|
||||
|
||||
function Inputmask(alias, options, internal) {
|
||||
//allow instanciating without new
|
||||
if (!(this instanceof Inputmask)) {
|
||||
return new Inputmask(alias, options, internal);
|
||||
}
|
||||
|
||||
this.el = undefined;
|
||||
this.events = {};
|
||||
this.maskset = undefined;
|
||||
this.refreshValue = false; //indicate a refresh from the inputvalue is needed (form.reset)
|
||||
|
||||
if (internal !== true) {
|
||||
//init options
|
||||
if ($.isPlainObject(alias)) {
|
||||
options = alias;
|
||||
} else {
|
||||
options = options || {};
|
||||
if (alias) options.alias = alias;
|
||||
}
|
||||
this.opts = $.extend(true, {}, this.defaults, options);
|
||||
this.noMasksCache = options && options.definitions !== undefined;
|
||||
this.userOptions = options || {}; //user passed options
|
||||
resolveAlias(this.opts.alias, options, this.opts);
|
||||
this.isRTL = this.opts.numericInput;
|
||||
}
|
||||
}
|
||||
|
||||
Inputmask.prototype = {
|
||||
dataAttribute: "data-inputmask", //data attribute prefix used for attribute binding
|
||||
//options default
|
||||
defaults: {
|
||||
placeholder: "_",
|
||||
optionalmarker: ["[", "]"],
|
||||
quantifiermarker: ["{", "}"],
|
||||
groupmarker: ["(", ")"],
|
||||
alternatormarker: "|",
|
||||
escapeChar: "\\",
|
||||
mask: null, //needs tobe null instead of undefined as the extend method does not consider props with the undefined value
|
||||
regex: null, //regular expression as a mask
|
||||
oncomplete: $.noop, //executes when the mask is complete
|
||||
onincomplete: $.noop, //executes when the mask is incomplete and focus is lost
|
||||
oncleared: $.noop, //executes when the mask is cleared
|
||||
repeat: 0, //repetitions of the mask: * ~ forever, otherwise specify an integer
|
||||
greedy: false, //true: allocated buffer for the mask and repetitions - false: allocate only if needed
|
||||
autoUnmask: false, //automatically unmask when retrieving the value with $.fn.val or value if the browser supports __lookupGetter__ or getOwnPropertyDescriptor
|
||||
removeMaskOnSubmit: false, //remove the mask before submitting the form.
|
||||
clearMaskOnLostFocus: true,
|
||||
insertMode: true, //insert the input or overwrite the input
|
||||
clearIncomplete: false, //clear the incomplete input on blur
|
||||
alias: null,
|
||||
onKeyDown: $.noop, //callback to implement autocomplete on certain keys for example. args => event, buffer, caretPos, opts
|
||||
onBeforeMask: null, //executes before masking the initial value to allow preprocessing of the initial value. args => initialValue, opts => return processedValue
|
||||
onBeforePaste: function (pastedValue, opts) {
|
||||
return $.isFunction(opts.onBeforeMask) ? opts.onBeforeMask.call(this, pastedValue, opts) : pastedValue;
|
||||
}, //executes before masking the pasted value to allow preprocessing of the pasted value. args => pastedValue, opts => return processedValue
|
||||
onBeforeWrite: null, //executes before writing to the masked element. args => event, opts
|
||||
onUnMask: null, //executes after unmasking to allow postprocessing of the unmaskedvalue. args => maskedValue, unmaskedValue, opts
|
||||
showMaskOnFocus: true, //show the mask-placeholder when the input has focus
|
||||
showMaskOnHover: true, //show the mask-placeholder when hovering the empty input
|
||||
onKeyValidation: $.noop, //executes on every key-press with the result of isValid. Params: key, result, opts
|
||||
skipOptionalPartCharacter: " ", //a character which can be used to skip an optional part of a mask
|
||||
numericInput: false, //numericInput input direction style (input shifts to the left while holding the caret position)
|
||||
rightAlign: false, //align to the right
|
||||
undoOnEscape: true, //pressing escape reverts the value to the value before focus
|
||||
//numeric basic properties
|
||||
radixPoint: "", //".", // | ","
|
||||
_radixDance: false, //dance around the radixPoint
|
||||
groupSeparator: "", //",", // | "."
|
||||
//numeric basic properties
|
||||
keepStatic: null, //try to keep the mask static while typing. Decisions to alter the mask will be posponed if possible - null see auto selection for multi masks
|
||||
positionCaretOnTab: true, //when enabled the caret position is set after the latest valid position on TAB
|
||||
tabThrough: false, //allows for tabbing through the different parts of the masked field
|
||||
supportsInputType: ["text", "tel", "url", "password", "search"], //list with the supported input types
|
||||
//specify keyCodes which should not be considered in the keypress event, otherwise the preventDefault will stop their default behavior especially in FF
|
||||
ignorables: [8, 9, 13, 19, 27, 33, 34, 35, 36, 37, 38, 39, 40, 45, 46, 93, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 0, 229],
|
||||
isComplete: null, //override for isComplete - args => buffer, opts - return true || false
|
||||
preValidation: null, //hook to preValidate the input. Usefull for validating regardless the definition. args => buffer, pos, char, isSelection, opts => return true/false/command object
|
||||
postValidation: null, //hook to postValidate the result from isValid. Usefull for validating the entry as a whole. args => buffer, pos, currentResult, opts => return true/false/json
|
||||
staticDefinitionSymbol: undefined, //specify a definitionSymbol for static content, used to make matches for alternators
|
||||
jitMasking: false, //just in time masking ~ only mask while typing, can n (number), true or false
|
||||
nullable: true, //return nothing instead of the buffertemplate when the user hasn't entered anything.
|
||||
inputEventOnly: false, //dev option - testing inputfallback behavior
|
||||
noValuePatching: false, //disable value property patching
|
||||
positionCaretOnClick: "lvp", //none, lvp (based on the last valid position (default), radixFocus (position caret to radixpoint on initial click), select (select the whole input), ignore (ignore the click and continue the mask)
|
||||
casing: null, //mask-level casing. Options: null, "upper", "lower" or "title" or callback args => elem, test, pos, validPositions return charValue
|
||||
inputmode: "verbatim", //specify the inputmode - already in place for when browsers will support it
|
||||
colorMask: false, //enable css styleable mask
|
||||
disablePredictiveText: false, //disable Predictive Text on mobile devices
|
||||
importDataAttributes: true, //import data-inputmask attributes
|
||||
shiftPositions: true //shift position of the mask entries on entry and deletion.
|
||||
},
|
||||
definitions: {
|
||||
"9": { //\uFF11-\uFF19 #1606
|
||||
validator: "[0-9\uFF11-\uFF19]",
|
||||
definitionSymbol: "*"
|
||||
},
|
||||
"a": { //\u0410-\u044F\u0401\u0451\u00C0-\u00FF\u00B5 #76
|
||||
validator: "[A-Za-z\u0410-\u044F\u0401\u0451\u00C0-\u00FF\u00B5]",
|
||||
definitionSymbol: "*"
|
||||
},
|
||||
"*": {
|
||||
validator: "[0-9\uFF11-\uFF19A-Za-z\u0410-\u044F\u0401\u0451\u00C0-\u00FF\u00B5]"
|
||||
}
|
||||
},
|
||||
aliases: {}, //aliases definitions
|
||||
masksCache: {},
|
||||
mask: function (elems) {
|
||||
var that = this;
|
||||
if (typeof elems === "string") {
|
||||
elems = document.getElementById(elems) || document.querySelectorAll(elems);
|
||||
}
|
||||
elems = elems.nodeName ? [elems] : elems;
|
||||
$.each(elems, function (ndx, el) {
|
||||
var scopedOpts = $.extend(true, {}, that.opts);
|
||||
if (importAttributeOptions(el, scopedOpts, $.extend(true, {}, that.userOptions), that.dataAttribute)) {
|
||||
var maskset = generateMaskSet(scopedOpts, that.noMasksCache);
|
||||
if (maskset !== undefined) {
|
||||
if (el.inputmask !== undefined) {
|
||||
el.inputmask.opts.autoUnmask = true; //force autounmasking when remasking
|
||||
el.inputmask.remove();
|
||||
}
|
||||
//store inputmask instance on the input with element reference
|
||||
el.inputmask = new Inputmask(undefined, undefined, true);
|
||||
el.inputmask.opts = scopedOpts;
|
||||
el.inputmask.noMasksCache = that.noMasksCache;
|
||||
el.inputmask.userOptions = $.extend(true, {}, that.userOptions);
|
||||
el.inputmask.isRTL = scopedOpts.isRTL || scopedOpts.numericInput;
|
||||
el.inputmask.el = el;
|
||||
el.inputmask.maskset = maskset;
|
||||
|
||||
$.data(el, "_inputmask_opts", scopedOpts);
|
||||
|
||||
maskScope.call(el.inputmask, {
|
||||
"action": "mask"
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return elems && elems[0] ? (elems[0].inputmask || this) : this;
|
||||
},
|
||||
option: function (options, noremask) { //set extra options || retrieve value of a current option
|
||||
if (typeof options === "string") {
|
||||
return this.opts[options];
|
||||
} else if (typeof options === "object") {
|
||||
$.extend(this.userOptions, options); //user passed options
|
||||
//remask
|
||||
if (this.el && noremask !== true) {
|
||||
this.mask(this.el);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
},
|
||||
unmaskedvalue: function (value) {
|
||||
this.maskset = this.maskset || generateMaskSet(this.opts, this.noMasksCache);
|
||||
return maskScope.call(this, {
|
||||
"action": "unmaskedvalue",
|
||||
"value": value
|
||||
});
|
||||
},
|
||||
remove: function () {
|
||||
return maskScope.call(this, {
|
||||
"action": "remove"
|
||||
});
|
||||
},
|
||||
getemptymask: function () { //return the default (empty) mask value, usefull for setting the default value in validation
|
||||
this.maskset = this.maskset || generateMaskSet(this.opts, this.noMasksCache);
|
||||
return maskScope.call(this, {
|
||||
"action": "getemptymask"
|
||||
});
|
||||
},
|
||||
hasMaskedValue: function () { //check wheter the returned value is masked or not; currently only works reliable when using jquery.val fn to retrieve the value
|
||||
return !this.opts.autoUnmask;
|
||||
},
|
||||
isComplete: function () {
|
||||
this.maskset = this.maskset || generateMaskSet(this.opts, this.noMasksCache);
|
||||
return maskScope.call(this, {
|
||||
"action": "isComplete"
|
||||
});
|
||||
},
|
||||
getmetadata: function () { //return mask metadata if exists
|
||||
this.maskset = this.maskset || generateMaskSet(this.opts, this.noMasksCache);
|
||||
return maskScope.call(this, {
|
||||
"action": "getmetadata"
|
||||
});
|
||||
},
|
||||
isValid: function (value) {
|
||||
this.maskset = this.maskset || generateMaskSet(this.opts, this.noMasksCache);
|
||||
return maskScope.call(this, {
|
||||
"action": "isValid",
|
||||
"value": value
|
||||
});
|
||||
},
|
||||
format: function (value, metadata) {
|
||||
this.maskset = this.maskset || generateMaskSet(this.opts, this.noMasksCache);
|
||||
return maskScope.call(this, {
|
||||
"action": "format",
|
||||
"value": value,
|
||||
"metadata": metadata //true/false getmetadata
|
||||
});
|
||||
},
|
||||
setValue: function (value) {
|
||||
if (this.el) {
|
||||
$(this.el).trigger("setvalue", [value]);
|
||||
}
|
||||
},
|
||||
analyseMask: analyseMask,
|
||||
positionColorMask: function (input, template) {
|
||||
input.style.left = template.offsetLeft + "px";
|
||||
}
|
||||
};
|
||||
|
||||
function resolveAlias(aliasStr, options, opts) {
|
||||
var aliasDefinition = Inputmask.prototype.aliases[aliasStr];
|
||||
if (aliasDefinition) {
|
||||
if (aliasDefinition.alias) resolveAlias(aliasDefinition.alias, undefined, opts); //alias is another alias
|
||||
$.extend(true, opts, aliasDefinition); //merge alias definition in the options
|
||||
$.extend(true, opts, options); //reapply extra given options
|
||||
return true;
|
||||
} else //alias not found - try as mask
|
||||
if (opts.mask === null) {
|
||||
opts.mask = aliasStr;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function importAttributeOptions(npt, opts, userOptions, dataAttribute) {
|
||||
function importOption(option, optionData) {
|
||||
optionData = optionData !== undefined ? optionData : npt.getAttribute(dataAttribute + "-" + option);
|
||||
if (optionData !== null) {
|
||||
if (typeof optionData === "string") {
|
||||
if (option.indexOf("on") === 0) {
|
||||
optionData = window[optionData];
|
||||
}//get function definition
|
||||
else if (optionData === "false") {
|
||||
optionData = false;
|
||||
} else if (optionData === "true") optionData = true;
|
||||
}
|
||||
userOptions[option] = optionData;
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.importDataAttributes === true) {
|
||||
var attrOptions = npt.getAttribute(dataAttribute), option, dataoptions, optionData, p;
|
||||
|
||||
if (attrOptions && attrOptions !== "") {
|
||||
attrOptions = attrOptions.replace(/'/g, "\"");
|
||||
dataoptions = JSON.parse("{" + attrOptions + "}");
|
||||
}
|
||||
|
||||
//resolve aliases
|
||||
if (dataoptions) { //pickup alias from dataAttribute
|
||||
optionData = undefined;
|
||||
for (p in dataoptions) {
|
||||
if (p.toLowerCase() === "alias") {
|
||||
optionData = dataoptions[p];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
importOption("alias", optionData); //pickup alias from dataAttribute-alias
|
||||
if (userOptions.alias) {
|
||||
resolveAlias(userOptions.alias, userOptions, opts);
|
||||
}
|
||||
|
||||
for (option in opts) {
|
||||
if (dataoptions) {
|
||||
optionData = undefined;
|
||||
for (p in dataoptions) {
|
||||
if (p.toLowerCase() === option.toLowerCase()) {
|
||||
optionData = dataoptions[p];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
importOption(option, optionData);
|
||||
}
|
||||
}
|
||||
$.extend(true, opts, userOptions);
|
||||
|
||||
//handle dir=rtl
|
||||
if (npt.dir === "rtl" || opts.rightAlign) {
|
||||
npt.style.textAlign = "right";
|
||||
}
|
||||
|
||||
if (npt.dir === "rtl" || opts.numericInput) {
|
||||
npt.dir = "ltr";
|
||||
npt.removeAttribute("dir");
|
||||
opts.isRTL = true;
|
||||
}
|
||||
|
||||
return Object.keys(userOptions).length;
|
||||
}
|
||||
|
||||
//apply defaults, definitions, aliases
|
||||
Inputmask.extendDefaults = function (options) {
|
||||
$.extend(true, Inputmask.prototype.defaults, options);
|
||||
};
|
||||
Inputmask.extendDefinitions = function (definition) {
|
||||
$.extend(true, Inputmask.prototype.definitions, definition);
|
||||
};
|
||||
Inputmask.extendAliases = function (alias) {
|
||||
$.extend(true, Inputmask.prototype.aliases, alias);
|
||||
};
|
||||
//static fn on inputmask
|
||||
Inputmask.format = function (value, options, metadata) {
|
||||
return Inputmask(options).format(value, metadata);
|
||||
};
|
||||
Inputmask.unmask = function (value, options) {
|
||||
return Inputmask(options).unmaskedvalue(value);
|
||||
};
|
||||
Inputmask.isValid = function (value, options) {
|
||||
return Inputmask(options).isValid(value);
|
||||
};
|
||||
Inputmask.remove = function (elems) {
|
||||
if (typeof elems === "string") {
|
||||
elems = document.getElementById(elems) || document.querySelectorAll(elems);
|
||||
}
|
||||
elems = elems.nodeName ? [elems] : elems;
|
||||
$.each(elems, function (ndx, el) {
|
||||
if (el.inputmask) el.inputmask.remove();
|
||||
});
|
||||
};
|
||||
Inputmask.setValue = function (elems, value) {
|
||||
if (typeof elems === "string") {
|
||||
elems = document.getElementById(elems) || document.querySelectorAll(elems);
|
||||
}
|
||||
elems = elems.nodeName ? [elems] : elems;
|
||||
$.each(elems, function (ndx, el) {
|
||||
if (el.inputmask) el.inputmask.setValue(value); else $(el).trigger("setvalue", [value]);
|
||||
});
|
||||
};
|
||||
Inputmask.escapeRegex = function (str) {
|
||||
var specials = ["/", ".", "*", "+", "?", "|", "(", ")", "[", "]", "{", "}", "\\", "$", "^"];
|
||||
return str.replace(new RegExp("(\\" + specials.join("|\\") + ")", "gim"), "\\$1");
|
||||
};
|
||||
Inputmask.keyCode = {
|
||||
BACKSPACE: 8,
|
||||
BACKSPACE_SAFARI: 127,
|
||||
DELETE: 46,
|
||||
DOWN: 40,
|
||||
END: 35,
|
||||
ENTER: 13,
|
||||
ESCAPE: 27,
|
||||
HOME: 36,
|
||||
INSERT: 45,
|
||||
LEFT: 37,
|
||||
PAGE_DOWN: 34,
|
||||
PAGE_UP: 33,
|
||||
RIGHT: 39,
|
||||
SPACE: 32,
|
||||
TAB: 9,
|
||||
UP: 38,
|
||||
X: 88,
|
||||
CONTROL: 17
|
||||
};
|
||||
Inputmask.dependencyLib = $;
|
||||
|
||||
//make inputmask available
|
||||
window.Inputmask = Inputmask;
|
||||
module.exports = Inputmask;
|
||||
Reference in New Issue
Block a user