2 * Reusable data formatting functions
4 Ext
.define('Ext.util.Format', {
12 * The global default date format.
14 defaultDateFormat
: 'm/d/Y',
17 trimRe
: /^[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000]+|[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000]+$/g,
18 formatRe
: /\{(\d+)\}/g,
19 escapeRegexRe
: /([-.*+?^${}()|[\]\/\\])/g,
21 iso8601TestRe
: /\d\dT\d\d/,
22 iso8601SplitRe
: /[- :T\.Z\+]/,
25 * Truncate a string and add an ellipsis ('...') to the end if it exceeds the specified length.
26 * @param {String} value The string to truncate.
27 * @param {Number} length The maximum length to allow before truncating.
28 * @param {Boolean} [word=false] True to try to find a common word break.
29 * @return {String} The converted text.
31 ellipsis: function(value
, len
, word
) {
32 if (value
&& value
.length
> len
) {
34 var vs
= value
.substr(0, len
- 2),
35 index
= Math
.max(vs
.lastIndexOf(' '), vs
.lastIndexOf('.'), vs
.lastIndexOf('!'), vs
.lastIndexOf('?'));
36 if (index
!= -1 && index
>= (len
- 15)) {
37 return vs
.substr(0, index
) + "...";
40 return value
.substr(0, len
- 3) + "...";
46 * Escapes the passed string for use in a regular expression.
50 escapeRegex: function(s
) {
51 return s
.replace(Ext
.util
.Format
.escapeRegexRe
, "\\$1");
55 * Escapes the passed string for ' and \.
56 * @param {String} string The string to escape.
57 * @return {String} The escaped string.
59 escape: function(string
) {
60 return string
.replace(Ext
.util
.Format
.escapeRe
, "\\$1");
64 * Utility function that allows you to easily switch a string between two alternating values. The passed value
65 * is compared to the current string, and if they are equal, the other value that was passed in is returned. If
66 * they are already different, the first value passed in is returned.
68 * __Note:__ This method returns the new value but does not change the current string.
70 * // alternate sort directions
71 * sort = Ext.util.Format.toggle(sort, 'ASC', 'DESC');
73 * // instead of conditional logic:
74 * sort = (sort === 'ASC' ? 'DESC' : 'ASC');
76 * @param {String} string The current string
77 * @param {String} value The value to compare to the current string
78 * @param {String} other The new value to use if the string already equals the first value passed in
79 * @return {String} The new value
81 toggle: function(string
, value
, other
) {
82 return string
== value
? other
: value
;
86 * Trims whitespace from either end of a string, leaving spaces within the string intact. Example:
88 * var s = ' foo bar ';
89 * alert('-' + s + '-'); // alerts "- foo bar -"
90 * alert('-' + Ext.util.Format.trim(s) + '-'); // alerts "-foo bar-"
92 * @param {String} string The string to escape
93 * @return {String} The trimmed string
95 trim: function(string
) {
96 return string
.replace(Ext
.util
.Format
.trimRe
, "");
100 * Pads the left side of a string with a specified character. This is especially useful
101 * for normalizing number and date strings. Example usage:
103 * var s = Ext.util.Format.leftPad('123', 5, '0');
104 * // s now contains the string: '00123'
106 * @param {String} string The original string.
107 * @param {Number} size The total length of the output string.
108 * @param {String} [char=' '] (optional) The character with which to pad the original string.
109 * @return {String} The padded string.
111 leftPad: function (val
, size
, ch
) {
112 var result
= String(val
);
114 while (result
.length
< size
) {
115 result
= ch
+ result
;
121 * Allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens. Each
122 * token must be unique, and must increment in the format {0}, {1}, etc. Example usage:
124 * var cls = 'my-class', text = 'Some text';
125 * var s = Ext.util.Format.format('<div class="{0}">{1}</div>', cls, text);
126 * // s now contains the string: '<div class="my-class">Some text</div>'
128 * @param {String} string The tokenized string to be formatted.
129 * @param {String...} values The values to replace token {0}, {1}, etc.
130 * @return {String} The formatted string.
132 format: function (format
) {
133 var args
= Ext
.toArray(arguments
, 1);
134 return format
.replace(Ext
.util
.Format
.formatRe
, function(m
, i
) {
140 * Convert certain characters (&, <, >, and ') to their HTML character equivalents for literal display in web pages.
141 * @param {String} value The string to encode.
142 * @return {String} The encoded text.
144 htmlEncode: function(value
) {
145 return ! value
? value
: String(value
).replace(/&/g, "&").replace(/>/g, ">").replace(/</g, "<").replace(/"/g, ""
;");
149 * Convert certain characters (&, <, >, and ') from their HTML character equivalents.
150 * @param {String} value The string to decode.
151 * @return {String} The decoded text.
153 htmlDecode: function(value) {
154 return ! value ? value: String(value).replace(/>/g, ">").replace(/</g, "<").replace(/"/g, '"').replace(/&/g, "&");
158 * Parse a value into a formatted date using the specified format pattern.
159 * Note that this uses the native Javascript Date.parse() method and is therefore subject to its idiosyncrasies.
160 * Most formats assume the local timezone unless specified. One notable exception is 'YYYY
-MM
-DD
' (note the dashes)
161 * which is typically interpreted in UTC and can cause date shifting.
162 * @param {String/Date} value The value to format. Strings must conform to the format expected by the JavaScript
163 * Date object's
[parse() method
](http
://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/parse).
164 * @param
{String
} [format
='m/d/Y'] (optional
) Any valid date format string
.
165 * @return {String
} The formatted date string
.
167 date: function(value
, format
) {
172 if (!Ext
.isDate(value
)) {
173 date
= new Date(Date
.parse(value
));
175 // Dates with ISO 8601 format are not well supported by mobile devices, this can work around the issue.
176 if (this.iso8601TestRe
.test(value
)) {
177 // Fix for older android browsers to properly implement ISO 8601 formatted dates with timezone
178 if (Ext
.os
.is
.Android
&& Ext
.os
.version
.isLessThan("3.0")) {
180 * This code is modified from the following source: <https://github.com/csnover/js-iso8601>
181 * © 2011 Colin Snover <http://zetafleet.com>
182 * Released under MIT license.
184 var potentialUndefinedKeys
= [ 1, 4, 5, 6, 7, 10, 11 ];
185 var dateParsed
, minutesOffset
= 0;
197 // 10 tzHH (optional)
198 // 11 tzmm (optional)
199 if ((dateParsed
= /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec(value
))) {
201 //Set any undefined values needed for Date to 0
202 for (var i
= 0, k
; (k
= potentialUndefinedKeys
[i
]); ++i
) {
203 dateParsed
[k
] = +dateParsed
[k
] || 0;
206 // Fix undefined month and decrement
207 dateParsed
[2] = (+dateParsed
[2] || 1) - 1;
209 dateParsed
[3] = +dateParsed
[3] || 1;
211 // Correct for timezone
212 if (dateParsed
[8] !== 'Z' && dateParsed
[9] !== undefined) {
213 minutesOffset
= dateParsed
[10] * 60 + dateParsed
[11];
215 if (dateParsed
[9] === '+') {
216 minutesOffset
= 0 - minutesOffset
;
220 // Calculate valid date
221 date
= new Date(Date
.UTC(dateParsed
[1], dateParsed
[2], dateParsed
[3], dateParsed
[4], dateParsed
[5] + minutesOffset
, dateParsed
[6], dateParsed
[7]));
224 date
= value
.split(this.iso8601SplitRe
);
225 date
= new Date(date
[0], date
[1] - 1, date
[2], date
[3], date
[4], date
[5]);
230 // Dates with the format "2012-01-20" fail, but "2012/01/20" work in some browsers. We'll try and
232 date
= new Date(Date
.parse(value
.replace(this.dashesRe
, "/")));
235 Ext
.Logger
.error("Cannot parse the passed value " + value
+ " into a valid date");
241 return Ext
.Date
.format(value
, format
|| Ext
.util
.Format
.defaultDateFormat
);