inputmask.numeric.extensions.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  1. /*
  2. Input Mask plugin extensions
  3. http://github.com/RobinHerbots/jquery.inputmask
  4. Copyright (c) Robin Herbots
  5. Licensed under the MIT license
  6. */
  7. var Inputmask = require("../inputmask"), $ = Inputmask.dependencyLib, keyCode = require("../keycode");
  8. function autoEscape(txt, opts) {
  9. var escapedTxt = "";
  10. for (var i = 0; i < txt.length; i++) {
  11. if (Inputmask.prototype.definitions[txt.charAt(i)] ||
  12. opts.definitions[txt.charAt(i)] ||
  13. opts.optionalmarker[0] === txt.charAt(i) ||
  14. opts.optionalmarker[1] === txt.charAt(i) ||
  15. opts.quantifiermarker[0] === txt.charAt(i) ||
  16. opts.quantifiermarker[1] === txt.charAt(i) ||
  17. opts.groupmarker[0] === txt.charAt(i) ||
  18. opts.groupmarker[1] === txt.charAt(i) ||
  19. opts.alternatormarker === txt.charAt(i)) {
  20. escapedTxt += "\\" + txt.charAt(i);
  21. } else {
  22. escapedTxt += txt.charAt(i);
  23. }
  24. }
  25. return escapedTxt;
  26. }
  27. function alignDigits(buffer, digits, opts, force) {
  28. if (digits > 0 && (!opts.digitsOptional || force)) {
  29. var radixPosition = $.inArray(opts.radixPoint, buffer);
  30. if (radixPosition === -1) {
  31. buffer.push(opts.radixPoint);
  32. radixPosition = buffer.length - 1;
  33. }
  34. for (var i = 1; i <= digits; i++) {
  35. buffer[radixPosition + i] = buffer[radixPosition + i] || "0";
  36. }
  37. }
  38. return buffer;
  39. }
  40. function findValidator(symbol, maskset) {
  41. var posNdx = 0;
  42. if (symbol === "+") {
  43. for (posNdx in maskset.validPositions);
  44. posNdx = parseInt(posNdx);
  45. }
  46. for (var tstNdx in maskset.tests) {
  47. tstNdx = parseInt(tstNdx);
  48. if (tstNdx >= posNdx) {
  49. for (var ndx = 0, ndxl = maskset.tests[tstNdx].length; ndx < ndxl; ndx++) {
  50. if ((maskset.validPositions[tstNdx] === undefined || symbol === "-") && maskset.tests[tstNdx][ndx].match.def === symbol) {
  51. return tstNdx + ((maskset.validPositions[tstNdx] !== undefined && symbol !== "-") ? 1 : 0);
  52. }
  53. }
  54. }
  55. }
  56. return posNdx;
  57. }
  58. function findValid(symbol, maskset) {
  59. var ret = -1;
  60. $.each(maskset.validPositions, function (ndx, tst) {
  61. if (tst && tst.match.def === symbol) {
  62. ret = parseInt(ndx);
  63. return false;
  64. }
  65. });
  66. return ret;
  67. }
  68. function parseMinMaxOptions(opts) {
  69. if (opts.parseMinMaxOptions === undefined) {
  70. // convert min and max options
  71. if (opts.min !== null) {
  72. opts.min = opts.min.toString().replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "");
  73. if (opts.radixPoint === ",") opts.min = opts.min.replace(opts.radixPoint, ".");
  74. opts.min = isFinite(opts.min) ? parseFloat(opts.min) : NaN;
  75. if (isNaN(opts.min)) opts.min = Number.MIN_VALUE;
  76. }
  77. if (opts.max !== null) {
  78. opts.max = opts.max.toString().replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "");
  79. if (opts.radixPoint === ",") opts.max = opts.max.replace(opts.radixPoint, ".");
  80. opts.max = isFinite(opts.max) ? parseFloat(opts.max) : NaN;
  81. if (isNaN(opts.max)) opts.max = Number.MAX_VALUE;
  82. }
  83. opts.parseMinMaxOptions = "done";
  84. }
  85. }
  86. function genMask(opts) {
  87. opts.repeat = 0;
  88. //treat equal separator and radixpoint
  89. if (opts.groupSeparator === opts.radixPoint && opts.digits && opts.digits !== "0") {
  90. if (opts.radixPoint === ".") {
  91. opts.groupSeparator = ",";
  92. } else if (opts.radixPoint === ",") {
  93. opts.groupSeparator = ".";
  94. } else {
  95. opts.groupSeparator = "";
  96. }
  97. }
  98. //prevent conflict with default skipOptionalPartCharacter
  99. if (opts.groupSeparator === " ") {
  100. opts.skipOptionalPartCharacter = undefined;
  101. }
  102. //enforce placeholder to single
  103. if (opts.placeholder.length > 1) {
  104. opts.placeholder = opts.placeholder.charAt(0);
  105. }
  106. //only allow radixfocus when placeholder = 0
  107. if (opts.positionCaretOnClick === "radixFocus" && opts.placeholder === "") {
  108. opts.positionCaretOnClick = "lvp";
  109. }
  110. var decimalDef = "0", radixPointDef = opts.radixPoint;
  111. if (opts.numericInput === true && opts.__financeInput === undefined) { //finance people input style
  112. decimalDef = "1";
  113. opts.positionCaretOnClick = opts.positionCaretOnClick === "radixFocus" ? "lvp" : opts.positionCaretOnClick;
  114. opts.digitsOptional = false;
  115. if (isNaN(opts.digits)) opts.digits = 2;
  116. opts._radixDance = false;
  117. radixPointDef = opts.radixPoint === "," ? "^" : "¨";
  118. if (opts.radixPoint !== "" && opts.definitions[radixPointDef] === undefined) {
  119. //update separatot definition
  120. opts.definitions[radixPointDef] = {};
  121. opts.definitions[radixPointDef].validator = "[" + opts.radixPoint + "]";
  122. opts.definitions[radixPointDef].placeholder = opts.radixPoint;
  123. opts.definitions[radixPointDef].static = true;
  124. opts.definitions[radixPointDef].generated = true; //forced marker as generated input
  125. }
  126. } else {
  127. opts.__financeInput = false; //needed to keep original selection when remasking
  128. opts.numericInput = true;
  129. }
  130. var mask = "[+]", altMask;
  131. mask += autoEscape(opts.prefix, opts);
  132. if (opts.groupSeparator !== "") {
  133. if (opts.definitions[opts.groupSeparator] === undefined) {
  134. //update separatot definition
  135. opts.definitions[opts.groupSeparator] = {};
  136. opts.definitions[opts.groupSeparator].validator = "[" + opts.groupSeparator + "]";
  137. opts.definitions[opts.groupSeparator].placeholder = opts.groupSeparator;
  138. opts.definitions[opts.groupSeparator].static = true;
  139. opts.definitions[opts.groupSeparator].generated = true; //forced marker as generated input
  140. }
  141. mask += opts._mask(opts);
  142. } else {
  143. mask += "9{+}";
  144. }
  145. if (opts.digits !== undefined && opts.digits !== 0) {
  146. var dq = opts.digits.toString().split(",");
  147. if (isFinite(dq[0]) && dq[1] && isFinite(dq[1])) {
  148. mask += radixPointDef + decimalDef + "{" + opts.digits + "}";
  149. } else if (isNaN(opts.digits) || parseInt(opts.digits) > 0) {
  150. if (opts.digitsOptional) {
  151. altMask = mask + radixPointDef + decimalDef + "{0," + opts.digits + "}";
  152. // mask += "[" + opts.radixPoint + "]";
  153. opts.keepStatic = true;
  154. } else {
  155. mask += radixPointDef + decimalDef + "{" + opts.digits + "}";
  156. }
  157. }
  158. }
  159. mask += autoEscape(opts.suffix, opts);
  160. mask += "[-]";
  161. if (altMask) {
  162. mask = [(altMask + autoEscape(opts.suffix, opts) + "[-]"), mask];
  163. }
  164. opts.greedy = false; //enforce greedy false
  165. parseMinMaxOptions(opts);
  166. // console.log(mask);
  167. return mask;
  168. }
  169. function hanndleRadixDance(pos, c, radixPos, maskset, opts) {
  170. if (opts._radixDance && opts.numericInput && c !== opts.negationSymbol.back) {
  171. if (pos <= radixPos && (radixPos > 0 || c == opts.radixPoint) && (maskset.validPositions[pos - 1] === undefined || maskset.validPositions[pos - 1].input !== opts.negationSymbol.back)) {
  172. pos -= 1;
  173. }
  174. }
  175. return pos;
  176. }
  177. function decimalValidator(chrs, maskset, pos, strict, opts) {
  178. var radixPos = maskset.buffer ? maskset.buffer.indexOf(opts.radixPoint) : -1,
  179. result = radixPos !== -1 && new RegExp("[0-9\uFF11-\uFF19]").test(chrs);
  180. if (opts._radixDance && result && maskset.validPositions[radixPos] == undefined) {
  181. return {
  182. insert: {
  183. pos: radixPos === pos ? radixPos + 1 : radixPos,
  184. c: opts.radixPoint
  185. },
  186. pos: pos
  187. };
  188. }
  189. return result;
  190. }
  191. function checkForLeadingZeroes(buffer, opts) {
  192. //check leading zeros
  193. var numberMatches = new RegExp("(^" + (opts.negationSymbol.front !== "" ? Inputmask.escapeRegex(opts.negationSymbol.front) + "?" : "") + Inputmask.escapeRegex(opts.prefix) + ")(.*)(" + Inputmask.escapeRegex(opts.suffix) + (opts.negationSymbol.back != "" ? Inputmask.escapeRegex(opts.negationSymbol.back) + "?" : "") + "$)").exec(buffer.slice().reverse().join("")),
  194. number = numberMatches ? numberMatches[2] : "", leadingzeroes = false;
  195. if (number) {
  196. number = number.split(opts.radixPoint.charAt(0))[0];
  197. leadingzeroes = new RegExp("^[0" + opts.groupSeparator + "]*").exec(number);
  198. }
  199. return leadingzeroes && (leadingzeroes[0].length > 1 || leadingzeroes[0].length > 0 && leadingzeroes[0].length < number.length) ? leadingzeroes : false;
  200. }
  201. //number aliases
  202. Inputmask.extendAliases({
  203. "numeric": {
  204. mask: genMask,
  205. _mask: function (opts) {
  206. return "(" + opts.groupSeparator + "999){+|1}";
  207. },
  208. digits: "*", //number of fractionalDigits
  209. digitsOptional: true,
  210. enforceDigitsOnBlur: false,
  211. radixPoint: ".",
  212. positionCaretOnClick: "radixFocus",
  213. _radixDance: true,
  214. groupSeparator: "",
  215. allowMinus: true,
  216. negationSymbol: {
  217. front: "-", //"("
  218. back: "" //")"
  219. },
  220. prefix: "",
  221. suffix: "",
  222. min: null, //minimum value
  223. max: null, //maximum value
  224. step: 1,
  225. unmaskAsNumber: false,
  226. roundingFN: Math.round, //Math.floor , fn(x)
  227. inputmode: "numeric",
  228. shortcuts: { k: "000", m: "000000" },
  229. //global options
  230. placeholder: "0",
  231. greedy: false,
  232. rightAlign: true,
  233. insertMode: true,
  234. autoUnmask: false,
  235. skipOptionalPartCharacter: "",
  236. definitions: {
  237. "0": {
  238. validator: decimalValidator
  239. },
  240. "1": {
  241. validator: decimalValidator,
  242. definitionSymbol: "*"
  243. },
  244. "+": {
  245. validator: function (chrs, maskset, pos, strict, opts) {
  246. return (opts.allowMinus && (chrs === "-" || chrs === opts.negationSymbol.front));
  247. }
  248. },
  249. "-": {
  250. validator: function (chrs, maskset, pos, strict, opts) {
  251. return (opts.allowMinus && chrs === opts.negationSymbol.back);
  252. }
  253. }
  254. },
  255. preValidation: function (buffer, pos, c, isSelection, opts, maskset, caretPos, strict) {
  256. if (opts.__financeInput !== false && c === opts.radixPoint) return false;
  257. var pattern;
  258. if ((pattern = (opts.shortcuts && opts.shortcuts[c]))) {
  259. if (pattern.length > 1) {
  260. var inserts = [];
  261. for (var i = 0; i < pattern.length; i++) {
  262. inserts.push({ pos: pos + i, c: pattern[i], strict: false });
  263. }
  264. }
  265. return {
  266. insert: inserts
  267. };
  268. }
  269. var radixPos = $.inArray(opts.radixPoint, buffer), initPos = pos;
  270. ;
  271. pos = hanndleRadixDance(pos, c, radixPos, maskset, opts);
  272. if (c === "-" || c === opts.negationSymbol.front) {
  273. if (opts.allowMinus !== true) return false;
  274. var isNegative = false,
  275. front = findValid("+", maskset), back = findValid("-", maskset);
  276. if (front !== -1) {
  277. isNegative = [front, back];
  278. }
  279. return isNegative !== false ? {
  280. remove: isNegative,
  281. caret: initPos
  282. } : {
  283. insert: [
  284. { pos: findValidator("+", maskset), c: opts.negationSymbol.front, fromIsValid: true },
  285. { pos: findValidator("-", maskset), c: opts.negationSymbol.back, fromIsValid: undefined }],
  286. caret: initPos + opts.negationSymbol.back.length
  287. };
  288. }
  289. if (strict) return true;
  290. if (radixPos !== -1 && (opts._radixDance === true && isSelection === false && c === opts.radixPoint && (opts.digits !== undefined && (isNaN(opts.digits) || parseInt(opts.digits) > 0)) && radixPos !== pos)) {
  291. return {
  292. "caret": opts._radixDance && pos === radixPos - 1 ? radixPos + 1 : radixPos
  293. };
  294. }
  295. if (isSelection && opts.__financeInput === false) {
  296. if (opts.digitsOptional) {
  297. return { rewritePosition: caretPos.end };
  298. } else if (!opts.digitsOptional) {
  299. if (caretPos.begin > radixPos && caretPos.end <= radixPos) {
  300. if (c === opts.radixPoint) {
  301. return {
  302. insert: { pos: radixPos + 1, c: "0", fromIsValid: true },
  303. rewritePosition: radixPos
  304. };
  305. } else {
  306. return { rewritePosition: radixPos + 1 };
  307. }
  308. } else if (caretPos.begin < radixPos) {
  309. return { rewritePosition: caretPos.begin - 1 };
  310. }
  311. }
  312. }
  313. return { rewritePosition: pos };
  314. },
  315. postValidation: function (buffer, pos, currentResult, opts, maskset, strict) {
  316. if (currentResult === false) return currentResult;
  317. if (strict) return true;
  318. if (opts.min !== null || opts.max !== null) {
  319. var unmasked = opts.onUnMask(buffer.slice().reverse().join(""), undefined, $.extend({}, opts, {
  320. unmaskAsNumber: true
  321. }));
  322. if (opts.min !== null && unmasked < opts.min && (unmasked.toString().length >= opts.min.toString().length || unmasked < 0)) {
  323. return {
  324. refreshFromBuffer: true,
  325. buffer: alignDigits(opts.min.toString().replace(".", opts.radixPoint).split(""), opts.digits, opts).reverse()
  326. };
  327. }
  328. if (opts.max !== null && unmasked > opts.max) {
  329. return {
  330. refreshFromBuffer: true,
  331. buffer: alignDigits(opts.max.toString().replace(".", opts.radixPoint).split(""), opts.digits, opts).reverse()
  332. };
  333. }
  334. }
  335. return currentResult;
  336. },
  337. onUnMask: function (maskedValue, unmaskedValue, opts) {
  338. if (unmaskedValue === "" && opts.nullable === true) {
  339. return unmaskedValue;
  340. }
  341. var processValue = maskedValue.replace(opts.prefix, "");
  342. processValue = processValue.replace(opts.suffix, "");
  343. processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "");
  344. if (opts.placeholder.charAt(0) !== "") {
  345. processValue = processValue.replace(new RegExp(opts.placeholder.charAt(0), "g"), "0");
  346. }
  347. if (opts.unmaskAsNumber) {
  348. if (opts.radixPoint !== "" && processValue.indexOf(opts.radixPoint) !== -1) processValue = processValue.replace(Inputmask.escapeRegex.call(this, opts.radixPoint), ".");
  349. processValue = processValue.replace(new RegExp("^" + Inputmask.escapeRegex(opts.negationSymbol.front)), "-");
  350. processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.negationSymbol.back) + "$"), "");
  351. return Number(processValue);
  352. }
  353. return processValue;
  354. }
  355. ,
  356. isComplete: function (buffer, opts) {
  357. var maskedValue = (opts.numericInput ? buffer.slice().reverse() : buffer).join("");
  358. maskedValue = maskedValue.replace(new RegExp("^" + Inputmask.escapeRegex(opts.negationSymbol.front)), "-");
  359. maskedValue = maskedValue.replace(new RegExp(Inputmask.escapeRegex(opts.negationSymbol.back) + "$"), "");
  360. maskedValue = maskedValue.replace(opts.prefix, "");
  361. maskedValue = maskedValue.replace(opts.suffix, "");
  362. maskedValue = maskedValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator) + "([0-9]{3})", "g"), "$1");
  363. if (opts.radixPoint === ",") maskedValue = maskedValue.replace(Inputmask.escapeRegex(opts.radixPoint), ".");
  364. return isFinite(maskedValue);
  365. }
  366. ,
  367. onBeforeMask: function (initialValue, opts) {
  368. var radixPoint = opts.radixPoint || ",";
  369. if ((typeof initialValue == "number" || opts.inputType === "number") && radixPoint !== "") {
  370. initialValue = initialValue.toString().replace(".", radixPoint);
  371. }
  372. var valueParts = initialValue.split(radixPoint),
  373. integerPart = valueParts[0].replace(/[^\-0-9]/g, ""),
  374. decimalPart = valueParts.length > 1 ? valueParts[1].replace(/[^0-9]/g, "") : "",
  375. forceDigits = valueParts.length > 1;
  376. initialValue = integerPart + (decimalPart !== "" ? radixPoint + decimalPart : decimalPart);
  377. var digits = 0;
  378. if (radixPoint !== "") {
  379. digits = decimalPart.length;
  380. if (decimalPart !== "") {
  381. var digitsFactor = Math.pow(10, digits || 1);
  382. if (isFinite(opts.digits)) {
  383. digits = parseInt(opts.digits);
  384. digitsFactor = Math.pow(10, digits);
  385. }
  386. //make the initialValue a valid javascript number for the parsefloat
  387. initialValue = initialValue.replace(Inputmask.escapeRegex(radixPoint), ".");
  388. if (isFinite(initialValue)) {
  389. initialValue = (opts.roundingFN(parseFloat(initialValue) * digitsFactor) / digitsFactor).toFixed(digits);
  390. }
  391. initialValue = initialValue.toString().replace(".", radixPoint);
  392. }
  393. }
  394. //this needs to be in a separate part and not directly in decimalPart to allow rounding
  395. if (opts.digits === 0 && initialValue.indexOf(Inputmask.escapeRegex(radixPoint)) !== -1) {
  396. initialValue = initialValue.substring(0, initialValue.indexOf(Inputmask.escapeRegex(radixPoint)));
  397. }
  398. if (opts.min !== null || opts.max !== null) {
  399. var numberValue = initialValue.toString().replace(radixPoint, ".");
  400. if (opts.min !== null && numberValue < opts.min) {
  401. initialValue = opts.min.toString().replace(".", radixPoint);
  402. } else if (opts.max !== null && numberValue > opts.max) {
  403. initialValue = opts.max.toString().replace(".", radixPoint);
  404. }
  405. }
  406. return alignDigits(initialValue.toString().split(""), digits, opts, forceDigits).join("");
  407. }
  408. ,
  409. onBeforeWrite: function (e, buffer, caretPos, opts) {
  410. function stripBuffer(buffer, stripRadix) {
  411. if (opts.__financeInput !== false || stripRadix) {
  412. var position = $.inArray(opts.radixPoint, buffer);
  413. if (position !== -1) {
  414. buffer.splice(position, 1);
  415. }
  416. }
  417. if (opts.groupSeparator !== "") {
  418. while ((position = buffer.indexOf(opts.groupSeparator)) !== -1) {
  419. buffer.splice(position, 1);
  420. }
  421. }
  422. return buffer;
  423. }
  424. var result,
  425. leadingzeroes = checkForLeadingZeroes(buffer, opts);
  426. if (leadingzeroes) {
  427. var buf = buffer.slice().reverse(), caretNdx = buf.join("").indexOf(leadingzeroes[0]);
  428. buf.splice(caretNdx, leadingzeroes[0].length);
  429. var newCaretPos = buf.length - caretNdx;
  430. stripBuffer(buf);
  431. result = {
  432. refreshFromBuffer: true,
  433. buffer: buf.reverse(),
  434. caret: caretPos < newCaretPos ? caretPos : newCaretPos
  435. };
  436. }
  437. if (e) {
  438. switch (e.type) {
  439. case "blur":
  440. case "checkval":
  441. if (opts.min !== null) {
  442. var unmasked = opts.onUnMask(buffer.slice().reverse().join(""), undefined, $.extend({}, opts, {
  443. unmaskAsNumber: true
  444. }));
  445. if (opts.min !== null && unmasked < opts.min) {
  446. return {
  447. refreshFromBuffer: true,
  448. buffer: alignDigits(opts.min.toString().replace(".", opts.radixPoint).split(""), opts.digits, opts).reverse()
  449. };
  450. }
  451. }
  452. if (buffer[buffer.length - 1] === opts.negationSymbol.front) { //strip negation symbol on blur when value is 0
  453. var nmbrMtchs = new RegExp("(^" + (opts.negationSymbol.front != "" ? Inputmask.escapeRegex(opts.negationSymbol.front) + "?" : "") + Inputmask.escapeRegex(opts.prefix) + ")(.*)(" + Inputmask.escapeRegex(opts.suffix) + (opts.negationSymbol.back != "" ? Inputmask.escapeRegex(opts.negationSymbol.back) + "?" : "") + "$)").exec(stripBuffer(buffer.slice(), true).reverse().join("")),
  454. number = nmbrMtchs ? nmbrMtchs[2] : "";
  455. if (number == 0) {
  456. result = { refreshFromBuffer: true, buffer: [0] };
  457. }
  458. } else if (opts.radixPoint !== "" && buffer[0] === opts.radixPoint) { //strip radixpoint on blur when it is the latest char
  459. if (result && result.buffer) {
  460. result.buffer.shift();
  461. } else {
  462. buffer.shift();
  463. result =
  464. { refreshFromBuffer: true, buffer: stripBuffer(buffer) };
  465. }
  466. }
  467. if (opts.enforceDigitsOnBlur) {
  468. result = result || {};
  469. var bffr = (result && result.buffer) || buffer.slice().reverse();
  470. result.refreshFromBuffer = true;
  471. result.buffer = alignDigits(bffr, opts.digits, opts, true).reverse();
  472. }
  473. }
  474. }
  475. return result;
  476. },
  477. onKeyDown: function (e, buffer, caretPos, opts) {
  478. var $input = $(this), bffr;
  479. if (e.ctrlKey) {
  480. switch (e.keyCode) {
  481. case keyCode.UP:
  482. this.inputmask.__valueSet.call(this, parseFloat(this.inputmask.unmaskedvalue()) + parseInt(opts.step));
  483. $input.trigger("setvalue");
  484. return false;
  485. case keyCode.DOWN:
  486. this.inputmask.__valueSet.call(this, parseFloat(this.inputmask.unmaskedvalue()) - parseInt(opts.step));
  487. $input.trigger("setvalue");
  488. return false;
  489. }
  490. }
  491. if (!e.shiftKey && (e.keyCode === keyCode.DELETE || e.keyCode === keyCode.BACKSPACE || e.keyCode === keyCode.BACKSPACE_SAFARI)) {
  492. if (buffer[e.keyCode === keyCode.DELETE ? caretPos.begin - 1 : caretPos.end] === opts.negationSymbol.front) {
  493. bffr = buffer.slice().reverse();
  494. if (opts.negationSymbol.front !== "") bffr.shift();
  495. if (opts.negationSymbol.back !== "") bffr.pop();
  496. $input.trigger("setvalue", [bffr.join(""), caretPos.begin]);
  497. return false;
  498. } else if (opts._radixDance === true) {
  499. var radixPos = $.inArray(opts.radixPoint, buffer);
  500. if (!opts.digitsOptional) {
  501. if (radixPos !== -1 && (caretPos.begin < radixPos || caretPos.end < radixPos || (e.keyCode === keyCode.DELETE && caretPos.begin === radixPos))) {
  502. if (caretPos.begin === caretPos.end && (e.keyCode === keyCode.BACKSPACE || e.keyCode === keyCode.BACKSPACE_SAFARI)) { //only adjust when not a selection
  503. caretPos.begin++;
  504. }
  505. bffr = buffer.slice().reverse();
  506. bffr.splice(bffr.length - caretPos.begin, caretPos.begin - caretPos.end + 1);
  507. // console.log(caretPos);
  508. bffr = alignDigits(bffr, opts.digits, opts).join("");
  509. $input.trigger("setvalue", [bffr, caretPos.begin >= bffr.length ? radixPos + 1 : caretPos.begin]);
  510. return false;
  511. }
  512. } else if (radixPos === 0) {
  513. bffr = buffer.slice().reverse();
  514. bffr.pop();
  515. $input.trigger("setvalue", [bffr.join(""), caretPos.begin >= bffr.length ? bffr.length : caretPos.begin]);
  516. return false;
  517. }
  518. }
  519. }
  520. }
  521. },
  522. "currency": {
  523. prefix: "", //"$ ",
  524. groupSeparator: ",",
  525. alias: "numeric",
  526. digits: 2,
  527. digitsOptional: false
  528. },
  529. "decimal": {
  530. alias: "numeric"
  531. },
  532. "integer": {
  533. alias: "numeric",
  534. digits: 0
  535. },
  536. "percentage": {
  537. alias: "numeric",
  538. min: 0,
  539. max: 100,
  540. suffix: " %",
  541. digits: 0,
  542. allowMinus: false
  543. },
  544. "indianns": { //indian numbering system
  545. alias: "numeric",
  546. _mask: function (opts) {
  547. return "(" + opts.groupSeparator + "99){*|1}(" + opts.groupSeparator + "999){1|1}";
  548. },
  549. groupSeparator: ",",
  550. radixPoint: ".",
  551. placeholder: "0",
  552. digits: 2,
  553. digitsOptional: false
  554. }
  555. });
  556. module.exports = Inputmask;