I have a html <input> element that I want to accept only numbers and to be recognised on mobile devices as a number field. I also want invalid characters to be swallowed, just like for standard type=number swallowing disallowed characters.
I've tried the obvious type=number but it has a number of shortcomings. Specifically it allows 'e', '+' and '-' (at least in chrome), but these were easy to fix with some JS. The real problem is with the '.' character, I want to be able to enter floating point numbers e.g. '0.10', '5.5054', but don't want to be able to enter invalid strings like '0.10.1' for instance. I tried to resolve this by allowing only 1 '.' at a time but this failed as the input.value gets massaged by the browser e.g. '5.' becomes '5', '5..' becomes null (!) and it seems impossible to get the raw string value typed in the input. The above means checking for existing '.'s and taking action appears to be a dead end...
Core questions:
Is there a way I missing to inspect and conform the input?
'Is there a way of marking an input as a number without the logistical baggage of type=number?
Note:
* I realise that you can paste whatever you want in, I consider that behaviour pathological and shouldn't be covered by input prevention.
Update
To clarify, I have already tried keypress, keydown etc events and they aren't adequate as I want to see how many '.'s exist in the input currently to choose whether or not to allow another. At this point the input.value has been massaged by the browser to remove '.'s. I want to conditionally allow characters based on the current number of '.'s that have been entered.
Example
HTML (angular style binding for brevity)
<input type="number" (keydown)="keyDown()">
JS
function keyDown($event: KeyboardEvent) {
const inputField = // obtain reference to input element
const value = inputField.value;
if ( value.indexOf('.') !== -1 && $event.key === '.') { // disallow another . if one is present
// ! input field prunes . so this check isn't sufficient
$event.preventDefault();
return;
}
// This is the crux of the problem e.g.
// type 5. into input field, value === 5
// type 5.. into the input field, value === null
// Since the . char is removed by the input element there's no way to know how many are present!
console.log(value);
}
Summary
Is there a way to signal that an <input> is of type number without using the type=number attribute setting.
i.e. mobile devices recognise and display number pad etc
For an <input> that has type=number is there a way to swallow all key input that doesn't result in a valid number
Before the character is added to the input by the browser, no janky deletion on keyup
Is there a way to signal that an <input> is of type number without using the type=number attribute setting.
i.e. mobile devices recognise and display number pad etc
Use inputmode="decimal" instead of type="number" to signal a mobile device to use a number pad keyboard input. This way you can continue to use type="text" and process the input as needed.
See MDN for more info and inputtypes.com to test on a device.
A slightly different approach. It allows digits, only 1 period, and backspace. All the rest of KeyboardEvent.keys including ctrl + v and ctrl + c are ignored. But if wish to allow them, you can do so.
To check if the character is one of the 10 digits, I am using event.key since they can have two different codes: Digits[0-9] and Numpad[0-9]. But for the period and backspace, I am using event.code since they have only one code.
const input = document.querySelector("#number_input");
const App = {
isDigit: function(key) {
const digits = [
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9"
];
return digits.includes(key);
},
isPeriod: function(code) {
return code === "Period";
},
isBackSpace: function(code) {
return code === "Backspace";
},
handleEvent: function(event) {
const key = event.key;
const code = event.code;
const value = input.value;
if (App.isDigit(key) || App.isPeriod(code) || App.isBackSpace(code)) {
if (App.isPeriod(code) && value.indexOf(key) !== -1) {
event.preventDefault();
}
} else {
event.preventDefault();
}
}
};
input.onkeydown = App.handleEvent
<input id="number_input" />
A clever hack
Since you insist to use a number input. First use, a dummy text input which you can hide it using either CSS or Js and validate its value instead of the number input.
const input = document.querySelector("#number_input");
const dummyInput = document.querySelector("#dummy_input")
const App = {
isDigit: function(key) {
const digits = [
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9"
];
return digits.includes(key);
},
isPeriod: function(code) {
return code === "Period";
},
isBackSpace: function(code) {
return code === "Backspace";
},
handleEvent: function(event) {
const key = event.key;
const code = event.code;
const dummyValue = dummyInput.value;
if (App.isBackSpace(code)) {
dummyInput.value = dummyValue.substring(0, dummyValue.length - 1)
} else {
if (App.isDigit(key) || App.isPeriod(code)) {
if (App.isPeriod(code) && dummyValue.indexOf(key) !== -1) {
event.preventDefault();
} else {
dummyInput.value += event.key
}
} else {
event.preventDefault();
}
}
}
};
input.onkeydown = App.handleEvent
<input type="number" id="number_input" />
<input type="text" id="dummy_input" />
Update
All of the answers that use input[type="number"] have a problem. You can change the input's value to a negative number by mouse wheel/spinner. To fix the issue, set a minimum value for the input.
<input type="number" min="1" id="number_input" />
You need to listen for onchange events and then change value of the dummy input.
const input = document.querySelector("#number_input");
const dummyInput = document.querySelector("#dummy_input")
const App = {
isDigit: function(key) {
const digits = [
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9"
];
return digits.includes(key);
},
isPeriod: function(code) {
return code === "Period";
},
isBackSpace: function(code) {
return code === "Backspace";
},
handleEvent: function(event) {
const key = event.key;
const code = event.code;
const dummyValue = dummyInput.value;
if (App.isBackSpace(code)) {
dummyInput.value = dummyValue.substring(0, dummyValue.length - 1)
} else {
if (App.isDigit(key) || App.isPeriod(code)) {
if (App.isPeriod(code) && dummyValue.indexOf(key) !== -1) {
event.preventDefault();
} else {
dummyInput.value += event.key
}
} else {
event.preventDefault();
}
}
},
handleChange: function(event) {
dummyInput.value = event.target.value
}
};
input.onkeydown = App.handleEvent;
input.onchange = App.handleChange;
<input type="number" min="1" id="number_input" />
<input type="text" id="dummy_input" />
trigger special function for onkeypress and check if your allowed character are typed or not. If not - prevent the default behavior.
let special = document.getElementById('special_input');
special.addEventListener("keypress", function(e) {
let dot = 46;
// allowed char: 0-9, .
let allow_char = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, dot];
if (allow_char.indexOf(e.which) !== -1) {
// only 1 dot
if (e.which == 46 && special.value.indexOf('.') !== -1)
e.preventDefault();
} else {
e.preventDefault();
}
});
<input id='special_input'>
updated
The answer is updated as per requirement changes.
okay I try to fix one more problem and that is paste
according to following code you can not paste anything, you can only paste numbers, if you try to paste string, the input box will become empty automatically :)
let special = document.getElementById('inputField');
special.addEventListener("keypress", function(e) {
let dot = 46;
// allowed char: 0-9, .
let allow_char = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, dot];
if (allow_char.indexOf(e.which) !== -1) {
// only 1 dot
if (e.which == 46 && special.value.indexOf('.') !== -1)
e.preventDefault();
} else {
e.preventDefault();
}
});
function checkString()
{
setTimeout(() => {
var value = document.getElementById("inputField").value;
value = parseInt(value);
if(isNaN(value))
document.getElementById("inputField").value = "";
}, 100);
}
<input type="number" id="inputField" onpaste="checkString()"/>
Check truthy with
value == parseFloat(value)
parseFloat() will capture the first decimal point and remove any additional ones.
Using '==' instead of '===' will make sure the reference value isn't changed.
function keyDown($event: KeyboardEvent) {
const inputField = // obtain reference to input element
const value = inputField.value;
if ( value == parseFloat(value)) { // disallow another . if one is present
// ! input field prunes . so this check isn't sufficient
$event.preventDefault();
return;
}
// This is the crux of the problem e.g.
// type 5. into input field, value === 5
// type 5.. into the input field, value === null
// Since the . char is removed by the input element there's no way to know how many are present!
console.log(value);
}
Here is a similar test you can run in node.js to verify it accomplishes what you are going for.
function numCheck (value) {
if (value == parseFloat(value)) {
console.log(value)
} else {
console.log('not a number')
}
}
numCheck("5");
numCheck("5.5");
numCheck("5.5.5");
numCheck("A");
For restrictions, Regex is best way to go. Register event listener on keypress
numbersOnly(event) {
const numbers = /^([0-9])$/;
const result = numbers.test(event.key);
return result;
}
Above function will swallow charset, if it doesn't match regex
Javascript Regex: validating a double/float
Above link has regex, who allows double/float. Hope it helps :)
This may be what your looking for:
This input eats all caracters exept for numbers and "."
let prev = "";
function keyUp(event) {
if ((!event.target.value && event.keyCode !== 8) || event.target.value.indexOf('e') !== -1 || parseFloat(event.target.value) == NaN) {
event.target.value = prev;
} else {
prev = event.target.value;
}
}
<input type="number" onkeyup="keyUp(event)">
Perhaps an indirect solution to your problem. You can look into validity property to determine if the input is valid.
You can check the validity without the need to access the value, which may not be returned in case of invalid input.
HTML:
<input type="number" id="num" step="0.1"/>
JS:
var numField = document.getElementById('num');
numField.addEventListener("keyup", event => {
if(!numField.validity.valid)
{
alert('invalid input');
}
});
Some tests:
34 -> valid
3.4 -> valid
e -> invalid
+4 -> valid
3.4. -> invalid
3.4.. -> invalid
.4 -> valid (evaluates to 0.4)
3e+2 -> valid
1e -> invalid
eee -> invalid
-0.3e+1 -> valid
..32e.. -> invalid
This works both with pasting and inputting the values.
UPDATE:
The original question is a bit verbose. I am trying to break it down and answer part by part.
Input[type="number"] allows access to the value only if it is valid and returns empty otherwise. Thus, you can know if value is correct or not, however you cannot get the invalid value.
You could get around this by pushing individual keypresses into a buffer. However, maintaining sync between the buffer and actual value is challenging due to copy/paste, input field swallowing certain keys, moving the cursor around and inserting keys, etc. Implementing reliable cross-platform support for all of this seems like overkill. A better approach would be to implement other means to input the number, e.g. a slider. This resource covers the basics of designing number inputs
So, you are left with knowing if the current input is valid and the last key pressed. The problem is that certain invalid inputs, e.g. "4." may lead to a valid input "4.1". Thus, just swallowing the last key in case the input turns invalid is out of the question.
You could implement a rule that if invalid input is not turned into a valid one within 2 keystrokes (or 1 second) the input returns to last valid state swallowing the invalid input. However, I would argue that this creates UX problems because users may not be used to such behavior and it opens doors for users submitting technically valid, yet unwanted values.
Core questions:
Is there a way I missing to inspect and conform the input?
Is there a way of marking an input as a number without the logistical baggage of type=number?
Apparently not.
Yes, there is by rethinking the way how you enter numeric values.
Related
I am doing a decimal number input validation where I want to prevent typing 'point' for the second consecutive time
For example-
Above in the input box after keypress of the first period, I shouldn't be able to keypress it for the second consecutive time.
I have done this so far-
if (e.which === 190) {
if(value === '') {
e.preventDefault()
this.setState({[error]: "Only one period allowed in decimal numbers!"});
return false;
}
}
But this only prevents the 3rd keypress and allows the second period.
How do I prevent the keypress using JavaScript?
PS- I am using input field if type- 'number'. So the after I press the second dot the e.target.value becomes null.
You can use regular expression alongwith onChange event.
testHanlder = (event) => {
let value = event.target.value;
if (value) {
value = value.replace(/\.+/g, ".")
this.setState({value})
}
}
Even if it passes the second decimal number issue, it will still allow alphabets inside the input field.
Instead you could use:-
var textBox = document.getElementById("txt")
textBox.addEventListener("keyup",function(e) {
var floatValue = parseFloat(textBox.value) || ""
if(floatValue !== textBox.value) textBox.value = floatValue
})
I'm doing input validation on the following field and I want to set a default value. What I mean by default value is I want to set some value to input field if the field is empty.
var inputBox = document.getElementById("inputBox");
inputBox.addEventListener("input", function() {
validateInput(this);
});
inputBox.addEventListener("keydown", function(e) {
validateInput(this, e);
});
function validateInput(elm, e) {
// handle keydown event
if (e) {
// do not allow floating-point numbers, if it's not expected
if (!isFloat(elm.step)) {
if (e.key == ".") {
e.preventDefault();
}
}
}
// handle input event
else {
// do not allow leading zeros
while (elm.value.length > 1 && elm.value[0] === "0") {
elm.value = elm.value.toString().slice(1);
}
// input should be between min and max
if (elm.validity.rangeUnderflow) {
elm.value = elm.min;
} else if (elm.validity.rangeOverflow) {
elm.value = elm.max;
}
}
}
function isFloat(x) {
var f = parseFloat(x);
var floor = Math.floor(f);
var fraction = f - floor;
if (fraction > 0) {
return true;
}
return false;
}
<input type="number" id="inputBox" min="0" max="16581375" step="1" value="0" />
In a very straightforward approach, I can add the following to the end of validateInput()
// set default value, empty field isn't allowed
if (elm.value == "") {
elm.value = elm.min;
}
but this breaks some functionality. For example, I can't enter exponential values (e.g. 1e+5).
Input field does its own check at input. The moment I enter 1e, it evaluates to NaN and the value property of the element is set to "", but visually, 1e is still entered on the field. So, you see, the entered value and the HTMLInputElement.value might differ.
To be able to set a default value, I should be able to check the entered value, not the parsed one by the element. Something like this would probably work:
// set default value, empty field isn't allowed
if (elm.value == "" && !elm.stringValue.includes(e)) {
elm.value = elm.min;
}
But of course, there's no such stringValue property. One way I can think of to get around this problem is to use a text input field and do an extra validation for number.
Is there a way to make this work with number input field?
Looks like you need to parse exponential values into numbers.
I think, this solution should help you: https://stackoverflow.com/a/18719988/6420563
This solution made for text field but i think it will also work for number input.
i want to get the character typed into an html text input field on keypress
then validate the character entered against a list of characters
and return false if it isn't found in that list
(i don't want to use regular expressions)
by 'list' i mean this:
var acceptable = 'abcd12';
this would prevent, for example, the character 'e' being entered, and so on
the html would look like this:
<input id='someId' type='text' onkeypress='return check(this,event);'>
and the javascript:
function check(element,e) {
var acceptable = 'abcd12';
// now get what character was entered
// if it's in the list, return true
// if it's not in the list, return false
}
Generally, you would want to bind an onChange event handler to the input field like this:
jQuery('#someId').change(function() {
var acceptable = ['1', '2', 'a', 'b', 'y'];
var text = jQuery(this).val();
var allowed = true;
// Loop through each character in the string
var length = text.length;
for (var i = 0; i < length; i++) {
// This if condition is fulfilled if the character
// is not in the array of acceptable characters
if (jQuery.inArray(text[i], acceptable) != -1)
allowed = false;
}
if (allowed)
// The input is valid
else
// The input contains an unallowed character
});
IMPORTANT:
You always have to do server side verification of the data submitted via a form. Anyone can mess with the code in your script and the HTML code. There are many ways to send false data to your server, no matter what you do to prevent it. Therefore it is extremely important to always do server side verification, since the server environment is entirely in your control.
Side note
The onChange event handler only fires when the field loses focus. If this behaviour is undesirable for you, use this:
jQuery('#someId').on('change keypress paste focus textInput input',function(){
// The same code as above can be used here
}
See this link for more information on this.
If you create a variable chr with the character that was entered, then
acceptable.indexOf(chr) !== -1
will be true if the character is acceptable (in the string).
I'll propose a solution without regexes, although I don't understand that constraint.
Here is a logical proposal to validate your strings.
Take your input string, replace occurrences of each of the valid characters in it with '' (empty string), then just verify that the length is 0. If there are characters left (length > 0), validation doesn't pass.
Also note there are other ways of doing this. Modern browsers support the pattern attribute on text inputs, which will validate against a regex (which is trivial to write for this case).
Here is a demo of this in action.
HTML
<input type="text">
JavaScript
input = document.querySelector("input");
restrictChars(input, "abc");
function restrictChars(input, chars) {
input.addEventListener("keypress", function (e) {
e.preventDefault();
var character = String.fromCharCode(e.keyCode);
var isValid = chars.indexOf(character) != -1;
if (isValid) {
input.value += character;
}
});
}
Basically we prevent the default behaviour of the keypress event (to prevent typing) and use it to obtain the pressed key from the event.keyCode. Then, we test to see if that character is present in the chars parameter (without the use of unnecessary regex in my opinion), if it is, we simulate the normal behaviour by adding the character to the <input>'s value, if it's not, we do absolutely nothing, resulting in nothing getting typed.
Hope this helps!
I've made a small jQuery-based solution:
$(document).ready(function() {
$('#input').keypress(function(e) {
var allowed = '02468abc';
var e = e||window.event;
var k = e.keyCode||e.which;
var r = allowed.indexOf(String.fromCharCode(k))!=-1;
r = (k==8||(k>=35&&k<=40)||k==46)?true:r;
if(!r) {
e.returnValue = false;
if(e.preventDefault)
e.preventDefault();
}
});
});
Add the characters you want to pass inside the variable allowed, in this code, allowed characters are 0, 2, 4, 6, 8, a, b, and c.
Just make sure you have this in your HTML:
<input id="input" type="text"/>
You should be good to go using this.
If jQuery is not an option, leave a comment and I'll add some jQuery-less code.
Edit: Changed code to allow use of arrow keys, backspace, home, end, and delete.
Rou's code is clean, but keycode will always return capital letters. If you need this to be case-sensitive, keycode won't work.
I'm also assuming you always want to check the last character entered.
function check(e,element) {
var acceptable = 'abcd12';
var char = element.value.charAt(element.value.length - 1);
if(acceptable.indexOf(char)>=0){
document.getElementById("result").innerHTML="true";
}
else
{
document.getElementById("result").innerHTML="false";
}
}
var inputElement = document.getElementById('someId');
inputElement.addEventListener('keyup', function( e ) {
check( e, inputElement )
});
Here's the code in JSFiddle if you want to modify it: http://jsfiddle.net/hckytaez/4/
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
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);
});
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"/>.
I have a JavaScript function that validates an input field and prevents the user from typing anything that doesn't match the condition. This function is based on event.keyCode.
I'm trying to modify the function to use a RegExp and validates not "per character" but "per whole input" so that it does the same, but with different conditions:
numeric only
allowed decimal "." or ","
Here is the function in its current form, using event.keyCode:
function isNumeric(evt, alertDIVid, alertMsg) {
var charCode = (evt.which) ? evt.which : event.keyCode
if (charCode >= 48 && charCode <= 57) {
document.getElementById(alertDIVid).innerHTML = '';
return true;
}
else {
document.getElementById(alertDIVid).innerHTML = alertMsg;
return false;
}
}
document.getElementById('AMNT').onkeypress = function(event) {
event = event || window.event;
return isNumeric(event, 'numericalert', 'Numeric values only!')
};
In order to do the kind of validation you want, you need to listen to the keyup event instead. This event fires after the field is changed, so that you know the new value of the field. You also need to know the previous value of the field so you can "reset" it if what the user typed turns out to be invalid.
For example:
(function() {
var previousValue = document.getElementById('myInput').value;
var pattern = /^\d*((\.|,)\d*)?$/;
function validateInput(event) {
event = event || window.event;
var newValue = event.target.value || '';
if (newValue.match(pattern)) {
// Valid input; update previousValue:
previousValue = newValue;
} else {
// Invalid input; reset field value:
event.target.value = previousValue;
}
}
document.getElementById('myInput').onkeyup = validateInput;
}());
Working demo: http://jsfiddle.net/8kUdG/
It's worth noting that this will also validate empty strings, as well as unfinished numbers, like 5, or 42. (otherwise the user would have to insert the decimal sign after typing the decimals, which would be... weird).
And finally, keep in mind that this might not be a cross-browser safe solution. If you need a pure-JavaScript solution, you will need to refine it (i.e., this might not work in IE).
Edit: of course, showing an error message instead of resetting the input field to the previous value is also perfectly possible (updated JSFiddle):
(function() {
var pattern = /^(?=.)\d*(?:[.,]\d+)?$/;
var error = document.getElementById('error');
document.getElementById('myInput').onkeyup = function(event) {
event = event || window.event;
var newValue = event.target.value || '';
if (newValue.match(pattern)) {
error.innerHTML = '';
} else {
error.innerHTML = 'Not a valid number!';
}
};
}());
I leave it up to you to replace the alert with something more user-friendly.
The easiest solution would be something like this
// Returns true on valid, false on invalid
function myInputFilter(input)
{
var value = input.value;
var regex = /^[\d\,\.]*$/;
if(!regex.test(value))
return false;
return true;
}
You could edit the function to just take a string argument, but I've chosen to have it accept the text input element instead. The RegEx can be replaced by anything, I've made a simple one for this example. I would refine it a bit if I were you (You can use the excellent online tool RegExr)
Here is an example of the filter implemented
http://jsfiddle.net/kVV77/
You can use following regular expression:
/^[+-]?(?=.)(?:\d+,)*\d*(?:\.\d+)?$/
to allow only any number of comma and only one dot . with the condition that number cannot start with a comma. Number can have optional + or - at the start.