0

I want to format numbers in a comma separated fashion. I have found this jsfiddle which caters to my requirement. I need to add another pureComputed value for my vm, and I tried it with this way by modifing modified jsfiddle.

However, I'm getting an error in console saying:

Unable to process binding "text: function (){return Test }" Message: undefined is not a function.

What am I missing here? my js is

(function ($) {
var cleanInput = function (value) {
    return parseFloat(value.replace(/[^0-9.-]/, ''));
}

var formatInput = 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.bindingHandlers.money = {
    init: function (elm, valueAccessor) {
        $(elm).change(function () {
            valueAccessor()(cleanInput(elm.value));
        }).addClass('money');
    },
    update: function (elm, valueAccessor, allBindingsAccessor) {
        var value =ko.utils.unwrapObservable(valueAccessor())
        $elm = $(elm),
        method = $elm.is(":input") ? "val" : "html";

        $elm[method](formatInput(value)).toggleClass('negative', value < 0);
    }
};})(jQuery);


$(function(){
var viewModel={
    Cash:ko.observable(1234.56),
    Test : ko.pureComputed(function() {
        return (self.Cash() * 10).toFixed(0);
    })
}
ko.applyBindings(viewModel);

});

Rifky
  • 1,444
  • 11
  • 26
  • Please include a minimal version of that sample code in the question as well. That way, if the link rots, this question will remain useful to future visitors. – Jeroen Dec 15 '14 at 07:16

1 Answers1

1

Your view model definition is worng: there is no self defined anywhere in your code.

You need to turn your viewmodel into a constructor function where you can define now the self to point to the this

var ViewModel = function() {
    var self = this;
    self.Cash = ko.observable(1234.56);
    self.Test = ko.pureComputed(function() {
        return (self.Cash() * 10).toFixed(0);
    });
}
ko.applyBindings(new ViewModel());

Demo JSFiddle.

In you want to keep the object literal as your viewmodel you need to add the computed after you've created the viewmodel:

var viewModel = {
    Cash: ko.observable(1234.56)
}
viewModel.Test = ko.pureComputed(function () {
    return (ViewModel.Cash() * 10).toFixed(0);
});
ko.applyBindings(viewModel);

Demo JSFiddle.

See also: Difference between knockout View Models declared as object literals vs functions

Community
  • 1
  • 1
nemesv
  • 138,284
  • 16
  • 416
  • 359
  • it works, but when i want to display ```Test``` in ```money``` format, by changing `````` to `````` i'm getting the same error. pls find the updated JSfiddle. http://jsfiddle.net/r51ybL13/2/ – Rifky Dec 15 '14 at 07:57
  • Your computed returns a string so the `value.toFixed(2).replace('-', '').split('.')` fails in the format input. Either return a number from your computed `return (self.Cash() * 10);` http://jsfiddle.net/mhbq49km/. Or handle the case of `value` being a string in the `formatInput` function – nemesv Dec 15 '14 at 08:14