5

How do I restrict user input to a given length in an HTML5 input[type=number] textbox?

the answers to

How can I limit possible inputs in a HTML5 "number" element?

do not handle illegal inputs

<input class="quantity" type="number" min="0" max="99999" maxlength="5" />

$("quantity").keyup(function(){
    var $field = $(this);
    if ($field.val().length > Number($field.attr("maxlength"))) {
        var value = $field.val().slice(0, 5);
        $field.val(value);
    }
});

I know the maxlength attribute is not supported, but I use it to obtain the given length.

The above code works fine in firefox, but in chrome and safari it works only if I input five "VALID" characters. When I start typing any invalid characters, e.g. "a", "b" etc., I am able to type in more letters and the textbox color changes to red.

I found that when the input becomes invalid the $field.val() returns always empty string and the $field.val().length returns 0.

I even tried converting the keyCode to character intended to input and store it in a "data-value" attribute to the input box to check against and overwrite the value of the input but it didn't seem to be reliable.

Is there any solution with which I can make the input[type=number] behave same as input[type=text][maxlength=5]?

Community
  • 1
  • 1
Gopu
  • 148
  • 2
  • 8
  • Chrome uses built-in validators for HTML5 special input types. Changing the type to "text" in js is the solution for the uniform behaviour. – marooou Aug 07 '13 at 13:07
  • 1
    hmm.. it probably works in `Firefox` because it might be defaulting back to `type=text`.. it shows that `type=number` isn't even supported in Firefox http://caniuse.com/input-number – wirey00 Aug 07 '13 at 13:15
  • @mplungjan I have read that already. I am not eligible to comment on the response yet. I didn't get the specific answer what I am asking for. In fact the code I used above is from that question. But all seem to point out the cause but I want a solution. Please help. – Gopu Aug 07 '13 at 13:16
  • Right, I see now I should have read the question more thoroughly. – mplungjan Aug 07 '13 at 13:22
  • 1
    Here is one you can use http://stackoverflow.com/questions/9361193/why-is-input-type-number-maxlength-3-not-working-in-safari – mplungjan Aug 07 '13 at 13:24

4 Answers4

4

Here is my suggestion after testing a few things

  1. it handles more than one field with the quantity class
  2. it handles illegal input where supported
  3. initialises by storing all defaultValues of the fields with the class
  4. handles a weirdness with .index()
  5. works in IE<10 too
  6. tested in Safari 5.1 on Windows - it reacted to the is(":invalid") which however is invalid in IE8

Live Demo

var inputQuantity = [];
$(function() {
  $(".quantity").each(function(i) {
    inputQuantity[i]=this.defaultValue;
     $(this).data("idx",i); // save this field's index to access later
  });
  $(".quantity").on("keyup", function (e) {
    var $field = $(this),
        val=this.value,
        $thisIndex=parseInt($field.data("idx"),10); // retrieve the index
    // NOTE :invalid pseudo selector is not valid in IE8 so MUST be last
    if (this.validity && this.validity.badInput || isNaN(val) || $field.is(":invalid") ) { 
        this.value = inputQuantity[$thisIndex];
        return;
    } 
    if (val.length > Number($field.attr("maxlength"))) {
      val=val.slice(0, 5);
      $field.val(val);
    }
    inputQuantity[$thisIndex]=val;
  });      
});
animuson
  • 53,861
  • 28
  • 137
  • 147
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • Finally!! Thanks a lot @mplungjan. This does almost what I wanted. With a slight modification I get what I wanted. [Modified code](http://jsfiddle.net/Cfg6H/11/) – Gopu Aug 08 '13 at 07:29
  • I can't put it all in comments so I put it on fiddle. Your feedback is appreciated. Thanks. Is there any way I can put it here or could you please get my changes in your answer? – Gopu Aug 08 '13 at 07:38
  • I updated again to handle some unexpected issues I found when testing IE – mplungjan Aug 08 '13 at 08:36
  • Did you test this in safari? It seems invalid characters are accepted. – Gopu Aug 08 '13 at 10:58
  • I managed to make it work everywhere `if ((this.validity && this.validity.badInput) || $field.is(":invalid") || isNaN(val))` including windows Safari except for IOS Safari. In IOS Safari we simply can't replace the value of invalid textbox. – Gopu Aug 08 '13 at 11:41
  • Great. I updated my code. the is(":invalid") must come last to work in IE – mplungjan Aug 08 '13 at 12:06
  • Yes I noticed that, but is it possible even that to be prevented in IOS Safari? – Gopu Aug 08 '13 at 12:07
  • Not that I can see. So the issue is that you can type some of the number keyboard things in, but if you leave the field, it removes them so you are 99% there – mplungjan Aug 08 '13 at 12:11
  • there is ONE last thing to do. You can onfocus start monitoring using setInterval and onblur stop monitoring. That might work. – mplungjan Aug 08 '13 at 12:13
  • What do you suggest to monitor and how would it help? – Gopu Aug 08 '13 at 12:24
  • Actually we cannot. So ignore my last comment – mplungjan Aug 08 '13 at 12:47
2

I don't know my answer is useful for you? But i happy if i can help you. you should write a js method and then use it in your html page.

function limit(element) {
  var max_chars = 2;

  if(element.value.length > max_chars) {
    element.value = element.value.substr(0, max_chars);
  }
}


<input type="number" onkey ="limit(this);" onkeyup="limit(this);">
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • Thanks! But we can't check element.value.length because it will return 0 when invalid characters are typed. Thus the condition won't satisfy. – Gopu Aug 07 '13 at 13:31
0

Since there is no uniform support for HTML5 input types I suggest using this script template until all browsers will support them.

$(".quantity").each(function() {
    $(this).attr("type", "text")
    var min = $(this).attr("min");
    var max = $(this).attr("max");
    $(this).removeAttr("min").removeAttr("max");
    $(this).keyup(function(){
        var $field = $(this);
        if ($field.val().length > Number($field.attr("maxlength"))) {
            var value = $field.val().slice(0, 5);
            //   add js integer validation here using min and max
            $field.val(value);
        }
    });
});

Then we can simply leave HTML5 elements untouched

BenMorel
  • 34,448
  • 50
  • 182
  • 322
marooou
  • 221
  • 2
  • 9
  • Thanks, but I can't do that either. I have used the input[type=number] purposely to bring up the numeric onscreen keyboard on typing in an IOS safari browser. Changing it back to type=text would bring up the default alpha-numeric onscreen keyboard. It is the main reason I need to limit the length via JS. – Gopu Aug 07 '13 at 13:46
  • oh ok. This http://stackoverflow.com/questions/9361193/why-is-input-type-number-maxlength-3-not-working-in-safari sounds good though – marooou Aug 07 '13 at 13:47
0

to dynamically set max limit

function limit(element,max_chars) {

  if(element.value.length > max_chars) {
    element.value = element.value.substr(0, max_chars);
  }
}


<input type="number" onkey ="limit(this);" onkeyup="limit(this,2);">