I would like to ask you is it possible to format dynamically input value?
So when I'm entering some value it will dynamically add commas to format currency.
For example I'm writing 1234 and it will be formatted to 1'234 dynamically.
If I delete one number it will be changed to 123.
I'm thinking about some custom binding. But is it possible to add a rule for every change?
Cheer
You can use bindinghandler for this and create a custom binding:
ko.bindingHandlers.numeric = {
update: function(element, valueAccessor, allBindingsAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
var positions= ko.utils.unwrapObservable(allBindingsAccessor().positions) || ko.bindingHandlers.numeric.defaultPositions;
var formattedValue = parseFloat(value).toFixed(positions);
var finalFormatted = ko.bindingHandlers.numeric.withCommas(formattedValue);
ko.bindingHandlers.text.update(element, function() { return finalFormatted; });
},
defaultPositions: 2,
withCommas: function(original){
original+= '';
x = original.split('.');
x1 = x[0];
x2 = x.length > 1 ? ',' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + '.' + '$2');
}
return x1 + x2;
}
};
Then if you bind your value to the element, you just use this binding instead of the normal text
binding:
<span data-bind="numeric: myNumericObservable"></span>
The custom binding handler above formats the value to the German value: 1.202,22
But you can easily change it by replacing the '.' and the ','.
By the way, here is a solution for numeric value bindings in input
-tags:
ko.bindingHandlers.numericValue = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
ko.utils.registerEventHandler(element, 'change', function (event) {
var observable = valueAccessor();
var positions= ko.utils.unwrapObservable(allBindingsAccessor().positions) || ko.bindingHandlers.numericValue.defaultPositions;
if(ko.utils.unwrapObservable(allBindingsAccessor().positions)==0){
positions=0;
}
if(isNaN(parseFloat($(element).val())))
observable(0);
else {
if(!ko.utils.unwrapObservable(allBindingsAccessor().noDecimalPoints))
observable(parseFloat($(element).val().replace(".","").replace(",",".")).toFixed(positions).replace(",","."));
else
observable(parseFloat($(element).val().replace(".","").replace(",",".")).toFixed(positions));
}
});
},
update: function(element, valueAccessor, allBindingsAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
if(value!=null) {
var positions= ko.utils.unwrapObservable(allBindingsAccessor().positions) || ko.bindingHandlers.numericValue.defaultPositions;
if(ko.utils.unwrapObservable(allBindingsAccessor().positions)==0){
positions=0;
}
var formattedValue = parseFloat(value).toFixed(positions);
var finalFormatted = formattedValue;
if(!ko.utils.unwrapObservable(allBindingsAccessor().noDecimalPoints))
finalFormatted = ko.bindingHandlers.numericValue.withCommas(formattedValue);
ko.bindingHandlers.value.update(element, function() { return finalFormatted; });
}
},
defaultPositions: 2,
noDecimalPoints:false,
withCommas: function(original){
original+= '';
x = original.split('.');
x1 = x[0];
x2 = x.length > 1 ? ',' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + '.' + '$2');
}
return x1 + x2;
}
};
You can use this as follows:
<input tabindex="10" data-bind="numericValue: myNumericObservable">
You can also configuarte it:
<input data-bind="numericValue: myNumericObservable, positions: 0, noDecimalPoints: true">
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With