From a20a6377277a985fa596b0ea460d91b97f79b4a5 Mon Sep 17 00:00:00 2001 From: friendica Date: Fri, 13 Jul 2012 07:09:29 -0700 Subject: merge upstream, slider work, refactor ping module, language selection work --- library/jslider/js/jquery.numberformatter-1.2.3.js | 510 +++++++++++++++++++++ 1 file changed, 510 insertions(+) create mode 100644 library/jslider/js/jquery.numberformatter-1.2.3.js (limited to 'library/jslider/js/jquery.numberformatter-1.2.3.js') diff --git a/library/jslider/js/jquery.numberformatter-1.2.3.js b/library/jslider/js/jquery.numberformatter-1.2.3.js new file mode 100644 index 000000000..213db297a --- /dev/null +++ b/library/jslider/js/jquery.numberformatter-1.2.3.js @@ -0,0 +1,510 @@ +/** + * jquery.numberformatter - Formatting/Parsing Numbers in jQuery + * + * Written by + * Michael Abernethy (mike@abernethysoft.com), + * Andrew Parry (aparry0@gmail.com) + * + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * @author Michael Abernethy, Andrew Parry + * @version 1.2.3-SNAPSHOT ($Id$) + * + * Dependencies + * + * jQuery (http://jquery.com) + * jshashtable (http://www.timdown.co.uk/jshashtable) + * + * Notes & Thanks + * + * many thanks to advweb.nanasi.jp for his bug fixes + * jsHashtable is now used also, so thanks to the author for that excellent little class. + * + * 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. + * + * As of 1.2 the way this plugin works has changed slightly, parsing text to a number + * has 1 set of functions, formatting a number to text has it's own. Before things + * were a little confusing, so I wanted to separate the 2 out more. + * + * + * jQuery extension functions: + * + * formatNumber(options, writeBack, giveReturnValue) - Reads the value from the subject, parses to + * a Javascript Number object, then formats back to text using the passed options and write back to + * the subject. + * + * parseNumber(options) - Parses the value in the subject to a Number object using the passed options + * to decipher the actual number from the text, then writes the value as text back to the subject. + * + * + * Generic functions: + * + * formatNumber(numberString, options) - Takes a plain number as a string (e.g. '1002.0123') and returns + * a string of the given format options. + * + * parseNumber(numberString, options) - Takes a number as text that is formatted the same as the given + * options then and returns it as a plain Number object. + * + * To achieve the old way of combining parsing and formatting to keep say a input field always formatted + * to a given format after it has lost focus you'd simply use a combination of the functions. + * + * e.g. + * $("#salary").blur(function(){ + * $(this).parseNumber({format:"#,###.00", locale:"us"}); + * $(this).formatNumber({format:"#,###.00", locale:"us"}); + * }); + * + * 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 + * Arab Emirates -> "ae" + * Australia -> "au" + * Austria -> "at" + * Brazil -> "br" + * Canada -> "ca" + * China -> "cn" + * Czech -> "cz" + * Denmark -> "dk" + * Egypt -> "eg" + * Finland -> "fi" + * France -> "fr" + * Germany -> "de" + * Greece -> "gr" + * Great Britain -> "gb" + * Hong Kong -> "hk" + * India -> "in" + * Israel -> "il" + * Japan -> "jp" + * Russia -> "ru" + * South Korea -> "kr" + * Spain -> "es" + * Sweden -> "se" + * Switzerland -> "ch" + * Taiwan -> "tw" + * Thailand -> "th" + * United States -> "us" + * Vietnam -> "vn" + **/ + +(function(jQuery) { + + var nfLocales = new Hashtable(); + + var nfLocalesLikeUS = [ 'ae','au','ca','cn','eg','gb','hk','il','in','jp','sk','th','tw','us' ]; + var nfLocalesLikeDE = [ 'at','br','de','dk','es','gr','it','nl','pt','tr','vn' ]; + var nfLocalesLikeFR = [ 'cz','fi','fr','ru','se','pl' ]; + var nfLocalesLikeCH = [ 'ch' ]; + + var nfLocaleFormatting = [ [".", ","], [",", "."], [",", " "], [".", "'"] ]; + var nfAllLocales = [ nfLocalesLikeUS, nfLocalesLikeDE, nfLocalesLikeFR, nfLocalesLikeCH ] + + function FormatData(dec, group, neg) { + this.dec = dec; + this.group = group; + this.neg = neg; + }; + + function init() { + // write the arrays into the hashtable + for (var localeGroupIdx = 0; localeGroupIdx < nfAllLocales.length; localeGroupIdx++) { + localeGroup = nfAllLocales[localeGroupIdx]; + for (var i = 0; i < localeGroup.length; i++) { + nfLocales.put(localeGroup[i], localeGroupIdx); + } + } + }; + + function formatCodes(locale, isFullLocale) { + if (nfLocales.size() == 0) + init(); + + // default values + var dec = "."; + var group = ","; + var neg = "-"; + + if (isFullLocale == false) { + // Extract and convert to lower-case any language code from a real 'locale' formatted string, if not use as-is + // (To prevent locale format like : "fr_FR", "en_US", "de_DE", "fr_FR", "en-US", "de-DE") + if (locale.indexOf('_') != -1) + locale = locale.split('_')[1].toLowerCase(); + else if (locale.indexOf('-') != -1) + locale = locale.split('-')[1].toLowerCase(); + } + + // hashtable lookup to match locale with codes + var codesIndex = nfLocales.get(locale); + if (codesIndex) { + var codes = nfLocaleFormatting[codesIndex]; + if (codes) { + dec = codes[0]; + group = codes[1]; + } + } + return new FormatData(dec, group, neg); + }; + + + /* Formatting Methods */ + + + /** + * Formats anything containing a number in standard js number notation. + * + * @param {Object} options The formatting options to use + * @param {Boolean} writeBack (true) If the output value should be written back to the subject + * @param {Boolean} giveReturnValue (true) If the function should return the output string + */ + jQuery.fn.formatNumber = function(options, writeBack, giveReturnValue) { + + return this.each(function() { + // enforce defaults + if (writeBack == null) + writeBack = true; + if (giveReturnValue == null) + giveReturnValue = true; + + // get text + var text; + if (jQuery(this).is(":input")) + text = new String(jQuery(this).val()); + else + text = new String(jQuery(this).text()); + + // format + var returnString = jQuery.formatNumber(text, options); + + // set formatted string back, only if a success +// if (returnString) { + if (writeBack) { + if (jQuery(this).is(":input")) + jQuery(this).val(returnString); + else + jQuery(this).text(returnString); + } + if (giveReturnValue) + return returnString; +// } +// return ''; + }); + }; + + /** + * First parses a string and reformats it with the given options. + * + * @param {Object} numberString + * @param {Object} options + */ + jQuery.formatNumber = function(numberString, options){ + var options = jQuery.extend({}, jQuery.fn.formatNumber.defaults, options); + var formatData = formatCodes(options.locale.toLowerCase(), options.isFullLocale); + + var dec = formatData.dec; + var group = formatData.group; + var neg = formatData.neg; + + var validFormat = "0#-,."; + + // 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 < options.format.length; i++) { + if (validFormat.indexOf(options.format.charAt(i)) == -1) + prefix = prefix + options.format.charAt(i); + else + if (i == 0 && options.format.charAt(i) == '-') { + negativeInFront = true; + continue; + } + else + break; + } + var suffix = ""; + for (var i = options.format.length - 1; 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 (numberString.indexOf(group) > -1) + // numberString = numberString.replace(group, ''); + //var number = new Number(numberString.replace(dec, ".").replace(neg, "-")); + var number = new Number(numberString); + + return jQuery._formatNumber(number, options, suffix, prefix, negativeInFront); + }; + + /** + * Formats a Number object into a string, using the given formatting options + * + * @param {Object} numberString + * @param {Object} options + */ + jQuery._formatNumber = function(number, options, suffix, prefix, negativeInFront) { + var options = jQuery.extend({}, jQuery.fn.formatNumber.defaults, options); + var formatData = formatCodes(options.locale.toLowerCase(), options.isFullLocale); + + var dec = formatData.dec; + var group = formatData.group; + var neg = formatData.neg; + + var forcedToZero = false; + if (isNaN(number)) { + if (options.nanForceZero == true) { + number = 0; + forcedToZero = true; + } else + return null; + } + + // special case for percentages + if (suffix == "%") + number = number * 100; + + var returnString = ""; + if (options.format.indexOf(".") > -1) { + var decimalPortion = dec; + var decimalFormat = options.format.substring(options.format.lastIndexOf(".") + 1); + + // round or truncate number as needed + if (options.round == true) + number = new Number(number.toFixed(decimalFormat.length)); + else { + var numStr = number.toString(); + numStr = numStr.substring(0, numStr.lastIndexOf('.') + decimalFormat.length + 1); + number = new Number(numStr); + } + + var decimalValue = number % 1; + var decimalString = new String(decimalValue.toFixed(decimalFormat.length)); + decimalString = decimalString.substring(decimalString.lastIndexOf(".") + 1); + + for (var i = 0; i < decimalFormat.length; i++) { + if (decimalFormat.charAt(i) == '#' && decimalString.charAt(i) != '0') { + decimalPortion += decimalString.charAt(i); + continue; + } else if (decimalFormat.charAt(i) == '#' && decimalString.charAt(i) == '0') { + var notParsed = decimalString.substring(i); + if (notParsed.match('[1-9]')) { + decimalPortion += decimalString.charAt(i); + continue; + } else + break; + } else if (decimalFormat.charAt(i) == "0") + decimalPortion += decimalString.charAt(i); + } + returnString += decimalPortion + } else + number = Math.round(number); + + var ones = Math.floor(number); + if (number < 0) + ones = Math.ceil(number); + + var onesFormat = ""; + if (options.format.indexOf(".") == -1) + onesFormat = options.format; + else + onesFormat = options.format.substring(0, options.format.indexOf(".")); + + var onePortion = ""; + if (!(ones == 0 && onesFormat.substr(onesFormat.length - 1) == '#') || forcedToZero) { + // find how many digits are in the group + var oneText = new String(Math.abs(ones)); + var groupLength = 9999; + if (onesFormat.lastIndexOf(",") != -1) + groupLength = onesFormat.length - onesFormat.lastIndexOf(",") - 1; + var groupCount = 0; + for (var i = oneText.length - 1; i > -1; i--) { + onePortion = oneText.charAt(i) + onePortion; + groupCount++; + if (groupCount == groupLength && i != 0) { + onePortion = group + onePortion; + groupCount = 0; + } + } + + // account for any pre-data padding + if (onesFormat.length > onePortion.length) { + var padStart = onesFormat.indexOf('0'); + if (padStart != -1) { + var padLen = onesFormat.length - padStart; + + // pad to left with 0's or group char + var pos = onesFormat.length - onePortion.length - 1; + while (onePortion.length < padLen) { + var padChar = onesFormat.charAt(pos); + // replace with real group char if needed + if (padChar == ',') + padChar = group; + onePortion = padChar + onePortion; + pos--; + } + } + } + } + + if (!onePortion && onesFormat.indexOf('0', onesFormat.length - 1) !== -1) + onePortion = '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; + return returnString; + }; + + + /* Parsing Methods */ + + + /** + * Parses a number of given format from the element and returns a Number object. + * @param {Object} options + */ + jQuery.fn.parseNumber = function(options, writeBack, giveReturnValue) { + // enforce defaults + if (writeBack == null) + writeBack = true; + if (giveReturnValue == null) + giveReturnValue = true; + + // get text + var text; + if (jQuery(this).is(":input")) + text = new String(jQuery(this).val()); + else + text = new String(jQuery(this).text()); + + // parse text + var number = jQuery.parseNumber(text, options); + + if (number) { + if (writeBack) { + if (jQuery(this).is(":input")) + jQuery(this).val(number.toString()); + else + jQuery(this).text(number.toString()); + } + if (giveReturnValue) + return number; + } + }; + + /** + * Parses a string of given format into a Number object. + * + * @param {Object} string + * @param {Object} options + */ + jQuery.parseNumber = function(numberString, options) { + var options = jQuery.extend({}, jQuery.fn.parseNumber.defaults, options); + var formatData = formatCodes(options.locale.toLowerCase(), options.isFullLocale); + + var dec = formatData.dec; + var group = formatData.group; + var neg = formatData.neg; + + var valid = "1234567890.-"; + + // now we need to convert it into a number + while (numberString.indexOf(group)>-1) + numberString = numberString.replace(group,''); + numberString = numberString.replace(dec,".").replace(neg,"-"); + var validText = ""; + var hasPercent = false; + if (numberString.charAt(numberString.length - 1) == "%" || options.isPercentage == true) + hasPercent = true; + for (var i=0; i-1) + validText = validText + numberString.charAt(i); + } + var number = new Number(validText); + if (hasPercent) { + number = number / 100; + var decimalPos = validText.indexOf('.'); + if (decimalPos != -1) { + var decimalPoints = validText.length - decimalPos - 1; + number = number.toFixed(decimalPoints + 2); + } else { + number = number.toFixed(validText.length - 1); + } + } + + return number; + }; + + jQuery.fn.parseNumber.defaults = { + locale: "us", + decimalSeparatorAlwaysShown: false, + isPercentage: false, + isFullLocale: false + }; + + jQuery.fn.formatNumber.defaults = { + format: "#,###.00", + locale: "us", + decimalSeparatorAlwaysShown: false, + nanForceZero: true, + round: true, + isFullLocale: false + }; + + Number.prototype.toFixed = function(precision) { + return jQuery._roundNumber(this, precision); + }; + + jQuery._roundNumber = function(number, decimalPlaces) { + var power = Math.pow(10, decimalPlaces || 0); + var value = String(Math.round(number * power) / power); + + // ensure the decimal places are there + if (decimalPlaces > 0) { + var dp = value.indexOf("."); + if (dp == -1) { + value += '.'; + dp = 0; + } else { + dp = value.length - (dp + 1); + } + + while (dp < decimalPlaces) { + value += '0'; + dp++; + } + } + return value; + }; + + })(jQuery); \ No newline at end of file -- cgit v1.2.3