2 * Ext JS Library 2.2.1
\r
3 * Copyright(c) 2006-2009, Ext JS, LLC.
\r
4 * licensing@extjs.com
\r
6 * http://extjs.com/license
\r
10 Ext = {version: '2.2.1'};
\r
13 window["undefined"] = window["undefined"];
\r
17 * Ext core utilities and functions.
\r
22 * Copies all the properties of config to obj.
\r
23 * @param {Object} obj The receiver of the properties
\r
24 * @param {Object} config The source of the properties
\r
25 * @param {Object} defaults A different object that will also be applied for default values
\r
26 * @return {Object} returns obj
\r
29 Ext.apply = function(o, c, defaults){
\r
31 // no "this" reference for friendly out of scope calls
\r
32 Ext.apply(o, defaults);
\r
34 if(o && c && typeof c == 'object'){
\r
44 var ua = navigator.userAgent.toLowerCase();
\r
46 var isStrict = document.compatMode == "CSS1Compat",
\r
47 isOpera = ua.indexOf("opera") > -1,
\r
48 isChrome = ua.indexOf("chrome") > -1,
\r
49 isSafari = !isChrome && (/webkit|khtml/).test(ua),
\r
50 isSafari3 = isSafari && ua.indexOf('webkit/5') != -1,
\r
51 isIE = !isOpera && ua.indexOf("msie") > -1,
\r
52 isIE7 = !isOpera && ua.indexOf("msie 7") > -1,
\r
53 isIE8 = !isOpera && ua.indexOf("msie 8") > -1,
\r
54 isGecko = !isSafari && !isChrome && ua.indexOf("gecko") > -1,
\r
55 isGecko3 = isGecko && ua.indexOf("rv:1.9") > -1,
\r
56 isBorderBox = isIE && !isStrict,
\r
57 isWindows = (ua.indexOf("windows") != -1 || ua.indexOf("win32") != -1),
\r
58 isMac = (ua.indexOf("macintosh") != -1 || ua.indexOf("mac os x") != -1),
\r
59 isAir = (ua.indexOf("adobeair") != -1),
\r
60 isLinux = (ua.indexOf("linux") != -1),
\r
61 isSecure = window.location.href.toLowerCase().indexOf("https") === 0;
\r
63 // remove css image flicker
\r
66 document.execCommand("BackgroundImageCache", false, true);
\r
72 * True if the browser is in strict (standards-compliant) mode, as opposed to quirks mode
\r
75 isStrict : isStrict,
\r
77 * True if the page is running over SSL
\r
80 isSecure : isSecure,
\r
82 * True when the document is fully initialized and ready for action
\r
88 * True to automatically uncache orphaned Ext.Elements periodically (defaults to true)
\r
91 enableGarbageCollector : true,
\r
94 * True to automatically purge event listeners after uncaching an element (defaults to false).
\r
95 * Note: this only happens if enableGarbageCollector is true.
\r
98 enableListenerCollection:false,
\r
102 * URL to a blank file used by Ext when in secure mode for iframe src and onReady src to prevent
\r
103 * the IE insecure content warning (defaults to javascript:false).
\r
106 SSL_SECURE_URL : "javascript:false",
\r
109 * URL to a 1x1 transparent gif image used by Ext to create inline icons with CSS background images. (Defaults to
\r
110 * "http://extjs.com/s.gif" and you should change this to a URL on your server).
\r
113 BLANK_IMAGE_URL : "http:/"+"/extjs.com/s.gif",
\r
116 * A reusable empty function
\r
120 emptyFn : function(){},
\r
123 * Copies all the properties of config to obj if they don't already exist.
\r
124 * @param {Object} obj The receiver of the properties
\r
125 * @param {Object} config The source of the properties
\r
126 * @return {Object} returns obj
\r
128 applyIf : function(o, c){
\r
131 if(typeof o[p] == "undefined"){ o[p] = c[p]; }
\r
138 * Applies event listeners to elements by selectors when the document is ready.
\r
139 * The event name is specified with an @ suffix.
\r
142 // add a listener for click on all anchors in element with id foo
\r
143 '#foo a@click' : function(e, t){
\r
147 // add the same listener to multiple selectors (separated by comma BEFORE the @)
\r
148 '#foo a, #bar span.some-class@mouseover' : function(){
\r
153 * @param {Object} obj The list of behaviors to apply
\r
155 addBehaviors : function(o){
\r
157 Ext.onReady(function(){
\r
158 Ext.addBehaviors(o);
\r
162 var cache = {}; // simple cache for applying multiple behaviors to same selector does query multiple times
\r
164 var parts = b.split('@');
\r
165 if(parts[1]){ // for Object prototype breakers
\r
168 cache[s] = Ext.select(s);
\r
170 cache[s].on(parts[1], o[b]);
\r
177 * Generates unique ids. If the element already has an id, it is unchanged
\r
178 * @param {Mixed} el (optional) The element to generate an id for
\r
179 * @param {String} prefix (optional) Id prefix (defaults "ext-gen")
\r
180 * @return {String} The generated Id.
\r
182 id : function(el, prefix){
\r
183 prefix = prefix || "ext-gen";
\r
184 el = Ext.getDom(el);
\r
185 var id = prefix + (++idSeed);
\r
186 return el ? (el.id ? el.id : (el.id = id)) : id;
\r
190 * Extends one class with another class and optionally overrides members with the passed literal. This class
\r
191 * also adds the function "override()" to the class that can be used to override
\r
192 * members on an instance.
\r
194 * This function also supports a 2-argument call in which the subclass's constructor is
\r
195 * not passed as an argument. In this form, the parameters are as follows:</p><p>
\r
196 * <div class="mdetail-params"><ul>
\r
197 * <li><code>superclass</code>
\r
198 * <div class="sub-desc">The class being extended</div></li>
\r
199 * <li><code>overrides</code>
\r
200 * <div class="sub-desc">A literal with members which are copied into the subclass's
\r
201 * prototype, and are therefore shared among all instances of the new class.<p>
\r
202 * This may contain a special member named <tt><b>constructor</b></tt>. This is used
\r
203 * to define the constructor of the new class, and is returned. If this property is
\r
204 * <i>not</i> specified, a constructor is generated and returned which just calls the
\r
205 * superclass's constructor passing on its parameters.</p></div></li>
\r
206 * </ul></div></p><p>
\r
207 * For example, to create a subclass of the Ext GridPanel:
\r
209 MyGridPanel = Ext.extend(Ext.grid.GridPanel, {
\r
210 constructor: function(config) {
\r
211 // Your preprocessing here
\r
212 MyGridPanel.superclass.constructor.apply(this, arguments);
\r
213 // Your postprocessing here
\r
216 yourMethod: function() {
\r
222 * @param {Function} subclass The class inheriting the functionality
\r
223 * @param {Function} superclass The class being extended
\r
224 * @param {Object} overrides (optional) A literal with members which are copied into the subclass's
\r
225 * prototype, and are therefore shared between all instances of the new class.
\r
226 * @return {Function} The subclass constructor.
\r
229 extend : function(){
\r
230 // inline overrides
\r
231 var io = function(o){
\r
236 var oc = Object.prototype.constructor;
\r
238 return function(sb, sp, overrides){
\r
239 if(typeof sp == 'object'){
\r
242 sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};
\r
244 var F = function(){}, sbp, spp = sp.prototype;
\r
246 sbp = sb.prototype = new F();
\r
247 sbp.constructor=sb;
\r
249 if(spp.constructor == oc){
\r
250 spp.constructor=sp;
\r
252 sb.override = function(o){
\r
253 Ext.override(sb, o);
\r
256 Ext.override(sb, overrides);
\r
257 sb.extend = function(o){Ext.extend(sb, o);};
\r
263 * Adds a list of functions to the prototype of an existing class, overwriting any existing methods with the same name.
\r
264 * Usage:<pre><code>
\r
265 Ext.override(MyClass, {
\r
266 newMethod1: function(){
\r
269 newMethod2: function(foo){
\r
274 * @param {Object} origclass The class to override
\r
275 * @param {Object} overrides The list of functions to add to origClass. This should be specified as an object literal
\r
276 * containing one or more methods.
\r
279 override : function(origclass, overrides){
\r
281 var p = origclass.prototype;
\r
282 for(var method in overrides){
\r
283 p[method] = overrides[method];
\r
285 if(Ext.isIE && overrides.toString != origclass.toString){
\r
286 p.toString = overrides.toString;
\r
292 * Creates namespaces to be used for scoping variables and classes so that they are not global. Usage:
\r
294 Ext.namespace('Company', 'Company.data');
\r
295 Company.Widget = function() { ... }
\r
296 Company.data.CustomStore = function(config) { ... }
\r
298 * @param {String} namespace1
\r
299 * @param {String} namespace2
\r
300 * @param {String} etc
\r
301 * @method namespace
\r
303 namespace : function(){
\r
304 var a=arguments, o=null, i, j, d, rt;
\r
305 for (i=0; i<a.length; ++i) {
\r
308 eval('if (typeof ' + rt + ' == "undefined"){' + rt + ' = {};} o = ' + rt + ';');
\r
309 for (j=1; j<d.length; ++j) {
\r
310 o[d[j]]=o[d[j]] || {};
\r
317 * Takes an object and converts it to an encoded URL. e.g. Ext.urlEncode({foo: 1, bar: 2}); would return "foo=1&bar=2". Optionally, property values can be arrays, instead of keys and the resulting string that's returned will contain a name/value pair for each array value.
\r
318 * @param {Object} o
\r
321 urlEncode : function(o){
\r
327 var ov = o[key], k = encodeURIComponent(key);
\r
328 var type = typeof ov;
\r
329 if(type == 'undefined'){
\r
331 }else if(type != "function" && type != "object"){
\r
332 buf.push(k, "=", encodeURIComponent(ov), "&");
\r
333 }else if(Ext.isDate(ov)){
\r
334 var s = Ext.encode(ov).replace(/"/g, '');
\r
335 buf.push(k, "=", s, "&");
\r
336 }else if(Ext.isArray(ov)){
\r
338 for(var i = 0, len = ov.length; i < len; i++) {
\r
339 buf.push(k, "=", encodeURIComponent(ov[i] === undefined ? '' : ov[i]), "&");
\r
347 return buf.join("");
\r
351 * Takes an encoded URL and and converts it to an object. e.g. Ext.urlDecode("foo=1&bar=2"); would return {foo: "1", bar: "2"}
\r
352 * or Ext.urlDecode("foo=1&bar=2&bar=3&bar=4", false); would return {foo: "1", bar: ["2", "3", "4"]}.
\r
353 * @param {String} string
\r
354 * @param {Boolean} overwrite (optional) Items of the same name will overwrite previous values instead of creating an an array (Defaults to false).
\r
355 * @return {Object} A literal with members
\r
357 urlDecode : function(string, overwrite){
\r
358 if(!string || !string.length){
\r
362 var pairs = string.split('&');
\r
363 var pair, name, value;
\r
364 for(var i = 0, len = pairs.length; i < len; i++){
\r
365 pair = pairs[i].split('=');
\r
366 name = decodeURIComponent(pair[0]);
\r
367 value = decodeURIComponent(pair[1]);
\r
368 if(overwrite !== true){
\r
369 if(typeof obj[name] == "undefined"){
\r
371 }else if(typeof obj[name] == "string"){
\r
372 obj[name] = [obj[name]];
\r
373 obj[name].push(value);
\r
375 obj[name].push(value);
\r
385 * Iterates an array calling the passed function with each item, stopping if your function returns false. If the
\r
386 * passed array is not really an array, your function is called once with it.
\r
387 * The supplied function is called with (Object item, Number index, Array allItems).
\r
388 * @param {Array/NodeList/Mixed} array
\r
389 * @param {Function} fn
\r
390 * @param {Object} scope
\r
392 each : function(array, fn, scope){
\r
393 if(typeof array.length == "undefined" || typeof array == "string"){
\r
396 for(var i = 0, len = array.length; i < len; i++){
\r
397 if(fn.call(scope || array[i], array[i], i, array) === false){ return i; };
\r
402 combine : function(){
\r
403 var as = arguments, l = as.length, r = [];
\r
404 for(var i = 0; i < l; i++){
\r
406 if(Ext.isArray(a)){
\r
408 }else if(a.length !== undefined && !a.substr){
\r
409 r = r.concat(Array.prototype.slice.call(a, 0));
\r
418 * Escapes the passed string for use in a regular expression
\r
419 * @param {String} str
\r
422 escapeRe : function(s) {
\r
423 return s.replace(/([.*+?^${}()|[\]\/\\])/g, "\\$1");
\r
427 callback : function(cb, scope, args, delay){
\r
428 if(typeof cb == "function"){
\r
430 cb.defer(delay, scope, args || []);
\r
432 cb.apply(scope, args || []);
\r
438 * Return the dom node for the passed string (id), dom node, or Ext.Element
\r
439 * @param {Mixed} el
\r
440 * @return HTMLElement
\r
442 getDom : function(el){
\r
443 if(!el || !document){
\r
446 return el.dom ? el.dom : (typeof el == 'string' ? document.getElementById(el) : el);
\r
450 * Returns the current HTML document object as an {@link Ext.Element}.
\r
451 * @return Ext.Element The document
\r
453 getDoc : function(){
\r
454 return Ext.get(document);
\r
458 * Returns the current document body as an {@link Ext.Element}.
\r
459 * @return Ext.Element The document body
\r
461 getBody : function(){
\r
462 return Ext.get(document.body || document.documentElement);
\r
466 * Shorthand for {@link Ext.ComponentMgr#get}
\r
467 * @param {String} id
\r
468 * @return Ext.Component
\r
470 getCmp : function(id){
\r
471 return Ext.ComponentMgr.get(id);
\r
475 * Utility method for validating that a value is numeric, returning the specified default value if it is not.
\r
476 * @param {Mixed} value Should be a number, but any type will be handled appropriately
\r
477 * @param {Number} defaultValue The value to return if the original value is non-numeric
\r
478 * @return {Number} Value, if numeric, else defaultValue
\r
480 num : function(v, defaultValue){
\r
481 if(typeof v != 'number' || isNaN(v)){
\r
482 return defaultValue;
\r
488 * Attempts to destroy any objects passed to it by removing all event listeners, removing them from the
\r
489 * DOM (if applicable) and calling their destroy functions (if available). This method is primarily
\r
490 * intended for arguments of type {@link Ext.Element} and {@link Ext.Component}, but any subclass of
\r
491 * {@link Ext.util.Observable} can be passed in. Any number of elements and/or components can be
\r
492 * passed into this function in a single call as separate arguments.
\r
493 * @param {Mixed} arg1 An {@link Ext.Element} or {@link Ext.Component} to destroy
\r
494 * @param {Mixed} arg2 (optional)
\r
495 * @param {Mixed} etc... (optional)
\r
497 destroy : function(){
\r
498 for(var i = 0, a = arguments, len = a.length; i < len; i++) {
\r
501 if(typeof as.destroy == 'function'){
\r
505 as.removeAllListeners();
\r
513 * Removes a DOM node from the document. The body node will be ignored if passed in.
\r
514 * @param {HTMLElement} node The node to remove
\r
516 removeNode : isIE ? function(){
\r
518 return function(n){
\r
519 if(n && n.tagName != 'BODY'){
\r
520 d = d || document.createElement('div');
\r
526 if(n && n.parentNode && n.tagName != 'BODY'){
\r
527 n.parentNode.removeChild(n);
\r
531 // inpired by a similar function in mootools library
\r
533 * Returns the type of object that is passed in. If the object passed in is null or undefined it
\r
534 * return false otherwise it returns one of the following values:<ul>
\r
535 * <li><b>string</b>: If the object passed is a string</li>
\r
536 * <li><b>number</b>: If the object passed is a number</li>
\r
537 * <li><b>boolean</b>: If the object passed is a boolean value</li>
\r
538 * <li><b>date</b>: If the object passed is a Date object</li>
\r
539 * <li><b>function</b>: If the object passed is a function reference</li>
\r
540 * <li><b>object</b>: If the object passed is an object</li>
\r
541 * <li><b>array</b>: If the object passed is an array</li>
\r
542 * <li><b>regexp</b>: If the object passed is a regular expression</li>
\r
543 * <li><b>element</b>: If the object passed is a DOM Element</li>
\r
544 * <li><b>nodelist</b>: If the object passed is a DOM NodeList</li>
\r
545 * <li><b>textnode</b>: If the object passed is a DOM text node and contains something other than whitespace</li>
\r
546 * <li><b>whitespace</b>: If the object passed is a DOM text node and contains only whitespace</li>
\r
547 * @param {Mixed} object
\r
550 type : function(o){
\r
551 if(o === undefined || o === null){
\r
558 if(t == 'object' && o.nodeName) {
\r
559 switch(o.nodeType) {
\r
560 case 1: return 'element';
\r
561 case 3: return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace';
\r
564 if(t == 'object' || t == 'function') {
\r
565 switch(o.constructor) {
\r
566 case Array: return 'array';
\r
567 case RegExp: return 'regexp';
\r
568 case Date: return 'date';
\r
570 if(typeof o.length == 'number' && typeof o.item == 'function') {
\r
578 * Returns true if the passed value is null, undefined or an empty string.
\r
579 * @param {Mixed} value The value to test
\r
580 * @param {Boolean} allowBlank (optional) true to allow empty strings (defaults to false)
\r
581 * @return {Boolean}
\r
583 isEmpty : function(v, allowBlank){
\r
584 return v === null || v === undefined || (!allowBlank ? v === '' : false);
\r
588 * Utility method for validating that a value is non-empty (i.e. i) not null, ii) not undefined, and iii) not an empty string),
\r
589 * returning the specified default value if it is.
\r
590 * @param {Mixed} value The value to test
\r
591 * @param {Mixed} defaultValue The value to return if the original value is empty
\r
592 * @param {Boolean} allowBlank (optional) true to allow empty strings (defaults to false)
\r
593 * @return {Mixed} value, if non-empty, else defaultValue
\r
595 value : function(v, defaultValue, allowBlank){
\r
596 return Ext.isEmpty(v, allowBlank) ? defaultValue : v;
\r
600 * Returns true if the passed object is a JavaScript array, otherwise false.
\r
601 * @param {Object} The object to test
\r
602 * @return {Boolean}
\r
604 isArray : function(v){
\r
605 return v && typeof v.length == 'number' && typeof v.splice == 'function';
\r
609 * Returns true if the passed object is a JavaScript date object, otherwise false.
\r
610 * @param {Object} The object to test
\r
611 * @return {Boolean}
\r
613 isDate : function(v){
\r
614 return v && typeof v.getFullYear == 'function';
\r
618 * True if the detected browser is Opera.
\r
623 * True if the detected browser is Chrome.
\r
626 isChrome : isChrome,
\r
628 * True if the detected browser is Safari.
\r
631 isSafari : isSafari,
\r
633 * True if the detected browser is Safari 3.x.
\r
636 isSafari3 : isSafari3,
\r
638 * True if the detected browser is Safari 2.x.
\r
641 isSafari2 : isSafari && !isSafari3,
\r
643 * True if the detected browser is Internet Explorer.
\r
648 * True if the detected browser is Internet Explorer 6.x.
\r
651 isIE6 : isIE && !isIE7 && !isIE8,
\r
653 * True if the detected browser is Internet Explorer 7.x.
\r
658 * True if the detected browser is Internet Explorer 8.x.
\r
663 * True if the detected browser uses the Gecko layout engine (e.g. Mozilla, Firefox).
\r
668 * True if the detected browser uses a pre-Gecko 1.9 layout engine (e.g. Firefox 2.x).
\r
671 isGecko2 : isGecko && !isGecko3,
\r
673 * True if the detected browser uses a Gecko 1.9+ layout engine (e.g. Firefox 3.x).
\r
676 isGecko3 : isGecko3,
\r
678 * True if the detected browser is Internet Explorer running in non-strict mode.
\r
681 isBorderBox : isBorderBox,
\r
683 * True if the detected platform is Linux.
\r
688 * True if the detected platform is Windows.
\r
691 isWindows : isWindows,
\r
693 * True if the detected platform is Mac OS.
\r
698 * True if the detected platform is Adobe Air.
\r
704 * By default, Ext intelligently decides whether floating elements should be shimmed. If you are using flash,
\r
705 * you may want to set this to true.
\r
708 useShims : ((isIE && !isIE7) || (isMac && isGecko && !isGecko3))
\r
711 // in intellij using keyword "namespace" causes parsing errors
\r
712 Ext.ns = Ext.namespace;
\r
715 Ext.ns("Ext", "Ext.util", "Ext.grid", "Ext.dd", "Ext.tree", "Ext.data",
\r
716 "Ext.form", "Ext.menu", "Ext.state", "Ext.lib", "Ext.layout", "Ext.app", "Ext.ux");
\r
721 * These functions are available on every Function object (any JavaScript function).
\r
723 Ext.apply(Function.prototype, {
\r
725 * Creates a callback that passes arguments[0], arguments[1], arguments[2], ...
\r
726 * Call directly on any function. Example: <code>myFunction.createCallback(arg1, arg2)</code>
\r
727 * Will create a function that is bound to those 2 args. <b>If a specific scope is required in the
\r
728 * callback, use {@link #createDelegate} instead.</b> The function returned by createCallback always
\r
729 * executes in the window scope.
\r
730 * <p>This method is required when you want to pass arguments to a callback function. If no arguments
\r
731 * are needed, you can simply pass a reference to the function as a callback (e.g., callback: myFn).
\r
732 * However, if you tried to pass a function with arguments (e.g., callback: myFn(arg1, arg2)) the function
\r
733 * would simply execute immediately when the code is parsed. Example usage:
\r
735 var sayHi = function(name){
\r
736 alert('Hi, ' + name);
\r
739 // clicking the button alerts "Hi, Fred"
\r
742 renderTo: Ext.getBody(),
\r
743 handler: sayHi.createCallback('Fred')
\r
746 * @return {Function} The new function
\r
748 createCallback : function(/*args...*/){
\r
749 // make args available, in function below
\r
750 var args = arguments;
\r
752 return function() {
\r
753 return method.apply(window, args);
\r
758 * Creates a delegate (callback) that sets the scope to obj.
\r
759 * Call directly on any function. Example: <code>this.myFunction.createDelegate(this, [arg1, arg2])</code>
\r
760 * Will create a function that is automatically scoped to obj so that the <tt>this</tt> variable inside the
\r
761 * callback points to obj. Example usage:
\r
763 var sayHi = function(name){
\r
764 // Note this use of "this.text" here. This function expects to
\r
765 // execute within a scope that contains a text property. In this
\r
766 // example, the "this" variable is pointing to the btn object that
\r
767 // was passed in createDelegate below.
\r
768 alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.');
\r
771 var btn = new Ext.Button({
\r
773 renderTo: Ext.getBody()
\r
776 // This callback will execute in the scope of the
\r
777 // button instance. Clicking the button alerts
\r
778 // "Hi, Fred. You clicked the "Say Hi" button."
\r
779 btn.on('click', sayHi.createDelegate(btn, ['Fred']));
\r
781 * @param {Object} obj (optional) The object for which the scope is set
\r
782 * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
\r
783 * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
\r
784 * if a number the args are inserted at the specified position
\r
785 * @return {Function} The new function
\r
787 createDelegate : function(obj, args, appendArgs){
\r
789 return function() {
\r
790 var callArgs = args || arguments;
\r
791 if(appendArgs === true){
\r
792 callArgs = Array.prototype.slice.call(arguments, 0);
\r
793 callArgs = callArgs.concat(args);
\r
794 }else if(typeof appendArgs == "number"){
\r
795 callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first
\r
796 var applyArgs = [appendArgs, 0].concat(args); // create method call params
\r
797 Array.prototype.splice.apply(callArgs, applyArgs); // splice them in
\r
799 return method.apply(obj || window, callArgs);
\r
804 * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage:
\r
806 var sayHi = function(name){
\r
807 alert('Hi, ' + name);
\r
810 // executes immediately:
\r
813 // executes after 2 seconds:
\r
814 sayHi.defer(2000, this, ['Fred']);
\r
816 // this syntax is sometimes useful for deferring
\r
817 // execution of an anonymous function:
\r
819 alert('Anonymous');
\r
822 * @param {Number} millis The number of milliseconds for the setTimeout call (if 0 the function is executed immediately)
\r
823 * @param {Object} obj (optional) The object for which the scope is set
\r
824 * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
\r
825 * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
\r
826 * if a number the args are inserted at the specified position
\r
827 * @return {Number} The timeout id that can be used with clearTimeout
\r
829 defer : function(millis, obj, args, appendArgs){
\r
830 var fn = this.createDelegate(obj, args, appendArgs);
\r
832 return setTimeout(fn, millis);
\r
839 * Create a combined function call sequence of the original function + the passed function.
\r
840 * The resulting function returns the results of the original function.
\r
841 * The passed fcn is called with the parameters of the original function. Example usage:
\r
843 var sayHi = function(name){
\r
844 alert('Hi, ' + name);
\r
847 sayHi('Fred'); // alerts "Hi, Fred"
\r
849 var sayGoodbye = sayHi.createSequence(function(name){
\r
850 alert('Bye, ' + name);
\r
853 sayGoodbye('Fred'); // both alerts show
\r
855 * @param {Function} fcn The function to sequence
\r
856 * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window)
\r
857 * @return {Function} The new function
\r
859 createSequence : function(fcn, scope){
\r
860 if(typeof fcn != "function"){
\r
864 return function() {
\r
865 var retval = method.apply(this || window, arguments);
\r
866 fcn.apply(scope || this || window, arguments);
\r
872 * Creates an interceptor function. The passed fcn is called before the original one. If it returns false,
\r
873 * the original one is not called. The resulting function returns the results of the original function.
\r
874 * The passed fcn is called with the parameters of the original function. Example usage:
\r
876 var sayHi = function(name){
\r
877 alert('Hi, ' + name);
\r
880 sayHi('Fred'); // alerts "Hi, Fred"
\r
882 // create a new function that validates input without
\r
883 // directly modifying the original function:
\r
884 var sayHiToFriend = sayHi.createInterceptor(function(name){
\r
885 return name == 'Brian';
\r
888 sayHiToFriend('Fred'); // no alert
\r
889 sayHiToFriend('Brian'); // alerts "Hi, Brian"
\r
891 * @param {Function} fcn The function to call before the original
\r
892 * @param {Object} scope (optional) The scope of the passed fcn (Defaults to scope of original function or window)
\r
893 * @return {Function} The new function
\r
895 createInterceptor : function(fcn, scope){
\r
896 if(typeof fcn != "function"){
\r
900 return function() {
\r
902 fcn.method = method;
\r
903 if(fcn.apply(scope || this || window, arguments) === false){
\r
906 return method.apply(this || window, arguments);
\r
913 * These functions are available as static methods on the JavaScript String object.
\r
915 Ext.applyIf(String, {
\r
918 * Escapes the passed string for ' and \
\r
919 * @param {String} string The string to escape
\r
920 * @return {String} The escaped string
\r
923 escape : function(string) {
\r
924 return string.replace(/('|\\)/g, "\\$1");
\r
928 * Pads the left side of a string with a specified character. This is especially useful
\r
929 * for normalizing number and date strings. Example usage:
\r
931 var s = String.leftPad('123', 5, '0');
\r
932 // s now contains the string: '00123'
\r
934 * @param {String} string The original string
\r
935 * @param {Number} size The total length of the output string
\r
936 * @param {String} char (optional) The character with which to pad the original string (defaults to empty string " ")
\r
937 * @return {String} The padded string
\r
940 leftPad : function (val, size, ch) {
\r
941 var result = new String(val);
\r
945 while (result.length < size) {
\r
946 result = ch + result;
\r
948 return result.toString();
\r
952 * Allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens. Each
\r
953 * token must be unique, and must increment in the format {0}, {1}, etc. Example usage:
\r
955 var cls = 'my-class', text = 'Some text';
\r
956 var s = String.format('<div class="{0}">{1}</div>', cls, text);
\r
957 // s now contains the string: '<div class="my-class">Some text</div>'
\r
959 * @param {String} string The tokenized string to be formatted
\r
960 * @param {String} value1 The value to replace token {0}
\r
961 * @param {String} value2 Etc...
\r
962 * @return {String} The formatted string
\r
965 format : function(format){
\r
966 var args = Array.prototype.slice.call(arguments, 1);
\r
967 return format.replace(/\{(\d+)\}/g, function(m, i){
\r
974 * Utility function that allows you to easily switch a string between two alternating values. The passed value
\r
975 * is compared to the current string, and if they are equal, the other value that was passed in is returned. If
\r
976 * they are already different, the first value passed in is returned. Note that this method returns the new value
\r
977 * but does not change the current string.
\r
979 // alternate sort directions
\r
980 sort = sort.toggle('ASC', 'DESC');
\r
982 // instead of conditional logic:
\r
983 sort = (sort == 'ASC' ? 'DESC' : 'ASC');
\r
985 * @param {String} value The value to compare to the current string
\r
986 * @param {String} other The new value to use if the string already equals the first value passed in
\r
987 * @return {String} The new value
\r
989 String.prototype.toggle = function(value, other){
\r
990 return this == value ? other : value;
\r
994 * Trims whitespace from either end of a string, leaving spaces within the string intact. Example:
\r
996 var s = ' foo bar ';
\r
997 alert('-' + s + '-'); //alerts "- foo bar -"
\r
998 alert('-' + s.trim() + '-'); //alerts "-foo bar-"
\r
1000 * @return {String} The trimmed string
\r
1002 String.prototype.trim = function(){
\r
1003 var re = /^\s+|\s+$/g;
\r
1004 return function(){ return this.replace(re, ""); };
\r
1009 Ext.applyIf(Number.prototype, {
\r
1011 * Checks whether or not the current number is within a desired range. If the number is already within the
\r
1012 * range it is returned, otherwise the min or max value is returned depending on which side of the range is
\r
1013 * exceeded. Note that this method returns the constrained value but does not change the current number.
\r
1014 * @param {Number} min The minimum number in the range
\r
1015 * @param {Number} max The maximum number in the range
\r
1016 * @return {Number} The constrained value if outside the range, otherwise the current value
\r
1018 constrain : function(min, max){
\r
1019 return Math.min(Math.max(this, min), max);
\r
1025 Ext.applyIf(Array.prototype, {
\r
1027 * Checks whether or not the specified object exists in the array.
\r
1028 * @param {Object} o The object to check for
\r
1029 * @return {Number} The index of o in the array (or -1 if it is not found)
\r
1031 indexOf : function(o){
\r
1032 for (var i = 0, len = this.length; i < len; i++){
\r
1033 if(this[i] == o) return i;
\r
1039 * Removes the specified object from the array. If the object is not found nothing happens.
\r
1040 * @param {Object} o The object to remove
\r
1041 * @return {Array} this array
\r
1043 remove : function(o){
\r
1044 var index = this.indexOf(o);
\r
1046 this.splice(index, 1);
\r
1053 Returns the number of milliseconds between this date and date
\r
1054 @param {Date} date (optional) Defaults to now
\r
1055 @return {Number} The diff in milliseconds
\r
1056 @member Date getElapsed
\r
1058 Date.prototype.getElapsed = function(date) {
\r
1059 return Math.abs((date || new Date()).getTime()-this.getTime());
\r