Search code examples
javascript-globalize

Proper way of extending in Globalize 1.x


I had the following code to add custom functionality via Globalize 0.x:

Globalize.parseFloatAcceptDotAndComma =
    function (value, radix, cultureSelector) {
        value = value.replace(Globalize.locale(lang).numberFormat['.'] === '.' ? ',' : '.', Globalize.locale(lang).numberFormat['.']);
                return Globalize.parseFloat.call(this, value, radix, cultureSelector);
}

Since Globalize 1.x plugin's API is different, I'm eager to know how to achieve the same result in new version of the plugin?

Thanks.

BTW, I've included this method into "then" chain, after "then(Globalize.load)" - is it a proper way to go?

UPDATE: final working version - thanks to @rxaviers

    var lang = '@Thread.CurrentThread.CurrentUICulture.Name';

    Promise.all([
      // Core
      fetch('/Scripts/cldr/supplemental/likelySubtags.json'),

      // Date
      fetch('/Scripts/cldr/main/' + lang + '/ca-gregorian.json'),
      fetch('/Scripts/cldr/main/' + lang + '/timeZoneNames.json'),
      fetch('/Scripts/cldr/supplemental/timeData.json'),
      fetch('/Scripts/cldr/supplemental/weekData.json'),

      // Number
      fetch('/Scripts/cldr/main/' + lang + '/numbers.json'),
      fetch('/Scripts/cldr/supplemental/numberingSystems.json')
    ])
    .then(function(responses) {
        return Promise.all(responses.map(function(response) {
            return response.json();
        }));
    })
    .then(Globalize.load)
    .then(function () {
            Globalize.parseFloatAcceptDotAndComma =
            Globalize.prototype.parseFloatAcceptDotAndComma = function(value, options) {
            // Assert that value and options are valid.
            // Assert that this.cldr is present

            if (value.indexOf('.') >= 0 && value.indexOf(',') >= 0) {
                throw new Error('Both separators are present');
            }

            value = value.replace(/[,.]/, this.cldr.main('numbers/symbols-numberSystem-latn/decimal'));
            return this.parseNumber(value, options);
        }
    })
    .then(function() { Globalize.locale(lang); });

Solution

  • Note your solution won't handle Arabic and other languages that uses different digits than latin. Therefore, I don't recommend it. I believe there should be a better algorithm than this one.

    For general purposes of showing how to extend the Globalize class, here we go:

    First, make sure you have included the core and number modules. Then, you can:

    Globalize.parseFloatAcceptDotAndComma =
    Globalize.prototype.parseFloatAcceptDotAndComma = function( value, options ) {
        // Assert that value and options are valid.
        // Assert that this.cldr is present
    
        // I guess you should throw when both . and , are present.
        if ( value.indexOf( "." ) >= 0 && value.indexOf( "," ) >= 0 ) {
            throw new Error("Whops");
        }
    
        // Important:
        // Note your solution won't handle Arabic and other languages that
        // uses different digits than latin. Therefore, I DO NOT personally
        // recommend it.
    
        value = value.replace( /[,.]/, this.cldr.main( "numbers/symbols-numberSystem-latn/decimal" ));
        return this.parseNumber( value, options );
    };
    

    You will be able to use it like:

    Globalize.locale( "en" );
    Globalize.parseFloatAcceptDotAndComma( "3,14" );
    
    // Or
    var en = new Globalize( "en" );
    en.parseFloatAcceptDotAndComma( "3,14" );