views:

173

answers:

1

I've seen this format function referenced on several sites, but none of them have an explicit example of how to pass in a number into the function.

I've tried '12345'.format('0.00') which I believe is how it should be written, but it gives me the error that the object doesn't support the property or method. I've also tried Number('12345').format('0.00'); var num = '12345' // num.format('0.00'); format('0.00','12345') and have even tried using numbers instead of strings 12345.format(0.00). Am I missing something really obvious here?

Included copy of function for reference so you don't have to go to the site (with all missing pieces filled in).

/**
 * I ♥ Google
 */
String.prototype.stripNonNumeric = function() {
    var str = this + '';
    var rgx = /^\d|\.|-$/;
    var out = '';
    for( var i = 0; i < str.length; i++ ) {
        if( rgx.test( str.charAt(i) ) ) {
            if( !( ( str.charAt(i) == '.' && out.indexOf( '.' ) != -1 ) ||
            ( str.charAt(i) == '-' && out.length != 0 ) ) ) {
                out += str.charAt(i);
            }
        }
    }
    return out;
};

/**
 * Formats the number according to the 'format' string; adherses to the american number standard where a comma is inserted after every 3 digits.
 *  note: there should be only 1 contiguous number in the format, where a number consists of digits, period, and commas
 *        any other characters can be wrapped around this number, including '$', '%', or text
 *        examples (123456.789):
 *          '0' - (123456) show only digits, no precision
 *          '0.00' - (123456.78) show only digits, 2 precision
 *          '0.0000' - (123456.7890) show only digits, 4 precision
 *          '0,000' - (123,456) show comma and digits, no precision
 *          '0,000.00' - (123,456.78) show comma and digits, 2 precision
 *          '0,0.00' - (123,456.78) shortcut method, show comma and digits, 2 precision
 *
 * @method format
 * @param format {string} the way you would like to format this text
 * @return {string} the formatted number
 * @public
 */
Number.prototype.format = function(format) {
    if (!(typeof format == "string")) {return '';} // sanity check

    var hasComma = -1 < format.indexOf(','),
        psplit = format.stripNonNumeric().split('.'),
        that = this;

    // compute precision
    if (1 < psplit.length) {
        // fix number precision
        that = that.toFixed(psplit[1].length);
    }
    // error: too many periods
    else if (2 < psplit.length) {
        throw('NumberFormatException: invalid format, formats should have no more than 1 period: ' + format);
    }
    // remove precision
    else {
        that = that.toFixed(0);
    }

    // get the string now that precision is correct
    var fnum = that.toString();

    // format has comma, then compute commas
    if (hasComma) {
        // remove precision for computation
        psplit = fnum.split('.');

        var cnum = psplit[0],
            parr = [],
            j = cnum.length,
            m = Math.floor(j / 3),
            n = cnum.length % 3 || 3; // n cannot be ZERO or causes infinite loop

        // break the number into chunks of 3 digits; first chunk may be less than 3
        for (var i = 0; i < j; i += n) {
            if (i != 0) {n = 3;}
            parr[parr.length] = cnum.substr(i, n);
            m -= 1;
        }

        // put chunks back together, separated by comma
        fnum = parr.join(',');

        // add the precision back in
        if (psplit[1]) {fnum += '.' + psplit[1];}
    }

    // replace the number portion of the format with fnum
    return format.replace(/[\d,?\.?]+/, fnum);
};
+1  A: 

That is not the complete code - it's missing isType and stripNonNumeric methods. But anyways, since it's an extension on the Number objects itself, you can use it as:

(42).format('0.00');

or

var a = 42;
a.format('0.00');

'12345'.format('0.00') will not work as '12345' here is a string, but the method has been defined for a Number only.

See this question for why you need to enclose the number within parentheses, and ways you can get past it without using them, though I wouldn't recommend it - cause of all these rumors about maintenance programmers and axes and stuff. I'm not saying every maintenance programmer carries one in their backpacks, but why take chances. They loving hacking too but not with code.. hahahaha

Anurag
Actually you don't have to enclose the number in parentheses - you just need to leave a space between the number and the dot. This way the interpreter doesn't take the dot as the fraction separator but as a dot-operator. `42 .format('0.00')`
Andris
Yep, but I don't like it :) See the attached question - http://stackoverflow.com/questions/2726590/call-methods-on-native-javascript-types-without-wrapping-with for more details on this.
Anurag
I did notice that it was incomplete after reviewing it again. I don't understand how so many people on the net claimed this worked for them... but anyway, you answered my main question quite clearly. Thanks! A pity I can't get the function to work though.
George
googled stripNonNumeric and found something. isType is a waste - just check with typeof format == "string". See working example here - http://jsfiddle.net/CEGXX/. Updating your question with the complete code.
Anurag
the above link has some bugs. this is better http://jsfiddle.net/CEGXX/2/
Anurag
Awesome! I was about to just reply that I found similar code on google, but was having trouble outputting the decimals, but your second code works like a charm! thanks so much!
George
You're welcome. Glad you found it helpful!
Anurag