Upgrade to ExtJS 3.0.0 - Released 07/06/2009
[extjs.git] / docs / source / Ext-more.html
1 <html>\r
2 <head>\r
3   <title>The source code</title>\r
4     <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />\r
5     <script type="text/javascript" src="../resources/prettify/prettify.js"></script>\r
6 </head>\r
7 <body  onload="prettyPrint();">\r
8     <pre class="prettyprint lang-js">/**
9  * @class Ext
10  */
11
12 Ext.ns("Ext.grid", "Ext.dd", "Ext.tree", "Ext.form", "Ext.menu",
13        "Ext.state", "Ext.layout", "Ext.app", "Ext.ux", "Ext.chart", "Ext.direct");
14     <div id="prop-Ext-ux"></div>/**
15      * Namespace alloted for extensions to the framework.
16      * @property ux
17      * @type Object
18      */
19
20 Ext.apply(Ext, function(){
21     var E = Ext, idSeed = 0;
22
23     return {
24         <div id="prop-Ext-emptyFn"></div>/**
25         * A reusable empty function
26         * @property
27         * @type Function
28         */
29         emptyFn : function(){},
30
31         <div id="prop-Ext-BLANK_IMAGE_URL"></div>/**
32          * URL to a 1x1 transparent gif image used by Ext to create inline icons with CSS background images. 
33          * In older versions of IE, this defaults to "http://extjs.com/s.gif" and you should change this to a URL on your server.
34          * For other browsers it uses an inline data URL.
35          * @type String
36          */
37         BLANK_IMAGE_URL : Ext.isIE6 || Ext.isIE7 ?
38                             'http:/' + '/extjs.com/s.gif' :
39                             'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
40
41         extendX : function(supr, fn){
42             return Ext.extend(supr, fn(supr.prototype));
43         },
44
45         <div id="method-Ext-getDoc"></div>/**
46          * Returns the current HTML document object as an {@link Ext.Element}.
47          * @return Ext.Element The document
48          */
49         getDoc : function(){
50             return Ext.get(document);
51         },
52
53         <div id="method-Ext-isDate"></div>/**
54          * Returns true if the passed object is a JavaScript date object, otherwise false.
55          * @param {Object} object The object to test
56          * @return {Boolean}
57          */
58         isDate : function(v){
59             return Object.prototype.toString.apply(v) === '[object Date]';
60         },
61
62         <div id="method-Ext-num"></div>/**
63          * Utility method for validating that a value is numeric, returning the specified default value if it is not.
64          * @param {Mixed} value Should be a number, but any type will be handled appropriately
65          * @param {Number} defaultValue The value to return if the original value is non-numeric
66          * @return {Number} Value, if numeric, else defaultValue
67          */
68         num : function(v, defaultValue){
69             v = Number(v === null || typeof v == 'boolean'? NaN : v);
70             return isNaN(v)? defaultValue : v;
71         },
72
73         <div id="method-Ext-value"></div>/**
74          * <p>Utility method for returning a default value if the passed value is empty.</p>
75          * <p>The value is deemed to be empty if it is<div class="mdetail-params"><ul>
76          * <li>null</li>
77          * <li>undefined</li>
78          * <li>an empty array</li>
79          * <li>a zero length string (Unless the <tt>allowBlank</tt> parameter is <tt>true</tt>)</li>
80          * </ul></div>
81          * @param {Mixed} value The value to test
82          * @param {Mixed} defaultValue The value to return if the original value is empty
83          * @param {Boolean} allowBlank (optional) true to allow zero length strings to qualify as non-empty (defaults to false)
84          * @return {Mixed} value, if non-empty, else defaultValue
85          */
86         value : function(v, defaultValue, allowBlank){
87             return Ext.isEmpty(v, allowBlank) ? defaultValue : v;
88         },
89
90         <div id="method-Ext-escapeRe"></div>/**
91          * Escapes the passed string for use in a regular expression
92          * @param {String} str
93          * @return {String}
94          */
95         escapeRe : function(s) {
96             return s.replace(/([.*+?^${}()|[\]\/\\])/g, "\\$1");
97         },
98
99         sequence : function(o, name, fn, scope){
100             o[name] = o[name].createSequence(fn, scope);
101         },
102
103         <div id="method-Ext-addBehaviors"></div>/**
104          * Applies event listeners to elements by selectors when the document is ready.
105          * The event name is specified with an <tt>&#64;</tt> suffix.
106          * <pre><code>
107 Ext.addBehaviors({
108     // add a listener for click on all anchors in element with id foo
109     '#foo a&#64;click' : function(e, t){
110         // do something
111     },
112     
113     // add the same listener to multiple selectors (separated by comma BEFORE the &#64;)
114     '#foo a, #bar span.some-class&#64;mouseover' : function(){
115         // do something
116     }
117 });
118          * </code></pre> 
119          * @param {Object} obj The list of behaviors to apply
120          */
121         addBehaviors : function(o){
122             if(!Ext.isReady){
123                 Ext.onReady(function(){
124                     Ext.addBehaviors(o);
125                 });
126             } else {
127                 var cache = {}, // simple cache for applying multiple behaviors to same selector does query multiple times
128                     parts,
129                     b,
130                     s;
131                 for (b in o) {
132                     if ((parts = b.split('@'))[1]) { // for Object prototype breakers
133                         s = parts[0];
134                         if(!cache[s]){
135                             cache[s] = Ext.select(s);
136                         }
137                         cache[s].on(parts[1], o[b]);
138                     }
139                 }
140                 cache = null;
141             }
142         },
143
144
145         // deprecated
146         combine : function(){
147             var as = arguments, l = as.length, r = [];
148             for(var i = 0; i < l; i++){
149                 var a = as[i];
150                 if(Ext.isArray(a)){
151                     r = r.concat(a);
152                 }else if(a.length !== undefined && !a.substr){
153                     r = r.concat(Array.prototype.slice.call(a, 0));
154                 }else{
155                     r.push(a);
156                 }
157             }
158             return r;
159         },
160
161         <div id="method-Ext-copyTo"></div>/**
162          * Copies a set of named properties fom the source object to the destination object.
163          * <p>example:<pre><code>
164 ImageComponent = Ext.extend(Ext.BoxComponent, {
165     initComponent: function() {
166         this.autoEl = { tag: 'img' };
167         MyComponent.superclass.initComponent.apply(this, arguments);
168         this.initialBox = Ext.copyTo({}, this.initialConfig, 'x,y,width,height');
169     }
170 });
171          * </code></pre> 
172          * @param {Object} The destination object.
173          * @param {Object} The source object.
174          * @param {Array/String} Either an Array of property names, or a comma-delimited list
175          * of property names to copy.
176          * @return {Object} The modified object.
177         */
178         copyTo : function(dest, source, names){
179             if(typeof names == 'string'){
180                 names = names.split(/[,;\s]/);
181             }
182             Ext.each(names, function(name){
183                 if(source.hasOwnProperty(name)){
184                     dest[name] = source[name];
185                 }
186             }, this);
187             return dest;
188         },
189
190         <div id="method-Ext-destroy"></div>/**
191          * Attempts to destroy any objects passed to it by removing all event listeners, removing them from the
192          * DOM (if applicable) and calling their destroy functions (if available).  This method is primarily
193          * intended for arguments of type {@link Ext.Element} and {@link Ext.Component}, but any subclass of
194          * {@link Ext.util.Observable} can be passed in.  Any number of elements and/or components can be
195          * passed into this function in a single call as separate arguments.
196          * @param {Mixed} arg1 An {@link Ext.Element}, {@link Ext.Component}, or an Array of either of these to destroy
197          * @param {Mixed} arg2 (optional)
198          * @param {Mixed} etc... (optional)
199          */
200         destroy : function(){
201             Ext.each(arguments, function(arg){
202                 if(arg){
203                     if(Ext.isArray(arg)){
204                         this.destroy.apply(this, arg);
205                     }else if(Ext.isFunction(arg.destroy)){
206                         arg.destroy();
207                     }else if(arg.dom){
208                         arg.remove();
209                     }    
210                 }
211             }, this);
212         },
213
214         <div id="method-Ext-destroyMembers"></div>/**
215          * Attempts to destroy and then remove a set of named properties of the passed object.
216          * @param {Object} o The object (most likely a Component) who's properties you wish to destroy.
217          * @param {Mixed} arg1 The name of the property to destroy and remove from the object.
218          * @param {Mixed} etc... More property names to destroy and remove.
219          */
220         destroyMembers : function(o, arg1, arg2, etc){
221             for(var i = 1, a = arguments, len = a.length; i < len; i++) {
222                 Ext.destroy(o[a[i]]);
223                 delete o[a[i]];
224             }
225         },
226
227         <div id="method-Ext-clean"></div>/**
228          * Creates a copy of the passed Array with falsy values removed.
229          * @param {Array/NodeList} arr The Array from which to remove falsy values.
230          * @return {Array} The new, compressed Array.
231          */
232         clean : function(arr){
233             var ret = [];
234             Ext.each(arr, function(v){
235                 if(!!v){
236                     ret.push(v);
237                 }
238             });
239             return ret;
240         },
241
242         <div id="method-Ext-unique"></div>/**
243          * Creates a copy of the passed Array, filtered to contain only unique values.
244          * @param {Array} arr The Array to filter
245          * @return {Array} The new Array containing unique values.
246          */
247         unique : function(arr){
248             var ret = [],
249                 collect = {};
250
251             Ext.each(arr, function(v) {
252                 if(!collect[v]){
253                     ret.push(v);
254                 }
255                 collect[v] = true;
256             });
257             return ret;
258         },
259
260         <div id="method-Ext-flatten"></div>/**
261          * Recursively flattens into 1-d Array. Injects Arrays inline.
262          * @param {Array} arr The array to flatten
263          * @return {Array} The new, flattened array.
264          */
265         flatten : function(arr){
266             var worker = [];
267             function rFlatten(a) {
268                 Ext.each(a, function(v) {
269                     if(Ext.isArray(v)){
270                         rFlatten(v);
271                     }else{
272                         worker.push(v);
273                     }
274                 });
275                 return worker;
276             }
277             return rFlatten(arr);
278         },
279
280         <div id="method-Ext-min"></div>/**
281          * Returns the minimum value in the Array.
282          * @param {Array|NodeList} arr The Array from which to select the minimum value.
283          * @param {Function} comp (optional) a function to perform the comparision which determines minimization.
284          *                   If omitted the "<" operator will be used. Note: gt = 1; eq = 0; lt = -1
285          * @return {Object} The minimum value in the Array.
286          */
287         min : function(arr, comp){
288             var ret = arr[0];
289             comp = comp || function(a,b){ return a < b ? -1 : 1; };
290             Ext.each(arr, function(v) {
291                 ret = comp(ret, v) == -1 ? ret : v;
292             });
293             return ret;
294         },
295
296         <div id="method-Ext-max"></div>/**
297          * Returns the maximum value in the Array
298          * @param {Array|NodeList} arr The Array from which to select the maximum value.
299          * @param {Function} comp (optional) a function to perform the comparision which determines maximization.
300          *                   If omitted the ">" operator will be used. Note: gt = 1; eq = 0; lt = -1
301          * @return {Object} The maximum value in the Array.
302          */
303         max : function(arr, comp){
304             var ret = arr[0];
305             comp = comp || function(a,b){ return a > b ? 1 : -1; };
306             Ext.each(arr, function(v) {
307                 ret = comp(ret, v) == 1 ? ret : v;
308             });
309             return ret;
310         },
311
312         <div id="method-Ext-mean"></div>/**
313          * Calculates the mean of the Array
314          * @param {Array} arr The Array to calculate the mean value of.
315          * @return {Number} The mean.
316          */
317         mean : function(arr){
318            return Ext.sum(arr) / arr.length;
319         },
320
321         <div id="method-Ext-sum"></div>/**
322          * Calculates the sum of the Array
323          * @param {Array} arr The Array to calculate the sum value of.
324          * @return {Number} The sum.
325          */
326         sum : function(arr){
327            var ret = 0;
328            Ext.each(arr, function(v) {
329                ret += v;
330            });
331            return ret;
332         },
333
334         <div id="method-Ext-partition"></div>/**
335          * Partitions the set into two sets: a true set and a false set.
336          * Example: 
337          * Example2: 
338          * <pre><code>
339 // Example 1:
340 Ext.partition([true, false, true, true, false]); // [[true, true, true], [false, false]]
341
342 // Example 2:
343 Ext.partition(
344     Ext.query("p"),
345     function(val){
346         return val.className == "class1"
347     }
348 );
349 // true are those paragraph elements with a className of "class1",
350 // false set are those that do not have that className.
351          * </code></pre>
352          * @param {Array|NodeList} arr The array to partition
353          * @param {Function} truth (optional) a function to determine truth.  If this is omitted the element
354          *                   itself must be able to be evaluated for its truthfulness.
355          * @return {Array} [true<Array>,false<Array>]
356          */
357         partition : function(arr, truth){
358             var ret = [[],[]];
359             Ext.each(arr, function(v, i, a) {
360                 ret[ (truth && truth(v, i, a)) || (!truth && v) ? 0 : 1].push(v);
361             });
362             return ret;
363         },
364
365         <div id="method-Ext-invoke"></div>/**
366          * Invokes a method on each item in an Array.
367          * <pre><code>
368 // Example:
369 Ext.invoke(Ext.query("p"), "getAttribute", "id");
370 // [el1.getAttribute("id"), el2.getAttribute("id"), ..., elN.getAttribute("id")]
371          * </code></pre>
372          * @param {Array|NodeList} arr The Array of items to invoke the method on.
373          * @param {String} methodName The method name to invoke.
374          * @param {Anything} ... Arguments to send into the method invocation.
375          * @return {Array} The results of invoking the method on each item in the array.
376          */
377         invoke : function(arr, methodName){
378             var ret = [],
379                 args = Array.prototype.slice.call(arguments, 2);
380             Ext.each(arr, function(v,i) {
381                 if (v && typeof v[methodName] == "function") {
382                     ret.push(v[methodName].apply(v, args));
383                 } else {
384                     ret.push(undefined);
385                 }
386             });
387             return ret;
388         },
389
390         <div id="method-Ext-pluck"></div>/**
391          * Plucks the value of a property from each item in the Array
392          * <pre><code>
393 // Example:
394 Ext.pluck(Ext.query("p"), "className"); // [el1.className, el2.className, ..., elN.className]
395          * </code></pre>
396          * @param {Array|NodeList} arr The Array of items to pluck the value from.
397          * @param {String} prop The property name to pluck from each element.
398          * @return {Array} The value from each item in the Array.
399          */
400         pluck : function(arr, prop){
401             var ret = [];
402             Ext.each(arr, function(v) {
403                 ret.push( v[prop] );
404             });
405             return ret;
406         },
407
408         <div id="method-Ext-zip"></div>/**
409          * <p>Zips N sets together.</p>
410          * <pre><code>
411 // Example 1:
412 Ext.zip([1,2,3],[4,5,6]); // [[1,4],[2,5],[3,6]]
413 // Example 2:
414 Ext.zip(
415     [ "+", "-", "+"],
416     [  12,  10,  22],
417     [  43,  15,  96],
418     function(a, b, c){
419         return "$" + a + "" + b + "." + c
420     }
421 ); // ["$+12.43", "$-10.15", "$+22.96"]
422          * </code></pre>
423          * @param {Arrays|NodeLists} arr This argument may be repeated. Array(s) to contribute values.
424          * @param {Function} zipper (optional) The last item in the argument list. This will drive how the items are zipped together.
425          * @return {Array} The zipped set.
426          */
427         zip : function(){
428             var parts = Ext.partition(arguments, function( val ){ return !Ext.isFunction(val); }),
429                 arrs = parts[0],
430                 fn = parts[1][0],
431                 len = Ext.max(Ext.pluck(arrs, "length")),
432                 ret = [];
433
434             for (var i = 0; i < len; i++) {
435                 ret[i] = [];
436                 if(fn){
437                     ret[i] = fn.apply(fn, Ext.pluck(arrs, i));
438                 }else{
439                     for (var j = 0, aLen = arrs.length; j < aLen; j++){
440                         ret[i].push( arrs[j][i] );
441                     }
442                 }
443             }
444             return ret;
445         },
446
447         <div id="method-Ext-getCmp"></div>/**
448          * This is shorthand reference to {@link Ext.ComponentMgr#get}.
449          * Looks up an existing {@link Ext.Component Component} by {@link Ext.Component#id id}
450          * @param {String} id The component {@link Ext.Component#id id}
451          * @return Ext.Component The Component, <tt>undefined</tt> if not found, or <tt>null</tt> if a
452          * Class was found.
453         */
454         getCmp : function(id){
455             return Ext.ComponentMgr.get(id);
456         },
457
458         <div id="prop-Ext-useShims"></div>/**
459          * By default, Ext intelligently decides whether floating elements should be shimmed. If you are using flash,
460          * you may want to set this to true.
461          * @type Boolean
462          */
463         useShims: E.isIE6 || (E.isMac && E.isGecko2),
464
465         // inpired by a similar function in mootools library
466         <div id="method-Ext-type"></div>/**
467          * Returns the type of object that is passed in. If the object passed in is null or undefined it
468          * return false otherwise it returns one of the following values:<div class="mdetail-params"><ul>
469          * <li><b>string</b>: If the object passed is a string</li>
470          * <li><b>number</b>: If the object passed is a number</li>
471          * <li><b>boolean</b>: If the object passed is a boolean value</li>
472          * <li><b>date</b>: If the object passed is a Date object</li>
473          * <li><b>function</b>: If the object passed is a function reference</li>
474          * <li><b>object</b>: If the object passed is an object</li>
475          * <li><b>array</b>: If the object passed is an array</li>
476          * <li><b>regexp</b>: If the object passed is a regular expression</li>
477          * <li><b>element</b>: If the object passed is a DOM Element</li>
478          * <li><b>nodelist</b>: If the object passed is a DOM NodeList</li>
479          * <li><b>textnode</b>: If the object passed is a DOM text node and contains something other than whitespace</li>
480          * <li><b>whitespace</b>: If the object passed is a DOM text node and contains only whitespace</li>
481          * </ul></div>
482          * @param {Mixed} object
483          * @return {String}
484          */
485         type : function(o){
486             if(o === undefined || o === null){
487                 return false;
488             }
489             if(o.htmlElement){
490                 return 'element';
491             }
492             var t = typeof o;
493             if(t == 'object' && o.nodeName) {
494                 switch(o.nodeType) {
495                     case 1: return 'element';
496                     case 3: return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace';
497                 }
498             }
499             if(t == 'object' || t == 'function') {
500                 switch(o.constructor) {
501                     case Array: return 'array';
502                     case RegExp: return 'regexp';
503                     case Date: return 'date';
504                 }
505                 if(typeof o.length == 'number' && typeof o.item == 'function') {
506                     return 'nodelist';
507                 }
508             }
509             return t;
510         },
511
512         intercept : function(o, name, fn, scope){
513             o[name] = o[name].createInterceptor(fn, scope);
514         },
515
516         // internal
517         callback : function(cb, scope, args, delay){
518             if(Ext.isFunction(cb)){
519                 if(delay){
520                     cb.defer(delay, scope, args || []);
521                 }else{
522                     cb.apply(scope, args || []);
523                 }
524             }
525         }
526     };
527 }());
528
529 /**
530  * @class Function
531  * These functions are available on every Function object (any JavaScript function).
532  */
533 Ext.apply(Function.prototype, {
534     <div id="method-Function-createSequence"></div>/**
535      * Create a combined function call sequence of the original function + the passed function.
536      * The resulting function returns the results of the original function.
537      * The passed fcn is called with the parameters of the original function. Example usage:
538      * <pre><code>
539 var sayHi = function(name){
540     alert('Hi, ' + name);
541 }
542
543 sayHi('Fred'); // alerts "Hi, Fred"
544
545 var sayGoodbye = sayHi.createSequence(function(name){
546     alert('Bye, ' + name);
547 });
548
549 sayGoodbye('Fred'); // both alerts show
550 </code></pre>
551      * @param {Function} fcn The function to sequence
552      * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window)
553      * @return {Function} The new function
554      */
555     createSequence : function(fcn, scope){
556         var method = this;
557         return !Ext.isFunction(fcn) ?
558                 this :
559                 function(){
560                     var retval = method.apply(this || window, arguments);
561                     fcn.apply(scope || this || window, arguments);
562                     return retval;
563                 };
564     }
565 });
566
567
568 /**
569  * @class String
570  * These functions are available as static methods on the JavaScript String object.
571  */
572 Ext.applyIf(String, {
573
574     <div id="method-String-escape"></div>/**
575      * Escapes the passed string for ' and \
576      * @param {String} string The string to escape
577      * @return {String} The escaped string
578      * @static
579      */
580     escape : function(string) {
581         return string.replace(/('|\\)/g, "\\$1");
582     },
583
584     <div id="method-String-leftPad"></div>/**
585      * Pads the left side of a string with a specified character.  This is especially useful
586      * for normalizing number and date strings.  Example usage:
587      * <pre><code>
588 var s = String.leftPad('123', 5, '0');
589 // s now contains the string: '00123'
590      * </code></pre>
591      * @param {String} string The original string
592      * @param {Number} size The total length of the output string
593      * @param {String} char (optional) The character with which to pad the original string (defaults to empty string " ")
594      * @return {String} The padded string
595      * @static
596      */
597     leftPad : function (val, size, ch) {
598         var result = String(val);
599         if(!ch) {
600             ch = " ";
601         }
602         while (result.length < size) {
603             result = ch + result;
604         }
605         return result;
606     }
607 });
608
609 <div id="method-String-toggle"></div>/**
610  * Utility function that allows you to easily switch a string between two alternating values.  The passed value
611  * is compared to the current string, and if they are equal, the other value that was passed in is returned.  If
612  * they are already different, the first value passed in is returned.  Note that this method returns the new value
613  * but does not change the current string.
614  * <pre><code>
615 // alternate sort directions
616 sort = sort.toggle('ASC', 'DESC');
617
618 // instead of conditional logic:
619 sort = (sort == 'ASC' ? 'DESC' : 'ASC');
620 </code></pre>
621  * @param {String} value The value to compare to the current string
622  * @param {String} other The new value to use if the string already equals the first value passed in
623  * @return {String} The new value
624  */
625 String.prototype.toggle = function(value, other){
626     return this == value ? other : value;
627 };
628
629 <div id="method-String-trim"></div>/**
630  * Trims whitespace from either end of a string, leaving spaces within the string intact.  Example:
631  * <pre><code>
632 var s = '  foo bar  ';
633 alert('-' + s + '-');         //alerts "- foo bar -"
634 alert('-' + s.trim() + '-');  //alerts "-foo bar-"
635 </code></pre>
636  * @return {String} The trimmed string
637  */
638 String.prototype.trim = function(){
639     var re = /^\s+|\s+$/g;
640     return function(){ return this.replace(re, ""); };
641 }();
642
643 // here to prevent dependency on Date.js
644 <div id="method-Date-getElapsed"></div>/**
645  Returns the number of milliseconds between this date and date
646  @param {Date} date (optional) Defaults to now
647  @return {Number} The diff in milliseconds
648  @member Date getElapsed
649  */
650 Date.prototype.getElapsed = function(date) {
651     return Math.abs((date || new Date()).getTime()-this.getTime());
652 };
653
654
655 <div id="cls-Number"></div>/**
656  * @class Number
657  */
658 Ext.applyIf(Number.prototype, {
659     <div id="method-Number-constrain"></div>/**
660      * Checks whether or not the current number is within a desired range.  If the number is already within the
661      * range it is returned, otherwise the min or max value is returned depending on which side of the range is
662      * exceeded.  Note that this method returns the constrained value but does not change the current number.
663      * @param {Number} min The minimum number in the range
664      * @param {Number} max The maximum number in the range
665      * @return {Number} The constrained value if outside the range, otherwise the current value
666      */
667     constrain : function(min, max){
668         return Math.min(Math.max(this, min), max);
669     }
670 });
671 </pre>    \r
672 </body>\r
673 </html>