We can restrict user to input user more than two decimal number Ex. 23.81, 3452.83 Modified code is as below. The reference code is taken from the @Martin Surynek answer.
HTML -
<p>
<input data-bind="value: myNumberOne" /> (round to whole number)</p>
<p>
<input data-bind="num, value: myNumberTwo" /> (round to two decimals)</p>
Script -
<script>
ko.bindingHandlers.num = {
init: function (element, valueAccessor) {
$(element).on("keypress", function (event) {
//debugger
console.log(event.keyCode);
var $this = $(this);
var text = $this.val();
// Stop insert two dots
if ($this.val().indexOf('.') != -1 && (event.which == 190 || event.which == 110)) {
event.preventDefault();
}
// Allow: backspace, delete, tab, escape, and enter
if (event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 27 || event.keyCode ==
13 ||
// Allow: Ctrl+A
(event.keyCode == 65 && event.ctrlKey === true) ||
// Allow: . ,event.keyCode == 188 ||
( event.keyCode == 190 || event.keyCode == 110) ||
// Allow: home, end, left, right
(event.keyCode >= 35 && event.keyCode <= 39)) {
// let it happen, don't do anything
return;
}
// Ensure that it is a number and stop the keypress
if (event.shiftKey || (event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode >
105)) {
event.preventDefault();
}
if ((event.which == 46) && (text.indexOf('.') == -1)) {
setTimeout(function () {
if ($this.val().substring($this.val().indexOf('.')).length > 3) {
$this.val($this.val().substring(0, $this.val().indexOf('.') + 3));
}
}, 1);
}
if ((text.indexOf('.') != -1) &&
(text.substring(text.indexOf('.')).length > 2) &&
(event.which != 0 && event.which != 8) &&
($(this)[0].selectionStart >= text.length - 2)) {
event.preventDefault();
}
//console.log($(this)[0].selectionStart >= text.length - 2);
});
}
};
ko.extenders.numeric = function (target, precision) {
//create a writable computed observable to intercept writes to our observable
var result = ko.pureComputed({
read: target, //always return the original observables value
write: function (newValue) {
var current = target(),
roundingMultiplier = Math.pow(10, precision),
newValueAsNum = isNaN(newValue) ? 0 : parseFloat(+newValue),
valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;
//only write if it changed
if (valueToWrite !== current) {
target(valueToWrite);
} else {
//if the rounded value is the same, but a different value was written, force a notification for the current field
if (newValue !== current) {
target.notifySubscribers(valueToWrite);
}
}
}
}).extend({
notify: 'always'
});
//initialize with current value to make sure it is rounded appropriately
result(target());
//return the new computed observable
return result;
};
function AppViewModel(one, two) {
this.myNumberOne = ko.observable(one).extend({
numeric: 0
});
this.myNumberTwo = ko.observable(two).extend({
numeric: 2
});
}
ko.applyBindings(new AppViewModel(221.2234, 123.4525));
</script>
input type="text"
, what if you change it toinput type="number"
? I think those limit what you put into them to only numeric values. – Sapajou