123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861 |
- /*!
- * v0.1.5
- * Copyright (c) 2014 First Opinion
- * formatter.js is open sourced under the MIT license.
- *
- * thanks to digitalBush/jquery.maskedinput for some of the trickier
- * keycode handling
- */
- //
- // Uses CommonJS, AMD or browser globals to create a jQuery plugin.
- //
- // Similar to jqueryPlugin.js but also tries to
- // work in a CommonJS environment.
- // It is unlikely jQuery will run in a CommonJS
- // environment. See jqueryPlugin.js if you do
- // not want to add the extra CommonJS detection.
- //
- (function (root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['jQuery'], factory);
- } else if (typeof exports === 'object') {
- factory(require('jQuery'));
- } else {
- // Browser globals
- factory(root.jQuery);
- }
- }(this, function (jQuery) {
- /*
- * pattern.js
- *
- * Utilities to parse str pattern and return info
- *
- */
- var pattern = function () {
- // Define module
- var pattern = {};
- // Match information
- var DELIM_SIZE = 4;
- // Our regex used to parse
- var regexp = new RegExp('{{([^}]+)}}', 'g');
- //
- // Helper method to parse pattern str
- //
- var getMatches = function (pattern) {
- // Populate array of matches
- var matches = [], match;
- while (match = regexp.exec(pattern)) {
- matches.push(match);
- }
- return matches;
- };
- //
- // Create an object holding all formatted characters
- // with corresponding positions
- //
- pattern.parse = function (pattern) {
- // Our obj to populate
- var info = {
- inpts: {},
- chars: {}
- };
- // Pattern information
- var matches = getMatches(pattern), pLength = pattern.length;
- // Counters
- var mCount = 0, iCount = 0, i = 0;
- // Add inpts, move to end of match, and process
- var processMatch = function (val) {
- var valLength = val.length;
- for (var j = 0; j < valLength; j++) {
- info.inpts[iCount] = val.charAt(j);
- iCount++;
- }
- mCount++;
- i += val.length + DELIM_SIZE - 1;
- };
- // Process match or add chars
- for (i; i < pLength; i++) {
- if (mCount < matches.length && i === matches[mCount].index) {
- processMatch(matches[mCount][1]);
- } else {
- info.chars[i - mCount * DELIM_SIZE] = pattern.charAt(i);
- }
- }
- // Set mLength and return
- info.mLength = i - mCount * DELIM_SIZE;
- return info;
- };
- // Expose
- return pattern;
- }();
- /*
- * utils.js
- *
- * Independent helper methods (cross browser, etc..)
- *
- */
- var utils = function () {
- // Define module
- var utils = {};
- // Useragent info for keycode handling
- var uAgent = typeof navigator !== 'undefined' ? navigator.userAgent : null;
- //
- // Shallow copy properties from n objects to destObj
- //
- utils.extend = function (destObj) {
- for (var i = 1; i < arguments.length; i++) {
- for (var key in arguments[i]) {
- destObj[key] = arguments[i][key];
- }
- }
- return destObj;
- };
- //
- // Add a given character to a string at a defined pos
- //
- utils.addChars = function (str, chars, pos) {
- return str.substr(0, pos) + chars + str.substr(pos, str.length);
- };
- //
- // Remove a span of characters
- //
- utils.removeChars = function (str, start, end) {
- return str.substr(0, start) + str.substr(end, str.length);
- };
- //
- // Return true/false is num false between bounds
- //
- utils.isBetween = function (num, bounds) {
- bounds.sort(function (a, b) {
- return a - b;
- });
- return num > bounds[0] && num < bounds[1];
- };
- //
- // Helper method for cross browser event listeners
- //
- utils.addListener = function (el, evt, handler) {
- return typeof el.addEventListener !== 'undefined' ? el.addEventListener(evt, handler, false) : el.attachEvent('on' + evt, handler);
- };
- //
- // Helper method for cross browser implementation of preventDefault
- //
- utils.preventDefault = function (evt) {
- return evt.preventDefault ? evt.preventDefault() : evt.returnValue = false;
- };
- //
- // Helper method for cross browser implementation for grabbing
- // clipboard data
- //
- utils.getClip = function (evt) {
- if (evt.clipboardData) {
- return evt.clipboardData.getData('Text');
- }
- if (window.clipboardData) {
- return window.clipboardData.getData('Text');
- }
- };
- //
- // Loop over object and checking for matching properties
- //
- utils.getMatchingKey = function (which, keyCode, keys) {
- // Loop over and return if matched.
- for (var k in keys) {
- var key = keys[k];
- if (which === key.which && keyCode === key.keyCode) {
- return k;
- }
- }
- };
- //
- // Returns true/false if k is a del keyDown
- //
- utils.isDelKeyDown = function (which, keyCode) {
- var keys = {
- 'backspace': {
- 'which': 8,
- 'keyCode': 8
- },
- 'delete': {
- 'which': 46,
- 'keyCode': 46
- }
- };
- return utils.getMatchingKey(which, keyCode, keys);
- };
- //
- // Returns true/false if k is a del keyPress
- //
- utils.isDelKeyPress = function (which, keyCode) {
- var keys = {
- 'backspace': {
- 'which': 8,
- 'keyCode': 8,
- 'shiftKey': false
- },
- 'delete': {
- 'which': 0,
- 'keyCode': 46
- }
- };
- return utils.getMatchingKey(which, keyCode, keys);
- };
- // //
- // // Determine if keydown relates to specialKey
- // //
- // utils.isSpecialKeyDown = function (which, keyCode) {
- // var keys = {
- // 'tab': { 'which': 9, 'keyCode': 9 },
- // 'enter': { 'which': 13, 'keyCode': 13 },
- // 'end': { 'which': 35, 'keyCode': 35 },
- // 'home': { 'which': 36, 'keyCode': 36 },
- // 'leftarrow': { 'which': 37, 'keyCode': 37 },
- // 'uparrow': { 'which': 38, 'keyCode': 38 },
- // 'rightarrow': { 'which': 39, 'keyCode': 39 },
- // 'downarrow': { 'which': 40, 'keyCode': 40 },
- // 'F5': { 'which': 116, 'keyCode': 116 }
- // };
- // return utils.getMatchingKey(which, keyCode, keys);
- // };
- //
- // Determine if keypress relates to specialKey
- //
- utils.isSpecialKeyPress = function (which, keyCode) {
- var keys = {
- 'tab': {
- 'which': 0,
- 'keyCode': 9
- },
- 'enter': {
- 'which': 13,
- 'keyCode': 13
- },
- 'end': {
- 'which': 0,
- 'keyCode': 35
- },
- 'home': {
- 'which': 0,
- 'keyCode': 36
- },
- 'leftarrow': {
- 'which': 0,
- 'keyCode': 37
- },
- 'uparrow': {
- 'which': 0,
- 'keyCode': 38
- },
- 'rightarrow': {
- 'which': 0,
- 'keyCode': 39
- },
- 'downarrow': {
- 'which': 0,
- 'keyCode': 40
- },
- 'F5': {
- 'which': 116,
- 'keyCode': 116
- }
- };
- return utils.getMatchingKey(which, keyCode, keys);
- };
- //
- // Returns true/false if modifier key is held down
- //
- utils.isModifier = function (evt) {
- return evt.ctrlKey || evt.altKey || evt.metaKey;
- };
- //
- // Iterates over each property of object or array.
- //
- utils.forEach = function (collection, callback, thisArg) {
- if (collection.hasOwnProperty('length')) {
- for (var index = 0, len = collection.length; index < len; index++) {
- if (callback.call(thisArg, collection[index], index, collection) === false) {
- break;
- }
- }
- } else {
- for (var key in collection) {
- if (collection.hasOwnProperty(key)) {
- if (callback.call(thisArg, collection[key], key, collection) === false) {
- break;
- }
- }
- }
- }
- };
- // Expose
- return utils;
- }();
- /*
- * pattern-matcher.js
- *
- * Parses a pattern specification and determines appropriate pattern for an
- * input string
- *
- */
- var patternMatcher = function (pattern, utils) {
- //
- // Parse a matcher string into a RegExp. Accepts valid regular
- // expressions and the catchall '*'.
- // @private
- //
- var parseMatcher = function (matcher) {
- if (matcher === '*') {
- return /.*/;
- }
- return new RegExp(matcher);
- };
- //
- // Parse a pattern spec and return a function that returns a pattern
- // based on user input. The first matching pattern will be chosen.
- // Pattern spec format:
- // Array [
- // Object: { Matcher(RegExp String) : Pattern(Pattern String) },
- // ...
- // ]
- function patternMatcher(patternSpec) {
- var matchers = [], patterns = [];
- // Iterate over each pattern in order.
- utils.forEach(patternSpec, function (patternMatcher) {
- // Process single property object to obtain pattern and matcher.
- utils.forEach(patternMatcher, function (patternStr, matcherStr) {
- var parsedPattern = pattern.parse(patternStr), regExpMatcher = parseMatcher(matcherStr);
- matchers.push(regExpMatcher);
- patterns.push(parsedPattern);
- // Stop after one iteration.
- return false;
- });
- });
- var getPattern = function (input) {
- var matchedIndex;
- utils.forEach(matchers, function (matcher, index) {
- if (matcher.test(input)) {
- matchedIndex = index;
- return false;
- }
- });
- return matchedIndex === undefined ? null : patterns[matchedIndex];
- };
- return {
- getPattern: getPattern,
- patterns: patterns,
- matchers: matchers
- };
- }
- // Expose
- return patternMatcher;
- }(pattern, utils);
- /*
- * inpt-sel.js
- *
- * Cross browser implementation to get and set input selections
- *
- */
- var inptSel = function () {
- // Define module
- var inptSel = {};
- //
- // Get begin and end positions of selected input. Return 0's
- // if there is no selectiion data
- //
- inptSel.get = function (el) {
- // If normal browser return with result
- if (typeof el.selectionStart === 'number') {
- return {
- begin: el.selectionStart,
- end: el.selectionEnd
- };
- }
- // Uh-Oh. We must be IE. Fun with TextRange!!
- var range = document.selection.createRange();
- // Determine if there is a selection
- if (range && range.parentElement() === el) {
- var inputRange = el.createTextRange(), endRange = el.createTextRange(), length = el.value.length;
- // Create a working TextRange for the input selection
- inputRange.moveToBookmark(range.getBookmark());
- // Move endRange begin pos to end pos (hence endRange)
- endRange.collapse(false);
- // If we are at the very end of the input, begin and end
- // must both be the length of the el.value
- if (inputRange.compareEndPoints('StartToEnd', endRange) > -1) {
- return {
- begin: length,
- end: length
- };
- }
- // Note: moveStart usually returns the units moved, which
- // one may think is -length, however, it will stop when it
- // gets to the begin of the range, thus giving us the
- // negative value of the pos.
- return {
- begin: -inputRange.moveStart('character', -length),
- end: -inputRange.moveEnd('character', -length)
- };
- }
- //Return 0's on no selection data
- return {
- begin: 0,
- end: 0
- };
- };
- //
- // Set the caret position at a specified location
- //
- inptSel.set = function (el, pos) {
- // Normalize pos
- if (typeof pos !== 'object') {
- pos = {
- begin: pos,
- end: pos
- };
- }
- // If normal browser
- if (el.setSelectionRange) {
- el.focus();
- el.setSelectionRange(pos.begin, pos.end);
- } else if (el.createTextRange) {
- var range = el.createTextRange();
- range.collapse(true);
- range.moveEnd('character', pos.end);
- range.moveStart('character', pos.begin);
- range.select();
- }
- };
- // Expose
- return inptSel;
- }();
- /*
- * formatter.js
- *
- * Class used to format input based on passed pattern
- *
- */
- var formatter = function (patternMatcher, inptSel, utils) {
- // Defaults
- var defaults = {
- persistent: false,
- repeat: false,
- placeholder: ' '
- };
- // Regexs for input validation
- var inptRegs = {
- '9': /[0-9]/,
- 'a': /[A-Za-z]/,
- '*': /[A-Za-z0-9]/
- };
- //
- // Class Constructor - Called with new Formatter(el, opts)
- // Responsible for setting up required instance variables, and
- // attaching the event listener to the element.
- //
- function Formatter(el, opts) {
- // Cache this
- var self = this;
- // Make sure we have an element. Make accesible to instance
- self.el = el;
- if (!self.el) {
- throw new TypeError('Must provide an existing element');
- }
- // Merge opts with defaults
- self.opts = utils.extend({}, defaults, opts);
- // 1 pattern is special case
- if (typeof self.opts.pattern !== 'undefined') {
- self.opts.patterns = self._specFromSinglePattern(self.opts.pattern);
- delete self.opts.pattern;
- }
- // Make sure we have valid opts
- if (typeof self.opts.patterns === 'undefined') {
- throw new TypeError('Must provide a pattern or array of patterns');
- }
- self.patternMatcher = patternMatcher(self.opts.patterns);
- // Upate pattern with initial value
- self._updatePattern();
- // Init values
- self.hldrs = {};
- self.focus = 0;
- // Add Listeners
- utils.addListener(self.el, 'keydown', function (evt) {
- self._keyDown(evt);
- });
- utils.addListener(self.el, 'keypress', function (evt) {
- self._keyPress(evt);
- });
- utils.addListener(self.el, 'paste', function (evt) {
- self._paste(evt);
- });
- // Persistence
- if (self.opts.persistent) {
- // Format on start
- self._processKey('', false);
- self.el.blur();
- // Add Listeners
- utils.addListener(self.el, 'focus', function (evt) {
- self._focus(evt);
- });
- utils.addListener(self.el, 'click', function (evt) {
- self._focus(evt);
- });
- utils.addListener(self.el, 'touchstart', function (evt) {
- self._focus(evt);
- });
- }
- }
- //
- // @public
- // Add new char
- //
- Formatter.addInptType = function (chr, reg) {
- inptRegs[chr] = reg;
- };
- //
- // @public
- // Apply the given pattern to the current input without moving caret.
- //
- Formatter.prototype.resetPattern = function (str) {
- // Update opts to hold new pattern
- this.opts.patterns = str ? this._specFromSinglePattern(str) : this.opts.patterns;
- // Get current state
- this.sel = inptSel.get(this.el);
- this.val = this.el.value;
- // Init values
- this.delta = 0;
- // Remove all formatted chars from val
- this._removeChars();
- this.patternMatcher = patternMatcher(this.opts.patterns);
- // Update pattern
- var newPattern = this.patternMatcher.getPattern(this.val);
- this.mLength = newPattern.mLength;
- this.chars = newPattern.chars;
- this.inpts = newPattern.inpts;
- // Format on start
- this._processKey('', false, true);
- };
- //
- // @private
- // Determine correct format pattern based on input val
- //
- Formatter.prototype._updatePattern = function () {
- // Determine appropriate pattern
- var newPattern = this.patternMatcher.getPattern(this.val);
- // Only update the pattern if there is an appropriate pattern for the value.
- // Otherwise, leave the current pattern (and likely delete the latest character.)
- if (newPattern) {
- // Get info about the given pattern
- this.mLength = newPattern.mLength;
- this.chars = newPattern.chars;
- this.inpts = newPattern.inpts;
- }
- };
- //
- // @private
- // Handler called on all keyDown strokes. All keys trigger
- // this handler. Only process delete keys.
- //
- Formatter.prototype._keyDown = function (evt) {
- // The first thing we need is the character code
- var k = evt.which || evt.keyCode;
- // If delete key
- if (k && utils.isDelKeyDown(evt.which, evt.keyCode)) {
- // Process the keyCode and prevent default
- this._processKey(null, k);
- return utils.preventDefault(evt);
- }
- };
- //
- // @private
- // Handler called on all keyPress strokes. Only processes
- // character keys (as long as no modifier key is in use).
- //
- Formatter.prototype._keyPress = function (evt) {
- // The first thing we need is the character code
- var k, isSpecial;
- // Mozilla will trigger on special keys and assign the the value 0
- // We want to use that 0 rather than the keyCode it assigns.
- k = evt.which || evt.keyCode;
- isSpecial = utils.isSpecialKeyPress(evt.which, evt.keyCode);
- // Process the keyCode and prevent default
- if (!utils.isDelKeyPress(evt.which, evt.keyCode) && !isSpecial && !utils.isModifier(evt)) {
- this._processKey(String.fromCharCode(k), false);
- return utils.preventDefault(evt);
- }
- };
- //
- // @private
- // Handler called on paste event.
- //
- Formatter.prototype._paste = function (evt) {
- // Process the clipboard paste and prevent default
- this._processKey(utils.getClip(evt), false);
- return utils.preventDefault(evt);
- };
- //
- // @private
- // Handle called on focus event.
- //
- Formatter.prototype._focus = function () {
- // Wrapped in timeout so that we can grab input selection
- var self = this;
- setTimeout(function () {
- // Grab selection
- var selection = inptSel.get(self.el);
- // Char check
- var isAfterStart = selection.end > self.focus, isFirstChar = selection.end === 0;
- // If clicked in front of start, refocus to start
- if (isAfterStart || isFirstChar) {
- inptSel.set(self.el, self.focus);
- }
- }, 0);
- };
- //
- // @private
- // Using the provided key information, alter el value.
- //
- Formatter.prototype._processKey = function (chars, delKey, ignoreCaret) {
- // Get current state
- this.sel = inptSel.get(this.el);
- this.val = this.el.value;
- // Init values
- this.delta = 0;
- // If chars were highlighted, we need to remove them
- if (this.sel.begin !== this.sel.end) {
- this.delta = -1 * Math.abs(this.sel.begin - this.sel.end);
- this.val = utils.removeChars(this.val, this.sel.begin, this.sel.end);
- } else if (delKey && delKey === 46) {
- this._delete();
- } else if (delKey && this.sel.begin - 1 >= 0) {
- // Always have a delta of at least -1 for the character being deleted.
- this.val = utils.removeChars(this.val, this.sel.end - 1, this.sel.end);
- this.delta -= 1;
- } else if (delKey) {
- return true;
- }
- // If the key is not a del key, it should convert to a str
- if (!delKey) {
- // Add char at position and increment delta
- this.val = utils.addChars(this.val, chars, this.sel.begin);
- this.delta += chars.length;
- }
- // Format el.value (also handles updating caret position)
- this._formatValue(ignoreCaret);
- };
- //
- // @private
- // Deletes the character in front of it
- //
- Formatter.prototype._delete = function () {
- // Adjust focus to make sure its not on a formatted char
- while (this.chars[this.sel.begin]) {
- this._nextPos();
- }
- // As long as we are not at the end
- if (this.sel.begin < this.val.length) {
- // We will simulate a delete by moving the caret to the next char
- // and then deleting
- this._nextPos();
- this.val = utils.removeChars(this.val, this.sel.end - 1, this.sel.end);
- this.delta = -1;
- }
- };
- //
- // @private
- // Quick helper method to move the caret to the next pos
- //
- Formatter.prototype._nextPos = function () {
- this.sel.end++;
- this.sel.begin++;
- };
- //
- // @private
- // Alter element value to display characters matching the provided
- // instance pattern. Also responsible for updating
- //
- Formatter.prototype._formatValue = function (ignoreCaret) {
- // Set caret pos
- this.newPos = this.sel.end + this.delta;
- // Remove all formatted chars from val
- this._removeChars();
- // Switch to first matching pattern based on val
- this._updatePattern();
- // Validate inputs
- this._validateInpts();
- // Add formatted characters
- this._addChars();
- // Set value and adhere to maxLength
- this.el.value = this.val.substr(0, this.mLength);
- // Set new caret position
- if (typeof ignoreCaret === 'undefined' || ignoreCaret === false) {
- inptSel.set(this.el, this.newPos);
- }
- };
- //
- // @private
- // Remove all formatted before and after a specified pos
- //
- Formatter.prototype._removeChars = function () {
- // Delta shouldn't include placeholders
- if (this.sel.end > this.focus) {
- this.delta += this.sel.end - this.focus;
- }
- // Account for shifts during removal
- var shift = 0;
- // Loop through all possible char positions
- for (var i = 0; i <= this.mLength; i++) {
- // Get transformed position
- var curChar = this.chars[i], curHldr = this.hldrs[i], pos = i + shift, val;
- // If after selection we need to account for delta
- pos = i >= this.sel.begin ? pos + this.delta : pos;
- val = this.val.charAt(pos);
- // Remove char and account for shift
- if (curChar && curChar === val || curHldr && curHldr === val) {
- this.val = utils.removeChars(this.val, pos, pos + 1);
- shift--;
- }
- }
- // All hldrs should be removed now
- this.hldrs = {};
- // Set focus to last character
- this.focus = this.val.length;
- };
- //
- // @private
- // Make sure all inpts are valid, else remove and update delta
- //
- Formatter.prototype._validateInpts = function () {
- // Loop over each char and validate
- for (var i = 0; i < this.val.length; i++) {
- // Get char inpt type
- var inptType = this.inpts[i];
- // Checks
- var isBadType = !inptRegs[inptType], isInvalid = !isBadType && !inptRegs[inptType].test(this.val.charAt(i)), inBounds = this.inpts[i];
- // Remove if incorrect and inbounds
- if ((isBadType || isInvalid) && inBounds) {
- this.val = utils.removeChars(this.val, i, i + 1);
- this.focusStart--;
- this.newPos--;
- this.delta--;
- i--;
- }
- }
- };
- //
- // @private
- // Loop over val and add formatted chars as necessary
- //
- Formatter.prototype._addChars = function () {
- if (this.opts.persistent) {
- // Loop over all possible characters
- for (var i = 0; i <= this.mLength; i++) {
- if (!this.val.charAt(i)) {
- // Add placeholder at pos
- this.val = utils.addChars(this.val, this.opts.placeholder, i);
- this.hldrs[i] = this.opts.placeholder;
- }
- this._addChar(i);
- }
- // Adjust focus to make sure its not on a formatted char
- while (this.chars[this.focus]) {
- this.focus++;
- }
- } else {
- // Avoid caching val.length, as they may change in _addChar.
- for (var j = 0; j <= this.val.length; j++) {
- // When moving backwards there are some race conditions where we
- // dont want to add the character
- if (this.delta <= 0 && j === this.focus) {
- return true;
- }
- // Place character in current position of the formatted string.
- this._addChar(j);
- }
- }
- };
- //
- // @private
- // Add formattted char at position
- //
- Formatter.prototype._addChar = function (i) {
- // If char exists at position
- var chr = this.chars[i];
- if (!chr) {
- return true;
- }
- // If chars are added in between the old pos and new pos
- // we need to increment pos and delta
- if (utils.isBetween(i, [
- this.sel.begin - 1,
- this.newPos + 1
- ])) {
- this.newPos++;
- this.delta++;
- }
- // If character added before focus, incr
- if (i <= this.focus) {
- this.focus++;
- }
- // Updateholder
- if (this.hldrs[i]) {
- delete this.hldrs[i];
- this.hldrs[i + 1] = this.opts.placeholder;
- }
- // Update value
- this.val = utils.addChars(this.val, chr, i);
- };
- //
- // @private
- // Create a patternSpec for passing into patternMatcher that
- // has exactly one catch all pattern.
- //
- Formatter.prototype._specFromSinglePattern = function (patternStr) {
- return [{ '*': patternStr }];
- };
- // Expose
- return Formatter;
- }(patternMatcher, inptSel, utils);
- // A really lightweight plugin wrapper around the constructor,
- // preventing against multiple instantiations
- var pluginName = 'formatter';
- $.fn[pluginName] = function (options) {
- // Initiate plugin if options passed
- if (typeof options == 'object') {
- this.each(function () {
- if (!$.data(this, 'plugin_' + pluginName)) {
- $.data(this, 'plugin_' + pluginName,
- new formatter(this, options));
- }
- });
- }
- // Add resetPattern method to plugin
- this.resetPattern = function (str) {
- this.each(function () {
- var formatted = $.data(this, 'plugin_' + pluginName);
- // resetPattern for instance
- if (formatted) { formatted.resetPattern(str); }
- });
- // Chainable please
- return this;
- };
- // Chainable please
- return this;
- };
- $.fn[pluginName].addInptType = function (chr, regexp) {
- formatter.addInptType(chr, regexp);
- };
- }));
|