Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic currency format on input field

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

like image 214
Kosmonaft Avatar asked Mar 19 '23 11:03

Kosmonaft


1 Answers

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">
like image 151
Jan Hommes Avatar answered Mar 28 '23 23:03

Jan Hommes