Masked Input Plugin 1.2.2

There is now a new version of my Masked Input Plugin for jQuery.  This is primarily a bugfix release which addresses some edge cases.  Additionaly, I made a few changes that I feel make the plugin behave more natural so that the user experience isn't affected too much by using the plugin.
A few other things worth noting:  This is my first build for this plugin that uses a build script.  No longer am I compressing the javascript by hand.  I'm hoping to extend the script further so that future releases are easier.  Also, I'm now compressing the script with YUI Compressor.
This release has been tested with jQuery 1.3.2 and 1.2.6.
  • Fixed bug which blocked apple meta key.  This was keeping copy and paste via keyboard shortcut from working on Mac.
  • Fixed bug that caused mask literals to be pushed into the mask placeholder positions when verifying the data.
  • Fixed bug that prevented user input from completing when mask ended in mask literal.


  • Changed behavior on focus to select all text if focusing on a completed mask.
  • No more masking on readonly inputs.
  • Changed escape behavior to put the input back to the original value instead of just blanking the text.
  • Increased range of accepted characters for input.

43 Comments so far

  1. brett @ March 10th, 2009


    how do you enforce a number format such as:

    +61 XXXX XXXX

    Many thanks. Also did you get my email regarding enforcing capitalization? Is this possible?

  2. Jon Erickson @ March 11th, 2009

    Really sweet that you were able to add the select all as default functionality. =)

    I was the one with the SO post (

  3. Louis-Guillaume Carrier-Bédard @ March 20th, 2009

    Hi Josh,

    Thanks for the plugin.

  4. Steve @ March 24th, 2009


    Great plug-in.

    I see in 1.2.2 that the bug:
    Fixed bug that caused mask literals to be pushed into the mask placeholder positions when verifying the data.

    should be fixed. Unfortunately this appears to still exist.

    I’m trying to enforce a phone number format of 44 9999 999999 but after validation the field holds 44 4499 999999 which is obviously wrong!

    Also, is it possible to have a more flexible mask. Ideally I’d like to be able to specify that the last character (or more) in an input field can be left blank. For e.g. If the mask was a99 99aa then I’d like the user to be able to input something like z12 34z or z12 34yz.

    email me for more information if required.

    Many thanks for the plugin.

  5. Radioman @ March 26th, 2009

    “completed” function ceased to work

  6. morleydots @ April 2nd, 2009


    Here is a kind of a bug.
    I have a several masks for one input field. Mask changes depending on value of some other input field. So if you tring to change mask without page reloading there is a stange behavior appears () while you trying to enter some data into this inputs.

    It’s hard to explain for me, here is an example:

    Try to play with select field and then try to enter some data in the input.

  7. Rike @ April 7th, 2009

    Hi all,

    I have the same bug when trying to use “completed” function (v1.2.2). I tried to debug the library with Firebug, and I’m able to fix this issue by modifying the code of ‘seekNext’ function:

    function seekNext(pos) {
    while (++pos < len && !tests[pos]);
    return pos;

    The difference is “less than “instead of “less or equal”. I’m not sure, it is a good fix (I’m not a Javascrip geek !).

    Josh, please could you confirm this fix ?

  8. Rike @ April 7th, 2009

    Sorry I forgot:

    Great library, very useful !
    Thanks a lot.

  9. Rike @ April 7th, 2009

    An improvement proposal:

    Add a settings attribut “allowIncompleteValue” (true/false), and then call ‘checkVal’ function with this setting !

    It will able to define a mask without forcing the end user to loss his value if he don’t complete the field.

    (sorry for my english: hope you will understand what i mean)

  10. Radioman @ April 9th, 2009

    before apply new mask you should unmask previous

  11. Eric Crull @ April 14th, 2009

    I’ve seen some requests for the ability to suggest or partially suggest input to the user, which I have added in to the previous version of your plugin.
    You could add:
    $(“.timeStamp”).mask(“99:99″,{suggested:”0″, backspace:”suggested”} );
    would show 0_:__, since 75% of all times would start with a zero.
    I also made it accept a sparse array to suggest at the end of the field:
    $(“PD”).mask(“99.9″, {suggested:[,,,”0”]})
    would show __.0 but would allow the 0 to be changed when that character is highlighted.
    The changes are minimal and are very effective for repetitive entry. I’d like to email you a sample html file.
    I’ve been using it (IE6 and IE7) for about 6 months and it works very well for us.


  12. nathaniel @ April 27th, 2009

    OK, so I’m using 1.2.2 within ASP.Net. It works for masking, but if the mask definition is larger than the information within the textbox, it errors out.

    Let’s say I want to only have 5 alpha characters for some type of shorthand for an entity.

    $(".filteredname").mask("*****", { placeholder: " " });

    and in the codebehind I do:

    txtEntity.Text = “123”;

    then the mask wipes out the code. However, if I do:

    txtEntity.Text = “123456”;

    then the data displayed is “12345”, even though the “Value” of txtEntity is “123456”.

    So, weirdness. If the data is smaller than the length of the mask, it gets cleared, but if it’s larger, it gets shortened.

  13. Otto @ May 18th, 2009

    How can I mask hour? Is regex supported?
    For example: 23:00 is valid, but 25:00 isn’t. The 2nd digit depends on the first.


  14. Soup @ June 3rd, 2009

    What am I doing wrong? I’ve specified a mask of “99” to allow input of up to two digits. It works for values 10 to 99 but not for anything less that 10 unless there is a leading zero.

    Why can’t I just be able to enter a single digit from 0 to 9?

    BTW, thanks for your efforts on making a nice plugin.

  15. Romyn @ June 19th, 2009

    Hi Josh,

    Thanks – nice plugin.

    Echo what Otto mentioned – would be really useful if it could do times well. I currently have 99:99:99 but would be really handy to have 23:59:59 where the 23 part is a combined 2-digit. I would try and do this myself but being a bit of a js newbie I suspect it’s beyond me.

    Can’t have everything I suppose and some of us are just greedy – but if you ever fancy adding that I’m sure I wouldn’t be the only one to appreciate it – impending fatherhood allowing 😉

    Either way thanks again for your efforts.

    Kindest regards

  16. Marcel @ June 20th, 2009

    Hi, i’m getting some memory leak on page reload with masked input, when i do this: $(‘#field’).mask(‘99999-99’)

    Can you help me?

    Thnak you.

  17. Zito @ June 26th, 2009

    I have some problems if “completed” parameter.
    Debugging the plugin i found a way to fix the problem and a want to share.

    In the line 169
    if (settings.completed && next == len+)

    I made a change
    if (settings.completed && next == (len+1))

  18. Zito @ June 26th, 2009


    The original line 169
    In the line 169

    if (settings.completed && next == len)

    without the last “+”

  19. Livia @ June 26th, 2009


    I’m trying to unmask a value before submit, but it’s not working.
    Can someone help me?

    My code:
    $(document).ready(function() {
    rules: {
    cep: {
    rangelength: [8,9]
    cpf: {
    rangelength: [11,14]
    submitHandler: function(form) {



  20. Marcel @ July 3rd, 2009

    Hi, the sIEve Leak Detector is reporting a memory leak on page with masked input, when i do this: $(’#field’).mask(’99999-99′)

    Can you help me?

    Thnak you.

  21. Chris M @ July 29th, 2009


    Great control however, I am having a problem with the ‘completed’ setting. I have the latest version of the control and I have copied your example but my alert never appears. Am I correct to think as soon as a correct value is entered into the text box the completed function should fire?

    Any help would be great.


  22. Paul S @ October 20th, 2009

    Has worked stopped on this plugin? We have seen the same problem as Soup with the mask not working unless the value is exactly the same length as the mask. We would love to use this plugin.

  23. surama hotta @ November 10th, 2009

    I used this Masked Input individually (simple textbox), its works fine, but when I use both Watermark and this Masked Input, then first time the controls works fine and we can enter data, but when I change the focus from this controls without giving any data and again back to this control then it not entering data in proper format.

    Can anybody please help me.
    How to use both Watermark with Masked Input.


  24. Kevin @ November 18th, 2009

    What is the proper config to mask a US dollar amount:


    etc., basically want to allow any valid US dollar amount. How?


  25. Justin @ January 29th, 2010

    Hey, great plugin!

    I’m also wondering about about dollar values – any way to set a maximum mask ($99999.99) but accept fewer characters? ($99.99)


  26. Ofélia @ February 10th, 2010

    Hi Someone can help me !!

    I have a textbox with

    var Formatfield =”9999-999 ****************************************”;

    If the user want not complete the mask, the part * it’s free .

    thanks in advanced !!

  27. Sree @ February 16th, 2010

    can i use both watermark & Masked plugin at a time if yes how can i use it.

    i tried to fix my own function in plugin but it was working in normal aspx but its not working on “Master & Content page”

    Please sort it out

  28. ahmet ertaş @ July 1st, 2010

    for “default value” problem resolve is:

    (function(a){var c=(a.browser.msie?”paste”:”input”)+”.mask”;var b=(window.orientation!=undefined);a.mask={definitions:{“9″:”[0-9]”,a:”[A-Za-z]”,”*”:”[A-Za-z0-9]”}};a.fn.extend({caret:function(e,f){if(this.length==0){return}if(typeof e==”number”){f=(typeof f==”number”)?f:e;return this.each(function(){if(this.setSelectionRange){this.focus();this.setSelectionRange(e,f)}else{if(this.createTextRange){var g=this.createTextRange();g.collapse(true);g.moveEnd(“character”,f);g.moveStart(“character”,e);}}})}else{if(this[0].setSelectionRange){e=this[0].selectionStart;f=this[0].selectionEnd}else{if(document.selection&&document.selection.createRange){var d=document.selection.createRange();e=0-d.duplicate().moveStart(“character”,-100000);f=e+d.text.length}}return{begin:e,end:f}}},unmask:function(){return this.trigger(“unmask”)},mask:function(j,d){if(!j&&this.length>0){var f=a(this[0]);var“tests”);return“buffer”),function(l,m){return g[m]?l:null}).join(“”)}d=a.extend({placeholder:”_”,completed:null},d);var k=a.mask.definitions;var g=[];var e=j.length;var i=null;var h=j.length;a.each(j.split(“”),function(m,l){if(l==”?”){h–;e=m}else{if(k[l]){g.push(new RegExp(k[l]));if(i==null){i=g.length-1}}else{g.push(null)}}});return this.each(function(){var ORJ=$(this).val();var r=a(this);var“”),function(x,y){if(x!=”?”){return k[x]?d.placeholder:x}});var n=false;var q=r.val();“buffer”,m).data(“tests”,g);function v(x){while(++x=0){}for(var y=x;y<h;y++){if(g[y]){m[y]=d.placeholder;var z=v(y);if(z<h&&g[y].test(m[z])){m[y]=m[z]}else{break}}}s();r.caret(Math.max(i,x))}function u(y){for(var A=y,z=d.placeholder;A<h;A++){if(g[A]){var B=v(A);var x=m[A];m[A]=z;if(B<h&&g[B].test(x)){z=x}else{break}}}}function l(y){var x=a(this).caret();var z=y.keyCode;n=(z16&&z32&&z=32&&C186){var x=v(z.begin-1);if(x<h){var A=String.fromCharCode(C);if(g[x].test(A)){u(x);m[x]=A;s();var y=v(x);a(this).caret(y);if(d.completed&&y==h){}}}}}return false}function w(x,y){for(var z=x;z<y&&z<h;z++){if(g[z]){m[z]=d.placeholder}}}function s(){return r.val(m.join("")).val()}function p(y){var z=r.val();var C=-1;for(var B=0,x=0;B<h;B++){if(g[B]){m[B]=d.placeholder;while(x++z.length){break}}else{if(m[B]==z[x]&&B!=e){x++;C=B}}}if(!y&&C+1=e){s();if(!y){r.val(r.val().substring(0,C+1))}}}return(e?B:i)}if(!r.attr(“readonly”)){“unmask”,function(){r.unbind(“.mask”).removeData(“buffer”).removeData(“tests”)}).bind(“focus.mask”,function(){q=r.val();var x=p();s();setTimeout(function(){if(x==j.length){r.caret(0,x)}else{r.caret(x)}},0)}).bind(“blur.mask”,function(){p();if(r.val()!=q){r.change()}}).bind(“keydown.mask”,l).bind(“keypress.mask”,o).bind(c,function(){setTimeout(function(){r.caret(p(true))},0)})}p()})}})})(jQuery);

  29. gorpacrate @ July 8th, 2010

    if your ‘completed’ function doesn’t work, try to replace this line:

    if (settings.completed && next == len)

    (this is line number 169 of noncompressed plugin) with that:

    if (settings.completed && eval(+next – 1) == len)

    While using this plugin with firebug, i’ve noticed, that ‘next’ variable jumps up over a symbol when last char of mask entered. This way should work.

  30. Oliver Lillie @ July 15th, 2010

    Just wondering. Is it possible to mask anything else aside numbers. For example an email or url?

  31. Chuck @ July 20th, 2010

    Why does calling .mask() on an empty masked input field cause the field to be filled with the prompt character? This is causing me some problems trying to save the contents of a field without the mask literals.

  32. Andreas Buchholz @ August 5th, 2010

    Concerning the bug with repeated mask characters that was removed in version 1.1.4:

    I guess, it was reintroduced while implementing the acceptance of incomplete inputs by using a ‘?’. For me it is working fine now after applying the following modifications:

    Change line 190 from
    for (var i = 0, pos = 0; i < len; i++) {
    for (var i = 0, pos = firstNonMaskPos; i < len; i++) {

    Also line 197 from
    lastMatch = i;
    lastMatch = firstNonMaskPos;

    Also lines 204 and 205 from
    lastMatch = i;
    lastMatch = firstNonMaskPos;

    Maybe it can help anyone out there.


  33. Keith @ August 12th, 2010

    Is it possible to right justify the input. Like a mask of 99:99:99 that if you type 12 becomes __:__:12 or 1234 becomes __:12:34 and 123456 becomes 12:34:56. Think hours, minutes, seconds.

    Any thoughts?


  34. Peter @ August 18th, 2010

    I had a problem where masked input plugin is blanking out or emptying fields that aren’t completed.

    For example, if I have a zip code input mask of 99999-9999, and the user enters a 5-digit zip code, the field goes blank after the user leaves the field.

    It is extremely not obvious from the demo page, but adding a question mark (?) into the field allows you to keep those characters. The mask that works is as follows:


    Thanks for a great plugin.

  35. Josh Padnick @ October 13th, 2010

    Overall, great plugin! I encountered a frustrating bug where calling mask() on the same input field multiple times started causing strange behavior. While I believe this constitutes a genuine bug in the plugin, I found a nice workaround.

    Just call unmask() right before you call mask() again. You can execute the sequence as many times as you want and the behavior works great now.

  36. Rodrigo @ October 25th, 2010

    To unmask a field before submit I did the following (unmask() doesn’t work)

    $(“#form-name”).submit(function() {
    return true;


  37. Roman @ November 3rd, 2010

    I am getting wired behavior on IE6 if I set value without focusing on the input field (through javascript) and then focusing on next input element, IE6 clears my set values to empty.

    Thank you.

  38. Jayesh @ March 5th, 2011

    Great plug-in. I however wanted the mask to display by default in the text box something similar to AJAX control MaskedEditExtender where the attribute ClearMaskOnLostFocus when set to “false” displays the mask always in the textbox; this helps user experience as well. Any idea if the plug-in has that functionality

  39. wjama @ March 18th, 2011

    felicitacione, tengo un proyecto que usa la primera versión

    * Version: Beta 1
    * Release: 2007-06-01

    y durante todo este tiempo ha funcionado muy bien, ahora lo voy a actualizar, muchas gracias por tu esfuerzo y tiempo

  40. DJ @ November 29th, 2011

    great plugin. The problem I have is that I am validating some date fields with some document ready functions using
    var jVal= {“dueDateVal” : function() {
    …field validation code here

    and the use of the .mask

    $j(“#dueDate”).mask(“99/99/9999″,{placeholder:” “});

    at the beginning of document ready seems to cause the validation functions to execute twice.

    anyone experience this? suggestions?

  41. Mariano @ June 15th, 2012

    Very nice job dude!

    Thank you for sharing.
    I would like to sugest you to code a mask for aphabetic, numbers (just integer and for real), and for money in other countries. In Brazil we use R$1.222.000,00
    Phone numbers in some cities are +55 (xx) xxxxX-xxxx
    There is a fifth number in São Paulo, all over the country is +55 (xx) xxxx – xxxx (2-2-4-4).
    Maybe money and phone numbers could be configurable. Think about it…
    I will use your lib, and I will note the page it is yours!
    Thank you Dude!

  42. Donald Oppinger @ September 3rd, 2012

    Very nice plugin man!

    Just 2 things I was not able to find out by reading through your site:
    1) Is it possible to mask a price field with optional digits e.g. expected results for entered prices (European interpunctuation) :
    € 1.500,90 – mask “€ 9.999,99”
    € 17.200,00 – mask “€ 99.999,99”
    € 500,20 – mask “€ 999,99”
    In this case the “optional digits” function with questionmark (?) does not work because we have optional values in front of the part 999,99 …

    2) Is it possible to give the input a default value e.g € 1,00 via the masking plugin

    Thanks in advance, any help is highly appreciated!
    Kind regards

  43. Sergey Ponomarev @ July 4th, 2013

    I have same problem, and I found that this plugin supports option ‘unmaskedvalue’

Leave a reply