inputmask.numeric.extensions.js 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316
  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(factory) {
  10. if (typeof define === "function" && define.amd) {
  11. define(["inputmask.dependencyLib", "inputmask"], factory);
  12. } else if (typeof exports === "object") {
  13. module.exports = factory(require("./inputmask.dependencyLib.jquery"), require("./inputmask"));
  14. } else {
  15. factory(window.dependencyLib || jQuery, window.Inputmask);
  16. }
  17. }
  18. (function($, Inputmask) {
  19. //number aliases
  20. Inputmask.extendAliases({
  21. "numeric2": {
  22. mask: function(opts) {
  23. function autoEscape(txt) {
  24. var escapedTxt = "";
  25. for (var i = 0; i < txt.length; i++) {
  26. escapedTxt += opts.definitions[txt.charAt(i)] ? "\\" + txt.charAt(i) : txt.charAt(i);
  27. }
  28. return escapedTxt;
  29. }
  30. if (opts.repeat !== 0 && isNaN(opts.integerDigits)) {
  31. opts.integerDigits = opts.repeat;
  32. }
  33. opts.repeat = 0;
  34. if (opts.groupSeparator === opts.radixPoint) { //treat equal separator and radixpoint
  35. if (opts.radixPoint === ".") {
  36. opts.groupSeparator = ",";
  37. } else if (opts.radixPoint === ",") {
  38. opts.groupSeparator = ".";
  39. } else opts.groupSeparator = "";
  40. }
  41. if (opts.groupSeparator === " ") { //prevent conflict with default skipOptionalPartCharacter
  42. opts.skipOptionalPartCharacter = undefined;
  43. }
  44. opts.autoGroup = opts.autoGroup && opts.groupSeparator !== "";
  45. var seps = "+",
  46. mod = 0;
  47. if (opts.autoGroup) {
  48. if (typeof opts.groupSize == "string" && isFinite(opts.groupSize)) opts.groupSize = parseInt(opts.groupSize);
  49. if (isFinite(opts.integerDigits)) {
  50. seps = Math.floor(opts.integerDigits / opts.groupSize);
  51. mod = opts.integerDigits % opts.groupSize;
  52. }
  53. }
  54. //enforce placeholder to single
  55. if (opts.placeholder.length > 1) {
  56. opts.placeholder = opts.placeholder.charAt(0);
  57. }
  58. if (opts.jitMasking === true && opts.placeholder.length > 0) {
  59. opts.jitMasking = 1;
  60. }
  61. //only allow radixfocus when placeholder = 0
  62. opts.radixFocus = (opts.radixFocus || (opts.radixFocus === false && isNaN(opts.digits))) && opts.placeholder !== "" && opts.integerOptional === true;
  63. opts.definitions[";"] = opts.definitions["~"]; //clone integer def for decimals
  64. opts.definitions[";"].definitionSymbol = "~";
  65. var mask = autoEscape(opts.prefix);
  66. mask += "[+]";
  67. if (opts.autoGroup) {
  68. mask += "(" + opts.groupSeparator + "~{" + opts.groupSize + "}){" + seps + "}";
  69. if (mod > 0) mask += "~{" + mod + "}";
  70. } else {
  71. mask += "~{" + opts.integerDigits + "}";
  72. }
  73. if (opts.digits !== undefined && (isNaN(opts.digits) || parseInt(opts.digits) > 0)) {
  74. if (opts.digitsOptional || isNaN(opts.digits)) {
  75. mask += "[:;{1," + opts.digits + "}]";
  76. } else {
  77. mask += ":;{" + opts.digits + "}";
  78. if (isFinite(opts.jitMasking)) {
  79. if (opts.jitMasking < (1 + opts.radixPoint.length + (isFinite(opts.digits) ? opts.digits : 2))) {
  80. opts.jitMasking = (1 + opts.radixPoint.length + (isFinite(opts.digits) ? opts.digits : 2));
  81. }
  82. }
  83. }
  84. }
  85. if (opts.negationSymbol.back !== "") {
  86. mask += "[-]";
  87. }
  88. mask += autoEscape(opts.suffix);
  89. opts.greedy = false; //enforce greedy false
  90. console.log(mask);
  91. return mask;
  92. },
  93. placeholder: "",
  94. greedy: false,
  95. digits: "*", //number of fractionalDigits
  96. digitsOptional: true,
  97. radixPoint: ".",
  98. radixFocus: true,
  99. groupSize: 3,
  100. groupSeparator: "",
  101. autoGroup: false,
  102. allowPlus: true,
  103. allowMinus: true,
  104. negationSymbol: {
  105. front: "-", //"("
  106. back: "" //")"
  107. },
  108. integerDigits: "+", //number of integerDigits
  109. integerOptional: true,
  110. prefix: "",
  111. suffix: "",
  112. rightAlign: true,
  113. decimalProtect: true, //do not allow assumption of decimals input without entering the radixpoint
  114. min: null, //minimum value
  115. max: null, //maximum value
  116. step: 1,
  117. insertMode: true,
  118. autoUnmask: false,
  119. unmaskAsNumber: false,
  120. jitMasking: true,
  121. numericInput: true,
  122. onBeforeWrite: function(e, buffer, caretPos, opts) {
  123. // if (e && (e.type === "blur" || e.type === "checkval")) {
  124. // //handle minvalue
  125. // var maskedValue = buffer.join(""),
  126. // processValue = maskedValue.replace(opts.prefix, "");
  127. // processValue = processValue.replace(opts.suffix, "");
  128. // processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "");
  129. // if (opts.radixPoint === ",") processValue = processValue.replace(Inputmask.escapeRegex(opts.radixPoint), ".");
  130. //
  131. // if (isFinite(processValue)) {
  132. // if (isFinite(opts.min) && parseFloat(processValue) < parseFloat(opts.min)) {
  133. // return {
  134. // "refreshFromBuffer": true,
  135. // "buffer": (opts.prefix + opts.min).split("")
  136. // };
  137. // }
  138. // }
  139. // var tmpBufSplit = opts.radixPoint !== "" ? buffer.join("").split(opts.radixPoint) : [buffer.join("")],
  140. // matchRslt = tmpBufSplit[0].match(opts.regex.integerPart(opts)),
  141. // matchRsltDigits = tmpBufSplit.length === 2 ? tmpBufSplit[1].match(opts.regex.integerNPart(opts)) : undefined;
  142. // if (matchRslt) {
  143. // if ((matchRslt[0] === opts.negationSymbol.front + "0" || matchRslt[0] === opts.negationSymbol.front || matchRslt[0] === "+") && (matchRsltDigits === undefined || matchRsltDigits[0].match(/^0+$/))) {
  144. // buffer.splice(matchRslt.index, 1);
  145. // }
  146. // var radixPosition = $.inArray(opts.radixPoint, buffer);
  147. // if (radixPosition !== -1) {
  148. // if (isFinite(opts.digits) && !opts.digitsOptional) {
  149. // for (var i = 1; i <= opts.digits; i++) {
  150. // if (buffer[radixPosition + i] === undefined || buffer[radixPosition + i] === opts.placeholder.charAt(0)) {
  151. // buffer[radixPosition + i] = "0";
  152. // }
  153. // }
  154. // return {
  155. // "refreshFromBuffer": maskedValue !== buffer.join(""),
  156. // "buffer": buffer
  157. // };
  158. // } else if (radixPosition === buffer.length - opts.suffix.length - 1) {
  159. // buffer.splice(radixPosition, 1);
  160. // return {
  161. // "refreshFromBuffer": true,
  162. // "buffer": buffer
  163. // };
  164. // }
  165. // }
  166. // }
  167. // }
  168. },
  169. regex: {
  170. integerPart: function(opts) {
  171. return new RegExp("[\\d" + Inputmask.escapeRegex(opts.groupSeparator) + "]+[" + Inputmask.escapeRegex(opts.negationSymbol.front) + "\+]?$");
  172. },
  173. integerNPart: function(opts) {
  174. return new RegExp("[\\d" + Inputmask.escapeRegex(opts.groupSeparator) + "]+");
  175. }
  176. },
  177. signHandler: function(chrs, maskset, pos, strict, opts) {
  178. // if (!strict && (opts.allowMinus && chrs === "-") || (opts.allowPlus && chrs === "+")) {
  179. // var matchRslt = maskset.buffer.join("").match(opts.regex.integerPart(opts));
  180. //
  181. // if (matchRslt && matchRslt[0].length > 0) {
  182. // if (maskset.buffer[matchRslt.index] === (chrs === "-" ? "+" : opts.negationSymbol.front)) {
  183. // if (chrs === "-") {
  184. // if (opts.negationSymbol.back !== "") {
  185. // return {
  186. // "pos": matchRslt.index,
  187. // "c": opts.negationSymbol.front,
  188. // "remove": matchRslt.index,
  189. // "caret": pos,
  190. // "insert": {
  191. // "pos": maskset.buffer.length - opts.suffix.length - 1,
  192. // "c": opts.negationSymbol.back
  193. // }
  194. // };
  195. // } else {
  196. // return {
  197. // "pos": matchRslt.index,
  198. // "c": opts.negationSymbol.front,
  199. // "remove": matchRslt.index,
  200. // "caret": pos
  201. // };
  202. // }
  203. // } else {
  204. // if (opts.negationSymbol.back !== "") {
  205. // return {
  206. // "pos": matchRslt.index,
  207. // "c": "+",
  208. // "remove": [matchRslt.index, maskset.buffer.length - opts.suffix.length - 1],
  209. // "caret": pos
  210. // };
  211. // } else {
  212. // return {
  213. // "pos": matchRslt.index,
  214. // "c": "+",
  215. // "remove": matchRslt.index,
  216. // "caret": pos
  217. // };
  218. // }
  219. // }
  220. // } else if (maskset.buffer[matchRslt.index] === (chrs === "-" ? opts.negationSymbol.front : "+")) {
  221. // if (chrs === "-" && opts.negationSymbol.back !== "") {
  222. // return {
  223. // "remove": [matchRslt.index, maskset.buffer.length - opts.suffix.length - 1],
  224. // "caret": pos - 1
  225. // };
  226. // } else {
  227. // return {
  228. // "remove": matchRslt.index,
  229. // "caret": pos - 1
  230. // };
  231. // }
  232. // } else {
  233. // if (chrs === "-") {
  234. // if (opts.negationSymbol.back !== "") {
  235. // return {
  236. // "pos": matchRslt.index,
  237. // "c": opts.negationSymbol.front,
  238. // "caret": pos + 1,
  239. // "insert": {
  240. // "pos": maskset.buffer.length - opts.suffix.length,
  241. // "c": opts.negationSymbol.back
  242. // }
  243. // };
  244. // } else {
  245. // return {
  246. // "pos": matchRslt.index,
  247. // "c": opts.negationSymbol.front,
  248. // "caret": pos + 1
  249. // };
  250. // }
  251. // } else {
  252. // return {
  253. // "pos": matchRslt.index,
  254. // "c": chrs,
  255. // "caret": pos + 1
  256. // };
  257. // }
  258. // }
  259. // }
  260. // }
  261. return false;
  262. },
  263. radixHandler: function(chrs, maskset, pos, strict, opts) {
  264. if ($.inArray(chrs, [",", "."]) !== -1) chrs = opts.radixPoint;
  265. if (chrs === opts.radixPoint && (opts.digits !== undefined && (isNaN(opts.digits) || parseInt(opts.digits) > 0))) {
  266. var radixPos = $.inArray(opts.radixPoint, maskset.buffer);
  267. if (radixPos > -1) {
  268. return {
  269. caret: radixPos < pos ? radixPos : radixPos + 1
  270. }
  271. }
  272. }
  273. return false;
  274. },
  275. leadingZeroHandler: function(chrs, maskset, pos, strict, opts) {
  276. if (!strict) {
  277. if (maskset.buffer[maskset.buffer.length - opts.prefix.length - 1] === "0" && maskset.buffer[maskset.buffer.length - opts.prefix.length - 2] !== opts.radixPoint) {
  278. return {
  279. "pos": pos,
  280. "remove": maskset.buffer.length - opts.prefix.length - 1
  281. };
  282. }
  283. }
  284. return true;
  285. },
  286. postValidation: function(buffer, opts) {
  287. return true;
  288. //handle maxvalue
  289. var isValid = true,
  290. maskedValue = buffer.join(""),
  291. processValue = maskedValue.replace(opts.prefix, "");
  292. processValue = processValue.replace(opts.suffix, "");
  293. processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "");
  294. if (opts.radixPoint === ",") processValue = processValue.replace(Inputmask.escapeRegex(opts.radixPoint), ".");
  295. //handle negation symbol
  296. processValue = processValue.replace(new RegExp("^" + Inputmask.escapeRegex(opts.negationSymbol.front)), "-");
  297. processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.negationSymbol.back) + "$"), "");
  298. processValue = processValue === opts.negationSymbol.front ? processValue + "0" : processValue;
  299. if (isFinite(processValue)) {
  300. if (opts.max !== null && isFinite(opts.max)) {
  301. isValid = parseFloat(processValue) <= parseFloat(opts.max);
  302. }
  303. if (isValid && opts.min !== null && isFinite(opts.min) && (processValue <= 0 || processValue.toString().length >= opts.min.toString().length)) {
  304. isValid = parseFloat(processValue) >= parseFloat(opts.min);
  305. if (!isValid) {
  306. isValid = {
  307. "refreshFromBuffer": true,
  308. "buffer": (opts.prefix + opts.min).split("")
  309. };
  310. }
  311. }
  312. }
  313. return isValid;
  314. },
  315. definitions: {
  316. "~": {
  317. validator: function(chrs, maskset, pos, strict, opts) {
  318. var isValid = opts.signHandler(chrs, maskset, pos, strict, opts);
  319. if (!isValid) {
  320. isValid = opts.radixHandler(chrs, maskset, pos, strict, opts);
  321. if (!isValid) {
  322. isValid = strict ? new RegExp("[0-9" + Inputmask.escapeRegex(opts.groupSeparator) + "]").test(chrs) : new RegExp("[0-9]").test(chrs);
  323. if (isValid === true) {
  324. isValid = opts.leadingZeroHandler(chrs, maskset, pos, strict, opts);
  325. if (isValid === true && !strict && opts.radixFocus === true) {
  326. //handle overwrite when fixed precision
  327. var radixPosition = $.inArray(opts.radixPoint, maskset.buffer);
  328. if (radixPosition !== -1 && opts.digitsOptional === false && pos <= radixPosition && pos > 0) {
  329. isValid = {
  330. "pos": pos - 1,
  331. "remove": maskset.validPositions[pos] !== undefined ? pos - 1 : undefined
  332. };
  333. } //else isValid = pos >= 0;
  334. }
  335. }
  336. }
  337. }
  338. return isValid;
  339. },
  340. cardinality: 1,
  341. prevalidator: null
  342. },
  343. "+": {
  344. validator: function(chrs, maskset, pos, strict, opts) {
  345. var isValid = opts.signHandler(chrs, maskset, pos, strict, opts);
  346. if (!isValid) {
  347. isValid = opts.radixHandler(chrs, maskset, pos, strict, opts);
  348. if (!isValid && ((strict && opts.allowMinus && chrs === opts.negationSymbol.front) || (opts.allowMinus && chrs === "-") || (opts.allowPlus && chrs === "+"))) {
  349. if (chrs === "-") {
  350. if (opts.negationSymbol.back !== "") {
  351. isValid = {
  352. "pos": pos,
  353. "c": chrs === "-" ? opts.negationSymbol.front : "+",
  354. "caret": pos + 1,
  355. "insert": {
  356. "pos": maskset.buffer.length,
  357. "c": opts.negationSymbol.back
  358. }
  359. };
  360. } else {
  361. isValid = {
  362. "pos": pos,
  363. "c": chrs === "-" ? opts.negationSymbol.front : "+",
  364. "caret": pos + 1
  365. };
  366. }
  367. } else {
  368. isValid = true;
  369. }
  370. }
  371. }
  372. return isValid;
  373. },
  374. cardinality: 1,
  375. prevalidator: null,
  376. placeholder: ""
  377. },
  378. "-": {
  379. validator: function(chrs, maskset, pos, strict, opts) {
  380. var isValid = opts.signHandler(chrs, maskset, pos, strict, opts);
  381. if (!isValid) {
  382. isValid = opts.radixHandler(chrs, maskset, pos, strict, opts);
  383. if (!isValid && strict && opts.allowMinus && chrs === opts.negationSymbol.back) {
  384. isValid = true;
  385. }
  386. }
  387. return isValid;
  388. },
  389. cardinality: 1,
  390. prevalidator: null,
  391. placeholder: ""
  392. },
  393. ":": {
  394. validator: function(chrs, maskset, pos, strict, opts) {
  395. var isValid = opts.signHandler(chrs, maskset, pos, strict, opts);
  396. if (!isValid) {
  397. isValid = opts.radixHandler(chrs, maskset, pos, strict, opts);
  398. if (!isValid) {
  399. var radix = "[" + Inputmask.escapeRegex(opts.radixPoint) + ",\\." + "]";
  400. isValid = new RegExp(radix).test(chrs);
  401. if (!isValid && new RegExp("[0-9]").test(chrs)) {
  402. if ((opts.radixFocus !== true || (opts.radixFocus === true && strict)) && pos === $.inArray(opts.radixPoint, maskset.buffer)) {
  403. return isValid = {
  404. pos: pos,
  405. c: opts.radixPoint,
  406. insert: {
  407. pos: pos + 1,
  408. c: chrs,
  409. }
  410. }
  411. } else if (!strict) {
  412. return isValid = {
  413. pos: pos - 1,
  414. c: chrs
  415. }
  416. }
  417. }
  418. }
  419. }
  420. return isValid !== true ? isValid : {
  421. c: opts.radixPoint
  422. };
  423. },
  424. cardinality: 1,
  425. prevalidator: null,
  426. definitionSymbol: "~",
  427. placeholder: function(opts) {
  428. return opts.radixPoint;
  429. }
  430. }
  431. },
  432. onUnMask: function(maskedValue, unmaskedValue, opts) {
  433. var processValue = maskedValue.replace(opts.prefix, "");
  434. processValue = processValue.replace(opts.suffix, "");
  435. processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "");
  436. if (opts.unmaskAsNumber) {
  437. if (opts.radixPoint !== "" && processValue.indexOf(opts.radixPoint) !== -1) processValue = processValue.replace(Inputmask.escapeRegex.call(this, opts.radixPoint), ".");
  438. return Number(processValue);
  439. }
  440. return processValue;
  441. },
  442. isComplete: function(buffer, opts) {
  443. var maskedValue = buffer.join("");
  444. var processValue = maskedValue.replace(opts.prefix, "");
  445. processValue = processValue.replace(opts.suffix, "");
  446. processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "");
  447. if (opts.radixPoint === ",") processValue = processValue.replace(Inputmask.escapeRegex(opts.radixPoint), ".");
  448. return isFinite(processValue);
  449. },
  450. onBeforeMask: function(initialValue, opts) {
  451. if (opts.radixPoint !== "" && isFinite(initialValue)) {
  452. initialValue = initialValue.toString().replace(".", opts.radixPoint);
  453. } else {
  454. var kommaMatches = initialValue.match(/,/g);
  455. var dotMatches = initialValue.match(/\./g);
  456. if (dotMatches && kommaMatches) {
  457. if (dotMatches.length > kommaMatches.length) {
  458. initialValue = initialValue.replace(/\./g, "");
  459. initialValue = initialValue.replace(",", opts.radixPoint);
  460. } else if (kommaMatches.length > dotMatches.length) {
  461. initialValue = initialValue.replace(/,/g, "");
  462. initialValue = initialValue.replace(".", opts.radixPoint);
  463. } else { //equal
  464. initialValue = initialValue.indexOf(".") < initialValue.indexOf(",") ? initialValue.replace(/\./g, "") : initialValue = initialValue.replace(/,/g, "");
  465. }
  466. } else {
  467. initialValue = initialValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "");
  468. }
  469. }
  470. if (opts.digits === 0) {
  471. if (initialValue.indexOf(".") !== -1) {
  472. initialValue = initialValue.substring(0, initialValue.indexOf("."));
  473. } else if (initialValue.indexOf(",") !== -1) {
  474. initialValue = initialValue.substring(0, initialValue.indexOf(","));
  475. }
  476. }
  477. if (opts.radixPoint !== "" && isFinite(opts.digits) && initialValue.indexOf(opts.radixPoint) !== -1) {
  478. var valueParts = initialValue.split(opts.radixPoint),
  479. decPart = valueParts[1].match(new RegExp("\\d*"))[0];
  480. if (parseInt(opts.digits) < decPart.toString().length) {
  481. var digitsFactor = Math.pow(10, parseInt(opts.digits));
  482. //make the initialValue a valid javascript number for the parsefloat
  483. initialValue = initialValue.replace(Inputmask.escapeRegex(opts.radixPoint), ".");
  484. initialValue = Math.round(parseFloat(initialValue) * digitsFactor) / digitsFactor;
  485. initialValue = initialValue.toString().replace(".", opts.radixPoint);
  486. }
  487. }
  488. return initialValue.toString();
  489. },
  490. canClearPosition: function(maskset, position, lvp, strict, opts) {
  491. return true;
  492. var positionInput = maskset.validPositions[position].input,
  493. canClear = ((positionInput !== opts.radixPoint || (maskset.validPositions[position].match.fn !== null && opts.decimalProtect === false)) || isFinite(positionInput)) ||
  494. position === lvp ||
  495. positionInput === opts.groupSeparator ||
  496. positionInput === opts.negationSymbol.front ||
  497. positionInput === opts.negationSymbol.back;
  498. // if (canClear && isFinite(positionInput)) {
  499. // var matchRslt,
  500. // radixPos = $.inArray(opts.radixPoint, maskset.buffer);
  501. //
  502. // //inject radixpoint
  503. // var radixInjection = false;
  504. // if (maskset.validPositions[radixPos] === undefined) {
  505. // maskset.validPositions[radixPos] = {
  506. // input: opts.radixPoint
  507. // };
  508. // radixInjection = true;
  509. // }
  510. //
  511. // if (!strict && maskset.buffer) {
  512. // matchRslt = maskset.buffer.join("").substr(0, position).match(opts.regex.integerNPart(opts));
  513. // var pos = position + 1,
  514. // isNull = matchRslt == null || parseInt(matchRslt["0"].replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "")) === 0;
  515. // if (isNull) {
  516. // while (maskset.validPositions[pos] && (maskset.validPositions[pos].input === opts.groupSeparator || maskset.validPositions[pos].input === "0")) {
  517. // delete maskset.validPositions[pos];
  518. // pos++;
  519. // }
  520. // }
  521. // }
  522. //
  523. // var buffer = [];
  524. // //build new buffer from validPositions
  525. // for (var vp in maskset.validPositions) {
  526. // if (maskset.validPositions[vp].input !== undefined) buffer.push(maskset.validPositions[vp].input);
  527. // }
  528. // //remove radix Injection
  529. // if (radixInjection) {
  530. // delete maskset.validPositions[radixPos];
  531. // }
  532. //
  533. // if (radixPos > 0) {
  534. // var bufVal = buffer.join("");
  535. // matchRslt = bufVal.match(opts.regex.integerNPart(opts));
  536. // if (matchRslt) {
  537. // if (position <= radixPos) {
  538. // if (matchRslt["0"].indexOf("0") === 0) {
  539. // canClear = matchRslt.index !== position || opts.placeholder === "0";
  540. // } else {
  541. // var intPart = parseInt(matchRslt["0"].replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "")),
  542. // radixPart = parseInt(bufVal.split(opts.radixPoint)[1]);
  543. // if (intPart < 10 && maskset.validPositions[position] && (opts.placeholder !== "0" || radixPart > 0)) {
  544. // maskset.validPositions[position].input = "0";
  545. // maskset.p = opts.prefix.length + 1;
  546. // canClear = false;
  547. // }
  548. // }
  549. // } else if (matchRslt["0"].indexOf("0") === 0) {
  550. // if (bufVal.length === 3) {
  551. // maskset.validPositions = {};
  552. // canClear = false;
  553. // }
  554. // }
  555. // }
  556. // }
  557. // }
  558. return canClear;
  559. },
  560. onKeyDown: function(e, buffer, caretPos, opts) {
  561. // var $input = $(this);
  562. // if (e.ctrlKey) {
  563. // switch (e.keyCode) {
  564. // case Inputmask.keyCode.UP:
  565. // $input.val(parseFloat(this.inputmask.unmaskedvalue()) + parseInt(opts.step));
  566. // $input.trigger("setvalue");
  567. // break;
  568. // case Inputmask.keyCode.DOWN:
  569. // $input.val(parseFloat(this.inputmask.unmaskedvalue()) - parseInt(opts.step));
  570. // $input.trigger("setvalue");
  571. // break;
  572. // }
  573. // }
  574. }
  575. },
  576. "numeric": {
  577. mask: function(opts) {
  578. function autoEscape(txt) {
  579. var escapedTxt = "";
  580. for (var i = 0; i < txt.length; i++) {
  581. escapedTxt += opts.definitions[txt.charAt(i)] ? "\\" + txt.charAt(i) : txt.charAt(i);
  582. }
  583. return escapedTxt;
  584. }
  585. if (opts.repeat !== 0 && isNaN(opts.integerDigits)) {
  586. opts.integerDigits = opts.repeat;
  587. }
  588. opts.repeat = 0;
  589. if (opts.groupSeparator === opts.radixPoint) { //treat equal separator and radixpoint
  590. if (opts.radixPoint === ".") {
  591. opts.groupSeparator = ",";
  592. } else if (opts.radixPoint === ",") {
  593. opts.groupSeparator = ".";
  594. } else opts.groupSeparator = "";
  595. }
  596. if (opts.groupSeparator === " ") { //prevent conflict with default skipOptionalPartCharacter
  597. opts.skipOptionalPartCharacter = undefined;
  598. }
  599. opts.autoGroup = opts.autoGroup && opts.groupSeparator !== "";
  600. if (opts.autoGroup) {
  601. if (typeof opts.groupSize == "string" && isFinite(opts.groupSize)) opts.groupSize = parseInt(opts.groupSize);
  602. if (isFinite(opts.integerDigits)) {
  603. var seps = Math.floor(opts.integerDigits / opts.groupSize);
  604. var mod = opts.integerDigits % opts.groupSize;
  605. opts.integerDigits = parseInt(opts.integerDigits) + (mod === 0 ? seps - 1 : seps);
  606. if (opts.integerDigits < 1) {
  607. opts.integerDigits = "*";
  608. }
  609. }
  610. }
  611. //enforce placeholder to single
  612. if (opts.placeholder.length > 1) {
  613. opts.placeholder = opts.placeholder.charAt(0);
  614. }
  615. //only allow radixfocus when placeholder = 0
  616. opts.radixFocus = opts.radixFocus && opts.placeholder !== "" && opts.integerOptional === true;
  617. opts.definitions[";"] = opts.definitions["~"]; //clone integer def for decimals
  618. opts.definitions[";"].definitionSymbol = "~";
  619. if (opts.numericInput == true) { //finance people input style
  620. opts.radixFocus = false;
  621. opts.digitsOptional = false;
  622. if (isNaN(opts.digits)) opts.digits = 2;
  623. opts.decimalProtect = false;
  624. }
  625. var mask = autoEscape(opts.prefix);
  626. mask += "[+]";
  627. if (opts.integerOptional === true) {
  628. mask += "~{1," + opts.integerDigits + "}";
  629. } else mask += "~{" + opts.integerDigits + "}";
  630. if (opts.digits !== undefined && (isNaN(opts.digits) || parseInt(opts.digits) > 0)) {
  631. if (opts.digitsOptional) {
  632. mask += "[" + (opts.decimalProtect ? ":" : opts.radixPoint) + ";{1," + opts.digits + "}]";
  633. } else mask += (opts.decimalProtect ? ":" : opts.radixPoint) + ";{" + opts.digits + "}";
  634. }
  635. if (opts.negationSymbol.back !== "") {
  636. mask += "[-]";
  637. }
  638. mask += autoEscape(opts.suffix);
  639. opts.greedy = false; //enforce greedy false
  640. return mask;
  641. },
  642. placeholder: "",
  643. greedy: false,
  644. digits: "*", //number of fractionalDigits
  645. digitsOptional: true,
  646. radixPoint: ".",
  647. radixFocus: true,
  648. groupSize: 3,
  649. groupSeparator: "",
  650. autoGroup: false,
  651. allowPlus: true,
  652. allowMinus: true,
  653. negationSymbol: {
  654. front: "-", //"("
  655. back: "" //")"
  656. },
  657. integerDigits: "+", //number of integerDigits
  658. integerOptional: true,
  659. prefix: "",
  660. suffix: "",
  661. rightAlign: true,
  662. decimalProtect: true, //do not allow assumption of decimals input without entering the radixpoint
  663. min: null, //minimum value
  664. max: null, //maximum value
  665. step: 1,
  666. insertMode: true,
  667. autoUnmask: false,
  668. unmaskAsNumber: false,
  669. postFormat: function(buffer, pos, reformatOnly, opts) { //this needs to be removed // this is crap
  670. // console.log(buffer);
  671. if (opts.numericInput === true) {
  672. buffer = buffer.reverse();
  673. if (isFinite(pos)) {
  674. pos = buffer.join("").length - pos - 1;
  675. }
  676. }
  677. var suffixStripped = false,
  678. i, l;
  679. if (buffer.length >= opts.suffix.length && buffer.join("").indexOf(opts.suffix) === (buffer.length - opts.suffix.length)) {
  680. buffer.length = buffer.length - opts.suffix.length; //strip suffix
  681. suffixStripped = true;
  682. }
  683. //position overflow corrections
  684. pos = pos >= buffer.length ? buffer.length - 1 : (pos < opts.prefix.length ? opts.prefix.length : pos);
  685. var needsRefresh = false,
  686. charAtPos = buffer[pos];
  687. if (opts.groupSeparator === "" || (opts.numericInput !== true &&
  688. ($.inArray(opts.radixPoint, buffer) !== -1 && pos > $.inArray(opts.radixPoint, buffer)) ||
  689. new RegExp("[" + Inputmask.escapeRegex(opts.negationSymbol.front) + "\+]").test(charAtPos))) {
  690. if (suffixStripped) {
  691. for (i = 0, l = opts.suffix.length; i < l; i++) {
  692. buffer.push(opts.suffix.charAt(i));
  693. }
  694. }
  695. //console.log("return input " + buffer);
  696. return {
  697. pos: pos
  698. };
  699. }
  700. var cbuf = buffer.slice();
  701. if (charAtPos === opts.groupSeparator) {
  702. cbuf.splice(pos--, 1);
  703. charAtPos = cbuf[pos];
  704. }
  705. if (reformatOnly) {
  706. if (charAtPos !== opts.radixPoint) cbuf[pos] = "?";
  707. } else cbuf.splice(pos, 0, "?"); //set position indicator
  708. var bufVal = cbuf.join(""),
  709. bufValOrigin = bufVal;
  710. if (bufVal.length > 0 && opts.autoGroup || (reformatOnly && bufVal.indexOf(opts.groupSeparator) !== -1)) {
  711. var escapedGroupSeparator = Inputmask.escapeRegex(opts.groupSeparator);
  712. needsRefresh = bufVal.indexOf(opts.groupSeparator) === 0;
  713. bufVal = bufVal.replace(new RegExp(escapedGroupSeparator, "g"), "");
  714. var radixSplit = bufVal.split(opts.radixPoint);
  715. bufVal = opts.radixPoint === "" ? bufVal : radixSplit[0];
  716. if (bufVal !== (opts.prefix + "?0") && bufVal.length >= (opts.groupSize + opts.prefix.length)) {
  717. //needsRefresh = true;
  718. var reg = new RegExp("([-\+]?[\\d\?]+)([\\d\?]{" + opts.groupSize + "})");
  719. while (reg.test(bufVal)) {
  720. bufVal = bufVal.replace(reg, "$1" + opts.groupSeparator + "$2");
  721. bufVal = bufVal.replace(opts.groupSeparator + opts.groupSeparator, opts.groupSeparator);
  722. }
  723. }
  724. if (opts.radixPoint !== "" && radixSplit.length > 1) {
  725. bufVal += opts.radixPoint + radixSplit[1];
  726. }
  727. }
  728. needsRefresh = bufValOrigin !== bufVal;
  729. buffer.length = bufVal.length; //align the length
  730. for (i = 0, l = bufVal.length; i < l; i++) {
  731. buffer[i] = bufVal.charAt(i);
  732. }
  733. var newPos = $.inArray("?", buffer);
  734. if (newPos === -1 && charAtPos === opts.radixPoint) newPos = $.inArray(opts.radixPoint, buffer);
  735. if (reformatOnly) buffer[newPos] = charAtPos;
  736. else buffer.splice(newPos, 1);
  737. if (!needsRefresh && suffixStripped) {
  738. for (i = 0, l = opts.suffix.length; i < l; i++) {
  739. buffer.push(opts.suffix.charAt(i));
  740. }
  741. }
  742. // console.log("formatted " + buffer + " refresh " + needsRefresh);
  743. newPos = (opts.numericInput && isFinite(pos)) ? buffer.join("").length - newPos - 1 : newPos;
  744. if (opts.numericInput) {
  745. buffer = buffer.reverse();
  746. if ($.inArray(opts.radixPoint, buffer) < newPos && (buffer.join("").length - opts.suffix.length) !== newPos) {
  747. newPos = newPos - 1;
  748. }
  749. }
  750. return {
  751. pos: newPos,
  752. "refreshFromBuffer": needsRefresh,
  753. "buffer": buffer
  754. };
  755. },
  756. onBeforeWrite: function(e, buffer, caretPos, opts) {
  757. if (e && (e.type === "blur" || e.type === "checkval")) {
  758. //handle minvalue
  759. var maskedValue = buffer.join(""),
  760. processValue = maskedValue.replace(opts.prefix, "");
  761. processValue = processValue.replace(opts.suffix, "");
  762. processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "");
  763. if (opts.radixPoint === ",") processValue = processValue.replace(Inputmask.escapeRegex(opts.radixPoint), ".");
  764. if (isFinite(processValue)) {
  765. if (isFinite(opts.min) && parseFloat(processValue) < parseFloat(opts.min)) {
  766. return $.extend(true, {
  767. "refreshFromBuffer": true,
  768. "buffer": (opts.prefix + opts.min).split("")
  769. }, opts.postFormat((opts.prefix + opts.min).split(""), 0, true, opts));
  770. }
  771. }
  772. if (opts.numericInput !== true) {
  773. var tmpBufSplit = opts.radixPoint !== "" ? buffer.join("").split(opts.radixPoint) : [buffer.join("")],
  774. matchRslt = tmpBufSplit[0].match(opts.regex.integerPart(opts)),
  775. matchRsltDigits = tmpBufSplit.length === 2 ? tmpBufSplit[1].match(opts.regex.integerNPart(opts)) : undefined;
  776. if (matchRslt) {
  777. if ((matchRslt[0] === opts.negationSymbol.front + "0" || matchRslt[0] === opts.negationSymbol.front || matchRslt[0] === "+") && (matchRsltDigits === undefined || matchRsltDigits[0].match(/^0+$/))) {
  778. buffer.splice(matchRslt.index, 1);
  779. }
  780. var radixPosition = $.inArray(opts.radixPoint, buffer);
  781. if (radixPosition !== -1) {
  782. if (isFinite(opts.digits) && !opts.digitsOptional) {
  783. for (var i = 1; i <= opts.digits; i++) {
  784. if (buffer[radixPosition + i] === undefined || buffer[radixPosition + i] === opts.placeholder.charAt(0)) {
  785. buffer[radixPosition + i] = "0";
  786. }
  787. }
  788. return {
  789. "refreshFromBuffer": maskedValue !== buffer.join(""),
  790. "buffer": buffer
  791. };
  792. } else if (radixPosition === buffer.length - opts.suffix.length - 1) {
  793. buffer.splice(radixPosition, 1);
  794. return {
  795. "refreshFromBuffer": true,
  796. "buffer": buffer
  797. };
  798. }
  799. }
  800. }
  801. }
  802. }
  803. if (opts.autoGroup) {
  804. var rslt = opts.postFormat(buffer, opts.numericInput ? caretPos : caretPos - 1, true, opts);
  805. rslt.caret = caretPos <= opts.prefix.length ? rslt.pos : rslt.pos + 1;
  806. return rslt;
  807. }
  808. },
  809. regex: {
  810. integerPart: function(opts) {
  811. return new RegExp("[" + Inputmask.escapeRegex(opts.negationSymbol.front) + "\+]?\\d+");
  812. },
  813. integerNPart: function(opts) {
  814. return new RegExp("[\\d" + Inputmask.escapeRegex(opts.groupSeparator) + "]+");
  815. }
  816. },
  817. signHandler: function(chrs, maskset, pos, strict, opts) {
  818. if (!strict && (opts.allowMinus && chrs === "-") || (opts.allowPlus && chrs === "+")) {
  819. var matchRslt = maskset.buffer.join("").match(opts.regex.integerPart(opts));
  820. if (matchRslt && matchRslt[0].length > 0) {
  821. if (maskset.buffer[matchRslt.index] === (chrs === "-" ? "+" : opts.negationSymbol.front)) {
  822. if (chrs === "-") {
  823. if (opts.negationSymbol.back !== "") {
  824. return {
  825. "pos": matchRslt.index,
  826. "c": opts.negationSymbol.front,
  827. "remove": matchRslt.index,
  828. "caret": pos,
  829. "insert": {
  830. "pos": maskset.buffer.length - opts.suffix.length - 1,
  831. "c": opts.negationSymbol.back
  832. }
  833. };
  834. } else {
  835. return {
  836. "pos": matchRslt.index,
  837. "c": opts.negationSymbol.front,
  838. "remove": matchRslt.index,
  839. "caret": pos
  840. };
  841. }
  842. } else {
  843. if (opts.negationSymbol.back !== "") {
  844. return {
  845. "pos": matchRslt.index,
  846. "c": "+",
  847. "remove": [matchRslt.index, maskset.buffer.length - opts.suffix.length - 1],
  848. "caret": pos
  849. };
  850. } else {
  851. return {
  852. "pos": matchRslt.index,
  853. "c": "+",
  854. "remove": matchRslt.index,
  855. "caret": pos
  856. };
  857. }
  858. }
  859. } else if (maskset.buffer[matchRslt.index] === (chrs === "-" ? opts.negationSymbol.front : "+")) {
  860. if (chrs === "-" && opts.negationSymbol.back !== "") {
  861. return {
  862. "remove": [matchRslt.index, maskset.buffer.length - opts.suffix.length - 1],
  863. "caret": pos - 1
  864. };
  865. } else {
  866. return {
  867. "remove": matchRslt.index,
  868. "caret": pos - 1
  869. };
  870. }
  871. } else {
  872. if (chrs === "-") {
  873. if (opts.negationSymbol.back !== "") {
  874. return {
  875. "pos": matchRslt.index,
  876. "c": opts.negationSymbol.front,
  877. "caret": pos + 1,
  878. "insert": {
  879. "pos": maskset.buffer.length - opts.suffix.length,
  880. "c": opts.negationSymbol.back
  881. }
  882. };
  883. } else {
  884. return {
  885. "pos": matchRslt.index,
  886. "c": opts.negationSymbol.front,
  887. "caret": pos + 1
  888. };
  889. }
  890. } else {
  891. return {
  892. "pos": matchRslt.index,
  893. "c": chrs,
  894. "caret": pos + 1
  895. };
  896. }
  897. }
  898. }
  899. }
  900. return false;
  901. },
  902. radixHandler: function(chrs, maskset, pos, strict, opts) {
  903. if (!strict) {
  904. if ($.inArray(chrs, [",", "."]) !== -1) chrs = opts.radixPoint;
  905. if (chrs === opts.radixPoint && (opts.digits !== undefined && (isNaN(opts.digits) || parseInt(opts.digits) > 0))) {
  906. var radixPos = $.inArray(opts.radixPoint, maskset.buffer),
  907. integerValue = maskset.buffer.join("").match(opts.regex.integerPart(opts));
  908. if (radixPos !== -1 && maskset.validPositions[radixPos]) {
  909. if (maskset.validPositions[radixPos - 1]) {
  910. return {
  911. "caret": radixPos + 1
  912. };
  913. } else {
  914. return {
  915. "pos": integerValue.index,
  916. c: integerValue[0],
  917. "caret": radixPos + 1
  918. };
  919. }
  920. } else if (!integerValue || (integerValue["0"] === "0" && (integerValue.index + 1) !== pos)) {
  921. maskset.buffer[integerValue ? integerValue.index : pos] = "0";
  922. return {
  923. "pos": (integerValue ? integerValue.index : pos) + 1,
  924. c: opts.radixPoint
  925. };
  926. }
  927. }
  928. }
  929. return false;
  930. },
  931. leadingZeroHandler: function(chrs, maskset, pos, strict, opts) {
  932. if (opts.numericInput === true) {
  933. if (maskset.buffer[maskset.buffer.length - opts.prefix.length - 1] === "0") {
  934. return {
  935. "pos": pos,
  936. "remove": maskset.buffer.length - opts.prefix.length - 1
  937. };
  938. }
  939. } else {
  940. var matchRslt = maskset.buffer.join("").match(opts.regex.integerNPart(opts)),
  941. radixPosition = $.inArray(opts.radixPoint, maskset.buffer);
  942. if (matchRslt && !strict && (radixPosition === -1 || pos <= radixPosition)) {
  943. if (matchRslt["0"].indexOf("0") === 0) {
  944. if (pos < opts.prefix.length) pos = matchRslt.index; //position
  945. var _radixPosition = $.inArray(opts.radixPoint, maskset._buffer);
  946. var digitsMatch = maskset._buffer && maskset.buffer.slice(radixPosition).join("") === maskset._buffer.slice(_radixPosition).join("") || parseInt(maskset.buffer.slice(radixPosition + 1).join("")) === 0;
  947. 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";
  948. if (radixPosition === -1 || digitsMatch && integerMatch) {
  949. maskset.buffer.splice(matchRslt.index, 1);
  950. pos = pos > matchRslt.index ? pos - 1 : matchRslt.index;
  951. return {
  952. "pos": pos,
  953. "remove": matchRslt.index
  954. };
  955. } else if (matchRslt.index + 1 === pos || chrs === "0") {
  956. maskset.buffer.splice(matchRslt.index, 1);
  957. pos = matchRslt.index;
  958. return {
  959. "pos": pos,
  960. "remove": matchRslt.index
  961. };
  962. }
  963. } else if (chrs === "0" && pos <= matchRslt.index && matchRslt["0"] !== opts.groupSeparator) {
  964. return false;
  965. }
  966. }
  967. }
  968. return true;
  969. },
  970. postValidation: function(buffer, opts) {
  971. //handle maxvalue
  972. var isValid = true,
  973. maskedValue = buffer.join(""),
  974. processValue = maskedValue.replace(opts.prefix, "");
  975. processValue = processValue.replace(opts.suffix, "");
  976. processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "");
  977. if (opts.radixPoint === ",") processValue = processValue.replace(Inputmask.escapeRegex(opts.radixPoint), ".");
  978. //handle negation symbol
  979. processValue = processValue.replace(new RegExp("^" + Inputmask.escapeRegex(opts.negationSymbol.front)), "-");
  980. processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.negationSymbol.back) + "$"), "");
  981. processValue = processValue === opts.negationSymbol.front ? processValue + "0" : processValue;
  982. if (isFinite(processValue)) {
  983. if (opts.max !== null && isFinite(opts.max)) {
  984. isValid = parseFloat(processValue) <= parseFloat(opts.max);
  985. }
  986. if (isValid && opts.min !== null && isFinite(opts.min) && (processValue <= 0 || processValue.toString().length >= opts.min.toString().length)) {
  987. isValid = parseFloat(processValue) >= parseFloat(opts.min);
  988. if (!isValid) {
  989. isValid = $.extend(true, {
  990. "refreshFromBuffer": true,
  991. "buffer": (opts.prefix + opts.min).split("")
  992. }, opts.postFormat((opts.prefix + opts.min).split(""), 0, true, opts));
  993. isValid.refreshFromBuffer = true; //enforce refresh
  994. }
  995. }
  996. }
  997. return isValid;
  998. },
  999. definitions: {
  1000. "~": {
  1001. validator: function(chrs, maskset, pos, strict, opts) {
  1002. var isValid = opts.signHandler(chrs, maskset, pos, strict, opts);
  1003. if (!isValid) {
  1004. isValid = opts.radixHandler(chrs, maskset, pos, strict, opts);
  1005. if (!isValid) {
  1006. isValid = strict ? new RegExp("[0-9" + Inputmask.escapeRegex(opts.groupSeparator) + "]").test(chrs) : new RegExp("[0-9]").test(chrs);
  1007. if (isValid === true) {
  1008. isValid = opts.leadingZeroHandler(chrs, maskset, pos, strict, opts);
  1009. if (isValid === true) {
  1010. //handle overwrite when fixed precision
  1011. var radixPosition = $.inArray(opts.radixPoint, maskset.buffer);
  1012. if (radixPosition !== -1 && opts.digitsOptional === false && opts.numericInput !== true && pos > radixPosition && !strict) {
  1013. isValid = {
  1014. "pos": pos,
  1015. "remove": pos
  1016. };
  1017. } else {
  1018. isValid = {
  1019. pos: pos
  1020. };
  1021. }
  1022. }
  1023. }
  1024. }
  1025. }
  1026. return isValid;
  1027. },
  1028. cardinality: 1,
  1029. prevalidator: null
  1030. },
  1031. "+": {
  1032. validator: function(chrs, maskset, pos, strict, opts) {
  1033. var isValid = opts.signHandler(chrs, maskset, pos, strict, opts);
  1034. if (!isValid && ((strict && opts.allowMinus && chrs === opts.negationSymbol.front) || (opts.allowMinus && chrs === "-") || (opts.allowPlus && chrs === "+"))) {
  1035. if (chrs === "-") {
  1036. if (opts.negationSymbol.back !== "") {
  1037. isValid = {
  1038. "pos": pos,
  1039. "c": chrs === "-" ? opts.negationSymbol.front : "+",
  1040. "caret": pos + 1,
  1041. "insert": {
  1042. "pos": maskset.buffer.length,
  1043. "c": opts.negationSymbol.back
  1044. }
  1045. };
  1046. } else {
  1047. isValid = {
  1048. "pos": pos,
  1049. "c": chrs === "-" ? opts.negationSymbol.front : "+",
  1050. "caret": pos + 1
  1051. };
  1052. }
  1053. } else {
  1054. isValid = true;
  1055. }
  1056. }
  1057. return isValid;
  1058. },
  1059. cardinality: 1,
  1060. prevalidator: null,
  1061. placeholder: ""
  1062. },
  1063. "-": {
  1064. validator: function(chrs, maskset, pos, strict, opts) {
  1065. var isValid = opts.signHandler(chrs, maskset, pos, strict, opts);
  1066. if (!isValid && strict && opts.allowMinus && chrs === opts.negationSymbol.back) {
  1067. isValid = true;
  1068. }
  1069. return isValid;
  1070. },
  1071. cardinality: 1,
  1072. prevalidator: null,
  1073. placeholder: ""
  1074. },
  1075. ":": {
  1076. validator: function(chrs, maskset, pos, strict, opts) {
  1077. var isValid = opts.signHandler(chrs, maskset, pos, strict, opts);
  1078. if (!isValid) {
  1079. var radix = "[" + Inputmask.escapeRegex(opts.radixPoint) + ",\\." + "]";
  1080. isValid = new RegExp(radix).test(chrs);
  1081. if (isValid && maskset.validPositions[pos] && maskset.validPositions[pos].match.placeholder === opts.radixPoint) {
  1082. isValid = {
  1083. "caret": pos + 1
  1084. };
  1085. }
  1086. }
  1087. return isValid ? {
  1088. c: opts.radixPoint
  1089. } : isValid;
  1090. },
  1091. cardinality: 1,
  1092. prevalidator: null,
  1093. placeholder: function(opts) {
  1094. return opts.radixPoint;
  1095. }
  1096. }
  1097. },
  1098. onUnMask: function(maskedValue, unmaskedValue, opts) {
  1099. var processValue = maskedValue.replace(opts.prefix, "");
  1100. processValue = processValue.replace(opts.suffix, "");
  1101. processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "");
  1102. if (opts.unmaskAsNumber) {
  1103. if (opts.radixPoint !== "" && processValue.indexOf(opts.radixPoint) !== -1) processValue = processValue.replace(Inputmask.escapeRegex.call(this, opts.radixPoint), ".");
  1104. return Number(processValue);
  1105. }
  1106. return processValue;
  1107. },
  1108. isComplete: function(buffer, opts) {
  1109. var maskedValue = buffer.join(""),
  1110. bufClone = buffer.slice();
  1111. //verify separator positions
  1112. opts.postFormat(bufClone, 0, true, opts);
  1113. if (bufClone.join("") !== maskedValue) return false;
  1114. var processValue = maskedValue.replace(opts.prefix, "");
  1115. processValue = processValue.replace(opts.suffix, "");
  1116. processValue = processValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "");
  1117. if (opts.radixPoint === ",") processValue = processValue.replace(Inputmask.escapeRegex(opts.radixPoint), ".");
  1118. return isFinite(processValue);
  1119. },
  1120. onBeforeMask: function(initialValue, opts) {
  1121. if (opts.radixPoint !== "" && isFinite(initialValue)) {
  1122. initialValue = initialValue.toString().replace(".", opts.radixPoint);
  1123. } else {
  1124. var kommaMatches = initialValue.match(/,/g);
  1125. var dotMatches = initialValue.match(/\./g);
  1126. if (dotMatches && kommaMatches) {
  1127. if (dotMatches.length > kommaMatches.length) {
  1128. initialValue = initialValue.replace(/\./g, "");
  1129. initialValue = initialValue.replace(",", opts.radixPoint);
  1130. } else if (kommaMatches.length > dotMatches.length) {
  1131. initialValue = initialValue.replace(/,/g, "");
  1132. initialValue = initialValue.replace(".", opts.radixPoint);
  1133. } else { //equal
  1134. initialValue = initialValue.indexOf(".") < initialValue.indexOf(",") ? initialValue.replace(/\./g, "") : initialValue = initialValue.replace(/,/g, "");
  1135. }
  1136. } else {
  1137. initialValue = initialValue.replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "");
  1138. }
  1139. }
  1140. if (opts.digits === 0) {
  1141. if (initialValue.indexOf(".") !== -1) {
  1142. initialValue = initialValue.substring(0, initialValue.indexOf("."));
  1143. } else if (initialValue.indexOf(",") !== -1) {
  1144. initialValue = initialValue.substring(0, initialValue.indexOf(","));
  1145. }
  1146. }
  1147. if (opts.radixPoint !== "" && isFinite(opts.digits) && initialValue.indexOf(opts.radixPoint) !== -1) {
  1148. var valueParts = initialValue.split(opts.radixPoint),
  1149. decPart = valueParts[1].match(new RegExp("\\d*"))[0];
  1150. if (parseInt(opts.digits) < decPart.toString().length) {
  1151. var digitsFactor = Math.pow(10, parseInt(opts.digits));
  1152. //make the initialValue a valid javascript number for the parsefloat
  1153. initialValue = initialValue.replace(Inputmask.escapeRegex(opts.radixPoint), ".");
  1154. initialValue = Math.round(parseFloat(initialValue) * digitsFactor) / digitsFactor;
  1155. initialValue = initialValue.toString().replace(".", opts.radixPoint);
  1156. }
  1157. }
  1158. return initialValue.toString();
  1159. },
  1160. canClearPosition: function(maskset, position, lvp, strict, opts) {
  1161. var positionInput = maskset.validPositions[position].input,
  1162. canClear = ((positionInput !== opts.radixPoint || (maskset.validPositions[position].match.fn !== null && opts.decimalProtect === false)) || isFinite(positionInput)) ||
  1163. position === lvp ||
  1164. positionInput === opts.groupSeparator ||
  1165. positionInput === opts.negationSymbol.front ||
  1166. positionInput === opts.negationSymbol.back;
  1167. if (canClear && isFinite(positionInput)) {
  1168. var matchRslt,
  1169. radixPos = $.inArray(opts.radixPoint, maskset.buffer);
  1170. //inject radixpoint
  1171. var radixInjection = false;
  1172. if (maskset.validPositions[radixPos] === undefined) {
  1173. maskset.validPositions[radixPos] = {
  1174. input: opts.radixPoint
  1175. };
  1176. radixInjection = true;
  1177. }
  1178. if (!strict && maskset.buffer) {
  1179. matchRslt = maskset.buffer.join("").substr(0, position).match(opts.regex.integerNPart(opts));
  1180. var pos = position + 1,
  1181. isNull = matchRslt == null || parseInt(matchRslt["0"].replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "")) === 0;
  1182. if (isNull) {
  1183. while (maskset.validPositions[pos] && (maskset.validPositions[pos].input === opts.groupSeparator || maskset.validPositions[pos].input === "0")) {
  1184. delete maskset.validPositions[pos];
  1185. pos++;
  1186. }
  1187. }
  1188. }
  1189. var buffer = [];
  1190. //build new buffer from validPositions
  1191. for (var vp in maskset.validPositions) {
  1192. if (maskset.validPositions[vp].input !== undefined) buffer.push(maskset.validPositions[vp].input);
  1193. }
  1194. //remove radix Injection
  1195. if (radixInjection) {
  1196. delete maskset.validPositions[radixPos];
  1197. }
  1198. if (radixPos > 0) {
  1199. var bufVal = buffer.join("");
  1200. matchRslt = bufVal.match(opts.regex.integerNPart(opts));
  1201. if (matchRslt) {
  1202. if (position <= radixPos) {
  1203. if (matchRslt["0"].indexOf("0") === 0) {
  1204. canClear = matchRslt.index !== position || opts.placeholder === "0";
  1205. } else {
  1206. var intPart = parseInt(matchRslt["0"].replace(new RegExp(Inputmask.escapeRegex(opts.groupSeparator), "g"), "")),
  1207. radixPart = parseInt(bufVal.split(opts.radixPoint)[1]);
  1208. if (intPart < 10 && maskset.validPositions[position] && (opts.placeholder !== "0" || radixPart > 0)) {
  1209. maskset.validPositions[position].input = "0";
  1210. maskset.p = opts.prefix.length + 1;
  1211. canClear = false;
  1212. }
  1213. }
  1214. } else if (matchRslt["0"].indexOf("0") === 0) {
  1215. if (bufVal.length === 3) {
  1216. maskset.validPositions = {};
  1217. canClear = false;
  1218. }
  1219. }
  1220. }
  1221. }
  1222. }
  1223. return canClear;
  1224. },
  1225. onKeyDown: function(e, buffer, caretPos, opts) {
  1226. var $input = $(this);
  1227. if (e.ctrlKey) {
  1228. switch (e.keyCode) {
  1229. case Inputmask.keyCode.UP:
  1230. $input.val(parseFloat(this.inputmask.unmaskedvalue()) + parseInt(opts.step));
  1231. $input.trigger("setvalue");
  1232. break;
  1233. case Inputmask.keyCode.DOWN:
  1234. $input.val(parseFloat(this.inputmask.unmaskedvalue()) - parseInt(opts.step));
  1235. $input.trigger("setvalue");
  1236. break;
  1237. }
  1238. }
  1239. }
  1240. },
  1241. "currency": {
  1242. prefix: "$ ",
  1243. groupSeparator: ",",
  1244. alias: "numeric",
  1245. placeholder: "0",
  1246. autoGroup: true,
  1247. digits: 2,
  1248. digitsOptional: false,
  1249. clearMaskOnLostFocus: false
  1250. },
  1251. "decimal": {
  1252. alias: "numeric"
  1253. },
  1254. "integer": {
  1255. alias: "numeric",
  1256. digits: 0,
  1257. radixPoint: ""
  1258. },
  1259. "percentage": {
  1260. alias: "numeric",
  1261. digits: 2,
  1262. radixPoint: ".",
  1263. placeholder: "0",
  1264. autoGroup: false,
  1265. min: 0,
  1266. max: 100,
  1267. suffix: " %",
  1268. allowPlus: false,
  1269. allowMinus: false
  1270. }
  1271. });
  1272. return Inputmask;
  1273. }));