Knockout bindingHandler for comma separated numbers with same entry again in a textbox
Asked Answered
P

1

1

I needed to create a Knockout bindingHandler which would format the amount to comma separated numbers. After a little searching I found the solution here (Thanks to @nemesv for the solution) which uses http://numeraljs.com/ for the conversion.

the binder is as follows:

ko.bindingHandlers.formatMoney = {
  init: function(element, valueAccessor) {

    var value = valueAccessor();

    var interceptor = ko.computed({
        read: function() {
            return numeral(ko.unwrap(value)).format('0,0.00');
        },
        write: function(newValue) {
            if($.trim(newValue) == '')
                value("0");
            else
                value(numeral().unformat(newValue));
        }
    }).extend({ notify: 'always' });

    if(element.tagName.toLowerCase() == 'input' )
        ko.applyBindingsToNode(element, {
            value: interceptor
        });
    else
        ko.applyBindingsToNode(element, {
            text: interceptor
        });
  }
}

I used it and it works perfectly in normal cases. But I need to fix it when using it with textbox.

The issue is that an observable is being used which are normally only notified if the value actually changed. So the actual formater is applied if I type a different value every time. So for example

  • if I type 1234 for the first time and textbox loses focus, it gets converted to 1,234.00.
  • now if you type 1234 again in the textbox. it does not work and the binder's read method is not called.

What do I have to do to make the interceptor's read method fire everytime even if the observable has the same value.?

Sample Fiddle: http://jsfiddle.net/vEcSq/4/

Thanks.

Perversion answered 22/5, 2014 at 9:53 Comment(0)
D
3

You can use the valueHasMutated function on the observable to alert subscribers that it has changed, even if it hasn't. In the write function on the interceptor, add the following line as the last line of the function.

value.valueHasMutated();

I have updated your jsfiddle with the call and it seems to be working correctly.

Dwaynedweck answered 22/5, 2014 at 10:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.