inputmask.numeric.extensions.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. /*
  2. Input Mask plugin extensions
  3. http://github.com/RobinHerbots/jquery.inputmask
  4. Copyright (c) 2010 - Robin Herbots
  5. Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
  6. Version: 0.0.0-dev
  7. Optional extensions on the jquery.inputmask base
  8. */
  9. (function($) {
  10. //number aliases
  11. Inputmask.extendAliases({
  12. "numeric": {
  13. mask: function(opts) {
  14. function autoEscape(txt) {
  15. var escapedTxt = "";
  16. for (var i = 0; i < txt.length; i++) {
  17. escapedTxt += opts.definitions[txt[i]] ? "\\" + txt[i] : txt[i];
  18. }
  19. return escapedTxt;
  20. }
  21. if (opts.repeat !== 0 && isNaN(opts.integerDigits)) {
  22. opts.integerDigits = opts.repeat;
  23. }
  24. opts.repeat = 0;
  25. if (opts.groupSeparator === opts.radixPoint) { //treat equal separator and radixpoint
  26. if (opts.radixPoint === ".")
  27. opts.groupSeparator = ",";
  28. else if (opts.radixPoint === ",")
  29. opts.groupSeparator = ".";
  30. else opts.groupSeparator = "";
  31. }
  32. if (opts.groupSeparator === " ") { //prevent conflict with default skipOptionalPartCharacter
  33. opts.skipOptionalPartCharacter = undefined;
  34. }
  35. opts.autoGroup = opts.autoGroup && opts.groupSeparator !== "";
  36. if (opts.autoGroup) {
  37. if (typeof opts.groupSize == "string" && isFinite(opts.groupSize)) opts.groupSize = parseInt(opts.groupSize);
  38. if (isFinite(opts.integerDigits)) {
  39. var seps = Math.floor(opts.integerDigits / opts.groupSize);
  40. var mod = opts.integerDigits % opts.groupSize;
  41. opts.integerDigits = parseInt(opts.integerDigits) + (mod === 0 ? seps - 1 : seps);
  42. if (opts.integerDigits < 1) {
  43. opts.integerDigits = "*";
  44. }
  45. }
  46. }
  47. //enforce placeholder to single
  48. if (opts.placeholder.length > 1)
  49. opts.placeholder = opts.placeholder.charAt(0);
  50. //only allow radixfocus when placeholder = 0 ???? why was this needed????
  51. // opts.radixFocus = opts.radixFocus && opts.placeholder == "0";
  52. opts.definitions[";"] = opts.definitions["~"]; //clone integer def for decimals
  53. opts.definitions[";"].definitionSymbol = "~";
  54. if (opts.numericInput === true) { //finance people input style
  55. opts.radixFocus = false;
  56. opts.digitsOptional = false;
  57. if (isNaN(opts.digits)) opts.digits = 2;
  58. opts.decimalProtect = false;
  59. }
  60. var mask = autoEscape(opts.prefix);
  61. mask += "[+]";
  62. mask += "~{1," + opts.integerDigits + "}";
  63. if (opts.digits !== undefined && (isNaN(opts.digits) || parseInt(opts.digits) > 0)) {
  64. if (opts.digitsOptional)
  65. mask += "[" + (opts.decimalProtect ? ":" : opts.radixPoint) + ";{" + opts.digits + "}]";
  66. else mask += (opts.decimalProtect ? ":" : opts.radixPoint) + ";{" + opts.digits + "}";
  67. }
  68. if (opts.negationSymbol.back !== "")
  69. mask += "[-]";
  70. mask += autoEscape(opts.suffix);
  71. opts.greedy = false; //enforce greedy false
  72. return mask;
  73. },
  74. placeholder: "",
  75. greedy: false,
  76. digits: "*", //number of fractionalDigits
  77. digitsOptional: true,
  78. radixPoint: ".",
  79. radixFocus: true,
  80. groupSize: 3,
  81. groupSeparator: "",
  82. autoGroup: false,
  83. allowPlus: true,
  84. allowMinus: true,
  85. negationSymbol: {
  86. front: "-", //"("
  87. back: "" //")"
  88. },
  89. integerDigits: "+", //number of integerDigits
  90. prefix: "",
  91. suffix: "",
  92. rightAlign: true,
  93. decimalProtect: true, //do not allow assumption of decimals input without entering the radixpoint
  94. min: undefined, //minimum value
  95. max: undefined, //maximum value
  96. step: 1,
  97. insertMode: true,
  98. autoUnmask: false,
  99. unmaskAsNumber: false,
  100. postFormat: function(buffer, pos, reformatOnly, opts) { //this needs to be removed // this is crap
  101. // console.log(buffer);
  102. if (opts.numericInput === true) {
  103. buffer = buffer.reverse();
  104. if (isFinite(pos))
  105. pos = buffer.join('').length - pos - 1;
  106. }
  107. var negationStrip = false;
  108. var suffixStripped = false;
  109. if (buffer.length >= opts.suffix.length && buffer.join("").indexOf(opts.suffix) === (buffer.length - opts.suffix.length)) {
  110. buffer.length = buffer.length - opts.suffix.length; //strip suffix
  111. suffixStripped = true;
  112. }
  113. //position overflow corrections
  114. pos = pos >= buffer.length ? buffer.length - 1 : (pos < opts.prefix.length ? opts.prefix.length : pos);
  115. var needsRefresh = false,
  116. charAtPos = buffer[pos];
  117. if (opts.groupSeparator === "" || (opts.numericInput !== true &&
  118. ($.inArray(opts.radixPoint, buffer) !== -1 && pos > $.inArray(opts.radixPoint, buffer)) ||
  119. new RegExp("[" + Inputmask.escapeRegex(opts.negationSymbol.front) + "\+]").test(charAtPos))) {
  120. if (suffixStripped) {
  121. for (var i = 0, l = opts.suffix.length; i < l; i++) {
  122. buffer.push(opts.suffix.charAt(i));
  123. }
  124. }
  125. //console.log("return input " + buffer);
  126. return {
  127. pos: pos
  128. };
  129. }
  130. var cbuf = buffer.slice();
  131. if (charAtPos === opts.groupSeparator) {
  132. cbuf.splice(pos--, 1);
  133. charAtPos = cbuf[pos];
  134. }
  135. if (reformatOnly) {
  136. if (charAtPos !== opts.radixPoint) cbuf[pos] = "?";
  137. } else cbuf.splice(pos, 0, "?"); //set position indicator
  138. var bufVal = cbuf.join(''),
  139. bufValOrigin = bufVal;
  140. if (bufVal.length > 0 && opts.autoGroup || (reformatOnly && bufVal.indexOf(opts.groupSeparator) !== -1)) {
  141. var escapedGroupSeparator = Inputmask.escapeRegex(opts.groupSeparator);
  142. needsRefresh = bufVal.indexOf(opts.groupSeparator) === 0;
  143. bufVal = bufVal.replace(new RegExp(escapedGroupSeparator, "g"), '');
  144. var radixSplit = bufVal.split(opts.radixPoint);
  145. bufVal = opts.radixPoint === "" ? bufVal : radixSplit[0];
  146. if (bufVal !== (opts.prefix + "?0") && bufVal.length >= (opts.groupSize + opts.prefix.length)) {
  147. //needsRefresh = true;
  148. var reg = new RegExp('([-\+]?[\\d\?]+)([\\d\?]{' + opts.groupSize + '})');
  149. while (reg.test(bufVal)) {
  150. bufVal = bufVal.replace(reg, '$1' + opts.groupSeparator + '$2');
  151. bufVal = bufVal.replace(opts.groupSeparator + opts.groupSeparator, opts.groupSeparator);
  152. }
  153. }
  154. if (opts.radixPoint !== "" && radixSplit.length > 1)
  155. bufVal += opts.radixPoint + radixSplit[1];
  156. }
  157. needsRefresh = bufValOrigin !== bufVal;
  158. buffer.length = bufVal.length; //align the length
  159. for (var i = 0, l = bufVal.length; i < l; i++) {
  160. buffer[i] = bufVal.charAt(i);
  161. }
  162. var newPos = $.inArray("?", buffer);
  163. if (newPos === -1 && charAtPos === opts.radixPoint) newPos = $.inArray(opts.radixPoint, buffer);
  164. if (reformatOnly) buffer[newPos] = charAtPos;
  165. else buffer.splice(newPos, 1);
  166. if (!needsRefresh && suffixStripped) {
  167. for (var i = 0, l = opts.suffix.length; i < l; i++) {
  168. buffer.push(opts.suffix.charAt(i));
  169. }
  170. }
  171. //console.log("formatted " + buffer + " refresh " + needsRefresh);
  172. return {
  173. pos: (opts.numericInput && isFinite(pos)) ? buffer.join('').length - newPos - 1 : newPos,
  174. "refreshFromBuffer": needsRefresh,
  175. "buffer": opts.numericInput === true ? buffer.reverse() : buffer
  176. };
  177. },
  178. onBeforeWrite: function(e, buffer, caretPos, opts) {
  179. if (e && e.type == "blur") {
  180. //handle minvalue
  181. var maskedValue = buffer.join(''),
  182. processValue = maskedValue.replace(opts.prefix, "");
  183. processValue = processValue.replace(opts.suffix, "");
  184. processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "");
  185. if (opts.radixPoint === ",") processValue = processValue.replace(Inputmask.escapeRegex(opts.radixPoint), ".");
  186. if (isFinite(processValue)) {
  187. if (isFinite(opts.min) && parseFloat(processValue) < parseFloat(opts.min)) {
  188. return $.extend(true, {
  189. "refreshFromBuffer": true,
  190. "buffer": (opts.prefix + opts.min).split('')
  191. }, opts.postFormat((opts.prefix + opts.min).split(''), 0, true, opts));
  192. }
  193. }
  194. if (opts.numericInput !== true) {
  195. var tmpBufSplit = opts.radixPoint != "" ? buffer.join('').split(opts.radixPoint) : [buffer.join('')],
  196. matchRslt = tmpBufSplit[0].match(opts.regex.integerPart(opts)),
  197. matchRsltDigits = tmpBufSplit.length == 2 ? tmpBufSplit[1].match(opts.regex.integerNPart(opts)) : undefined;
  198. if (matchRslt && (matchRslt[0] == opts.negationSymbol.front + "0" || matchRslt[0] == opts.negationSymbol.front || matchRslt[0] == "+") && (matchRsltDigits == undefined || matchRsltDigits[0].match(/^0+$/))) {
  199. buffer.splice(matchRslt.index, 1);
  200. }
  201. var radixPosition = $.inArray(opts.radixPoint, buffer);
  202. if (radixPosition != -1) {
  203. if (isFinite(opts.digits) && !opts.digitsOptional) {
  204. for (var i = 1; i <= opts.digits; i++) {
  205. if (buffer[radixPosition + i] == undefined || buffer[radixPosition + i] == opts.placeholder.charAt(0)) buffer[radixPosition + i] = "0";
  206. }
  207. return {
  208. "refreshFromBuffer": true,
  209. "buffer": buffer
  210. };
  211. } else if (radixPosition == buffer.length - opts.suffix.length - 1) {
  212. buffer.splice(radixPosition, 1);
  213. return {
  214. "refreshFromBuffer": true,
  215. "buffer": buffer
  216. };
  217. }
  218. }
  219. }
  220. }
  221. if (opts.autoGroup) {
  222. var rslt = opts.postFormat(buffer, caretPos - 1, true, opts);
  223. rslt.caret = caretPos <= opts.prefix.length ? rslt.pos : rslt.pos + 1;
  224. return rslt;
  225. }
  226. },
  227. regex: {
  228. integerPart: function(opts) {
  229. return new RegExp('[' + Inputmask.escapeRegex(opts.negationSymbol.front) + '\+]?\\d+');
  230. },
  231. integerNPart: function(opts) {
  232. return new RegExp('[\\d' + Inputmask.escapeRegex(opts.groupSeparator) + ']+');
  233. }
  234. },
  235. signHandler: function(chrs, maskset, pos, strict, opts) {
  236. if (!strict && (opts.allowMinus && chrs === "-") || (opts.allowPlus && chrs === "+")) {
  237. var matchRslt = maskset.buffer.join('').match(opts.regex.integerPart(opts));
  238. if (matchRslt && matchRslt[0].length > 0) {
  239. if (maskset.buffer[matchRslt.index] == (chrs === "-" ? "+" : opts.negationSymbol.front)) {
  240. if (chrs == "-") {
  241. if (opts.negationSymbol.back != "")
  242. return {
  243. "pos": matchRslt.index,
  244. "c": opts.negationSymbol.front,
  245. "remove": matchRslt.index,
  246. "caret": pos,
  247. "insert": {
  248. "pos": maskset["buffer"].length - opts.suffix.length - 1,
  249. "c": opts.negationSymbol.back
  250. }
  251. };
  252. else return {
  253. "pos": matchRslt.index,
  254. "c": opts.negationSymbol.front,
  255. "remove": matchRslt.index,
  256. "caret": pos
  257. };
  258. } else {
  259. if (opts.negationSymbol.back != "")
  260. return {
  261. "pos": matchRslt.index,
  262. "c": "+",
  263. "remove": [matchRslt.index, maskset["buffer"].length - opts.suffix.length - 1],
  264. "caret": pos
  265. };
  266. else return {
  267. "pos": matchRslt.index,
  268. "c": "+",
  269. "remove": matchRslt.index,
  270. "caret": pos
  271. };
  272. }
  273. } else if (maskset.buffer[matchRslt.index] == (chrs === "-" ? opts.negationSymbol.front : "+")) {
  274. if (chrs == "-" && opts.negationSymbol.back != "") {
  275. return {
  276. "remove": [matchRslt.index, maskset["buffer"].length - opts.suffix.length - 1],
  277. "caret": pos - 1
  278. };
  279. } else {
  280. return {
  281. "remove": matchRslt.index,
  282. "caret": pos - 1
  283. };
  284. }
  285. } else {
  286. if (chrs == "-") {
  287. if (opts.negationSymbol.back != "")
  288. return {
  289. "pos": matchRslt.index,
  290. "c": opts.negationSymbol.front,
  291. "caret": pos + 1,
  292. "insert": {
  293. "pos": maskset["buffer"].length - opts.suffix.length,
  294. "c": opts.negationSymbol.back
  295. }
  296. };
  297. else return {
  298. "pos": matchRslt.index,
  299. "c": opts.negationSymbol.front,
  300. "caret": pos + 1
  301. };
  302. } else {
  303. return {
  304. "pos": matchRslt.index,
  305. "c": chrs,
  306. "caret": pos + 1
  307. };
  308. }
  309. }
  310. }
  311. }
  312. return false;
  313. },
  314. radixHandler: function(chrs, maskset, pos, strict, opts) {
  315. if (!strict) {
  316. if ($.inArray(chrs, [",", "."]) != -1) chrs = opts.radixPoint;
  317. if (chrs === opts.radixPoint && (opts.digits != undefined && (isNaN(opts.digits) || parseInt(opts.digits) > 0))) {
  318. var radixPos = $.inArray(opts.radixPoint, maskset.buffer),
  319. integerValue = maskset.buffer.join('').match(opts.regex.integerPart(opts));
  320. if (radixPos != -1 && maskset["validPositions"][radixPos]) {
  321. if (maskset["validPositions"][radixPos - 1])
  322. return {
  323. "caret": radixPos + 1
  324. };
  325. else return {
  326. "pos": integerValue.index,
  327. c: integerValue[0],
  328. "caret": radixPos + 1
  329. };
  330. } else if (!integerValue || (integerValue["0"] == "0" && (integerValue.index + 1) != pos)) {
  331. maskset.buffer[integerValue ? integerValue.index : pos] = "0";
  332. return {
  333. "pos": (integerValue ? integerValue.index : pos) + 1,
  334. c: opts.radixPoint
  335. };
  336. }
  337. }
  338. }
  339. return false;
  340. },
  341. leadingZeroHandler: function(chrs, maskset, pos, strict, opts) {
  342. if (opts.numericInput == true) {
  343. if (maskset.buffer[maskset.buffer.length - opts.prefix.length - 1] == "0")
  344. return {
  345. "pos": pos,
  346. "remove": maskset.buffer.length - opts.prefix.length - 1
  347. };
  348. } else {
  349. var matchRslt = maskset.buffer.join('').match(opts.regex.integerNPart(opts)),
  350. radixPosition = $.inArray(opts.radixPoint, maskset.buffer);
  351. if (matchRslt && !strict && (radixPosition == -1 || pos <= radixPosition)) {
  352. if (matchRslt["0"].indexOf("0") == 0) {
  353. if (pos < opts.prefix.length) pos = matchRslt.index; //position
  354. var _radixPosition = $.inArray(opts.radixPoint, maskset._buffer);
  355. var digitsMatch = maskset._buffer && maskset.buffer.slice(radixPosition).join('') == maskset._buffer.slice(_radixPosition).join('') || parseInt(maskset.buffer.slice(radixPosition + 1).join('')) == 0;
  356. var integerMatch = maskset._buffer && maskset.buffer.slice(matchRslt.index, radixPosition).join('') == maskset._buffer.slice(opts.prefix.length, _radixPosition).join('') || maskset.buffer.slice(matchRslt.index, radixPosition).join('') == "0";
  357. if (radixPosition == -1 || digitsMatch && integerMatch) {
  358. maskset.buffer.splice(matchRslt.index, 1);
  359. pos = pos > matchRslt.index ? pos - 1 : matchRslt.index;
  360. return {
  361. "pos": pos,
  362. "remove": matchRslt.index
  363. };
  364. } else if (matchRslt.index + 1 == pos || chrs == "0") {
  365. maskset.buffer.splice(matchRslt.index, 1);
  366. pos = matchRslt.index;
  367. return {
  368. "pos": pos,
  369. "remove": matchRslt.index
  370. };
  371. }
  372. } else if (chrs === "0" && pos <= matchRslt.index && matchRslt["0"] != opts.groupSeparator) {
  373. return false;
  374. }
  375. }
  376. }
  377. return true;
  378. },
  379. postValidation: function(buffer, opts) {
  380. //handle maxvalue
  381. var isValid = true,
  382. maskedValue = buffer.join(''),
  383. processValue = maskedValue.replace(opts.prefix, "");
  384. processValue = processValue.replace(opts.suffix, "");
  385. processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "");
  386. if (opts.radixPoint === ",") processValue = processValue.replace(Inputmask.escapeRegex(opts.radixPoint), ".");
  387. //handle negation symbol
  388. processValue = processValue.replace(new RegExp("^" + Inputmask.escapeRegex(opts.negationSymbol.front)), "-");
  389. processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.negationSymbol.back) + "$"), "");
  390. processValue = processValue == opts.negationSymbol.front ? processValue + "0" : processValue;
  391. if (isFinite(processValue)) {
  392. if (isFinite(opts.max)) {
  393. isValid = parseFloat(processValue) <= parseFloat(opts.max);
  394. }
  395. if (isValid && isFinite(opts.min) && (processValue <= 0 || processValue.toString().length >= opts.min.toString().length)) {
  396. isValid = parseFloat(processValue) >= parseFloat(opts.min);
  397. if (!isValid) {
  398. isValid = $.extend(true, {
  399. "refreshFromBuffer": true,
  400. "buffer": (opts.prefix + opts.min).split('')
  401. }, opts.postFormat((opts.prefix + opts.min).split(''), 0, true, opts));
  402. isValid.refreshFromBuffer = true; //enforce refresh
  403. }
  404. }
  405. }
  406. return isValid;
  407. },
  408. definitions: {
  409. '~': {
  410. validator: function(chrs, maskset, pos, strict, opts) {
  411. var isValid = opts.signHandler(chrs, maskset, pos, strict, opts);
  412. if (!isValid) {
  413. isValid = opts.radixHandler(chrs, maskset, pos, strict, opts);
  414. if (!isValid) {
  415. isValid = strict ? new RegExp("[0-9" + Inputmask.escapeRegex(opts.groupSeparator) + "]").test(chrs) : new RegExp("[0-9]").test(chrs);
  416. if (isValid === true) {
  417. isValid = opts.leadingZeroHandler(chrs, maskset, pos, strict, opts);
  418. if (isValid === true) {
  419. //handle overwrite when fixed precision
  420. var radixPosition = $.inArray(opts.radixPoint, maskset.buffer);
  421. if (radixPosition != -1 && opts.digitsOptional === false && pos > radixPosition && !strict) {
  422. isValid = {
  423. "pos": pos,
  424. "remove": pos
  425. };
  426. } else isValid = {
  427. pos: pos
  428. };
  429. }
  430. }
  431. }
  432. }
  433. return isValid;
  434. },
  435. cardinality: 1,
  436. prevalidator: null
  437. },
  438. '+': {
  439. validator: function(chrs, maskset, pos, strict, opts) {
  440. var isValid = opts.signHandler(chrs, maskset, pos, strict, opts),
  441. nbl;
  442. if (!isValid && ((strict && opts.allowMinus && chrs === opts.negationSymbol.front) || (opts.allowMinus && chrs == "-") || (opts.allowPlus && chrs == "+"))) {
  443. if (chrs == "-") {
  444. if (opts.negationSymbol.back != "")
  445. isValid = {
  446. "pos": pos,
  447. "c": chrs === "-" ? opts.negationSymbol.front : "+",
  448. "caret": pos + 1,
  449. "insert": {
  450. "pos": maskset["buffer"].length,
  451. "c": opts.negationSymbol.back
  452. }
  453. };
  454. else isValid = {
  455. "pos": pos,
  456. "c": chrs === "-" ? opts.negationSymbol.front : "+",
  457. "caret": pos + 1
  458. };
  459. } else {
  460. isValid = true;
  461. }
  462. }
  463. return isValid;
  464. },
  465. cardinality: 1,
  466. prevalidator: null,
  467. placeholder: ''
  468. },
  469. '-': {
  470. validator: function(chrs, maskset, pos, strict, opts) {
  471. var isValid = opts.signHandler(chrs, maskset, pos, strict, opts);
  472. if (!isValid && strict && opts.allowMinus && chrs === opts.negationSymbol.back) {
  473. isValid = true;
  474. }
  475. return isValid;
  476. },
  477. cardinality: 1,
  478. prevalidator: null,
  479. placeholder: ''
  480. },
  481. ':': {
  482. validator: function(chrs, maskset, pos, strict, opts) {
  483. var isValid = opts.signHandler(chrs, maskset, pos, strict, opts);
  484. if (!isValid) {
  485. var radix = "[" + Inputmask.escapeRegex(opts.radixPoint) + ",\\." + "]";
  486. isValid = new RegExp(radix).test(chrs);
  487. if (isValid && maskset["validPositions"][pos] && maskset["validPositions"][pos]["match"].placeholder == opts.radixPoint) {
  488. isValid = {
  489. "caret": pos + 1
  490. };
  491. }
  492. }
  493. return isValid ? {
  494. c: opts.radixPoint
  495. } : isValid;
  496. },
  497. cardinality: 1,
  498. prevalidator: null,
  499. placeholder: function(opts) {
  500. return opts.radixPoint;
  501. }
  502. }
  503. },
  504. onUnMask: function(maskedValue, unmaskedValue, opts) {
  505. var processValue = maskedValue.replace(opts.prefix, "");
  506. processValue = processValue.replace(opts.suffix, "");
  507. processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "");
  508. if (opts.unmaskAsNumber) {
  509. processValue = processValue.replace(Inputmask.escapeRegex.call(this, opts.radixPoint), ".");
  510. return Number(processValue);
  511. }
  512. return processValue;
  513. },
  514. isComplete: function(buffer, opts) {
  515. var maskedValue = buffer.join(''),
  516. bufClone = buffer.slice();
  517. //verify separator positions
  518. opts.postFormat(bufClone, 0, true, opts);
  519. if (bufClone.join('') !== maskedValue) return false;
  520. var processValue = maskedValue.replace(opts.prefix, "");
  521. processValue = processValue.replace(opts.suffix, "");
  522. processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "");
  523. if (opts.radixPoint === ",") processValue = processValue.replace(Inputmask.escapeRegex(opts.radixPoint), ".");
  524. return isFinite(processValue);
  525. },
  526. onBeforeMask: function(initialValue, opts) {
  527. if (opts.radixPoint !== "" && isFinite(initialValue)) {
  528. initialValue = initialValue.toString().replace(".", opts.radixPoint);
  529. } else {
  530. var kommaMatches = initialValue.match(/,/g);
  531. var dotMatches = initialValue.match(/\./g);
  532. if (dotMatches && kommaMatches) {
  533. if (dotMatches.length > kommaMatches.length) {
  534. initialValue = initialValue.replace(/\./g, "");
  535. initialValue = initialValue.replace(",", opts.radixPoint);
  536. } else if (kommaMatches.length > dotMatches.length) {
  537. initialValue = initialValue.replace(/,/g, "");
  538. initialValue = initialValue.replace(".", opts.radixPoint);
  539. } else { //equal
  540. initialValue = initialValue.indexOf(".") < initialValue.indexOf(",") ? initialValue.replace(/\./g, "") : initialValue = initialValue.replace(/,/g, "");
  541. }
  542. } else {
  543. initialValue = initialValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "");
  544. }
  545. }
  546. if (opts.digits == 0) {
  547. if (initialValue.indexOf(".") !== -1) {
  548. initialValue = initialValue.substring(0, initialValue.indexOf("."));
  549. } else if (initialValue.indexOf(",") !== -1) {
  550. initialValue = initialValue.substring(0, initialValue.indexOf(","));
  551. }
  552. }
  553. if (opts.radixPoint !== "" && isFinite(opts.digits) && initialValue.indexOf(opts.radixPoint) !== -1) {
  554. var valueParts = initialValue.split(opts.radixPoint),
  555. decPart = valueParts[1].match(new RegExp("\\d*"))[0];
  556. if (parseInt(opts.digits) < decPart.toString().length) {
  557. var digitsFactor = Math.pow(10, parseInt(opts.digits));
  558. //make the initialValue a valid javascript number for the parsefloat
  559. initialValue = initialValue.replace(Inputmask.escapeRegex(opts.radixPoint), ".");
  560. initialValue = Math.round(parseFloat(initialValue) * digitsFactor) / digitsFactor;
  561. initialValue = initialValue.toString().replace(".", opts.radixPoint);
  562. }
  563. }
  564. return initialValue.toString();
  565. },
  566. canClearPosition: function(maskset, position, lvp, strict, opts) {
  567. var positionInput = maskset.validPositions[position].input,
  568. canClear = ((positionInput != opts.radixPoint || (maskset.validPositions[position].match.fn != null && opts.decimalProtect == false)) || isFinite(positionInput)) ||
  569. position === lvp ||
  570. positionInput === opts.groupSeparator ||
  571. positionInput === opts.negationSymbol.front ||
  572. positionInput === opts.negationSymbol.back,
  573. posOffset = 0;
  574. if (canClear && isFinite(positionInput)) {
  575. var matchRslt
  576. if (!strict && maskset["buffer"]) {
  577. matchRslt = maskset["buffer"].join('').substr(0, position).match(opts.regex.integerNPart(opts));
  578. var pos = position + 1,
  579. isNull = matchRslt == null || parseInt(matchRslt["0"].replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "")) == 0;
  580. if (isNull) {
  581. while (maskset["validPositions"][pos] && (maskset["validPositions"][pos].input == opts.groupSeparator || maskset["validPositions"][pos].input == "0")) {
  582. delete maskset["validPositions"][pos];
  583. pos++;
  584. }
  585. }
  586. }
  587. var buffer = [];
  588. //build new buffer from validPositions
  589. for (var vp in maskset.validPositions) {
  590. buffer.push(maskset.validPositions[vp].input);
  591. }
  592. if (opts.numericInput == true) {
  593. position = buffer.join('').length - position;
  594. buffer.reverse();
  595. }
  596. matchRslt = buffer.join('').match(opts.regex.integerNPart(opts));
  597. var radixPosition = $.inArray(opts.radixPoint, maskset.buffer);
  598. if (matchRslt && (radixPosition == -1 || position <= radixPosition)) {
  599. if (matchRslt["0"].indexOf("0") == 0) {
  600. canClear = matchRslt.index != position || radixPosition == -1;
  601. } else {
  602. var intPart = parseInt(matchRslt["0"].replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), ""));
  603. if (radixPosition != -1 && intPart < 10 && maskset["validPositions"][position]) {
  604. maskset["validPositions"][position].input = "0";
  605. maskset["p"] = opts.prefix.length + 1;
  606. canClear = false;
  607. }
  608. }
  609. }
  610. }
  611. return canClear;
  612. },
  613. onKeyDown: function(e, buffer, caretPos, opts) {
  614. var $input = $(this);
  615. if (e.ctrlKey) {
  616. switch (e.keyCode) {
  617. case inputmask.keyCode.UP:
  618. $input.val(parseFloat(this.inputmask.unmaskedvalue()) + parseInt(opts.step));
  619. $input.triggerHandler('setvalue.inputmask');
  620. break;
  621. case inputmask.keyCode.DOWN:
  622. $input.val(parseFloat(this.inputmask.unmaskedvalue()) - parseInt(opts.step));
  623. $input.triggerHandler('setvalue.inputmask');
  624. break;
  625. }
  626. }
  627. },
  628. },
  629. 'currency': {
  630. prefix: "$ ",
  631. groupSeparator: ",",
  632. alias: "numeric",
  633. placeholder: "0",
  634. autoGroup: true,
  635. digits: 2,
  636. digitsOptional: false,
  637. clearMaskOnLostFocus: false
  638. },
  639. 'decimal': {
  640. alias: "numeric"
  641. },
  642. 'integer': {
  643. alias: "numeric",
  644. digits: 0,
  645. radixPoint: ""
  646. },
  647. 'percentage': {
  648. alias: "numeric",
  649. digits: 2,
  650. radixPoint: ".",
  651. placeholder: "0",
  652. autoGroup: false,
  653. min: 0,
  654. max: 100,
  655. suffix: " %",
  656. allowPlus: false,
  657. allowMinus: false
  658. },
  659. 'numeric2': {
  660. alias: "numeric"
  661. },
  662. });
  663. return Inputmask;
  664. })(jQuery);