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?
The hack is to use type="tel"
instead of type="number"
.
This solves the 2 main issues:
- It pulls up a number keypad on mobile devices
- It validates (and is not empty) with numbers or non-numbers as input.
Please see this JSFiddle: http://jsfiddle.net/timrpeterson/CZZEX/6/
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.
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
You're setting a numeric input field to a string which is not a number. What did you expect to happen? The whole point is that these fields don't allow or accept non-numeric input. They are documented as only accepting a floating point value.
There is no "hack" available or required; the solution is to stop using a number
input field for a value that isn't a number. Credit cards, phone numbers, etc; these things are not numbers. They contain digits as a subset of the valid characters, but they also contain completely non-numeric characters like spaces, hyphens and parenthesis. They need to be stored and treated as regular strings.
Use <input type="text"/>
.
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);
});