user3378165 user3378165 - 1 month ago 6
Javascript Question

Display $ sign in observable fields Knocout

On my MVC project I have a View with 3 calculators, each calculator has its own form and I have one View Model for all the 3 forms, the View Model contains multiple computed fields and the fields depends each other.

I'm looking for the way to add a $ sign to all fields, I just need it to display it to the client and then to get rid of it in the javascript/KO code (I can't do the calculations on the computed fields with a $ sign).

I wrote the following function:

this.formatCurrency = function (value) {
if (value && value !== "") {
value = value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return "$" + value;
}
}


But then I have to call this function from every single field:

<span data-bind='text: formatCurrency(improvements())'>


And also to remove the $ sign before any calculations on the computed.

Does anyone has a better idea of how to do that? I didn't come up with anything..

Answer

Thanks to @user3297291 's answer I got an idea of how to do it.

I have the following bindingHandler to handle my numeric values:

ko.bindingHandlers.numValue = {
init: function (element, valueAccessor) {
    function numValueHandler() {
        valueAccessor()(this.value);
    }
    $(element).on("input change", numValueHandler)
              .val(ko.unwrap(valueAccessor()));
    ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
        $(element).off("input change", numValueHandler);
    });
},
update: function (element, valueAccessor) {
    element.value =ko.unwrap(valueAccessor());
}
};

I added this line to remove the $ sign when I get the value:

parseFloat(("" + this.value).replace(/[^\.\d]/g, ""))

And added a $ sign before sending it back to the View:

 element.value ='$' + ko.unwrap(valueAccessor());

So the entire bindingHandler looks like this:

ko.bindingHandlers.numValue = {
init: function (element, valueAccessor) {
    function numValueHandler() {
        valueAccessor()(parseFloat(("" + this.value).replace(/[^\.\d]/g, "")));
    }
    $(element).on("input change", numValueHandler)
              .val(ko.unwrap(valueAccessor()));
    ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
        $(element).off("input change", numValueHandler);
    });
},
update: function (element, valueAccessor) {
    element.value ='$' + ko.unwrap(valueAccessor());
}
};

And the calls are:

<input type="text" data-bind="numValue: improvements" />
<input type="text" data-bind="numValue: improvements2" />
//etc..

That's working perfectly, without having to call the formatCurrency function on each field and with a few lines of code.

Thank you @user3297291 for your help!

Comments