3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * @class Ext.util.Format
18 This class is a centralized place for formatting functions inside the library. It includes
19 functions to format various different types of data, such as text, dates and numeric values.
22 This class contains several options for localization. These can be set once the library has loaded,
23 all calls to the functions from that point will use the locale settings that were specified.
30 This class also uses the default date format defined here: {@link Ext.Date#defaultFormat}.
32 __Using with renderers__
33 There are two helper functions that return a new function that can be used in conjunction with
38 renderer: Ext.util.Format.dateRenderer('Y-m-d')
41 renderer: Ext.util.Format.numberRenderer('0.000')
44 Functions that only take a single argument can also be passed directly:
47 renderer: Ext.util.Format.usMoney
49 dataIndex: 'productCode',
50 renderer: Ext.util.Format.uppercase
53 __Using with XTemplates__
54 XTemplates can also directly use Ext.util.Format functions:
57 'Date: {startDate:date("Y-m-d")}',
58 'Cost: {cost:usMoney}'
68 var UtilFormat = Ext.util.Format,
69 stripTagsRE = /<\/?[^>]+>/gi,
70 stripScriptsRe = /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,
73 // A RegExp to remove from a number format string, all characters except digits and '.'
74 formatCleanRe = /[^\d\.]/g,
76 // A RegExp to remove from a number format string, all characters except digits and the local decimal separator.
77 // Created on first use. The local decimal separator character must be initialized for this to be created.
80 Ext.apply(UtilFormat, {
83 * @property thousandSeparator
84 * <p>The character that the {@link #number} function uses as a thousand separator.</p>
85 * <p>This defaults to <code>,</code>, but may be overridden in a locale file.</p>
87 thousandSeparator: ',',
91 * @property decimalSeparator
92 * <p>The character that the {@link #number} function uses as a decimal point.</p>
93 * <p>This defaults to <code>.</code>, but may be overridden in a locale file.</p>
95 decimalSeparator: '.',
99 * @property currencyPrecision
100 * <p>The number of decimal places that the {@link #currency} function displays.</p>
101 * <p>This defaults to <code>2</code>, but may be overridden in a locale file.</p>
103 currencyPrecision: 2,
107 * @property currencySign
108 * <p>The currency sign that the {@link #currency} function displays.</p>
109 * <p>This defaults to <code>$</code>, but may be overridden in a locale file.</p>
115 * @property currencyAtEnd
116 * <p>This may be set to <code>true</code> to make the {@link #currency} function
117 * append the currency sign to the formatted value.</p>
118 * <p>This defaults to <code>false</code>, but may be overridden in a locale file.</p>
120 currencyAtEnd: false,
123 * Checks a reference and converts it to empty string if it is undefined
124 * @param {Mixed} value Reference to check
125 * @return {Mixed} Empty string if converted, otherwise the original value
127 undef : function(value) {
128 return value !== undefined ? value : "";
132 * Checks a reference and converts it to the default value if it's empty
133 * @param {Mixed} value Reference to check
134 * @param {String} defaultValue The value to insert of it's undefined (defaults to "")
137 defaultValue : function(value, defaultValue) {
138 return value !== undefined && value !== '' ? value : defaultValue;
142 * Returns a substring from within an original string
143 * @param {String} value The original text
144 * @param {Number} start The start index of the substring
145 * @param {Number} length The length of the substring
146 * @return {String} The substring
148 substr : function(value, start, length) {
149 return String(value).substr(start, length);
153 * Converts a string to all lower case letters
154 * @param {String} value The text to convert
155 * @return {String} The converted text
157 lowercase : function(value) {
158 return String(value).toLowerCase();
162 * Converts a string to all upper case letters
163 * @param {String} value The text to convert
164 * @return {String} The converted text
166 uppercase : function(value) {
167 return String(value).toUpperCase();
171 * Format a number as US currency
172 * @param {Number/String} value The numeric value to format
173 * @return {String} The formatted currency string
175 usMoney : function(v) {
176 return UtilFormat.currency(v, '$', 2);
180 * Format a number as a currency
181 * @param {Number/String} value The numeric value to format
182 * @param {String} sign The currency sign to use (defaults to {@link #currencySign})
183 * @param {Number} decimals The number of decimals to use for the currency (defaults to {@link #currencyPrecision})
184 * @param {Boolean} end True if the currency sign should be at the end of the string (defaults to {@link #currencyAtEnd})
185 * @return {String} The formatted currency string
187 currency: function(v, currencySign, decimals, end) {
188 var negativeSign = '',
196 decimals = decimals || UtilFormat.currencyPrecision;
197 format += format + (decimals > 0 ? '.' : '');
198 for (; i < decimals; i++) {
201 v = UtilFormat.number(v, format);
202 if ((end || UtilFormat.currencyAtEnd) === true) {
203 return Ext.String.format("{0}{1}{2}", negativeSign, v, currencySign || UtilFormat.currencySign);
205 return Ext.String.format("{0}{1}{2}", negativeSign, currencySign || UtilFormat.currencySign, v);
210 * Formats the passed date using the specified format pattern.
211 * @param {String/Date} value The value to format. If a string is passed, it is converted to a Date by the Javascript
212 * Date object's <a href="http://www.w3schools.com/jsref/jsref_parse.asp">parse()</a> method.
213 * @param {String} format (Optional) Any valid date format string. Defaults to {@link Ext.Date#defaultFormat}.
214 * @return {String} The formatted date string.
216 date: function(v, format) {
220 if (!Ext.isDate(v)) {
221 v = new Date(Date.parse(v));
223 return Ext.Date.dateFormat(v, format || Ext.Date.defaultFormat);
227 * Returns a date rendering function that can be reused to apply a date format multiple times efficiently
228 * @param {String} format Any valid date format string. Defaults to {@link Ext.Date#defaultFormat}.
229 * @return {Function} The date formatting function
231 dateRenderer : function(format) {
233 return UtilFormat.date(v, format);
238 * Strips all HTML tags
239 * @param {Mixed} value The text from which to strip tags
240 * @return {String} The stripped text
242 stripTags : function(v) {
243 return !v ? v : String(v).replace(stripTagsRE, "");
247 * Strips all script tags
248 * @param {Mixed} value The text from which to strip script tags
249 * @return {String} The stripped text
251 stripScripts : function(v) {
252 return !v ? v : String(v).replace(stripScriptsRe, "");
256 * Simple format for a file size (xxx bytes, xxx KB, xxx MB)
257 * @param {Number/String} size The numeric value to format
258 * @return {String} The formatted file size
260 fileSize : function(size) {
262 return size + " bytes";
263 } else if (size < 1048576) {
264 return (Math.round(((size*10) / 1024))/10) + " KB";
266 return (Math.round(((size*10) / 1048576))/10) + " MB";
271 * It does simple math for use in a template, for example:<pre><code>
272 * var tpl = new Ext.Template('{value} * 10 = {value:math("* 10")}');
274 * @return {Function} A function that operates on the passed value.
280 return function(v, a){
282 fns[a] = Ext.functionFactory('v', 'return v ' + a + ';');
289 * Rounds the passed number to the required decimal precision.
290 * @param {Number/String} value The numeric value to round.
291 * @param {Number} precision The number of decimal places to which to round the first parameter's value.
292 * @return {Number} The rounded value.
294 round : function(value, precision) {
295 var result = Number(value);
296 if (typeof precision == 'number') {
297 precision = Math.pow(10, precision);
298 result = Math.round(value * precision) / precision;
304 * <p>Formats the passed number according to the passed format string.</p>
305 * <p>The number of digits after the decimal separator character specifies the number of
306 * decimal places in the resulting string. The <u>local-specific</u> decimal character is used in the result.</p>
307 * <p>The <i>presence</i> of a thousand separator character in the format string specifies that
308 * the <u>locale-specific</u> thousand separator (if any) is inserted separating thousand groups.</p>
309 * <p>By default, "," is expected as the thousand separator, and "." is expected as the decimal separator.</p>
310 * <p><b>New to Ext4</b></p>
311 * <p>Locale-specific characters are always used in the formatted output when inserting
312 * thousand and decimal separators.</p>
313 * <p>The format string must specify separator characters according to US/UK conventions ("," as the
314 * thousand separator, and "." as the decimal separator)</p>
315 * <p>To allow specification of format strings according to local conventions for separator characters, add
316 * the string <code>/i</code> to the end of the format string.</p>
317 * <div style="margin-left:40px">examples (123456.789):
318 * <div style="margin-left:10px">
319 * 0 - (123456) show only digits, no precision<br>
320 * 0.00 - (123456.78) show only digits, 2 precision<br>
321 * 0.0000 - (123456.7890) show only digits, 4 precision<br>
322 * 0,000 - (123,456) show comma and digits, no precision<br>
323 * 0,000.00 - (123,456.78) show comma and digits, 2 precision<br>
324 * 0,0.00 - (123,456.78) shortcut method, show comma and digits, 2 precision<br>
325 * To allow specification of the formatting string using UK/US grouping characters (,) and decimal (.) for international numbers, add /i to the end.
326 * For example: 0.000,00/i
328 * @param {Number} v The number to format.
329 * @param {String} format The way you would like to format this text.
330 * @return {String} The formatted number.
332 number: function(v, formatString) {
336 v = Ext.Number.from(v, NaN);
340 var comma = UtilFormat.thousandSeparator,
341 dec = UtilFormat.decimalSeparator,
349 // The "/i" suffix allows caller to use a locale-specific formatting string.
350 // Clean the format string by removing all but numerals and the decimal separator.
351 // Then split the format string into pre and post decimal segments according to *what* the
352 // decimal separator is. If they are specifying "/i", they are using the local convention in the format string.
353 if (formatString.substr(formatString.length - 2) == '/i') {
354 if (!I18NFormatCleanRe) {
355 I18NFormatCleanRe = new RegExp('[^\\d\\' + UtilFormat.decimalSeparator + ']','g');
357 formatString = formatString.substr(0, formatString.length - 2);
359 hasComma = formatString.indexOf(comma) != -1;
360 psplit = formatString.replace(I18NFormatCleanRe, '').split(dec);
362 hasComma = formatString.indexOf(',') != -1;
363 psplit = formatString.replace(formatCleanRe, '').split('.');
366 if (1 < psplit.length) {
367 v = v.toFixed(psplit[1].length);
368 } else if(2 < psplit.length) {
371 sourceClass: "Ext.util.Format",
372 sourceMethod: "number",
374 formatString: formatString,
375 msg: "Invalid number format, should have no more than 1 decimal"
382 var fnum = v.toString();
384 psplit = fnum.split('.');
387 var cnum = psplit[0],
390 m = Math.floor(j / 3),
391 n = cnum.length % 3 || 3,
394 for (i = 0; i < j; i += n) {
399 parr[parr.length] = cnum.substr(i, n);
402 fnum = parr.join(comma);
404 fnum += dec + psplit[1];
408 fnum = psplit[0] + dec + psplit[1];
414 * Edge case. If we have a very small negative number it will get rounded to 0,
415 * however the initial check at the top will still report as negative. Replace
416 * everything but 1-9 and check if the string is empty to determine a 0 value.
418 neg = fnum.replace(/[^1-9]/g, '') !== '';
421 return (neg ? '-' : '') + formatString.replace(/[\d,?\.?]+/, fnum);
425 * Returns a number rendering function that can be reused to apply a number format multiple times efficiently
426 * @param {String} format Any valid number format string for {@link #number}
427 * @return {Function} The number formatting function
429 numberRenderer : function(format) {
431 return UtilFormat.number(v, format);
436 * Selectively do a plural form of a word based on a numeric value. For example, in a template,
437 * {commentCount:plural("Comment")} would result in "1 Comment" if commentCount was 1 or would be "x Comments"
438 * if the value is 0 or greater than 1.
439 * @param {Number} value The value to compare against
440 * @param {String} singular The singular form of the word
441 * @param {String} plural (optional) The plural form of the word (defaults to the singular with an "s")
443 plural : function(v, s, p) {
444 return v +' ' + (v == 1 ? s : (p ? p : s+'s'));
448 * Converts newline characters to the HTML tag <br/>
449 * @param {String} The string value to format.
450 * @return {String} The string with embedded <br/> tags in place of newlines.
452 nl2br : function(v) {
453 return Ext.isEmpty(v) ? '' : v.replace(nl2brRe, '<br/>');
457 * Capitalize the given string. See {@link Ext.String#capitalize}.
460 capitalize: Ext.String.capitalize,
463 * Truncate a string and add an ellipsis ('...') to the end if it exceeds the specified length.
464 * See {@link Ext.String#ellipsis}.
467 ellipsis: Ext.String.ellipsis,
470 * Formats to a string. See {@link Ext.String#format}
473 format: Ext.String.format,
476 * Convert certain characters (&, <, >, and ') from their HTML character equivalents.
477 * See {@link Ext.String#htmlDecode}.
480 htmlDecode: Ext.String.htmlDecode,
483 * Convert certain characters (&, <, >, and ') to their HTML character equivalents for literal display in web pages.
484 * See {@link Ext.String#htmlEncode}.
487 htmlEncode: Ext.String.htmlEncode,
490 * Adds left padding to a string. See {@link Ext.String#leftPad}
493 leftPad: Ext.String.leftPad,
496 * Trims any whitespace from either side of a string. See {@link Ext.String#trim}.
499 trim : Ext.String.trim,
502 * Parses a number or string representing margin sizes into an object. Supports CSS-style margin declarations
503 * (e.g. 10, "10", "10 10", "10 10 10" and "10 10 10 10" are all valid options and would return the same result)
504 * @param {Number|String} v The encoded margins
505 * @return {Object} An object with margin sizes for top, right, bottom and left
507 parseBox : function(box) {
508 if (Ext.isNumber(box)) {
509 box = box.toString();
511 var parts = box.split(' '),
515 parts[1] = parts[2] = parts[3] = parts[0];
526 top :parseInt(parts[0], 10) || 0,
527 right :parseInt(parts[1], 10) || 0,
528 bottom:parseInt(parts[2], 10) || 0,
529 left :parseInt(parts[3], 10) || 0
534 * Escapes the passed string for use in a regular expression
535 * @param {String} str
538 escapeRegex : function(s) {
539 return s.replace(/([\-.*+?\^${}()|\[\]\/\\])/g, "\\$1");