Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding decimal formatting to Knockout number data bindings

Tags:

knockout.js

I am using knockout to populate number values inside a table:

HTML:

<tbody data-bind="foreach: commision">
             <tr>
                 <td>
                    <span>R </span><span data-bind="text: Amount"></span>
                 </td>
             </tr>...
</tbody>

Knockout.js part pertaining to amount and commision

 var vm = {
            commision: ko.observable(),
            futurecommision: ko.observable(),
            commisionpaid: ko.observable(),
            totals: ko.observable(),
            commisionPaid: ko.observable(ko.utils.unwrapObservable(ko.mapping.fromJS({
                Date: null,
                Amount: 0
            }))),
...

Now how do i show the number being populated in decimal fomat, say .00 ? eg. 10.00

Currently it is only showing the number, eg 10

like image 328
DextrousDave Avatar asked Apr 15 '13 07:04

DextrousDave


2 Answers

Have a look at this KO Money Extender:

http://jsfiddle.net/digitalbush/R6MPU/

(function(){
    var format = function(value) {
        toks = value.toFixed(2).replace('-', '').split('.');
        var display = '$' + $.map(toks[0].split('').reverse(), function(elm, i) {
            return [(i % 3 === 0 && i > 0 ? ',' : ''), elm];
        }).reverse().join('') + '.' + toks[1];

        return value < 0 ? '-' + display : display;
    };

ko.subscribable.fn.money = function() {
    var target = this;

    var writeTarget = function(value) {
        var stripped=value
            .replace(/[^0-9.-]/g, '');

        target(parseFloat(stripped));
    };

    var result = ko.computed({
        read: function() {
            return target();
        },
        write: writeTarget
    });

    result.formatted = ko.computed({
        read: function() {
            return format(target());
        },
        write: writeTarget
    });

    result.isNegative = ko.computed(function(){
        return target()<0;
    });

    return result;
};
})();

//Wire it up
$(function() {
    var viewModel = {
        Cash: ko.observable(-1234.56).money(),
        Check: ko.observable(2000).money(),
        showJSON: function() {
            alert(ko.toJSON(viewModel));
        }
    };


    viewModel.Total = ko.computed(function() {
        return this.Cash() + this.Check();
    }, viewModel).money();
    ko.applyBindings(viewModel);
});
like image 56
David Van Staden Avatar answered Oct 06 '22 22:10

David Van Staden


You could look into writing a custom extender to handle this.

A basic extender is something like:

ko.extenders.numeric = function(target, precision) {
    var result = ko.computed({
        read: function() {
            return target().toFixed(precision); 
        },
        write: target 
    });

    result.raw = target;
    return result;
};

This is then used on your observables like:

var commissionPaid = ko.observable(whatever your value is).extend({numeric: 2});
like image 40
Thewads Avatar answered Oct 06 '22 23:10

Thewads