jquery_003.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. /* Masked Input plugin for jQuery
  2. Copyright (c) 2007-2013 Josh Bush (digitalbush.com)
  3. Licensed under the MIT license (http://digitalbush.com/projects/masked-input-plugin/#license)
  4. Version: 1.3.1 */
  5. //(function(e){function t(){var e=document.createElement("input"),t="onpaste";return e.setAttribute(t,""),"function"==typeof e[t]?"paste":"input"}var n,a=t()+".mask",r=navigator.userAgent,i=/iphone/i.test(r),o=/android/i.test(r);e.mask={definitions:{9:"[0-9]",a:"[A-Za-z]","*":"[A-Za-z0-9]"},dataName:"rawMaskFn",placeholder:"_"},e.fn.extend({caret:function(e,t){var n;if(0!==this.length&&!this.is(":hidden"))return"number"==typeof e?(t="number"==typeof t?t:e,this.each(function(){this.setSelectionRange?this.setSelectionRange(e,t):this.createTextRange&&(n=this.createTextRange(),n.collapse(!0),n.moveEnd("character",t),n.moveStart("character",e),n.select())})):(this[0].setSelectionRange?(e=this[0].selectionStart,t=this[0].selectionEnd):document.selection&&document.selection.createRange&&(n=document.selection.createRange(),e=0-n.duplicate().moveStart("character",-1e5),t=e+n.text.length),{begin:e,end:t})},unmask:function(){return this.trigger("unmask")},mask:function(t,r){var c,l,s,u,f,h;return!t&&this.length>0?(c=e(this[0]),c.data(e.mask.dataName)()):(r=e.extend({placeholder:e.mask.placeholder,completed:null},r),l=e.mask.definitions,s=[],u=h=t.length,f=null,e.each(t.split(""),function(e,t){"?"==t?(h--,u=e):l[t]?(s.push(RegExp(l[t])),null===f&&(f=s.length-1)):s.push(null)}),this.trigger("unmask").each(function(){function c(e){for(;h>++e&&!s[e];);return e}function d(e){for(;--e>=0&&!s[e];);return e}function m(e,t){var n,a;if(!(0>e)){for(n=e,a=c(t);h>n;n++)if(s[n]){if(!(h>a&&s[n].test(R[a])))break;R[n]=R[a],R[a]=r.placeholder,a=c(a)}b(),x.caret(Math.max(f,e))}}function p(e){var t,n,a,i;for(t=e,n=r.placeholder;h>t;t++)if(s[t]){if(a=c(t),i=R[t],R[t]=n,!(h>a&&s[a].test(i)))break;n=i}}function g(e){var t,n,a,r=e.which;8===r||46===r||i&&127===r?(t=x.caret(),n=t.begin,a=t.end,0===a-n&&(n=46!==r?d(n):a=c(n-1),a=46===r?c(a):a),k(n,a),m(n,a-1),e.preventDefault()):27==r&&(x.val(S),x.caret(0,y()),e.preventDefault())}function v(t){var n,a,i,l=t.which,u=x.caret();t.ctrlKey||t.altKey||t.metaKey||32>l||l&&(0!==u.end-u.begin&&(k(u.begin,u.end),m(u.begin,u.end-1)),n=c(u.begin-1),h>n&&(a=String.fromCharCode(l),s[n].test(a)&&(p(n),R[n]=a,b(),i=c(n),o?setTimeout(e.proxy(e.fn.caret,x,i),0):x.caret(i),r.completed&&i>=h&&r.completed.call(x))),t.preventDefault())}function k(e,t){var n;for(n=e;t>n&&h>n;n++)s[n]&&(R[n]=r.placeholder)}function b(){x.val(R.join(""))}function y(e){var t,n,a=x.val(),i=-1;for(t=0,pos=0;h>t;t++)if(s[t]){for(R[t]=r.placeholder;pos++<a.length;)if(n=a.charAt(pos-1),s[t].test(n)){R[t]=n,i=t;break}if(pos>a.length)break}else R[t]===a.charAt(pos)&&t!==u&&(pos++,i=t);return e?b():u>i+1?(x.val(""),k(0,h)):(b(),x.val(x.val().substring(0,i+1))),u?t:f}var x=e(this),R=e.map(t.split(""),function(e){return"?"!=e?l[e]?r.placeholder:e:void 0}),S=x.val();x.data(e.mask.dataName,function(){return e.map(R,function(e,t){return s[t]&&e!=r.placeholder?e:null}).join("")}),x.attr("readonly")||x.one("unmask",function(){x.unbind(".mask").removeData(e.mask.dataName)}).bind("focus.mask",function(){clearTimeout(n);var e;S=x.val(),e=y(),n=setTimeout(function(){b(),e==t.length?x.caret(0,e):x.caret(e)},10)}).bind("blur.mask",function(){y(),x.val()!=S&&x.change()}).bind("keydown.mask",g).bind("keypress.mask",v).bind(a,function(){setTimeout(function(){var e=y(!0);x.caret(e),r.completed&&e==x.val().length&&r.completed.call(x)},0)}),y()}))}})})(jQuery);
  6. (function($) {
  7. function getPasteEvent() {
  8. var el = document.createElement('input'),
  9. name = 'onpaste';
  10. el.setAttribute(name, '');
  11. return (typeof el[name] === 'function')?'paste':'input';
  12. }
  13. var pasteEventName = getPasteEvent() + ".mask",
  14. ua = navigator.userAgent,
  15. iPhone = /iphone/i.test(ua),
  16. chrome = /chrome/i.test(ua),
  17. android=/android/i.test(ua),
  18. caretTimeoutId;
  19. $.mask = {
  20. //Predefined character definitions
  21. definitions: {
  22. '9': "[0-9]",
  23. 'a': "[A-Za-z]",
  24. '*': "[A-Za-z0-9]"
  25. },
  26. autoclear: true,
  27. dataName: "rawMaskFn",
  28. placeholder: '_'
  29. };
  30. $.fn.extend({
  31. //Helper Function for Caret positioning
  32. caret: function(begin, end) {
  33. var range;
  34. if (this.length === 0 || this.is(":hidden")) {
  35. return;
  36. }
  37. if (typeof begin == 'number') {
  38. end = (typeof end === 'number') ? end : begin;
  39. return this.each(function() {
  40. if (this.setSelectionRange) {
  41. this.setSelectionRange(begin, end);
  42. } else if (this.createTextRange) {
  43. range = this.createTextRange();
  44. range.collapse(true);
  45. range.moveEnd('character', end);
  46. range.moveStart('character', begin);
  47. range.select();
  48. }
  49. });
  50. } else {
  51. if (this[0].setSelectionRange) {
  52. begin = this[0].selectionStart;
  53. end = this[0].selectionEnd;
  54. } else if (document.selection && document.selection.createRange) {
  55. range = document.selection.createRange();
  56. begin = 0 - range.duplicate().moveStart('character', -100000);
  57. end = begin + range.text.length;
  58. }
  59. return { begin: begin, end: end };
  60. }
  61. },
  62. unmask: function() {
  63. return this.trigger("unmask");
  64. },
  65. mask: function(mask, settings) {
  66. var input,
  67. defs,
  68. tests,
  69. partialPosition,
  70. firstNonMaskPos,
  71. len;
  72. if (!mask && this.length > 0) {
  73. input = $(this[0]);
  74. return input.data($.mask.dataName)();
  75. }
  76. settings = $.extend({
  77. autoclear: $.mask.autoclear,
  78. placeholder: $.mask.placeholder, // Load default placeholder
  79. completed: null
  80. }, settings);
  81. defs = $.mask.definitions;
  82. tests = [];
  83. partialPosition = len = mask.length;
  84. firstNonMaskPos = null;
  85. $.each(mask.split(""), function(i, c) {
  86. if (c == '?') {
  87. len--;
  88. partialPosition = i;
  89. } else if (defs[c]) {
  90. tests.push(new RegExp(defs[c]));
  91. if (firstNonMaskPos === null) {
  92. firstNonMaskPos = tests.length - 1;
  93. }
  94. } else {
  95. tests.push(null);
  96. }
  97. });
  98. return this.trigger("unmask").each(function() {
  99. var input = $(this),
  100. buffer = $.map(
  101. mask.split(""),
  102. function(c, i) {
  103. if (c != '?') {
  104. return defs[c] ? settings.placeholder[i % settings.placeholder.length] : c;
  105. }
  106. }),
  107. defaultBuffer = buffer.join(''),
  108. focusText = input.val();
  109. function seekNext(pos) {
  110. while (++pos < len && !tests[pos]);
  111. return pos;
  112. }
  113. function seekPrev(pos) {
  114. while (--pos >= 0 && !tests[pos]);
  115. return pos;
  116. }
  117. function shiftL(begin,end) {
  118. var i,
  119. j;
  120. if (begin<0) {
  121. return;
  122. }
  123. for (i = begin, j = seekNext(end); i < len; i++) {
  124. if (tests[i]) {
  125. if (j < len && tests[i].test(buffer[j])) {
  126. buffer[i] = buffer[j];
  127. buffer[j] = settings.placeholder;
  128. } else {
  129. break;
  130. }
  131. j = seekNext(j);
  132. }
  133. }
  134. writeBuffer();
  135. input.caret(Math.max(firstNonMaskPos, begin));
  136. }
  137. function shiftR(pos) {
  138. var i,
  139. c,
  140. j,
  141. t;
  142. for (i = pos, c = settings.placeholder; i < len; i++) {
  143. if (tests[i]) {
  144. j = seekNext(i);
  145. t = buffer[i];
  146. buffer[i] = c;
  147. if (j < len && tests[j].test(t)) {
  148. c = t;
  149. } else {
  150. break;
  151. }
  152. }
  153. }
  154. }
  155. function blurEvent(e) {
  156. checkVal();
  157. if (input.val() != focusText)
  158. input.change();
  159. }
  160. function keydownEvent(e) {
  161. var k = e.which,
  162. pos,
  163. begin,
  164. end;
  165. //backspace, delete, and escape get special treatment
  166. if (k === 8 || k === 46 || (iPhone && k === 127)) {
  167. pos = input.caret();
  168. begin = pos.begin;
  169. end = pos.end;
  170. if (end - begin === 0) {
  171. begin=k!==46?seekPrev(begin):(end=seekNext(begin-1));
  172. end=k===46?seekNext(end):end;
  173. }
  174. clearBuffer(begin, end);
  175. shiftL(begin, end - 1);
  176. e.preventDefault();
  177. } else if( k === 13 ) { // enter
  178. blurEvent.call(this, e);
  179. } else if (k === 27) { // escape
  180. input.val(focusText);
  181. input.caret(0, checkVal());
  182. e.preventDefault();
  183. }
  184. }
  185. function keypressEvent(e) {
  186. var k = e.which,
  187. pos = input.caret(),
  188. p,
  189. c,
  190. next;
  191. if (k == 0) {
  192. // unable to detect key pressed. Grab it from pos and adjust
  193. // this is a failsafe for mobile chrome
  194. // which can't detect keypress events
  195. // reliably
  196. if (pos.begin >= len) {
  197. input.val(input.val().substr(0, len));
  198. e.preventDefault();
  199. return false;
  200. }
  201. if (pos.begin == pos.end) {
  202. k = input.val().charCodeAt(pos.begin - 1);
  203. pos.begin--;
  204. pos.end--;
  205. }
  206. }
  207. if (e.ctrlKey || e.altKey || e.metaKey || k < 32) {//Ignore
  208. return;
  209. } else if ( k && k !== 13 ) {
  210. if (pos.end - pos.begin !== 0){
  211. clearBuffer(pos.begin, pos.end);
  212. shiftL(pos.begin, pos.end-1);
  213. }
  214. p = seekNext(pos.begin - 1);
  215. if (p < len) {
  216. c = String.fromCharCode(k);
  217. if (tests[p].test(c)) {
  218. shiftR(p);
  219. buffer[p] = c;
  220. writeBuffer();
  221. next = seekNext(p);
  222. if(android){
  223. setTimeout($.proxy($.fn.caret,input,next),0);
  224. }else{
  225. input.caret(next);
  226. }
  227. if (settings.completed && next >= len) {
  228. settings.completed.call(input);
  229. }
  230. }
  231. }
  232. e.preventDefault();
  233. }
  234. }
  235. function clearBuffer(start, end) {
  236. var i;
  237. for (i = start; i < end && i < len; i++) {
  238. if (tests[i]) {
  239. buffer[i] = settings.placeholder[i % settings.placeholder.length];
  240. }
  241. }
  242. }
  243. function writeBuffer() { input.val(buffer.join('')); }
  244. function checkVal(allow) {
  245. //try to place characters where they belong
  246. var test = input.val(),
  247. lastMatch = -1,
  248. i,
  249. c,
  250. pos;
  251. for (i = 0, pos = 0; i < len; i++) {
  252. if (tests[i]) {
  253. buffer[i] = settings.placeholder[i % settings.placeholder.length];
  254. while (pos++ < test.length) {
  255. c = test.charAt(pos - 1);
  256. if (tests[i].test(c)) {
  257. buffer[i] = c;
  258. lastMatch = i;
  259. break;
  260. }
  261. }
  262. if (pos > test.length) {
  263. break;
  264. }
  265. } else if (buffer[i] === test.charAt(pos) && i !== partialPosition) {
  266. pos++;
  267. lastMatch = i;
  268. }
  269. }
  270. if (allow) {
  271. writeBuffer();
  272. } else if (lastMatch + 1 < partialPosition) {
  273. if (settings.autoclear || buffer.join('') === defaultBuffer) {
  274. // Invalid value. Remove it and replace it with the
  275. // mask, which is the default behavior.
  276. input.val("");
  277. clearBuffer(0, len);
  278. } else {
  279. // Invalid value, but we opt to show the value to the
  280. // user and allow them to correct their mistake.
  281. writeBuffer();
  282. }
  283. } else {
  284. writeBuffer();
  285. input.val(input.val().substring(0, lastMatch + 1));
  286. }
  287. return (partialPosition ? i : firstNonMaskPos);
  288. }
  289. input.data($.mask.dataName,function(){
  290. return $.map(buffer, function(c, i) {
  291. return tests[i]&&c!=settings.placeholder[i % settings.placeholder.length] ? c : null;
  292. }).join('');
  293. });
  294. if (!input.attr("readonly"))
  295. input
  296. .one("unmask", function() {
  297. input
  298. .unbind(".mask")
  299. .removeData($.mask.dataName);
  300. })
  301. .bind("focus.mask", function() {
  302. clearTimeout(caretTimeoutId);
  303. var pos;
  304. focusText = input.val();
  305. pos = checkVal();
  306. caretTimeoutId = setTimeout(function(){
  307. writeBuffer();
  308. if (pos == mask.replace("?","").length) {
  309. input.caret(0, pos);
  310. } else {
  311. input.caret(pos);
  312. }
  313. }, 10);
  314. })
  315. .bind("blur.mask", blurEvent)
  316. .bind("keydown.mask", keydownEvent)
  317. .bind("keypress.mask", keypressEvent)
  318. .bind(pasteEventName, function() {
  319. setTimeout(function() {
  320. var pos=checkVal(true);
  321. input.caret(pos);
  322. if (settings.completed && pos == input.val().length)
  323. settings.completed.call(input);
  324. }, 0);
  325. });
  326. if (chrome && android) {
  327. input.bind("keyup.mask", keypressEvent);
  328. }
  329. checkVal(); //Perform initial check for existing values
  330. });
  331. }
  332. });
  333. })(jQuery);