|
|
@@ -1,301 +1,348 @@
|
|
|
-/*
|
|
|
-Input Mask plugin for jquery
|
|
|
-Copyright (c) 2010 Robin Herbots
|
|
|
-Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
|
|
|
-Version: 0.0.1
|
|
|
-
|
|
|
-This plugin is based on the masked input plugin written by Josh Bush (digitalbush.com)
|
|
|
-*/
|
|
|
-
|
|
|
-(function($) {
|
|
|
-
|
|
|
- $.fn.inputmask = function(mask, options) {
|
|
|
- var defaults = {
|
|
|
- placeholder: "_",
|
|
|
- onComplete: null,
|
|
|
- definitions: {
|
|
|
- '9': {
|
|
|
- "validator": "[0-9]",
|
|
|
- "cardinality": 1,
|
|
|
- 'prevalidator': null
|
|
|
- },
|
|
|
- 'a': {
|
|
|
- "validator": "[A-Za-z]",
|
|
|
- "cardinality": 1,
|
|
|
- "prevalidator": null
|
|
|
- },
|
|
|
- '*': {
|
|
|
- "validator": "[A-Za-z0-9]",
|
|
|
- "cardinality": 1,
|
|
|
- "prevalidator": null
|
|
|
- },
|
|
|
- 'd': { //day
|
|
|
- "validator": "0[1-9]|[12][0-9]|3[01]",
|
|
|
- "cardinality": 2,
|
|
|
- "prevalidator": [{ "validator": "[0-3]", "cardinality": 1}]
|
|
|
- },
|
|
|
- 'm': { //month
|
|
|
- "validator": "0[1-9]|1[012]",
|
|
|
- "cardinality": 2,
|
|
|
- "prevalidator": [{ "validator": "[01]", "cardinality": 1}]
|
|
|
- },
|
|
|
- 'y': { //year
|
|
|
- "validator": "(19|20)\\d\\d",
|
|
|
- "cardinality": 4,
|
|
|
- "prevalidator": [
|
|
|
- { "validator": "[12]", "cardinality": 1 },
|
|
|
- { "validator": "(19|20)", "cardinality": 2 },
|
|
|
- { "validator": "(19|20)\\d", "cardinality": 3 }
|
|
|
- ]
|
|
|
- }
|
|
|
- },
|
|
|
- keyCode: { ALT: 18, BACKSPACE: 8, CAPS_LOCK: 20, COMMA: 188, COMMAND: 91, COMMAND_LEFT: 91, COMMAND_RIGHT: 93, CONTROL: 17, DELETE: 46, DOWN: 40, END: 35, ENTER: 13, ESCAPE: 27, HOME: 36, INSERT: 45, LEFT: 37, MENU: 93, NUMPAD_ADD: 107, NUMPAD_DECIMAL: 110, NUMPAD_DIVIDE: 111, NUMPAD_ENTER: 108,
|
|
|
- NUMPAD_MULTIPLY: 106, NUMPAD_SUBTRACT: 109, PAGE_DOWN: 34, PAGE_UP: 33, PERIOD: 190, RIGHT: 39, SHIFT: 16, SPACE: 32, TAB: 9, UP: 38, WINDOWS: 91
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- function getMaskTemplate() {
|
|
|
- return $.map(mask.split(""), function(element, index) {
|
|
|
- var outElem = [];
|
|
|
- var maskdef = opts.definitions[element];
|
|
|
- if (maskdef) {
|
|
|
- for (i = 0; i < maskdef.cardinality; i++) {
|
|
|
- outElem.push(opts.placeholder);
|
|
|
- }
|
|
|
- } else outElem.push(element);
|
|
|
-
|
|
|
- return outElem;
|
|
|
- });
|
|
|
- };
|
|
|
-
|
|
|
- function getTestingChain() {
|
|
|
- return $.map(mask.split(""), function(element, index) {
|
|
|
- var outElem = [];
|
|
|
- var maskdef = opts.definitions[element];
|
|
|
- if (maskdef) {
|
|
|
- for (i = 1; i < maskdef.cardinality; i++) {
|
|
|
- var prevalidator = maskdef.prevalidator[i - 1];
|
|
|
- outElem.push([new RegExp(prevalidator.validator), prevalidator.cardinality]);
|
|
|
- }
|
|
|
- outElem.push([new RegExp(maskdef.validator), maskdef.cardinality]);
|
|
|
- } else outElem.push(null);
|
|
|
-
|
|
|
- return outElem;
|
|
|
- });
|
|
|
- };
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- var opts = $.extend({}, defaults, options);
|
|
|
-
|
|
|
- //init buffer
|
|
|
- var _buffer = getMaskTemplate();
|
|
|
- var pasteEventName = $.browser.msie ? 'paste' : 'input';
|
|
|
- var iPhone = (window.orientation != undefined);
|
|
|
- var tests = getTestingChain();
|
|
|
-
|
|
|
- return this.each(function() {
|
|
|
- var input = $(this);
|
|
|
- //init buffer
|
|
|
- var buffer = _buffer.slice();
|
|
|
- var undoBuffer = input.val();
|
|
|
- var ignore = false; //Variable for ignoring control keys
|
|
|
- var len = _buffer.length;
|
|
|
-
|
|
|
- //bind events
|
|
|
- if (!input.attr("readonly")) {
|
|
|
- input.bind("focus", function() {
|
|
|
- undoBuffer = input.val();
|
|
|
- var pos = checkVal();
|
|
|
- writeBuffer();
|
|
|
- setTimeout(function() {
|
|
|
- if (pos == _buffer.length)
|
|
|
- caret(input, 0, pos);
|
|
|
- else
|
|
|
- caret(input, pos);
|
|
|
- }, 0);
|
|
|
- }).bind("mouseenter", function() {
|
|
|
- if (input.val().length == 0)
|
|
|
- writeBuffer();
|
|
|
- }).bind("blur", function() {
|
|
|
- if (input.val() == _buffer.join('')) {
|
|
|
- input.val('');
|
|
|
- }
|
|
|
- checkVal();
|
|
|
- if (input.val() != undoBuffer)
|
|
|
- input.change();
|
|
|
- }).bind("mouseleave", function() {
|
|
|
- if (input.val() == _buffer.join(''))
|
|
|
- input.val('');
|
|
|
- }).bind("keydown", keydownEvent
|
|
|
- ).bind("keypress", keypressEvent
|
|
|
- ).bind(pasteEventName, function() {
|
|
|
- setTimeout(function() { caret(input, checkVal(true)); }, 0);
|
|
|
- });
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- checkVal();
|
|
|
-
|
|
|
- //private functions
|
|
|
- function writeBuffer() { return input.val(buffer.join('')).val(); };
|
|
|
- function clearBuffer(start, end) {
|
|
|
- for (var i = start; i < end && i < len; i++) {
|
|
|
- buffer[i] = _buffer[i];
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- function seekNext(pos) {
|
|
|
- while (++pos <= len && !tests[pos]);
|
|
|
- return pos;
|
|
|
- };
|
|
|
-
|
|
|
- function shiftL(pos) {
|
|
|
- while (!tests[pos] && --pos >= 0);
|
|
|
- for (var i = pos; i < len; i++) {
|
|
|
- if (tests[i]) {
|
|
|
- buffer[i] = opts.placeholder;
|
|
|
- var j = seekNext(i);
|
|
|
- if (j < len && isValid(i, buffer[j])) {
|
|
|
- buffer[i] = buffer[j];
|
|
|
- } else
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- writeBuffer();
|
|
|
- caret(input, pos);
|
|
|
- };
|
|
|
-
|
|
|
- function shiftR(pos) {
|
|
|
- for (var i = pos, c = opts.placeholder; i < len; i++) {
|
|
|
- if (tests[i]) {
|
|
|
- var j = seekNext(i);
|
|
|
- var t = buffer[i];
|
|
|
- buffer[i] = c;
|
|
|
- if (j < len && isValid(j, t))
|
|
|
- c = t;
|
|
|
- else
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- function caret(input, begin, end) {
|
|
|
- if (input.length == 0) return;
|
|
|
- if (typeof begin == 'number') {
|
|
|
- end = (typeof end == 'number') ? end : begin;
|
|
|
- return input.each(function() {
|
|
|
- if (this.setSelectionRange) {
|
|
|
- this.focus();
|
|
|
- this.setSelectionRange(begin, end);
|
|
|
- } else if (this.createTextRange) {
|
|
|
- var range = this.createTextRange();
|
|
|
- range.collapse(true);
|
|
|
- range.moveEnd('character', end);
|
|
|
- range.moveStart('character', begin);
|
|
|
- range.select();
|
|
|
- }
|
|
|
- });
|
|
|
- } else {
|
|
|
- if (input[0].setSelectionRange) {
|
|
|
- begin = input[0].selectionStart;
|
|
|
- end = input[0].selectionEnd;
|
|
|
- } else if (document.selection && document.selection.createRange) {
|
|
|
- var range = document.selection.createRange();
|
|
|
- begin = 0 - range.duplicate().moveStart('character', -100000);
|
|
|
- end = begin + range.text.length;
|
|
|
- }
|
|
|
- return { begin: begin, end: end };
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- function keydownEvent(e) {
|
|
|
- var pos = caret($(this));
|
|
|
- var k = e.keyCode;
|
|
|
- ignore = (k < 16 || (k > 16 && k < 32) || (k > 32 && k < 41));
|
|
|
-
|
|
|
- //delete selection before proceeding
|
|
|
- if ((pos.begin - pos.end) != 0 && (!ignore || k == opts.keyCode.BACKSPACE || k == opts.keyCode.DELETE))
|
|
|
- clearBuffer(pos.begin, pos.end);
|
|
|
-
|
|
|
- //backspace, delete, and escape get special treatment
|
|
|
- if (k == opts.keyCode.BACKSPACE || k == opts.keyCode.DELETE || (iPhone && k == 127)) {//backspace/delete
|
|
|
- shiftL(pos.begin + (k == opts.keyCode.DELETE ? 0 : -1));
|
|
|
- return false;
|
|
|
- } else if (k == opts.keyCode.ESCAPE) {//escape
|
|
|
- input.val(undoBuffer);
|
|
|
- caret(input, 0, checkVal());
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- function keypressEvent(e) {
|
|
|
- if (ignore) {
|
|
|
- ignore = false;
|
|
|
- //Fixes Mac FF bug on backspace
|
|
|
- return (e.keyCode == 8) ? false : null;
|
|
|
- }
|
|
|
- e = e || window.event;
|
|
|
- var k = e.charCode || e.keyCode || e.which;
|
|
|
- var pos = caret($(this));
|
|
|
-
|
|
|
- if (e.ctrlKey || e.altKey || e.metaKey) {//Ignore
|
|
|
- return true;
|
|
|
- } else if ((k >= 32 && k <= 125) || k > 186) {//typeable characters
|
|
|
- var p = seekNext(pos.begin - 1);
|
|
|
- if (p < len) {
|
|
|
- var c = String.fromCharCode(k);
|
|
|
- if (isValid(p, c)) {
|
|
|
- shiftR(p);
|
|
|
- buffer[p] = c;
|
|
|
- writeBuffer();
|
|
|
- var next = seekNext(p);
|
|
|
- caret($(this), next);
|
|
|
- if (opts.onComplete && next == len)
|
|
|
- opts.onComplete.call(input);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- function isValid(pos, c) {
|
|
|
- var inputValue = input.val();
|
|
|
-
|
|
|
- var loopend = 0;
|
|
|
- if (c) { loopend = 1; ; }
|
|
|
-
|
|
|
- var chrs = '';
|
|
|
- for (var i = tests[pos][1]; i > loopend; i--) {
|
|
|
- chrs += inputValue.charAt(pos - (i - 1));
|
|
|
- }
|
|
|
-
|
|
|
- if (c) { chrs += c; }
|
|
|
-
|
|
|
- return tests[pos][0].test(chrs);
|
|
|
- }
|
|
|
-
|
|
|
- function checkVal(clearInvalid) {
|
|
|
- var inputValue = input.val();
|
|
|
- var lastMatch = -1;
|
|
|
- for (var i = 0; i < inputValue.length; i++) {
|
|
|
- if (tests[i]) {
|
|
|
- buffer[i] = opts.placeholder;
|
|
|
- if (isValid(i)) {
|
|
|
- buffer[i] = inputValue.charAt(i);
|
|
|
- lastMatch = i;
|
|
|
- } else break;
|
|
|
- } else if (buffer[i] == inputValue.charAt(i)) {
|
|
|
- lastMatch = i;
|
|
|
- }
|
|
|
- }
|
|
|
- if (clearInvalid) {
|
|
|
- writeBuffer();
|
|
|
- }
|
|
|
- return lastMatch + 1;
|
|
|
- };
|
|
|
-
|
|
|
- });
|
|
|
- };
|
|
|
-
|
|
|
+/*
|
|
|
+Input Mask plugin for jquery
|
|
|
+Copyright (c) 2010 Robin Herbots
|
|
|
+Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
|
|
|
+Version: 0.0.2
|
|
|
+
|
|
|
+This plugin is based on the masked input plugin written by Josh Bush (digitalbush.com)
|
|
|
+*/
|
|
|
+
|
|
|
+(function($) {
|
|
|
+
|
|
|
+ $.fn.inputmask = function(fn, options) {
|
|
|
+ //options default
|
|
|
+ var defaults = {
|
|
|
+ placeholder: "_",
|
|
|
+ mask: null,
|
|
|
+ onComplete: null,
|
|
|
+ definitions: {
|
|
|
+ '9': {
|
|
|
+ "validator": "[0-9]",
|
|
|
+ "cardinality": 1,
|
|
|
+ 'prevalidator': null
|
|
|
+ },
|
|
|
+ 'a': {
|
|
|
+ "validator": "[A-Za-z]",
|
|
|
+ "cardinality": 1,
|
|
|
+ "prevalidator": null
|
|
|
+ },
|
|
|
+ '*': {
|
|
|
+ "validator": "[A-Za-z0-9]",
|
|
|
+ "cardinality": 1,
|
|
|
+ "prevalidator": null
|
|
|
+ },
|
|
|
+ 'd': { //day
|
|
|
+ "validator": "0[1-9]|[12][0-9]|3[01]",
|
|
|
+ "cardinality": 2,
|
|
|
+ "prevalidator": [{ "validator": "[0-3]", "cardinality": 1}]
|
|
|
+ },
|
|
|
+ 'm': { //month
|
|
|
+ "validator": "0[1-9]|1[012]",
|
|
|
+ "cardinality": 2,
|
|
|
+ "prevalidator": [{ "validator": "[01]", "cardinality": 1}]
|
|
|
+ },
|
|
|
+ 'y': { //year
|
|
|
+ "validator": "(19|20)\\d\\d",
|
|
|
+ "cardinality": 4,
|
|
|
+ "prevalidator": [
|
|
|
+ { "validator": "[12]", "cardinality": 1 },
|
|
|
+ { "validator": "(19|20)", "cardinality": 2 },
|
|
|
+ { "validator": "(19|20)\\d", "cardinality": 3 }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ keyCode: { ALT: 18, BACKSPACE: 8, CAPS_LOCK: 20, COMMA: 188, COMMAND: 91, COMMAND_LEFT: 91, COMMAND_RIGHT: 93, CONTROL: 17, DELETE: 46, DOWN: 40, END: 35, ENTER: 13, ESCAPE: 27, HOME: 36, INSERT: 45, LEFT: 37, MENU: 93, NUMPAD_ADD: 107, NUMPAD_DECIMAL: 110, NUMPAD_DIVIDE: 111, NUMPAD_ENTER: 108,
|
|
|
+ NUMPAD_MULTIPLY: 106, NUMPAD_SUBTRACT: 109, PAGE_DOWN: 34, PAGE_UP: 33, PERIOD: 190, RIGHT: 39, SHIFT: 16, SPACE: 32, TAB: 9, UP: 38, WINDOWS: 91
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ var opts = $.extend({}, defaults, options);
|
|
|
+
|
|
|
+ if (typeof fn == "string") {
|
|
|
+ if (fn == 'mask') {
|
|
|
+ //init buffer
|
|
|
+ var _buffer = getMaskTemplate();
|
|
|
+ var pasteEventName = $.browser.msie ? 'paste' : 'input';
|
|
|
+ var iPhone = (window.orientation != undefined);
|
|
|
+ var tests = getTestingChain();
|
|
|
+
|
|
|
+ return this.each(function() {
|
|
|
+ mask($(this));
|
|
|
+ });
|
|
|
+ } else if (fn == 'unmaskedvalue') {
|
|
|
+ return unmaskedvalue($(this));
|
|
|
+ } else { //maybe fn is a mask so we try
|
|
|
+ //set mask
|
|
|
+ opts.mask = fn;
|
|
|
+
|
|
|
+ //init buffer
|
|
|
+ var _buffer = getMaskTemplate();
|
|
|
+ var pasteEventName = $.browser.msie ? 'paste' : 'input';
|
|
|
+ var iPhone = (window.orientation != undefined);
|
|
|
+ var tests = getTestingChain();
|
|
|
+
|
|
|
+ return this.each(function() {
|
|
|
+ mask($(this));
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //functions
|
|
|
+ function getMaskTemplate() {
|
|
|
+ return $.map(opts.mask.split(""), function(element, index) {
|
|
|
+ var outElem = [];
|
|
|
+ var maskdef = opts.definitions[element];
|
|
|
+ if (maskdef) {
|
|
|
+ for (i = 0; i < maskdef.cardinality; i++) {
|
|
|
+ outElem.push(opts.placeholder);
|
|
|
+ }
|
|
|
+ } else outElem.push(element);
|
|
|
+
|
|
|
+ return outElem;
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ function getTestingChain() {
|
|
|
+ return $.map(opts.mask.split(""), function(element, index) {
|
|
|
+ var outElem = [];
|
|
|
+ var maskdef = opts.definitions[element];
|
|
|
+ if (maskdef) {
|
|
|
+ for (i = 1; i < maskdef.cardinality; i++) {
|
|
|
+ var prevalidator = maskdef.prevalidator[i - 1];
|
|
|
+ outElem.push([new RegExp(prevalidator.validator), prevalidator.cardinality]);
|
|
|
+ }
|
|
|
+ outElem.push([new RegExp(maskdef.validator), maskdef.cardinality]);
|
|
|
+ } else outElem.push(null);
|
|
|
+
|
|
|
+ return outElem;
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ function unmaskedvalue(el) {
|
|
|
+ var tests = el.data('tests');
|
|
|
+ if (tests) {
|
|
|
+ return $.map(el.val().split(""), function(element, index) {
|
|
|
+ return tests[index] ? element : null;
|
|
|
+ }).join('');
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return el.val();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function mask(el) {
|
|
|
+ var input = $(el);
|
|
|
+ //store tests in the input element - used to get the unmasked value
|
|
|
+ input.data('tests', tests);
|
|
|
+
|
|
|
+ //init buffer
|
|
|
+ var buffer = _buffer.slice();
|
|
|
+ var undoBuffer = input.val();
|
|
|
+ var ignore = false; //Variable for ignoring control keys
|
|
|
+ var len = _buffer.length;
|
|
|
+
|
|
|
+ //bind events
|
|
|
+ if (!input.attr("readonly")) {
|
|
|
+ input.bind("focus", function() {
|
|
|
+ undoBuffer = input.val();
|
|
|
+ var pos = checkVal();
|
|
|
+ writeBuffer();
|
|
|
+ setTimeout(function() {
|
|
|
+ if (pos == _buffer.length)
|
|
|
+ caret(input, 0, pos);
|
|
|
+ else
|
|
|
+ caret(input, pos);
|
|
|
+ }, 0);
|
|
|
+ }).bind("mouseenter", function() {
|
|
|
+ if (input.val().length == 0)
|
|
|
+ writeBuffer();
|
|
|
+ }).bind("blur", function() {
|
|
|
+ if (input.val() == _buffer.join('')) {
|
|
|
+ input.val('');
|
|
|
+ } else {
|
|
|
+ checkVal();
|
|
|
+ if (input.val() != undoBuffer)
|
|
|
+ input.change();
|
|
|
+ }
|
|
|
+ }).bind("mouseleave", function() {
|
|
|
+ if (input.val() == _buffer.join(''))
|
|
|
+ input.val('');
|
|
|
+ }).bind("keydown", keydownEvent
|
|
|
+ ).bind("keypress", keypressEvent
|
|
|
+ ).bind(pasteEventName, function() {
|
|
|
+ setTimeout(function() { caret(input, checkVal(true)); }, 0);
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ checkVal();
|
|
|
+
|
|
|
+
|
|
|
+ //private functions
|
|
|
+ function writeBuffer() { return input.val(buffer.join('')).val(); };
|
|
|
+ function clearBuffer(start, end) {
|
|
|
+ for (var i = start; i < end && i < len; i++) {
|
|
|
+ buffer[i] = _buffer[i];
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ function seekNext(pos) {
|
|
|
+ while (++pos <= len && !isMask(pos));
|
|
|
+ return pos;
|
|
|
+ };
|
|
|
+
|
|
|
+ function shiftL(pos) {
|
|
|
+ while (!isMask(pos) && --pos >= 0);
|
|
|
+ for (var i = pos; i < len; i++) {
|
|
|
+ if (isMask(i)) {
|
|
|
+ buffer[i] = opts.placeholder;
|
|
|
+ var j = seekNext(i);
|
|
|
+ if (j < len && isValid(i, buffer[j])) {
|
|
|
+ buffer[i] = buffer[j];
|
|
|
+ } else
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ writeBuffer();
|
|
|
+ caret(input, pos);
|
|
|
+ };
|
|
|
+
|
|
|
+ function shiftR(pos) {
|
|
|
+ for (var i = pos, c = opts.placeholder; i < len; i++) {
|
|
|
+ if (isMask(i)) {
|
|
|
+ var j = seekNext(i);
|
|
|
+ var t = buffer[i];
|
|
|
+ buffer[i] = c;
|
|
|
+ if (j < len && isValid(j, t))
|
|
|
+ c = t;
|
|
|
+ else
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ function caret(input, begin, end) {
|
|
|
+ if (input.length == 0) return;
|
|
|
+ if (typeof begin == 'number') {
|
|
|
+ end = (typeof end == 'number') ? end : begin;
|
|
|
+ return input.each(function() {
|
|
|
+ if (this.setSelectionRange) {
|
|
|
+ this.focus();
|
|
|
+ this.setSelectionRange(begin, end);
|
|
|
+ } else if (this.createTextRange) {
|
|
|
+ var range = this.createTextRange();
|
|
|
+ range.collapse(true);
|
|
|
+ range.moveEnd('character', end);
|
|
|
+ range.moveStart('character', begin);
|
|
|
+ range.select();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ if (input[0].setSelectionRange) {
|
|
|
+ begin = input[0].selectionStart;
|
|
|
+ end = input[0].selectionEnd;
|
|
|
+ } else if (document.selection && document.selection.createRange) {
|
|
|
+ var range = document.selection.createRange();
|
|
|
+ begin = 0 - range.duplicate().moveStart('character', -100000);
|
|
|
+ end = begin + range.text.length;
|
|
|
+ }
|
|
|
+ return { begin: begin, end: end };
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ function keydownEvent(e) {
|
|
|
+ var pos = caret($(this));
|
|
|
+ var k = e.keyCode;
|
|
|
+ ignore = (k < 16 || (k > 16 && k < 32) || (k > 32 && k < 41));
|
|
|
+
|
|
|
+ //delete selection before proceeding
|
|
|
+ if ((pos.begin - pos.end) != 0 && (!ignore || k == opts.keyCode.BACKSPACE || k == opts.keyCode.DELETE))
|
|
|
+ clearBuffer(pos.begin, pos.end);
|
|
|
+
|
|
|
+ //backspace, delete, and escape get special treatment
|
|
|
+ if (k == opts.keyCode.BACKSPACE || k == opts.keyCode.DELETE || (iPhone && k == 127)) {//backspace/delete
|
|
|
+ shiftL(pos.begin + (k == opts.keyCode.DELETE ? 0 : -1));
|
|
|
+ return false;
|
|
|
+ } else if (k == opts.keyCode.ESCAPE) {//escape
|
|
|
+ input.val(undoBuffer);
|
|
|
+ caret(input, 0, checkVal());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function keypressEvent(e) {
|
|
|
+ if (ignore) {
|
|
|
+ ignore = false;
|
|
|
+ //Fixes Mac FF bug on backspace
|
|
|
+ return (e.keyCode == 8) ? false : null;
|
|
|
+ }
|
|
|
+ e = e || window.event;
|
|
|
+ var k = e.charCode || e.keyCode || e.which;
|
|
|
+ var pos = caret($(this));
|
|
|
+
|
|
|
+ if (e.ctrlKey || e.altKey || e.metaKey) {//Ignore
|
|
|
+ return true;
|
|
|
+ } else if ((k >= 32 && k <= 125) || k > 186) {//typeable characters
|
|
|
+ var p = seekNext(pos.begin - 1);
|
|
|
+ if (p < len) {
|
|
|
+ var c = String.fromCharCode(k);
|
|
|
+ if (isValid(p, c)) {
|
|
|
+ shiftR(p);
|
|
|
+ buffer[p] = c;
|
|
|
+ writeBuffer();
|
|
|
+ var next = seekNext(p);
|
|
|
+ caret($(this), next);
|
|
|
+ if (opts.onComplete && next == len)
|
|
|
+ opts.onComplete.call(input);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ function isValid(pos, c) {
|
|
|
+ var inputValue = input.val();
|
|
|
+
|
|
|
+ var loopend = 0;
|
|
|
+ if (c) { loopend = 1; ; }
|
|
|
+
|
|
|
+ var chrs = '';
|
|
|
+ for (var i = tests[pos][1]; i > loopend; i--) {
|
|
|
+ chrs += buffer[pos - (i - 1)];
|
|
|
+ }
|
|
|
+
|
|
|
+ if (c) { chrs += c; }
|
|
|
+
|
|
|
+ return tests[pos][0].test(chrs);
|
|
|
+ }
|
|
|
+
|
|
|
+ function isMask(pos) {
|
|
|
+ return tests[pos];
|
|
|
+ }
|
|
|
+
|
|
|
+ function checkVal(clearInvalid) {
|
|
|
+ var inputValue = input.val();
|
|
|
+ var lastMatch = -1;
|
|
|
+ for (var i = 0; i < inputValue.length; i++) {
|
|
|
+ for (var pos = lastMatch+1; pos < len; pos++) {
|
|
|
+ if(isMask(pos)){
|
|
|
+ buffer[pos] = opts.placeholder;
|
|
|
+ if (isValid(pos, inputValue.charAt(i))) {
|
|
|
+ buffer[pos] = inputValue.charAt(i);
|
|
|
+ lastMatch = pos;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }else { //nonmask
|
|
|
+ lastMatch++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (clearInvalid) {
|
|
|
+ writeBuffer();
|
|
|
+ }
|
|
|
+ return seekNext(lastMatch);
|
|
|
+ };
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
})(jQuery);
|