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. 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, {
82 * @property {String} thousandSeparator
83 * <p>The character that the {@link #number} function uses as a thousand separator.</p>
84 * <p>This may be overridden in a locale file.</p>
86 thousandSeparator: ',',
89 * @property {String} decimalSeparator
90 * <p>The character that the {@link #number} function uses as a decimal point.</p>
91 * <p>This may be overridden in a locale file.</p>
93 decimalSeparator: '.',
96 * @property {Number} currencyPrecision
97 * <p>The number of decimal places that the {@link #currency} function displays.</p>
98 * <p>This may be overridden in a locale file.</p>
100 currencyPrecision: 2,
103 * @property {String} currencySign
104 * <p>The currency sign that the {@link #currency} function displays.</p>
105 * <p>This may be overridden in a locale file.</p>
110 * @property {Boolean} currencyAtEnd
111 * <p>This may be set to <code>true</code> to make the {@link #currency} function
112 * append the currency sign to the formatted value.</p>
113 * <p>This may be overridden in a locale file.</p>
115 currencyAtEnd: false,
118 * Checks a reference and converts it to empty string if it is undefined
119 * @param {Object} value Reference to check
120 * @return {Object} Empty string if converted, otherwise the original value
122 undef : function(value) {
123 return value !== undefined ? value : "";
127 * Checks a reference and converts it to the default value if it's empty
128 * @param {Object} value Reference to check
129 * @param {String} defaultValue The value to insert of it's undefined (defaults to "")
132 defaultValue : function(value, defaultValue) {
133 return value !== undefined && value !== '' ? value : defaultValue;
137 * Returns a substring from within an original string
138 * @param {String} value The original text
139 * @param {Number} start The start index of the substring
140 * @param {Number} length The length of the substring
141 * @return {String} The substring
143 substr : function(value, start, length) {
144 return String(value).substr(start, length);
148 * Converts a string to all lower case letters
149 * @param {String} value The text to convert
150 * @return {String} The converted text
152 lowercase : function(value) {
153 return String(value).toLowerCase();
157 * Converts a string to all upper case letters
158 * @param {String} value The text to convert
159 * @return {String} The converted text
161 uppercase : function(value) {
162 return String(value).toUpperCase();
166 * Format a number as US currency
167 * @param {Number/String} value The numeric value to format
168 * @return {String} The formatted currency string
170 usMoney : function(v) {
171 return UtilFormat.currency(v, '$', 2);
175 * Format a number as a currency
176 * @param {Number/String} value The numeric value to format
177 * @param {String} sign The currency sign to use (defaults to {@link #currencySign})
178 * @param {Number} decimals The number of decimals to use for the currency (defaults to {@link #currencyPrecision})
179 * @param {Boolean} end True if the currency sign should be at the end of the string (defaults to {@link #currencyAtEnd})
180 * @return {String} The formatted currency string
182 currency: function(v, currencySign, decimals, end) {
183 var negativeSign = '',
191 decimals = decimals || UtilFormat.currencyPrecision;
192 format += format + (decimals > 0 ? '.' : '');
193 for (; i < decimals; i++) {
196 v = UtilFormat.number(v, format);
197 if ((end || UtilFormat.currencyAtEnd) === true) {
198 return Ext.String.format("{0}{1}{2}", negativeSign, v, currencySign || UtilFormat.currencySign);
200 return Ext.String.format("{0}{1}{2}", negativeSign, currencySign || UtilFormat.currencySign, v);
205 * Formats the passed date using the specified format pattern.
206 * @param {String/Date} value The value to format. If a string is passed, it is converted to a Date by the Javascript
207 * Date object's <a href="http://www.w3schools.com/jsref/jsref_parse.asp">parse()</a> method.
208 * @param {String} format (Optional) Any valid date format string. Defaults to {@link Ext.Date#defaultFormat}.
209 * @return {String} The formatted date string.
211 date: function(v, format) {
215 if (!Ext.isDate(v)) {
216 v = new Date(Date.parse(v));
218 return Ext.Date.dateFormat(v, format || Ext.Date.defaultFormat);
222 * Returns a date rendering function that can be reused to apply a date format multiple times efficiently
223 * @param {String} format Any valid date format string. Defaults to {@link Ext.Date#defaultFormat}.
224 * @return {Function} The date formatting function
226 dateRenderer : function(format) {
228 return UtilFormat.date(v, format);
233 * Strips all HTML tags
234 * @param {Object} value The text from which to strip tags
235 * @return {String} The stripped text
237 stripTags : function(v) {
238 return !v ? v : String(v).replace(stripTagsRE, "");
242 * Strips all script tags
243 * @param {Object} value The text from which to strip script tags
244 * @return {String} The stripped text
246 stripScripts : function(v) {
247 return !v ? v : String(v).replace(stripScriptsRe, "");
251 * Simple format for a file size (xxx bytes, xxx KB, xxx MB)
252 * @param {Number/String} size The numeric value to format
253 * @return {String} The formatted file size
255 fileSize : function(size) {
257 return size + " bytes";
258 } else if (size < 1048576) {
259 return (Math.round(((size*10) / 1024))/10) + " KB";
261 return (Math.round(((size*10) / 1048576))/10) + " MB";
266 * It does simple math for use in a template, for example:<pre><code>
267 * var tpl = new Ext.Template('{value} * 10 = {value:math("* 10")}');
269 * @return {Function} A function that operates on the passed value.
275 return function(v, a){
277 fns[a] = Ext.functionFactory('v', 'return v ' + a + ';');
284 * Rounds the passed number to the required decimal precision.
285 * @param {Number/String} value The numeric value to round.
286 * @param {Number} precision The number of decimal places to which to round the first parameter's value.
287 * @return {Number} The rounded value.
289 round : function(value, precision) {
290 var result = Number(value);
291 if (typeof precision == 'number') {
292 precision = Math.pow(10, precision);
293 result = Math.round(value * precision) / precision;
299 * <p>Formats the passed number according to the passed format string.</p>
300 * <p>The number of digits after the decimal separator character specifies the number of
301 * decimal places in the resulting string. The <u>local-specific</u> decimal character is used in the result.</p>
302 * <p>The <i>presence</i> of a thousand separator character in the format string specifies that
303 * the <u>locale-specific</u> thousand separator (if any) is inserted separating thousand groups.</p>
304 * <p>By default, "," is expected as the thousand separator, and "." is expected as the decimal separator.</p>
305 * <p><b>New to Ext JS 4</b></p>
306 * <p>Locale-specific characters are always used in the formatted output when inserting
307 * thousand and decimal separators.</p>
308 * <p>The format string must specify separator characters according to US/UK conventions ("," as the
309 * thousand separator, and "." as the decimal separator)</p>
310 * <p>To allow specification of format strings according to local conventions for separator characters, add
311 * the string <code>/i</code> to the end of the format string.</p>
312 * <div style="margin-left:40px">examples (123456.789):
313 * <div style="margin-left:10px">
314 * 0 - (123456) show only digits, no precision<br>
315 * 0.00 - (123456.78) show only digits, 2 precision<br>
316 * 0.0000 - (123456.7890) show only digits, 4 precision<br>
317 * 0,000 - (123,456) show comma and digits, no precision<br>
318 * 0,000.00 - (123,456.78) show comma and digits, 2 precision<br>
319 * 0,0.00 - (123,456.78) shortcut method, show comma and digits, 2 precision<br>
320 * To allow specification of the formatting string using UK/US grouping characters (,) and decimal (.) for international numbers, add /i to the end.
321 * For example: 0.000,00/i
323 * @param {Number} v The number to format.
324 * @param {String} format The way you would like to format this text.
325 * @return {String} The formatted number.
327 number: function(v, formatString) {
331 v = Ext.Number.from(v, NaN);
335 var comma = UtilFormat.thousandSeparator,
336 dec = UtilFormat.decimalSeparator,
344 // The "/i" suffix allows caller to use a locale-specific formatting string.
345 // Clean the format string by removing all but numerals and the decimal separator.
346 // Then split the format string into pre and post decimal segments according to *what* the
347 // decimal separator is. If they are specifying "/i", they are using the local convention in the format string.
348 if (formatString.substr(formatString.length - 2) == '/i') {
349 if (!I18NFormatCleanRe) {
350 I18NFormatCleanRe = new RegExp('[^\\d\\' + UtilFormat.decimalSeparator + ']','g');
352 formatString = formatString.substr(0, formatString.length - 2);
354 hasComma = formatString.indexOf(comma) != -1;
355 psplit = formatString.replace(I18NFormatCleanRe, '').split(dec);
357 hasComma = formatString.indexOf(',') != -1;
358 psplit = formatString.replace(formatCleanRe, '').split('.');
361 if (1 < psplit.length) {
362 v = v.toFixed(psplit[1].length);
363 } else if(2 < psplit.length) {
366 sourceClass: "Ext.util.Format",
367 sourceMethod: "number",
369 formatString: formatString,
370 msg: "Invalid number format, should have no more than 1 decimal"
377 var fnum = v.toString();
379 psplit = fnum.split('.');
382 var cnum = psplit[0],
385 m = Math.floor(j / 3),
386 n = cnum.length % 3 || 3,
389 for (i = 0; i < j; i += n) {
394 parr[parr.length] = cnum.substr(i, n);
397 fnum = parr.join(comma);
399 fnum += dec + psplit[1];
403 fnum = psplit[0] + dec + psplit[1];
409 * Edge case. If we have a very small negative number it will get rounded to 0,
410 * however the initial check at the top will still report as negative. Replace
411 * everything but 1-9 and check if the string is empty to determine a 0 value.
413 neg = fnum.replace(/[^1-9]/g, '') !== '';
416 return (neg ? '-' : '') + formatString.replace(/[\d,?\.?]+/, fnum);
420 * Returns a number rendering function that can be reused to apply a number format multiple times efficiently
421 * @param {String} format Any valid number format string for {@link #number}
422 * @return {Function} The number formatting function
424 numberRenderer : function(format) {
426 return UtilFormat.number(v, format);
431 * Selectively do a plural form of a word based on a numeric value. For example, in a template,
432 * {commentCount:plural("Comment")} would result in "1 Comment" if commentCount was 1 or would be "x Comments"
433 * if the value is 0 or greater than 1.
434 * @param {Number} value The value to compare against
435 * @param {String} singular The singular form of the word
436 * @param {String} plural (optional) The plural form of the word (defaults to the singular with an "s")
438 plural : function(v, s, p) {
439 return v +' ' + (v == 1 ? s : (p ? p : s+'s'));
443 * Converts newline characters to the HTML tag <br/>
444 * @param {String} The string value to format.
445 * @return {String} The string with embedded <br/> tags in place of newlines.
447 nl2br : function(v) {
448 return Ext.isEmpty(v) ? '' : v.replace(nl2brRe, '<br/>');
452 * Alias for {@link Ext.String#capitalize}.
454 * @alias Ext.String#capitalize
456 capitalize: Ext.String.capitalize,
459 * Alias for {@link Ext.String#ellipsis}.
461 * @alias Ext.String#ellipsis
463 ellipsis: Ext.String.ellipsis,
466 * Alias for {@link Ext.String#format}.
468 * @alias Ext.String#format
470 format: Ext.String.format,
473 * Alias for {@link Ext.String#htmlDecode}.
475 * @alias Ext.String#htmlDecode
477 htmlDecode: Ext.String.htmlDecode,
480 * Alias for {@link Ext.String#htmlEncode}.
482 * @alias Ext.String#htmlEncode
484 htmlEncode: Ext.String.htmlEncode,
487 * Alias for {@link Ext.String#leftPad}.
489 * @alias Ext.String#leftPad
491 leftPad: Ext.String.leftPad,
494 * Alias for {@link Ext.String#trim}.
496 * @alias Ext.String#trim
498 trim : Ext.String.trim,
501 * Parses a number or string representing margin sizes into an object. Supports CSS-style margin declarations
502 * (e.g. 10, "10", "10 10", "10 10 10" and "10 10 10 10" are all valid options and would return the same result)
503 * @param {Number/String} v The encoded margins
504 * @return {Object} An object with margin sizes for top, right, bottom and left
506 parseBox : function(box) {
507 if (Ext.isNumber(box)) {
508 box = box.toString();
510 var parts = box.split(' '),
514 parts[1] = parts[2] = parts[3] = parts[0];
525 top :parseInt(parts[0], 10) || 0,
526 right :parseInt(parts[1], 10) || 0,
527 bottom:parseInt(parts[2], 10) || 0,
528 left :parseInt(parts[3], 10) || 0
533 * Escapes the passed string for use in a regular expression
534 * @param {String} str
537 escapeRegex : function(s) {
538 return s.replace(/([\-.*+?\^${}()|\[\]\/\\])/g, "\\$1");