I currently working on some regex logic to enforce the input of field to ONLY accept (replace/display) a number (no alpha characters) and enforce a 2 decimal place limit...
I"m not sure how I can make this more efficient, and also add in the (max) 2 decimal place limit/restriction?
Here is my current on keyup() function
$("#amount").on("keyup", function(){
var valid = /^\d{0,9}(\.\d{0,2})?$/.test(this.value);
val = this.value;
if(!valid){
console.log('bad character found');
//strip out commas
this.value = val.replace(/,/g , "");
//strip out all non-numeric characters (leaving decimal)
//this.value = val.replace(/[^\d.-]/g, "");
this.value = val.replace(/[^0-9.]/g, "");
//enforce only (max) 2 decimal places
}
});
I was originally using this, but it is FLAWED (if you go back and add in a comma into the current/existing number, it removes the last digit/character in the field.. (even though that is not the offending character)
var valid = /^\d{0,9}(\.\d{0,2})?$/.test(this.value);
val = this.value;
if(!valid){
//console.log("Invalid input!");
this.value = val.substring(0, val.length - 1);
}
To be clear...
The value DOES NOT have to have a decimal, and forced 2 digits after said decimal point.. but if there IS one.. I need to enforce a 2 character limit after decimal point..
update 1:
ok.. so I have things 'close' (although one line of REGEX would be nice!)
My last 'to-do' item.. is to somehow enforce (if there is a 'dot'... that it only has 2 decimal places after it..... although a dot/decimal is -not- required)
$("#amount").on("keyup", function(){
var valid = /^\d{0,9}(\.\d{0,2})?$/.test(this.value);
val = this.value;
console.log("ORIGINAL VAL: " + val);
if(!valid){
console.log('bad character found');
var dotCheck = val.indexOf("..");
if(dotCheck >= 0){
console.log('DOT CHECK: ' + dotCheck);
console.log("PRE VAL: " + val);
val = val.replace("..", "?");
console.log("POST VAL: " + val);
}
//strip out commas
val = val.replace(/,/g , "");
console.log("AFTER COMMA VAL: " + val);
//strip out all non-numeric characters (leaving decimal)
val = val.replace(/[^0-9.]/g, "");
console.log("AFTER CHAR VAL: " + val);
//output to field
this.value = val;
}
});
update final:
(final working solution)... still checking out the regex solution posted below...
no more than 2 digits after decimal point
$("#amount").on("keyup", function(){
var valid = /^\d{0,9}(\.\d{0,2})?$/.test(this.value);
val = this.value;
if(!valid){
var dotCheck = val.indexOf("..");
if(dotCheck >= 0){
val = val.replace("..", ".");
}
//strip out commas
val = val.replace(/,/g , "");
//strip out all non-numeric characters (leaving decimal)
val = val.replace(/[^0-9.]/g, "");
//enforce 2 decimal places (max)
var totalLength = val.length;
var only2DecimalsCount = val.indexOf(".");
if(only2DecimalsCount >= 0 && totalLength > (only2DecimalsCount + 2)){
val = val.substring(0, (only2DecimalsCount + 3));
}
//output to field
this.value = val;
}
});
EDIT: I found that this does NOT handle something likeL
1.9.9 (bummer)
Here is a modified version of your final edit... I added a line to check for the situation: 1.2.3 and replace it with a pattern to remove the second dot. Did it without a look behind because it may not be supported. Here is the line: val = val.replace(/(\.)(.)(\.)/g, ".$2");
The ".$2"
will replace the .#. with a dot and the pattern group that is the wildcard (.) in this case. Your other check at the bottom will catch a double dot ".." situation.
$("#amount").on("keyup", function () {
var valid = /^\d{0,9}(\.\d{0,2})?$/.test(this.value);
val = this.value;
console.log("ORIGINAL VAL: " + val);
if (!valid) {
var dotCheck = val.indexOf("..");
if (dotCheck >= 0) {
val = val.replace("..", ".");
}
val = val.replace(/(\.)(.)(\.)/g, ".$2");
//strip out commas
val = val.replace(/,/g, "");
//strip out all non-numeric characters (leaving decimal)
val = val.replace(/[^0-9.]/g, "");
//enforce 2 decimal places (max)
var totalLength = val.length;
var only2DecimalsCount = val.indexOf(".");
if (only2DecimalsCount >= 0 && totalLength > (only2DecimalsCount + 2)) {
val = val.substring(0, (only2DecimalsCount + 3));
}
//output to field
this.value = val;
}
});
EDIT: Fixed new line by adding parenthesis. Explanation: Parenthesis "groups" the pieces of the pattern together (1-based index). So the new linehas 3 groups - (\.)- 1, (.)- 2, (\.)- 3
. Replacing with $2
will call group #2 which in this case is the wildcard.