HTML5 input type=number value is empty in Webkit if has spaces or non-numeric characters?

40,502

Solution 1

The hack is to use type="tel" instead of type="number".

This solves the 2 main issues:

  1. It pulls up a number keypad on mobile devices
  2. It validates (and is not empty) with numbers or non-numbers as input.

Please see this JSFiddle: http://jsfiddle.net/timrpeterson/CZZEX/6/

Solution 2

I can suggest two ways. 1. Prevent chars in input

# updated to support more numerical characters related
$(window).keydown(function(e) {
  if($('input[type=number]').index($(e.target))!=-1) {
    if(
      ($.inArray(e.keyCode, [48,49,50,51,52,53,54,55,56,57,58,96,97,98,99,100,101,102,103,104,105,8,13,190,189]) == -1) // digits, digits in num pad, 'back', 'enter', '.', '-'
      || (e.keyCode == 190 && $(e.target).val().indexOf(".") != -1) // not allow double dot '.'
      || (e.keyCode == 190 && $(e.target).val().length == 0) // not allow dot '.' at the begining
    ) {
      e.preventDefault();
    }
  }
});

or 2. Change input's type on fly

$('input[type=number]').focus(function() {
    $(this).prop('type', 'text');
});

this allows to put whatever you want and change its type back onblur

$(this).blur(function() {
    $(this).prop('type', 'number');
});

But still you cannot store nonnumerical values in input with type=number, so val() will always return you empty string if it meets char or space.

So, at least you have to remove all garbage with .replace(/[^\d]/g, '') - that means "remove all except numbers" before you change type back

In my example I show both methods + clear input values.

Solution 3

A way to control input number is to set it empty on blur when you can't read value

static formattedDecimalInput(input, maxScale, allowEmpty = true) {
    input = $(input);

    input.on("blur", function(e) {
        var inputVal = input.val();

        if(inputVal != "" || !allowEmpty) {
            if(inputVal == "") {
                inputVal = "0";
            }
            var number = Number(inputVal);
            input.val(number.toFixed(maxScale));    
        } else {
            input.val("");
        }
    });
}

You can formatted it by the way, and if you have invalid char on server side you can send a bad request response.

If you want a requiered field, you can just check if the input is empty with javascript before your server call

It is not really the answer of the initial question but I was looking for a user friendly control for this type of input when I arrived here

Solution 4

My hack for this problem includes the following (i use jQuery validators):

    $(document).on('keyup', '[type="number"]', function () {
        if (this.validity.badInput) {
            $(this).attr('data-badinput', true);
        }
    });

Later in validator method i do this:

    $.validator.addMethod('isInteger', function (value, element, parameterValue) {
        if ($(element).attr('data-badinput')) {
            //We know nasty browser always clears incorrect input, so empty string will look OK next time
            $(element).removeAttr('data-badinput');
            return false;
        }
        return !value || /^-?\d+$/.test(value);
    });
Share:
40,502
tim peterson
Author by

tim peterson

web programming-javascript, php, mysql, css, html-is my thang

Updated on October 05, 2020

Comments

  • tim peterson
    tim peterson over 3 years

    This is strange behavior to me but on Webkit browsers (Chrome/Safari, not Firefox) if I include a space in a string of numbers in an <input type=number> then the value of that input is empty.

    See this JSFiddle: http://jsfiddle.net/timrpeterson/CZZEX/5/

    Here's the code:

    <input id='withOutspace' type='number' value='123'>
    <input id='with_space' type='number' value='123 123'>
    <button>click</button>
    
    $('button').click(function(){ 
        alert("withOut:"+$('#withOutspace').val()+" |||| with:"+$('#with_space').val());
    });
    

    If you go to this JSFiddle, you'll notice that the with_space input is empty. But if you put it in it a number that has a space or any non-numeric characters, the alert will say that input is empty.

    Obviously, this is a disaster for form validation with credit card numbers, etc. so does anyone have a hack for this?

  • tim peterson
    tim peterson over 10 years
    If I'm so crazy the why does Firefox preserve it as a string? That seems the most inclusive/safest default behavior. Also the type=number is better for mobile devices b/c it pulls up number pad. I have to respectfully disagree on this one.
  • sdeburca
    sdeburca over 10 years
    you can set the inputmode (html5) attribute for an input field to 'numeric'. that might give you the number pad
  • tim peterson
    tim peterson over 10 years
    Mobile device usability is rate-limiting. Think Webkit has it wrong.
  • user229044
    user229044 over 10 years
    @timpeterson Not according to the specifications. You can respectfully disagree all you want, but, respectfully, that just makes you wrong too.
  • tim peterson
    tim peterson over 10 years
    @meagar, -@sdeburca may have solved the debate if inputmode='numeric' is respected by Webkit
  • tim peterson
    tim peterson over 10 years
    @meagar , -@sdeburca: Just checked, inputmode='numeric' isn't respected my mobile safari. I still much rather not annoy 99% of the world by making them click an extra button to reach the numberpad (not to mention, failing validation with often cryptic or in this case without an error message) rather than point out to them that "123-123" is in fact not a number.
  • user229044
    user229044 over 10 years
    @timpeterson That's the same question. You just linked to this same page.
  • tim peterson
    tim peterson over 10 years
  • Jason
    Jason over 10 years
    The problem with using tel is that it shows the phone number keyboard which does not have decimals or the negative sign which are often used in number fields (e.g. currency). (Tested on iPhone)
  • tim peterson
    tim peterson over 10 years
    yes using type="tel" instead of type="number" depends on the use case. Credit cards (and phone numbers obviously) would be better with type="tel" because of the two reasons I mention above.
  • mcm69
    mcm69 about 10 years
    I would add codes 97-106 (numpad numbers) to the allowed list too.
  • njzk2
    njzk2 almost 10 years
    What did you expect to happen? valueAsNumber returns NaN, which makes sense. value returns an empty string, which does not allow me to add relaxation to the constraints, such as removing the spaces, normalizing the use of . or , for decimal separator...
  • miyasudokoro
    miyasudokoro over 9 years
    I fully agree with @njzk2. My problem is that even with only allowing certain keys, you can still type --3..1.. With no way to access that invalid input and correct it, you are stuck preventing invalid inputs. But if you tell it "only allow .- if there isn't already .- in the field", then if the user highlights the number and tries to type . or - over it, they can't, and I can't correct for that because type=number doesn't have selectionStart or selectionEnd. So far, this thing is more trouble than it's worth.
  • fguillen
    fguillen about 9 years
    The event wall described here is the best workaround I've found so far
  • fguillen
    fguillen about 9 years
    I'm including all this keyCodes 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 8, 13, 190, 189. Which are: digits, digits in num pad, 'back', 'enter', '.', '-'
  • fguillen
    fguillen about 9 years
    Also we have to take care of the double dots like "10..34" which would make the number field to fail again. I'm editing the original answer with all these suggestions
  • Aaron Sherman
    Aaron Sherman about 9 years
    On Chrome 41 if you change the input type from number to text it clears the value preventing you from do a "quick cast"
  • James
    James over 8 years
    I think testing the keycodes will not prevent someone copy pasting bad characters into the field
  • yolenoyer
    yolenoyer over 8 years
    The behaviour of value causes another problem : a plugin like autoGrowInput (github.com/Pixabay/jQuery-autoGrowInput) can't work with <input type="number">
  • scuds
    scuds over 8 years
    What about accessibility? Doesn't this prove to be troublesome for screenreaders?
  • Alexander
    Alexander over 8 years
    What did you expect to happen? - I expect that if i enter text instead of number in this field - if this is allowed - on form submit the text is not cleared and i see i enter wrong thing. Currently, my numeric field, that allows empty values, is successfully submitted AUTOMATICALLY after clearing alpha characters from numeric field. This is INCORRECT behavior (seen at least in Firefox).
  • David Rector
    David Rector over 6 years
    What did you expect to happen? Well, I expected to be able to detect the difference between an empty field and a field with garbage so I can tell the user what to fix. Telling the user "The numeric field cannot be empty" when it has non-numeric data makes me look stupid. I want to tell them "Please enter only numeric data in the numeric field."
  • Matthieu Riegler
    Matthieu Riegler over 5 years
    fyi chrome alows eeee as an valid input but returns "" (empty string) for the input value
  • Vizz85
    Vizz85 over 5 years
    @James key combination (paste, select all, etc) are also prevented. Tested on chrome and safari