I have a text input where I want it to format while typing a value allowing 2 decimal places and 1000 separators. It should only allow digits. I have done the following but
You can limit the keys in the keydown
event instead of keyup
and allow specific keys to take effect, and then format the input on keyup
event:
$("#testinput").on("keydown", function(e) {
var keycode = (event.which) ? event.which : event.keyCode;
if (e.shiftKey == true || e.ctrlKey == true) return false;
if ([8, 110, 39, 37, 46].indexOf(keycode) >= 0 || // allow tab, dot, left and right arrows, delete keys
(keycode == 190 && this.value.indexOf('.') === -1) || // allow dot if not exists in the value
(keycode == 110 && this.value.indexOf('.') === -1) || // allow dot if not exists in the value
(keycode >= 48 && keycode <= 57) || // allow numbers
(keycode >= 96 && keycode <= 105)) { // allow numpad numbers
// check for the decimals after dot and prevent any digits
var parts = this.value.split('.');
if (parts.length > 1 && // has decimals
parts[1].length >= 2 && // should limit this
(
(keycode >= 48 && keycode <= 57) || (keycode >= 96 && keycode <= 105)
) // requested key is a digit
) {
return false;
} else {
if (keycode == 110) {
this.value += ".";
return false;
}
return true;
}
} else {
return false;
}
}).on("keyup", function() {
var parts = this.value.split('.');
parts[0] = parts[0].replace(/,/g, '').replace(/^0+/g, '');
if (parts[0] == "") parts[0] = "0";
var calculated = parts[0].replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,");
if (parts.length >= 2) calculated += "." + parts[1].substring(0, 2);
this.value = calculated;
if (this.value == "NaN" || this.value == "") this.value = 0;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="testinput">
My solution uses successive .replace
.replace(/(?!\.)\D/g, "")
deletes all non numeric characters except .
.replace(/(?<=\..*)\./g, "")
removes all extra .
except the first .
.replace(/(?<=\.\d\d).*/g, "")
deletes everything after 2 decimal places .replace(/\B(?=(\d{3})+(?!\d))/g, ",")
inserts commas at appropriate placesI have modified the event to account for all changes to input field as .on('change click keyup input paste'
Snippet:
$('#price').on('change click keyup input paste',(function (event) {
$(this).val(function (index, value) {
return '$' + value.replace(/(?!\.)\D/g, "").replace(/(?<=\..*)\./g, "").replace(/(?<=\.\d\d).*/g, "").replace(/\B(?=(\d{3})+(?!\d))/g, ",");
});
}));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="text" id="price" name="price" />
$('#price').on('keyup click change paste input', function (event) {
$(this).val(function (index, value) {
if (value != "") {
//return '$' + value.replace(/\D/g, "").replace(/\B(?=(\d{3})+(?!\d))/g, ",");
var decimalCount;
value.match(/\./g) === null ? decimalCount = 0 : decimalCount = value.match(/\./g);
if (decimalCount.length > 1) {
value = value.slice(0, -1);
}
var components = value.toString().split(".");
if (components.length === 1)
components[0] = value;
components[0] = components[0].replace(/\D/g, '').replace(/\B(?=(\d{3})+(?!\d))/g, ',');
if (components.length === 2) {
components[1] = components[1].replace(/\D/g, '').replace(/^\d{3}$/, '');
}
if (components.join('.') != '')
return '$' + components.join('.');
else
return '';
}
});
});