/** * jquery.numberformatter - Formatting/Parsing Numbers in jQuery * Written by Michael Abernethy (mike@abernethysoft.com) * * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * Date: 2/6/08 * * @author Michael Abernethy * @version 1.1.2 * * many thanks to advweb.nanasi.jp for his bug fixes * * This plugin can be used to format numbers as text and parse text as Numbers * Because we live in an international world, we cannot assume that everyone * uses "," to divide thousands, and "." as a decimal point. * * The format() function will take the text within any selector by calling * text() or val() on them, getting the String, and applying the specified format to it. * It will return the jQuery object * * The parse() function will take the text within any selector by calling text() * or val() on them, turning the String into a Number, and returning these * values in a Number array. * It WILL BREAK the jQuery chain, and return an Array of Numbers. * * The syntax for the formatting is: * 0 = Digit * # = Digit, zero shows as absent * . = Decimal separator * - = Negative sign * , = Grouping Separator * % = Percent (multiplies the number by 100) * For example, a format of "#,###.00" and text of 4500.20 will * display as "4.500,20" with a locale of "de", and "4,500.20" with a locale of "us" * * * As of now, the only acceptable locales are * United States -> "us" * Arab Emirates -> "ae" * Egypt -> "eg" * Israel -> "il" * Japan -> "jp" * South Korea -> "kr" * Thailand -> "th" * China -> "cn" * Hong Kong -> "hk" * Taiwan -> "tw" * Australia -> "au" * Canada -> "ca" * Great Britain -> "gb" * India -> "in" * Germany -> "de" * Vietnam -> "vn" * Spain -> "es" * Denmark -> "dk" * Austria -> "at" * Greece -> "gr" * Brazil -> "br" * Czech -> "cz" * France -> "fr" * Finland -> "fi" * Russia -> "ru" * Sweden -> "se" * Switzerland -> "ch" * * TODO * Separate positive and negative patterns separated by a ":" (e.g. use (#,###) for accounting) * More options may come in the future (currency) **/ (function(jQuery) { function FormatData(dec, group, neg) { this.dec = dec; this.group = group; this.neg = neg; }; function formatCodes(locale) { // default values var dec = "."; var group = ","; var neg = "-"; if (locale == "us" || locale == "ae" || locale == "eg" || locale == "il" || locale == "jp" || locale == "sk" || locale == "th" || locale == "cn" || locale == "hk" || locale == "tw" || locale == "au" || locale == "ca" || locale == "gb" || locale == "in" ) { dec = "."; group = ","; } else if (locale == "de" || locale == "vn" || locale == "es" || locale == "dk" || locale == "at" || locale == "gr" || locale == "br" ) { dec = ","; group = "."; } else if (locale == "cz" || locale == "fr" || locale == "fi" || locale == "ru" || locale == "se" ) { group = " "; dec = ","; } else if (locale == "ch") { group = "'"; dec = "."; } return new FormatData(dec, group, neg); }; jQuery.formatNumber = function(number, options) { var options = jQuery.extend({},jQuery.fn.parse.defaults, options); var formatData = formatCodes(options.locale.toLowerCase()); var dec = formatData.dec; var group = formatData.group; var neg = formatData.neg; var numString = new String(number); numString = numString.replace(".",dec).replace("-",neg); return numString; }; jQuery.fn.parse = function(options) { var options = jQuery.extend({},jQuery.fn.parse.defaults, options); var formatData = formatCodes(options.locale.toLowerCase()); var dec = formatData.dec; var group = formatData.group; var neg = formatData.neg; var valid = "1234567890.-"; var array = []; this.each(function(){ var text = new String(jQuery(this).text()); if (jQuery(this).is(":input")) text = new String(jQuery(this).val()); // now we need to convert it into a number while (text.indexOf(group)>-1) text = text.replace(group,''); text = text.replace(dec,".").replace(neg,"-"); var validText = ""; var hasPercent = false; if (text.charAt(text.length-1)=="%") hasPercent = true; for (var i=0; i-1) validText = validText + text.charAt(i); } var number = new Number(validText); if (hasPercent) { number = number / 100; number = number.toFixed(validText.length-1); } array.push(number); }); return array; }; jQuery.fn.format = function(options) { var options = jQuery.extend({},jQuery.fn.format.defaults, options); var formatData = formatCodes(options.locale.toLowerCase()); var dec = formatData.dec; var group = formatData.group; var neg = formatData.neg; var validFormat = "0#-,."; return this.each(function(){ var text = new String(jQuery(this).text()); if (jQuery(this).is(":input")) text = new String(jQuery(this).val()); // strip all the invalid characters at the beginning and the end // of the format, and we'll stick them back on at the end // make a special case for the negative sign "-" though, so // we can have formats like -$23.32 var prefix = ""; var negativeInFront = false; for (var i=0; i=0; i--) { if (validFormat.indexOf(options.format.charAt(i))==-1) suffix = options.format.charAt(i) + suffix; else break; } options.format = options.format.substring(prefix.length); options.format = options.format.substring(0, options.format.length - suffix.length); // now we need to convert it into a number while (text.indexOf(group)>-1) text = text.replace(group,''); var number = new Number(text.replace(dec,".").replace(neg,"-")); // special case for percentages if (suffix == "%") number = number * 100; var returnString = ""; var decimalValue = number % 1; if (options.format.indexOf(".") > -1) { var decimalPortion = dec; var decimalFormat = options.format.substring(options.format.lastIndexOf(".")+1); var decimalString = new String(decimalValue.toFixed(decimalFormat.length)); decimalString = decimalString.substring(decimalString.lastIndexOf(".")+1); for (var i=0; i-1; i--) { onePortion = oneText.charAt(i) + onePortion; groupCount++; if (groupCount == groupLength && i!=0) { onePortion = group + onePortion; groupCount = 0; } } } returnString = onePortion + returnString; // handle special case where negative is in front of the invalid // characters if (number < 0 && negativeInFront && prefix.length > 0) { prefix = neg + prefix; } else if (number < 0) { returnString = neg + returnString; } if (! options.decimalSeparatorAlwaysShown) { if (returnString.lastIndexOf(dec) == returnString.length - 1) { returnString = returnString.substring(0, returnString.length - 1); } } returnString = prefix + returnString + suffix; if (jQuery(this).is(":input")) jQuery(this).val(returnString); else jQuery(this).text(returnString); }); }; jQuery.fn.parse.defaults = { locale: "us", decimalSeparatorAlwaysShown: false }; jQuery.fn.format.defaults = { format: "#,###.00", locale: "us", decimalSeparatorAlwaysShown: false }; })(jQuery);