1

I'm using Knockout MVC im my project (ASP.NET MVC3, Razor). I can't find now to change decimal format. I want to use comma as a decimal separator. When I bind data using non-knockout Razor helper, it renders it correctly (with comma), but when I bind using Knockout binding it renders the number with the dot as comma separator.

How to change the decimal format that is would use comma?

Lukasz Lysik
  • 10,462
  • 3
  • 51
  • 72
  • Maybe this can help you: http://stackoverflow.com/questions/2901102/how-to-print-number-with-commas-as-thousands-separators-in-javascript – sphair Dec 03 '12 at 13:29
  • @sphair, thank you for this link. Is would help me if I exactly knew where the value is assigned to the control. It happens somewhere inside KnockoutJS code, but I don't know where (the code is too complicated for). – Lukasz Lysik Dec 03 '12 at 14:02
  • Sorry, I didn't catch that you were using Knockout MVC, thought it was plain Knockout. – sphair Dec 03 '12 at 14:05
  • Knockout MVC uses plain Knockout underneath. But still, I don't know how to do this. – Lukasz Lysik Dec 03 '12 at 15:34
  • please see my answer. was this the issue? if not, let me know - there may be other things to try. – Sethi Dec 04 '12 at 11:21

1 Answers1

8

You're looking at the differences between your server and client locale.

Your .NET code formats numbers with respect to the server locale whereas your JS code formats numbers with respect to the browsers locale.

Try changing the locale/region within your browser.

EDIT:

(I am leaving the above in case it helps anyone else, even though it did not help you)

The issue is your understanding of the differences between server-side and client-side.

Razor code is executed on the server and 'translated' into HTML.

Whereas, the server treats Javascript as text and just part of the HTML document it is sending.

Javascript is executed on the clients machine (i.e. the browser).

How the Razor Helper formats the number is based on the locale set on the server. Whereas, the javascript will format the number based on the locale set in the browser.

To force Knockout/Javascript to format the number how you want regardless of the locale (on the client-side), you can write a custom-binding using the following method at it's core:

function formatWithComma(x, precision, seperator) {
    var options = {
        precision: precision || 2,
        seperator: seperator || ','
    }
    var formatted = x.toFixed( options.precision );
    var regex = new RegExp('^(\\d+)[^\\d](\\d{' + options.precision + '})$');
    formatted = formatted.replace(regex, '$1' + options.seperator + '$2');
    return formatted;
}

So your binding will look something like this:

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

        var observable = valueAccessor();

        var interceptor = ko.computed(function() {
            return formatWithComma( observable() );
        }

        ko.applyBindingsToNode( element , { value: interceptor } );

    }
}

And then in your Razor view:

@ko.Bind.Custom("commaDecimalFormatter ", m => m.MyCustom)

(Please note, I've never used KnockoutMVC and so this last line is straight from the documentation with the binding name changed - it is untested.

Also, I have used a ko.computed and so this binding is read-only - using it on an <input> element will be pointless. It's better used on a <span>. You can make this a two-way binding implementing the reverse:

ko.computed( {
    read: function() {
        /* method as above */
    },
    write: function(newValue) {
        /* implement reverse */
        observable( newValue );
    }
}

EDIT 2

Hope this fiddle makes it clearer

Michael Gaskill
  • 7,913
  • 10
  • 38
  • 43
Sethi
  • 1,378
  • 8
  • 14
  • Hi! Thank you for the answer, but it's not the problem of locale/region in the browser. It is set correctly. Besides, on the same page I bind the same property using standard Razor helper and it works ok. – Lukasz Lysik Dec 04 '12 at 13:59
  • Hi! The first part helped indeed. Thanks! But unfortunately I'm total JavaScript dummy and I don't know how to implement code in the places you put comments in `ko.computed`. – Lukasz Lysik Dec 17 '12 at 10:47
  • i've added a link to a [fiddle](http://jsfiddle.net/rRaHm/2/). Does that make it any clearer? – Sethi Dec 17 '12 at 13:50