Common class accounting. js for javascript digital formatting

Source: Internet
Author: User
Tags number strings

Code content and
The accounting. js code is as follows: Copy codeThe Code is as follows :/*!
* Accounting. js v0.3.2
* Copyright 2011, Joss Crowcroft
*
* Freely distributable under the MIT license.
* Portions of accounting. js are wrongly red or borrowed from underscore. js
*
* Full details and documentation:
* Http://josscrowcroft.github.com/accounting.js/
*/
(Function (root, undefined ){
/* --- Setup ---*/
// Create the local library object, to be exported or referenced globally later
Var lib = {};
// Current version
Lib. version = '0. 3.2 ';
/* --- Exposed settings ---*/
// The library's settings configuration object. Contains default parameters
// Currency and number formatting
Lib. settings = {
Currency :{
Symbol: "$", // default currency symbol is '$'
Format: "% s % v", // controls output: % s = symbol, % v = value (can be object, see docs)
Decimal: ".", // decimal point separator
Thousand: ",", // thousands separator
Precision: 2, // decimal places
Grouping: 3 // digit grouping (not implemented yet)
},
Number :{
Precision: 0, // default precision on numbers is 0
Grouping: 3, // digit grouping (not implemented yet)
Thousand :",",
Decimal :"."
}
};
/* --- Internal Helper Methods ---*/
// Store reference to possibly-available ECMAScript 5 methods for later
Var nativeMap = Array. prototype. map,
NativeIsArray = Array. isArray,
ToString = Object. prototype. toString;
/**
* Tests whether supplied parameter is a string
* From underscore. js
*/
Function isString (obj ){
Return !! (Obj = ''| (obj & obj. charCodeAt & obj. substr ));
}
/**
* Tests whether supplied parameter is a string
* From underscore. js, delegates to ECMA5's native Array. isArray
*/
Function isArray (obj ){
Return nativeIsArray? NativeIsArray (obj): toString. call (obj) = '[object Array]';
}
/**
* Tests whether supplied parameter is a true object
*/
Function isObject (obj ){
Return obj & toString. call (obj) = '[object Object]';
}
/**
* Extends an object with a defaults object, similar to underscore's _. defaults
*
* Used for processing acting parameter handling from API methods
*/
Function defaults (object, defs ){
Var key;
Object = object || {};
Defs = defs | {};
// Iterate over object non-prototype properties:
For (key in defs ){
If (defs. hasOwnProperty (key )){
// Replace values with defaults only if undefined (allow empty/zero values ):
If (object [key] = null) object [key] = defs [key];
}
}
Return object;
}
/**
* Implementation of 'array. map () 'for iteration loops
*
* Returns a new Array as a result of calling 'iterator' on each array value.
* Defers to native Array. map if available
*/
Function map (obj, iterator, context ){
Var results = [], I, j;
If (! Obj) return results;
// Use native. map method if it exists:
If (nativeMap & obj. map === nativeMap) return obj. map (iterator, context );
// Fallback for native. map:
For (I = 0, j = obj. length; I <j; I ++ ){
Results [I] = iterator. call (context, obj [I], I, obj );
}
Return results;
}
/**
* Check and normalise the value of precision (must be positive integer)
*/
Function checkPrecision (val, base ){
Val = Math. round (Math. abs (val ));
Return isNaN (val )? Base: val;
}
/**
* Parses a format string or object and returns format obj for use in rendering
*
* 'Format' is either a string with the default (positive) format, or object
* Containing 'pos' (required), 'neg' and 'zero 'values (or a function returning
* Either a string or object)
*
* Either string or format. pos must contain "% v" (value) to be valid
*/
Function checkCurrencyFormat (format ){
Var defaults = lib. settings. currency. format;
// Allow function as format parameter (shocould return string or object ):
If (typeof format = "function") format = format ();
// Format can be a string, in which case 'value' ("% v") must be present:
If (isString (format) & format. match ("% v ")){
// Create and return positive, negative and zero formats:
Return {
Pos: format,
Neg: format. replace ("-", ""). replace ("% v", "-% v "),
Zero: format
};
// If no format, or object is missing valid positive value, use defaults:
} Else if (! Format |! Format. pos |! Format. pos. match ("% v ")){
// If defaults is a string, casts it to an object for faster checking next time:
Return (! IsString (defaults ))? Defaults: lib. settings. currency. format = {
Pos: defaults,
Neg: defaults. replace ("% v", "-% v "),
Zero: defaults
};
}
// Otherwise, assume format was fine:
Return format;
}
/* --- API Methods ---*/
/**
* Takes a string/array of strings, removes all formatting/cruft and returns the raw float value
* Alias: accounting. 'parse (string )'
*
* Decimal must be encoded in the regular expression to match floats (defaults
* Accounting. settings. number. decimal), so if the number uses a non-standard decimal
* Separator, provide it as the second argument.
*
* Also matches bracketed negatives (eg. "$ (1.99)" =>-1.99)
*
* Doesn't throw any errors ('nan's become 0) but this may change in future
*/
Var unformat = lib. unformat = lib. parse = function (value, decimal ){
// Recursively unformat arrays:
If (isArray (value )){
Return map (value, function (val ){
Return unformat (val, decimal );
});
}
// Fails silently (need decent errors ):
Value = value | 0;
// Return the value as-is if it's already a number:
If (typeof value = "number") return value;
// Default decimal point comes from settings, but cocould be set to eg. "," in opts:
Decimal = decimal | lib. settings. number. decimal;
// Build regex to strip out everything blocks t digits, decimal point and minus sign:
Var regex = new RegExp ("[^ 0-" + decimal + "]", ["g"]),
Unformatted = parseFloat (
("" + Value)
. Replace (/\ (. *) \)/, "-$1") // replace bracketed values with negatives
. Replace (regex, '') // strip out any cruft
. Replace (decimal, '.') // make sure decimal point is standard
);
// This will fail silently which may cause trouble, let's wait and see:
Return! IsNaN (unformatted )? Unformatted: 0;
};
/**
* Implementation of toFixed () that treats floats more like decimals
*
* Fixes binary rounding issues (eg. (0.615). toFixed (2) = "0.61") that present
* Problems for accounting-and finance-related software.
*/
Var toFixed = lib. toFixed = function (value, precision ){
Precision = checkPrecision (precision, lib. settings. number. precision );
Var power = Math. pow (10, precision );
// Multiply up by precision, round accurately, then divide and use native toFixed ():
Return (Math. round (lib. unformat (value) * power)/power). toFixed (precision );
};
/**
* Format a number, with comma-separated thousands and custom precision/decimal places
*
* Localise by overriding the precision and thousand/decimal separators
* 2nd parameter 'height' can be an object matching 'settings. number'
*/
Var formatNumber = lib. formatNumber = function (number, precision, thousand, decimal ){
// Resursively format arrays:
If (isArray (number )){
Return map (number, function (val ){
Return formatNumber (val, precision, thousand, decimal );
});
}
// Clean up number:
Number = unformat (number );
// Build options object from second param (if object) or all params, extending defaults:
Var opts = defaults (
(IsObject (precision )? Precision :{
Precision: precision,
Thousand: thousand,
Decimal: decimal
}),
Lib. settings. number
),
// Clean up precision
UsePrecision = checkPrecision (opts. precision ),
// Do some calc:
Negative = number <0? "-":"",
Base = parseInt (toFixed (Math. abs (number | 0), usePrecision), 10) + "",
Mod = base. length> 3? Base. length % 3: 0;
// Format the number:
Return negative + (mod? Base. substr (0, mod) + opts. thousand: "") + base. substr (mod). replace (/(\ d {3 })(? = \ D)/g, "$1" + opts. thousand) + (usePrecision? Opts. decimal + toFixed (Math. abs (number), usePrecision). split ('.') [1]: "");
};
/**
* Format a number into currency
*
* Usage: accounting. formatMoney (number, symbol, precision, thousandsSep, decimalSep, format)
* Defaults: (0, "$", 2, ".", "% s % v ")
*
* Localise by overriding the symbol, precision, thousand/decimal separators and format
* Second param can be an object matching 'settings. currency 'which is the easiest way.
*
* To do: tidy up the parameters
*/
Var formatMoney = lib. formatMoney = function (number, symbol, precision, thousand, decimal, format ){
// Resursively format arrays:
If (isArray (number )){
Return map (number, function (val ){
Return formatMoney (val, symbol, precision, thousand, decimal, format );
});
}
// Clean up number:
Number = unformat (number );
// Build options object from second param (if object) or all params, extending defaults:
Var opts = defaults (
(IsObject (symbol )? Symbol :{
Symbol: symbol,
Precision: precision,
Thousand: thousand,
Decimal: decimal,
Format: format
}),
Lib. settings. currency
),
// Check format (returns object with pos, neg and zero ):
Formats = checkCurrencyFormat (opts. format ),
// Choose which format to use for this value:
UseFormat = number> 0? Formats. pos: number <0? Formats. neg: formats. zero;
// Return with currency symbol added:
Return useFormat. replace ('% s', opts. symbol ). replace ('% V', formatNumber (Math. abs (number), checkPrecision (opts. precision), opts. thousand, opts. decimal ));
};
/**
* Format a list of numbers into an accounting column, padding with whitespace
* To line up currency symbols, thousand separators and decimals places
*
* List shoshould be an array of numbers
* Second parameter can be an object containing keys that matches the params
*
* Returns array of accouting-formatted number strings of same length
*
* NB: 'white-space: pre' CSS rule is required on the list container to prevent
* Browsers from collapsing the whitespace in the output strings.
*/
Lib. formatColumn = function (list, symbol, precision, thousand, decimal, format ){
If (! List) return [];
// Build options object from second param (if object) or all params, extending defaults:
Var opts = defaults (
(IsObject (symbol )? Symbol :{
Symbol: symbol,
Precision: precision,
Thousand: thousand,
Decimal: decimal,
Format: format
}),
Lib. settings. currency
),
// Check format (returns object with pos, neg and zero), only need pos for now:
Formats = checkCurrencyFormat (opts. format ),
// Whether to pad at start of string or after currency symbol:
PadAfterSymbol = formats. pos. indexOf ("% s") <formats. pos. indexOf ("% v ")? True: false,
// Store value for the length of the longest string in the column:
MaxLength = 0,
// Format the list according to options, store the length of the longest string:
Formatted = map (list, function (val, I ){
If (isArray (val )){
// Recursively format columns if list is a multi-dimen1_array:
Return lib. formatColumn (val, opts );
} Else {
// Clean up the value
Val = unformat (val );
// Choose which format to use for this value (pos, neg or zero ):
Var useFormat = val> 0? Formats. pos: val <0? Formats. neg: formats. zero,
// Format this value, push into formatted list and save the length:
FVal = useFormat. replace ('% s', opts. symbol ). replace ('% V', formatNumber (Math. abs (val), checkPrecision (opts. precision), opts. thousand, opts. decimal ));
If (fVal. length> maxLength) maxLength = fVal. length;
Return fVal;
}
});
// Pad each number in the list and send back the column of numbers:
Return map (formatted, function (val, I ){
// Only if this is a string (not a nested array, which wowould have already been padded ):
If (isString (val) & val. length <maxLength ){
// Depending on symbol position, pad after symbol or at index 0:
Return padAfterSymbol? Val. replace (opts. symbol, opts. symbol + (new Array (maxLength-val. length + 1 ). join (""): (new Array (maxLength-val. length + 1 ). join ("") + val;
}
Return val;
});
};
/* --- Module Definition ---*/
// Export accounting for CommonJS. If being loaded as an AMD module, define it as such.
// Otherwise, just add 'account' to the global object
If (typeof exports! = 'Undefined '){
If (typeof module! = 'Undefined' & module. exports ){
Exports = module. exports = lib;
}
Exports. accounting = lib;
} Else if (typeof define ==== 'function' & define. amd ){
// Return the library as an AMD module:
Define ([], function (){
Return lib;
});
} Else {
// Use accounting. noConflict to restore 'accounting' back to its original value.
// Returns a reference to the library's 'accounting' object;
// E.g. 'var numbers = accounting. noConflict ();'
Lib. noConflict = (function (oldAccounting ){
Return function (){
// Reset the value of the root's 'accounting' variable:
Root. accounting = oldAccounting;
// Delete the noConflict method:
Lib. noConflict = undefined;
// Return reference to the library to re-assign it:
Return lib;
};
}) (Root. accounting );
// Declare 'fx 'on the root (global/window) object:
Root ['accounting'] = lib;
}
// Root will be 'window' in browser or 'global' on the server:
} (This ));

Https://raw.github.com/josscrowcroft/accounting.js/master/accounting.js
Use instance
FormatMoneyCopy codeThe Code is as follows: formatMoney
// Default usage:
Accounting. formatMoney (12345678); // $12,345,678.00
// European formatting (custom symbol and separators), cocould also use options object as second param:
Accounting. formatMoney (4999.99, "", 2, ".", ","); // 4.999, 99
// Negative values are formatted nicely, too:
Accounting. formatMoney (-500000, "£", 0); // £-500,000
// Simple 'format' string allows control of symbol position [% v = value, % s = symbol]:
Accounting. formatMoney (5318008, {symbol: "GBP", format: "% v % s"}); // 5,318,008.00 GBP

FormatNumberCopy codeThe Code is as follows: accounting. formatNumber (5318008); // 5,318,008
Accounting. formatNumber (9876543.21, 3, ""); // 9 876 543.210

UnformatCopy codeThe Code is as follows: accounting. unformat ("£ 12,345,678.90 GBP"); // 12345678.9

Official Demo: http://josscrowcroft.github.com/accounting.js/

Accounting. js

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.