Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / docs / source / Format.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-util-Format'>/**
19 </span> * @class Ext.util.Format
20
21 This class is a centralized place for formatting functions inside the library. It includes
22 functions to format various different types of data, such as text, dates and numeric values.
23
24 __Localization__
25 This class contains several options for localization. These can be set once the library has loaded,
26 all calls to the functions from that point will use the locale settings that were specified.
27 Options include:
28 - thousandSeparator
29 - decimalSeparator
30 - currenyPrecision
31 - currencySign
32 - currencyAtEnd
33 This class also uses the default date format defined here: {@link Ext.Date#defaultFormat}.
34
35 __Using with renderers__
36 There are two helper functions that return a new function that can be used in conjunction with 
37 grid renderers:
38
39     columns: [{
40         dataIndex: 'date',
41         renderer: Ext.util.Format.dateRenderer('Y-m-d')
42     }, {
43         dataIndex: 'time',
44         renderer: Ext.util.Format.numberRenderer('0.000')
45     }]
46     
47 Functions that only take a single argument can also be passed directly:
48     columns: [{
49         dataIndex: 'cost',
50         renderer: Ext.util.Format.usMoney
51     }, {
52         dataIndex: 'productCode',
53         renderer: Ext.util.Format.uppercase
54     }]
55     
56 __Using with XTemplates__
57 XTemplates can also directly use Ext.util.Format functions:
58
59     new Ext.XTemplate([
60         'Date: {startDate:date(&quot;Y-m-d&quot;)}',
61         'Cost: {cost:usMoney}'
62     ]);
63
64  * @markdown
65  * @singleton
66  */
67 (function() {
68     Ext.ns('Ext.util');
69
70     Ext.util.Format = {};
71     var UtilFormat     = Ext.util.Format,
72         stripTagsRE    = /&lt;\/?[^&gt;]+&gt;/gi,
73         stripScriptsRe = /(?:&lt;script.*?&gt;)((\n|\r|.)*?)(?:&lt;\/script&gt;)/ig,
74         nl2brRe        = /\r?\n/g,
75
76         // A RegExp to remove from a number format string, all characters except digits and '.'
77         formatCleanRe  = /[^\d\.]/g,
78
79         // A RegExp to remove from a number format string, all characters except digits and the local decimal separator.
80         // Created on first use. The local decimal separator character must be initialized for this to be created.
81         I18NFormatCleanRe;
82
83     Ext.apply(UtilFormat, {
84 <span id='Ext-util-Format-property-thousandSeparator'>        /**
85 </span>         * @type String
86          * @property thousandSeparator
87          * &lt;p&gt;The character that the {@link #number} function uses as a thousand separator.&lt;/p&gt;
88          * &lt;p&gt;This defaults to &lt;code&gt;,&lt;/code&gt;, but may be overridden in a locale file.&lt;/p&gt;
89          */
90         thousandSeparator: ',',
91
92 <span id='Ext-util-Format-property-decimalSeparator'>        /**
93 </span>         * @type String
94          * @property decimalSeparator
95          * &lt;p&gt;The character that the {@link #number} function uses as a decimal point.&lt;/p&gt;
96          * &lt;p&gt;This defaults to &lt;code&gt;.&lt;/code&gt;, but may be overridden in a locale file.&lt;/p&gt;
97          */
98         decimalSeparator: '.',
99
100 <span id='Ext-util-Format-property-currencyPrecision'>        /**
101 </span>         * @type Number
102          * @property currencyPrecision
103          * &lt;p&gt;The number of decimal places that the {@link #currency} function displays.&lt;/p&gt;
104          * &lt;p&gt;This defaults to &lt;code&gt;2&lt;/code&gt;, but may be overridden in a locale file.&lt;/p&gt;
105          */
106         currencyPrecision: 2,
107
108 <span id='Ext-util-Format-property-currencySign'>        /**
109 </span>         * @type String
110          * @property currencySign
111          * &lt;p&gt;The currency sign that the {@link #currency} function displays.&lt;/p&gt;
112          * &lt;p&gt;This defaults to &lt;code&gt;$&lt;/code&gt;, but may be overridden in a locale file.&lt;/p&gt;
113          */
114         currencySign: '$',
115
116 <span id='Ext-util-Format-property-currencyAtEnd'>        /**
117 </span>         * @type Boolean
118          * @property currencyAtEnd
119          * &lt;p&gt;This may be set to &lt;code&gt;true&lt;/code&gt; to make the {@link #currency} function
120          * append the currency sign to the formatted value.&lt;/p&gt;
121          * &lt;p&gt;This defaults to &lt;code&gt;false&lt;/code&gt;, but may be overridden in a locale file.&lt;/p&gt;
122          */
123         currencyAtEnd: false,
124
125 <span id='Ext-util-Format-method-undef'>        /**
126 </span>         * Checks a reference and converts it to empty string if it is undefined
127          * @param {Mixed} value Reference to check
128          * @return {Mixed} Empty string if converted, otherwise the original value
129          */
130         undef : function(value) {
131             return value !== undefined ? value : &quot;&quot;;
132         },
133
134 <span id='Ext-util-Format-method-defaultValue'>        /**
135 </span>         * Checks a reference and converts it to the default value if it's empty
136          * @param {Mixed} value Reference to check
137          * @param {String} defaultValue The value to insert of it's undefined (defaults to &quot;&quot;)
138          * @return {String}
139          */
140         defaultValue : function(value, defaultValue) {
141             return value !== undefined &amp;&amp; value !== '' ? value : defaultValue;
142         },
143
144 <span id='Ext-util-Format-method-substr'>        /**
145 </span>         * Returns a substring from within an original string
146          * @param {String} value The original text
147          * @param {Number} start The start index of the substring
148          * @param {Number} length The length of the substring
149          * @return {String} The substring
150          */
151         substr : function(value, start, length) {
152             return String(value).substr(start, length);
153         },
154
155 <span id='Ext-util-Format-method-lowercase'>        /**
156 </span>         * Converts a string to all lower case letters
157          * @param {String} value The text to convert
158          * @return {String} The converted text
159          */
160         lowercase : function(value) {
161             return String(value).toLowerCase();
162         },
163
164 <span id='Ext-util-Format-method-uppercase'>        /**
165 </span>         * Converts a string to all upper case letters
166          * @param {String} value The text to convert
167          * @return {String} The converted text
168          */
169         uppercase : function(value) {
170             return String(value).toUpperCase();
171         },
172
173 <span id='Ext-util-Format-method-usMoney'>        /**
174 </span>         * Format a number as US currency
175          * @param {Number/String} value The numeric value to format
176          * @return {String} The formatted currency string
177          */
178         usMoney : function(v) {
179             return UtilFormat.currency(v, '$', 2);
180         },
181
182 <span id='Ext-util-Format-method-currency'>        /**
183 </span>         * Format a number as a currency
184          * @param {Number/String} value The numeric value to format
185          * @param {String} sign The currency sign to use (defaults to {@link #currencySign})
186          * @param {Number} decimals The number of decimals to use for the currency (defaults to {@link #currencyPrecision})
187          * @param {Boolean} end True if the currency sign should be at the end of the string (defaults to {@link #currencyAtEnd})
188          * @return {String} The formatted currency string
189          */
190         currency: function(v, currencySign, decimals, end) {
191             var negativeSign = '',
192                 format = &quot;,0&quot;,
193                 i = 0;
194             v = v - 0;
195             if (v &lt; 0) {
196                 v = -v;
197                 negativeSign = '-';
198             }
199             decimals = decimals || UtilFormat.currencyPrecision;
200             format += format + (decimals &gt; 0 ? '.' : '');
201             for (; i &lt; decimals; i++) {
202                 format += '0';
203             }
204             v = UtilFormat.number(v, format); 
205             if ((end || UtilFormat.currencyAtEnd) === true) {
206                 return Ext.String.format(&quot;{0}{1}{2}&quot;, negativeSign, v, currencySign || UtilFormat.currencySign);
207             } else {
208                 return Ext.String.format(&quot;{0}{1}{2}&quot;, negativeSign, currencySign || UtilFormat.currencySign, v);
209             }
210         },
211
212 <span id='Ext-util-Format-method-date'>        /**
213 </span>         * Formats the passed date using the specified format pattern.
214          * @param {String/Date} value The value to format. If a string is passed, it is converted to a Date by the Javascript
215          * Date object's &lt;a href=&quot;http://www.w3schools.com/jsref/jsref_parse.asp&quot;&gt;parse()&lt;/a&gt; method.
216          * @param {String} format (Optional) Any valid date format string. Defaults to {@link Ext.Date#defaultFormat}.
217          * @return {String} The formatted date string.
218          */
219         date: function(v, format) {
220             if (!v) {
221                 return &quot;&quot;;
222             }
223             if (!Ext.isDate(v)) {
224                 v = new Date(Date.parse(v));
225             }
226             return Ext.Date.dateFormat(v, format || Ext.Date.defaultFormat);
227         },
228
229 <span id='Ext-util-Format-method-dateRenderer'>        /**
230 </span>         * Returns a date rendering function that can be reused to apply a date format multiple times efficiently
231          * @param {String} format Any valid date format string. Defaults to {@link Ext.Date#defaultFormat}.
232          * @return {Function} The date formatting function
233          */
234         dateRenderer : function(format) {
235             return function(v) {
236                 return UtilFormat.date(v, format);
237             };
238         },
239
240 <span id='Ext-util-Format-method-stripTags'>        /**
241 </span>         * Strips all HTML tags
242          * @param {Mixed} value The text from which to strip tags
243          * @return {String} The stripped text
244          */
245         stripTags : function(v) {
246             return !v ? v : String(v).replace(stripTagsRE, &quot;&quot;);
247         },
248
249 <span id='Ext-util-Format-method-stripScripts'>        /**
250 </span>         * Strips all script tags
251          * @param {Mixed} value The text from which to strip script tags
252          * @return {String} The stripped text
253          */
254         stripScripts : function(v) {
255             return !v ? v : String(v).replace(stripScriptsRe, &quot;&quot;);
256         },
257
258 <span id='Ext-util-Format-method-fileSize'>        /**
259 </span>         * Simple format for a file size (xxx bytes, xxx KB, xxx MB)
260          * @param {Number/String} size The numeric value to format
261          * @return {String} The formatted file size
262          */
263         fileSize : function(size) {
264             if (size &lt; 1024) {
265                 return size + &quot; bytes&quot;;
266             } else if (size &lt; 1048576) {
267                 return (Math.round(((size*10) / 1024))/10) + &quot; KB&quot;;
268             } else {
269                 return (Math.round(((size*10) / 1048576))/10) + &quot; MB&quot;;
270             }
271         },
272
273 <span id='Ext-util-Format-method-math'>        /**
274 </span>         * It does simple math for use in a template, for example:&lt;pre&gt;&lt;code&gt;
275          * var tpl = new Ext.Template('{value} * 10 = {value:math(&quot;* 10&quot;)}');
276          * &lt;/code&gt;&lt;/pre&gt;
277          * @return {Function} A function that operates on the passed value.
278          * @method
279          */
280         math : function(){
281             var fns = {};
282
283             return function(v, a){
284                 if (!fns[a]) {
285                     fns[a] = Ext.functionFactory('v', 'return v ' + a + ';');
286                 }
287                 return fns[a](v);
288             };
289         }(),
290
291 <span id='Ext-util-Format-method-round'>        /**
292 </span>         * Rounds the passed number to the required decimal precision.
293          * @param {Number/String} value The numeric value to round.
294          * @param {Number} precision The number of decimal places to which to round the first parameter's value.
295          * @return {Number} The rounded value.
296          */
297         round : function(value, precision) {
298             var result = Number(value);
299             if (typeof precision == 'number') {
300                 precision = Math.pow(10, precision);
301                 result = Math.round(value * precision) / precision;
302             }
303             return result;
304         },
305
306 <span id='Ext-util-Format-method-number'>        /**
307 </span>         * &lt;p&gt;Formats the passed number according to the passed format string.&lt;/p&gt;
308          * &lt;p&gt;The number of digits after the decimal separator character specifies the number of
309          * decimal places in the resulting string. The &lt;u&gt;local-specific&lt;/u&gt; decimal character is used in the result.&lt;/p&gt;
310          * &lt;p&gt;The &lt;i&gt;presence&lt;/i&gt; of a thousand separator character in the format string specifies that
311          * the &lt;u&gt;locale-specific&lt;/u&gt; thousand separator (if any) is inserted separating thousand groups.&lt;/p&gt;
312          * &lt;p&gt;By default, &quot;,&quot; is expected as the thousand separator, and &quot;.&quot; is expected as the decimal separator.&lt;/p&gt;
313          * &lt;p&gt;&lt;b&gt;New to Ext4&lt;/b&gt;&lt;/p&gt;
314          * &lt;p&gt;Locale-specific characters are always used in the formatted output when inserting
315          * thousand and decimal separators.&lt;/p&gt;
316          * &lt;p&gt;The format string must specify separator characters according to US/UK conventions (&quot;,&quot; as the
317          * thousand separator, and &quot;.&quot; as the decimal separator)&lt;/p&gt;
318          * &lt;p&gt;To allow specification of format strings according to local conventions for separator characters, add
319          * the string &lt;code&gt;/i&lt;/code&gt; to the end of the format string.&lt;/p&gt;
320          * &lt;div style=&quot;margin-left:40px&quot;&gt;examples (123456.789):
321          * &lt;div style=&quot;margin-left:10px&quot;&gt;
322          * 0 - (123456) show only digits, no precision&lt;br&gt;
323          * 0.00 - (123456.78) show only digits, 2 precision&lt;br&gt;
324          * 0.0000 - (123456.7890) show only digits, 4 precision&lt;br&gt;
325          * 0,000 - (123,456) show comma and digits, no precision&lt;br&gt;
326          * 0,000.00 - (123,456.78) show comma and digits, 2 precision&lt;br&gt;
327          * 0,0.00 - (123,456.78) shortcut method, show comma and digits, 2 precision&lt;br&gt;
328          * To allow specification of the formatting string using UK/US grouping characters (,) and decimal (.) for international numbers, add /i to the end.
329          * For example: 0.000,00/i
330          * &lt;/div&gt;&lt;/div&gt;
331          * @param {Number} v The number to format.
332          * @param {String} format The way you would like to format this text.
333          * @return {String} The formatted number.
334          */
335         number: function(v, formatString) {
336             if (!formatString) {
337                 return v;
338             }
339             v = Ext.Number.from(v, NaN);
340             if (isNaN(v)) {
341                 return '';
342             }
343             var comma = UtilFormat.thousandSeparator,
344                 dec   = UtilFormat.decimalSeparator,
345                 i18n  = false,
346                 neg   = v &lt; 0,
347                 hasComma,
348                 psplit;
349
350             v = Math.abs(v);
351
352             // The &quot;/i&quot; suffix allows caller to use a locale-specific formatting string.
353             // Clean the format string by removing all but numerals and the decimal separator.
354             // Then split the format string into pre and post decimal segments according to *what* the
355             // decimal separator is. If they are specifying &quot;/i&quot;, they are using the local convention in the format string.
356             if (formatString.substr(formatString.length - 2) == '/i') {
357                 if (!I18NFormatCleanRe) {
358                     I18NFormatCleanRe = new RegExp('[^\\d\\' + UtilFormat.decimalSeparator + ']','g');
359                 }
360                 formatString = formatString.substr(0, formatString.length - 2);
361                 i18n   = true;
362                 hasComma = formatString.indexOf(comma) != -1;
363                 psplit = formatString.replace(I18NFormatCleanRe, '').split(dec);
364             } else {
365                 hasComma = formatString.indexOf(',') != -1;
366                 psplit = formatString.replace(formatCleanRe, '').split('.');
367             }
368
369             if (1 &lt; psplit.length) {
370                 v = v.toFixed(psplit[1].length);
371             } else if(2 &lt; psplit.length) {
372                 //&lt;debug&gt;
373                 Ext.Error.raise({
374                     sourceClass: &quot;Ext.util.Format&quot;,
375                     sourceMethod: &quot;number&quot;,
376                     value: v,
377                     formatString: formatString,
378                     msg: &quot;Invalid number format, should have no more than 1 decimal&quot;
379                 });
380                 //&lt;/debug&gt;
381             } else {
382                 v = v.toFixed(0);
383             }
384
385             var fnum = v.toString();
386
387             psplit = fnum.split('.');
388
389             if (hasComma) {
390                 var cnum = psplit[0],
391                     parr = [],
392                     j    = cnum.length,
393                     m    = Math.floor(j / 3),
394                     n    = cnum.length % 3 || 3,
395                     i;
396
397                 for (i = 0; i &lt; j; i += n) {
398                     if (i !== 0) {
399                         n = 3;
400                     }
401
402                     parr[parr.length] = cnum.substr(i, n);
403                     m -= 1;
404                 }
405                 fnum = parr.join(comma);
406                 if (psplit[1]) {
407                     fnum += dec + psplit[1];
408                 }
409             } else {
410                 if (psplit[1]) {
411                     fnum = psplit[0] + dec + psplit[1];
412                 }
413             }
414             
415             if (neg) {
416                 /*
417                  * Edge case. If we have a very small negative number it will get rounded to 0,
418                  * however the initial check at the top will still report as negative. Replace
419                  * everything but 1-9 and check if the string is empty to determine a 0 value.
420                  */
421                 neg = fnum.replace(/[^1-9]/g, '') !== '';
422             }
423
424             return (neg ? '-' : '') + formatString.replace(/[\d,?\.?]+/, fnum);
425         },
426
427 <span id='Ext-util-Format-method-numberRenderer'>        /**
428 </span>         * Returns a number rendering function that can be reused to apply a number format multiple times efficiently
429          * @param {String} format Any valid number format string for {@link #number}
430          * @return {Function} The number formatting function
431          */
432         numberRenderer : function(format) {
433             return function(v) {
434                 return UtilFormat.number(v, format);
435             };
436         },
437
438 <span id='Ext-util-Format-method-plural'>        /**
439 </span>         * Selectively do a plural form of a word based on a numeric value. For example, in a template,
440          * {commentCount:plural(&quot;Comment&quot;)}  would result in &quot;1 Comment&quot; if commentCount was 1 or would be &quot;x Comments&quot;
441          * if the value is 0 or greater than 1.
442          * @param {Number} value The value to compare against
443          * @param {String} singular The singular form of the word
444          * @param {String} plural (optional) The plural form of the word (defaults to the singular with an &quot;s&quot;)
445          */
446         plural : function(v, s, p) {
447             return v +' ' + (v == 1 ? s : (p ? p : s+'s'));
448         },
449
450 <span id='Ext-util-Format-method-nl2br'>        /**
451 </span>         * Converts newline characters to the HTML tag &amp;lt;br/&gt;
452          * @param {String} The string value to format.
453          * @return {String} The string with embedded &amp;lt;br/&gt; tags in place of newlines.
454          */
455         nl2br : function(v) {
456             return Ext.isEmpty(v) ? '' : v.replace(nl2brRe, '&lt;br/&gt;');
457         },
458
459 <span id='Ext-util-Format-method-capitalize'>        /**
460 </span>         * Capitalize the given string. See {@link Ext.String#capitalize}.
461          * @method
462          */
463         capitalize: Ext.String.capitalize,
464
465 <span id='Ext-util-Format-method-ellipsis'>        /**
466 </span>         * Truncate a string and add an ellipsis ('...') to the end if it exceeds the specified length.
467          * See {@link Ext.String#ellipsis}.
468          * @method
469          */
470         ellipsis: Ext.String.ellipsis,
471
472 <span id='Ext-util-Format-method-format'>        /**
473 </span>         * Formats to a string. See {@link Ext.String#format}
474          * @method
475          */
476         format: Ext.String.format,
477
478 <span id='Ext-util-Format-method-htmlDecode'>        /**
479 </span>         * Convert certain characters (&amp;, &lt;, &gt;, and ') from their HTML character equivalents.
480          * See {@link Ext.String#htmlDecode}.
481          * @method
482          */
483         htmlDecode: Ext.String.htmlDecode,
484
485 <span id='Ext-util-Format-method-htmlEncode'>        /**
486 </span>         * Convert certain characters (&amp;, &lt;, &gt;, and ') to their HTML character equivalents for literal display in web pages.
487          * See {@link Ext.String#htmlEncode}.
488          * @method
489          */
490         htmlEncode: Ext.String.htmlEncode,
491
492 <span id='Ext-util-Format-method-leftPad'>        /**
493 </span>         * Adds left padding to a string. See {@link Ext.String#leftPad}
494          * @method
495          */
496         leftPad: Ext.String.leftPad,
497
498 <span id='Ext-util-Format-method-trim'>        /**
499 </span>         * Trims any whitespace from either side of a string. See {@link Ext.String#trim}.
500          * @method
501          */
502         trim : Ext.String.trim,
503
504 <span id='Ext-util-Format-method-parseBox'>        /**
505 </span>         * Parses a number or string representing margin sizes into an object. Supports CSS-style margin declarations
506          * (e.g. 10, &quot;10&quot;, &quot;10 10&quot;, &quot;10 10 10&quot; and &quot;10 10 10 10&quot; are all valid options and would return the same result)
507          * @param {Number|String} v The encoded margins
508          * @return {Object} An object with margin sizes for top, right, bottom and left
509          */
510         parseBox : function(box) {
511             if (Ext.isNumber(box)) {
512                 box = box.toString();
513             }
514             var parts  = box.split(' '),
515                 ln = parts.length;
516
517             if (ln == 1) {
518                 parts[1] = parts[2] = parts[3] = parts[0];
519             }
520             else if (ln == 2) {
521                 parts[2] = parts[0];
522                 parts[3] = parts[1];
523             }
524             else if (ln == 3) {
525                 parts[3] = parts[1];
526             }
527
528             return {
529                 top   :parseInt(parts[0], 10) || 0,
530                 right :parseInt(parts[1], 10) || 0,
531                 bottom:parseInt(parts[2], 10) || 0,
532                 left  :parseInt(parts[3], 10) || 0
533             };
534         },
535
536 <span id='Ext-util-Format-method-escapeRegex'>        /**
537 </span>         * Escapes the passed string for use in a regular expression
538          * @param {String} str
539          * @return {String}
540          */
541         escapeRegex : function(s) {
542             return s.replace(/([\-.*+?\^${}()|\[\]\/\\])/g, &quot;\\$1&quot;);
543         }
544     });
545 })();
546 </pre>
547 </body>
548 </html>