- /**\r
- * Centers the Element in either the viewport, or another Element.\r
- * @param {Mixed} centerIn (optional) The element in which to center the element.\r
- */\r
- center : function(centerIn){\r
- return this.alignTo(centerIn || document, 'c-c'); \r
- } \r
-});\r
-/**\r
- * @class Ext.Element\r
- */\r
-Ext.Element.addMethods(function(){\r
- var PARENTNODE = 'parentNode',\r
- NEXTSIBLING = 'nextSibling',\r
- PREVIOUSSIBLING = 'previousSibling',\r
- DQ = Ext.DomQuery,\r
- GET = Ext.get;\r
- \r
- return {\r
- /**\r
- * Looks at this node and then at parent nodes for a match of the passed simple selector (e.g. div.some-class or span:first-child)\r
- * @param {String} selector The simple selector to test\r
- * @param {Number/Mixed} maxDepth (optional) The max depth to search as a number or element (defaults to 50 || document.body)\r
- * @param {Boolean} returnEl (optional) True to return a Ext.Element object instead of DOM node\r
- * @return {HTMLElement} The matching DOM node (or null if no match was found)\r
- */\r
- findParent : function(simpleSelector, maxDepth, returnEl){\r
- var p = this.dom,\r
- b = document.body, \r
- depth = 0, \r
- stopEl; \r
- if(Ext.isGecko && Object.prototype.toString.call(p) == '[object XULElement]') {\r
- return null;\r
- }\r
- maxDepth = maxDepth || 50;\r
- if (isNaN(maxDepth)) {\r
- stopEl = Ext.getDom(maxDepth);\r
- maxDepth = Number.MAX_VALUE;\r
- }\r
- while(p && p.nodeType == 1 && depth < maxDepth && p != b && p != stopEl){\r
- if(DQ.is(p, simpleSelector)){\r
- return returnEl ? GET(p) : p;\r
- }\r
- depth++;\r
- p = p.parentNode;\r
- }\r
- return null;\r
- },\r
- \r
- /**\r
- * Looks at parent nodes for a match of the passed simple selector (e.g. div.some-class or span:first-child)\r
- * @param {String} selector The simple selector to test\r
- * @param {Number/Mixed} maxDepth (optional) The max depth to\r
- search as a number or element (defaults to 10 || document.body)\r
- * @param {Boolean} returnEl (optional) True to return a Ext.Element object instead of DOM node\r
- * @return {HTMLElement} The matching DOM node (or null if no match was found)\r
- */\r
- findParentNode : function(simpleSelector, maxDepth, returnEl){\r
- var p = Ext.fly(this.dom.parentNode, '_internal');\r
- return p ? p.findParent(simpleSelector, maxDepth, returnEl) : null;\r
- },\r
- \r
- /**\r
- * Walks up the dom looking for a parent node that matches the passed simple selector (e.g. div.some-class or span:first-child).\r
- * This is a shortcut for findParentNode() that always returns an Ext.Element.\r
- * @param {String} selector The simple selector to test\r
- * @param {Number/Mixed} maxDepth (optional) The max depth to\r
- search as a number or element (defaults to 10 || document.body)\r
- * @return {Ext.Element} The matching DOM node (or null if no match was found)\r
- */\r
- up : function(simpleSelector, maxDepth){\r
- return this.findParentNode(simpleSelector, maxDepth, true);\r
- },\r
- \r
- /**\r
- * Creates a {@link Ext.CompositeElement} for child nodes based on the passed CSS selector (the selector should not contain an id).\r
- * @param {String} selector The CSS selector\r
- * @param {Boolean} unique (optional) True to create a unique Ext.Element for each child (defaults to false, which creates a single shared flyweight object)\r
- * @return {CompositeElement/CompositeElementLite} The composite element\r
- */\r
- select : function(selector, unique){\r
- return Ext.Element.select(selector, unique, this.dom);\r
- },\r
- \r
- /**\r
- * Selects child nodes based on the passed CSS selector (the selector should not contain an id).\r
- * @param {String} selector The CSS selector\r
- * @return {Array} An array of the matched nodes\r
- */\r
- query : function(selector, unique){\r
- return DQ.select(selector, this.dom);\r
- },\r
- \r
- /**\r
- * Selects a single child at any depth below this element based on the passed CSS selector (the selector should not contain an id).\r
- * @param {String} selector The CSS selector\r
- * @param {Boolean} returnDom (optional) True to return the DOM node instead of Ext.Element (defaults to false)\r
- * @return {HTMLElement/Ext.Element} The child Ext.Element (or DOM node if returnDom = true)\r
- */\r
- child : function(selector, returnDom){\r
- var n = DQ.selectNode(selector, this.dom);\r
- return returnDom ? n : GET(n);\r
- },\r
- \r
- /**\r
- * Selects a single *direct* child based on the passed CSS selector (the selector should not contain an id).\r
- * @param {String} selector The CSS selector\r
- * @param {Boolean} returnDom (optional) True to return the DOM node instead of Ext.Element (defaults to false)\r
- * @return {HTMLElement/Ext.Element} The child Ext.Element (or DOM node if returnDom = true)\r
- */\r
- down : function(selector, returnDom){\r
- var n = DQ.selectNode(" > " + selector, this.dom);\r
- return returnDom ? n : GET(n);\r
- },\r
- \r
- /**\r
- * Gets the parent node for this element, optionally chaining up trying to match a selector\r
- * @param {String} selector (optional) Find a parent node that matches the passed simple selector\r
- * @param {Boolean} returnDom (optional) True to return a raw dom node instead of an Ext.Element\r
- * @return {Ext.Element/HTMLElement} The parent node or null\r
- */\r
- parent : function(selector, returnDom){\r
- return this.matchNode(PARENTNODE, PARENTNODE, selector, returnDom);\r
- },\r
- \r
- /**\r
- * Gets the next sibling, skipping text nodes\r
- * @param {String} selector (optional) Find the next sibling that matches the passed simple selector\r
- * @param {Boolean} returnDom (optional) True to return a raw dom node instead of an Ext.Element\r
- * @return {Ext.Element/HTMLElement} The next sibling or null\r
- */\r
- next : function(selector, returnDom){\r
- return this.matchNode(NEXTSIBLING, NEXTSIBLING, selector, returnDom);\r
- },\r
- \r
- /**\r
- * Gets the previous sibling, skipping text nodes\r
- * @param {String} selector (optional) Find the previous sibling that matches the passed simple selector\r
- * @param {Boolean} returnDom (optional) True to return a raw dom node instead of an Ext.Element\r
- * @return {Ext.Element/HTMLElement} The previous sibling or null\r
- */\r
- prev : function(selector, returnDom){\r
- return this.matchNode(PREVIOUSSIBLING, PREVIOUSSIBLING, selector, returnDom);\r
- },\r
- \r
- \r
- /**\r
- * Gets the first child, skipping text nodes\r
- * @param {String} selector (optional) Find the next sibling that matches the passed simple selector\r
- * @param {Boolean} returnDom (optional) True to return a raw dom node instead of an Ext.Element\r
- * @return {Ext.Element/HTMLElement} The first child or null\r
- */\r
- first : function(selector, returnDom){\r
- return this.matchNode(NEXTSIBLING, 'firstChild', selector, returnDom);\r
- },\r
- \r
- /**\r
- * Gets the last child, skipping text nodes\r
- * @param {String} selector (optional) Find the previous sibling that matches the passed simple selector\r
- * @param {Boolean} returnDom (optional) True to return a raw dom node instead of an Ext.Element\r
- * @return {Ext.Element/HTMLElement} The last child or null\r
- */\r
- last : function(selector, returnDom){\r
- return this.matchNode(PREVIOUSSIBLING, 'lastChild', selector, returnDom);\r
- },\r
- \r
- matchNode : function(dir, start, selector, returnDom){\r
- var n = this.dom[start];\r
- while(n){\r
- if(n.nodeType == 1 && (!selector || DQ.is(n, selector))){\r
- return !returnDom ? GET(n) : n;\r
- }\r
- n = n[dir];\r
- }\r
- return null;\r
- } \r
- }\r
-}());/**\r
- * @class Ext.Element\r
- */\r
-Ext.Element.addMethods(\r
-function() {\r
- var GETDOM = Ext.getDom,\r
- GET = Ext.get,\r
- DH = Ext.DomHelper,\r
- isEl = function(el){\r
- return (el.nodeType || el.dom || typeof el == 'string'); \r
- };\r
- \r
- return {\r
- /**\r
- * Appends the passed element(s) to this element\r
- * @param {String/HTMLElement/Array/Element/CompositeElement} el\r
- * @return {Ext.Element} this\r
- */\r
- appendChild: function(el){ \r
- return GET(el).appendTo(this); \r
- },\r
- \r
- /**\r
- * Appends this element to the passed element\r
- * @param {Mixed} el The new parent element\r
- * @return {Ext.Element} this\r
- */\r
- appendTo: function(el){ \r
- GETDOM(el).appendChild(this.dom); \r
- return this;\r
- },\r
- \r
- /**\r
- * Inserts this element before the passed element in the DOM\r
- * @param {Mixed} el The element before which this element will be inserted\r
- * @return {Ext.Element} this\r
- */\r
- insertBefore: function(el){ \r
- (el = GETDOM(el)).parentNode.insertBefore(this.dom, el);\r
- return this;\r
- },\r
- \r
- /**\r
- * Inserts this element after the passed element in the DOM\r
- * @param {Mixed} el The element to insert after\r
- * @return {Ext.Element} this\r
- */\r
- insertAfter: function(el){\r
- (el = GETDOM(el)).parentNode.insertBefore(this.dom, el.nextSibling);\r
- return this;\r
- },\r
- \r
- /**\r
- * Inserts (or creates) an element (or DomHelper config) as the first child of this element\r
- * @param {Mixed/Object} el The id or element to insert or a DomHelper config to create and insert\r
- * @return {Ext.Element} The new child\r
- */\r
- insertFirst: function(el, returnDom){\r
- el = el || {};\r
- if(isEl(el)){ // element\r
- el = GETDOM(el);\r
- this.dom.insertBefore(el, this.dom.firstChild);\r
- return !returnDom ? GET(el) : el;\r
- }else{ // dh config\r
- return this.createChild(el, this.dom.firstChild, returnDom);\r
- }\r
- },\r
- \r
- /**\r
- * Replaces the passed element with this element\r
- * @param {Mixed} el The element to replace\r
- * @return {Ext.Element} this\r
- */\r
- replace: function(el){\r
- el = GET(el);\r
- this.insertBefore(el);\r
- el.remove();\r
- return this;\r
- },\r
- \r
- /**\r
- * Replaces this element with the passed element\r
- * @param {Mixed/Object} el The new element or a DomHelper config of an element to create\r
- * @return {Ext.Element} this\r
- */\r
- replaceWith: function(el){\r
- var me = this,\r
- Element = Ext.Element;\r
- if(isEl(el)){\r
- el = GETDOM(el);\r
- me.dom.parentNode.insertBefore(el, me.dom);\r
- }else{\r
- el = DH.insertBefore(me.dom, el);\r
- }\r
- \r
- delete Element.cache[me.id];\r
- Ext.removeNode(me.dom); \r
- me.id = Ext.id(me.dom = el);\r
- return Element.cache[me.id] = me; \r
- },\r
- \r
- /**\r
- * Creates the passed DomHelper config and appends it to this element or optionally inserts it before the passed child element.\r
- * @param {Object} config DomHelper element config object. If no tag is specified (e.g., {tag:'input'}) then a div will be\r
- * automatically generated with the specified attributes.\r
- * @param {HTMLElement} insertBefore (optional) a child element of this element\r
- * @param {Boolean} returnDom (optional) true to return the dom node instead of creating an Element\r
- * @return {Ext.Element} The new child element\r
- */\r
- createChild: function(config, insertBefore, returnDom){\r
- config = config || {tag:'div'};\r
- return insertBefore ? \r
- DH.insertBefore(insertBefore, config, returnDom !== true) : \r
- DH[!this.dom.firstChild ? 'overwrite' : 'append'](this.dom, config, returnDom !== true);\r
- },\r
- \r
- /**\r
- * Creates and wraps this element with another element\r
- * @param {Object} config (optional) DomHelper element config object for the wrapper element or null for an empty div\r
- * @param {Boolean} returnDom (optional) True to return the raw DOM element instead of Ext.Element\r
- * @return {HTMLElement/Element} The newly created wrapper element\r
- */\r
- wrap: function(config, returnDom){ \r
- var newEl = DH.insertBefore(this.dom, config || {tag: "div"}, !returnDom);\r
- newEl.dom ? newEl.dom.appendChild(this.dom) : newEl.appendChild(this.dom);\r
- return newEl;\r
- },\r
- \r
- /**\r
- * Inserts an html fragment into this element\r
- * @param {String} where Where to insert the html in relation to this element - beforeBegin, afterBegin, beforeEnd, afterEnd.\r
- * @param {String} html The HTML fragment\r
- * @param {Boolean} returnEl (optional) True to return an Ext.Element (defaults to false)\r
- * @return {HTMLElement/Ext.Element} The inserted node (or nearest related if more than 1 inserted)\r
- */\r
- insertHtml : function(where, html, returnEl){\r
- var el = DH.insertHtml(where, this.dom, html);\r
- return returnEl ? Ext.get(el) : el;\r
- }\r
- }\r
-}());/**\r
- * @class Ext.Element\r
- */\r
-Ext.apply(Ext.Element.prototype, function() {\r
- var GETDOM = Ext.getDom,\r
- GET = Ext.get,\r
- DH = Ext.DomHelper;\r
- \r
- return { \r
- /**\r
- * Inserts (or creates) the passed element (or DomHelper config) as a sibling of this element\r
- * @param {Mixed/Object/Array} el The id, element to insert or a DomHelper config to create and insert *or* an array of any of those.\r
- * @param {String} where (optional) 'before' or 'after' defaults to before\r
- * @param {Boolean} returnDom (optional) True to return the raw DOM element instead of Ext.Element\r
- * @return {Ext.Element} the inserted Element\r
- */\r
- insertSibling: function(el, where, returnDom){\r
- var me = this,\r
- rt;\r
- \r
- if(Ext.isArray(el)){ \r
- Ext.each(el, function(e) {\r
- rt = me.insertSibling(e, where, returnDom);\r
- });\r
- return rt;\r
- }\r
- \r
- where = (where || 'before').toLowerCase();\r
- el = el || {};\r
- \r
- if(el.nodeType || el.dom){\r
- rt = me.dom.parentNode.insertBefore(GETDOM(el), where == 'before' ? me.dom : me.dom.nextSibling);\r
- if (!returnDom) {\r
- rt = GET(rt);\r
- }\r
- }else{\r
- if (where == 'after' && !me.dom.nextSibling) {\r
- rt = DH.append(me.dom.parentNode, el, !returnDom);\r
- } else { \r
- rt = DH[where == 'after' ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom);\r
- }\r
- }\r
- return rt;\r
- }\r
- };\r
-}());/**\r
- * @class Ext.Element\r
- */\r
-Ext.Element.addMethods(function(){ \r
- // local style camelizing for speed\r
- var propCache = {},\r
- camelRe = /(-[a-z])/gi,\r
- classReCache = {},\r
- view = document.defaultView,\r
- propFloat = Ext.isIE ? 'styleFloat' : 'cssFloat',\r
- opacityRe = /alpha\(opacity=(.*)\)/i,\r
- trimRe = /^\s+|\s+$/g,\r
- EL = Ext.Element, \r
- PADDING = "padding",\r
- MARGIN = "margin",\r
- BORDER = "border",\r
- LEFT = "-left",\r
- RIGHT = "-right",\r
- TOP = "-top",\r
- BOTTOM = "-bottom",\r
- WIDTH = "-width", \r
- MATH = Math,\r
- HIDDEN = 'hidden',\r
- ISCLIPPED = 'isClipped',\r
- OVERFLOW = 'overflow',\r
- OVERFLOWX = 'overflow-x',\r
- OVERFLOWY = 'overflow-y',\r
- ORIGINALCLIP = 'originalClip',\r
- // special markup used throughout Ext when box wrapping elements \r
- borders = {l: BORDER + LEFT + WIDTH, r: BORDER + RIGHT + WIDTH, t: BORDER + TOP + WIDTH, b: BORDER + BOTTOM + WIDTH},\r
- paddings = {l: PADDING + LEFT, r: PADDING + RIGHT, t: PADDING + TOP, b: PADDING + BOTTOM},\r
- margins = {l: MARGIN + LEFT, r: MARGIN + RIGHT, t: MARGIN + TOP, b: MARGIN + BOTTOM},\r
- data = Ext.Element.data;\r
- \r
- \r
- // private \r
- function camelFn(m, a) {\r
- return a.charAt(1).toUpperCase();\r
- }\r
- \r
- // private (needs to be called => addStyles.call(this, sides, styles))\r
- function addStyles(sides, styles){\r
- var val = 0; \r
- \r
- Ext.each(sides.match(/\w/g), function(s) {\r
- if (s = parseInt(this.getStyle(styles[s]), 10)) {\r
- val += MATH.abs(s); \r
- }\r
- },\r
- this);\r
- return val;\r
- }\r
-\r
- function chkCache(prop) {\r
- return propCache[prop] || (propCache[prop] = prop == 'float' ? propFloat : prop.replace(camelRe, camelFn));\r
-\r
- }\r
- \r
- return { \r
- // private ==> used by Fx \r
- adjustWidth : function(width) {\r
- var me = this;\r
- var isNum = (typeof width == "number");\r
- if(isNum && me.autoBoxAdjust && !me.isBorderBox()){\r
- width -= (me.getBorderWidth("lr") + me.getPadding("lr"));\r
- }\r
- return (isNum && width < 0) ? 0 : width;\r
- },\r
- \r
- // private ==> used by Fx \r
- adjustHeight : function(height) {\r
- var me = this;\r
- var isNum = (typeof height == "number");\r
- if(isNum && me.autoBoxAdjust && !me.isBorderBox()){\r
- height -= (me.getBorderWidth("tb") + me.getPadding("tb")); \r
- }\r
- return (isNum && height < 0) ? 0 : height;\r
- },\r
- \r
- \r
- /**\r
- * Adds one or more CSS classes to the element. Duplicate classes are automatically filtered out.\r
- * @param {String/Array} className The CSS class to add, or an array of classes\r
- * @return {Ext.Element} this\r
- */\r
- addClass : function(className){\r
- var me = this;\r
- Ext.each(className, function(v) {\r
- me.dom.className += (!me.hasClass(v) && v ? " " + v : ""); \r
- });\r
- return me;\r
- },\r
- \r
- /**\r
- * Adds one or more CSS classes to this element and removes the same class(es) from all siblings.\r
- * @param {String/Array} className The CSS class to add, or an array of classes\r
- * @return {Ext.Element} this\r
- */\r
- radioClass : function(className){\r
- Ext.each(this.dom.parentNode.childNodes, function(v) {\r
- if(v.nodeType == 1) {\r
- Ext.fly(v, '_internal').removeClass(className); \r
- }\r
- });\r
- return this.addClass(className);\r
- },\r
- \r
- /**\r
- * Removes one or more CSS classes from the element.\r
- * @param {String/Array} className The CSS class to remove, or an array of classes\r
- * @return {Ext.Element} this\r
- */\r
- removeClass : function(className){\r
- var me = this;\r
- if (me.dom.className) {\r
- Ext.each(className, function(v) { \r
- me.dom.className = me.dom.className.replace(\r
- classReCache[v] = classReCache[v] || new RegExp('(?:^|\\s+)' + v + '(?:\\s+|$)', "g"), \r
- " "); \r
- }); \r
- }\r
- return me;\r
- },\r
- \r
- /**\r
- * Toggles the specified CSS class on this element (removes it if it already exists, otherwise adds it).\r
- * @param {String} className The CSS class to toggle\r
- * @return {Ext.Element} this\r
- */\r
- toggleClass : function(className){\r
- return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);\r
- },\r
- \r
- /**\r
- * Checks if the specified CSS class exists on this element's DOM node.\r
- * @param {String} className The CSS class to check for\r
- * @return {Boolean} True if the class exists, else false\r
- */\r
- hasClass : function(className){\r
- return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1;\r
- },\r
- \r
- /**\r
- * Replaces a CSS class on the element with another. If the old name does not exist, the new name will simply be added.\r
- * @param {String} oldClassName The CSS class to replace\r
- * @param {String} newClassName The replacement CSS class\r
- * @return {Ext.Element} this\r
- */\r
- replaceClass : function(oldClassName, newClassName){\r
- return this.removeClass(oldClassName).addClass(newClassName);\r
- },\r
- \r
- isStyle : function(style, val) {\r
- return this.getStyle(style) == val; \r
- },\r
- \r
- /**\r
- * Normalizes currentStyle and computedStyle.\r
- * @param {String} property The style property whose value is returned.\r
- * @return {String} The current value of the style property for this element.\r
- */\r
- getStyle : function(){ \r
- return view && view.getComputedStyle ?\r
- function(prop){\r
- var el = this.dom,\r
- v, \r
- cs;\r
- if(el == document) return null;\r
- prop = chkCache(prop);\r
- return (v = el.style[prop]) ? v : \r
- (cs = view.getComputedStyle(el, "")) ? cs[prop] : null;\r
- } :\r
- function(prop){ \r
- var el = this.dom, \r
- m, \r
- cs; \r
- \r
- if(el == document) return null; \r
- if (prop == 'opacity') {\r
- if (el.style.filter.match) { \r
- if(m = el.style.filter.match(opacityRe)){\r
- var fv = parseFloat(m[1]);\r
- if(!isNaN(fv)){\r
- return fv ? fv / 100 : 0;\r
- }\r
- }\r
- }\r
- return 1;\r
- }\r
- prop = chkCache(prop); \r
- return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);\r
- };\r
- }(),\r
- \r
- /**\r
- * Return the CSS color for the specified CSS attribute. rgb, 3 digit (like #fff) and valid values\r
- * are convert to standard 6 digit hex color.\r
- * @param {String} attr The css attribute\r
- * @param {String} defaultValue The default value to use when a valid color isn't found\r
- * @param {String} prefix (optional) defaults to #. Use an empty string when working with\r
- * color anims.\r
- */\r
- getColor : function(attr, defaultValue, prefix){\r
- var v = this.getStyle(attr),\r
- color = prefix || '#',\r
- h;\r
- \r
- if(!v || /transparent|inherit/.test(v)){\r
- return defaultValue;\r
- }\r
- if(/^r/.test(v)){\r
- Ext.each(v.slice(4, v.length -1).split(','), function(s){\r
- h = parseInt(s, 10);\r
- color += (h < 16 ? '0' : '') + h.toString(16); \r
- });\r
- }else{\r
- v = v.replace('#', '');\r
- color += v.length == 3 ? v.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : v;\r
- }\r
- return(color.length > 5 ? color.toLowerCase() : defaultValue);\r
- },\r
- \r
- /**\r
- * Wrapper for setting style properties, also takes single object parameter of multiple styles.\r
- * @param {String/Object} property The style property to be set, or an object of multiple styles.\r
- * @param {String} value (optional) The value to apply to the given property, or null if an object was passed.\r
- * @return {Ext.Element} this\r
- */\r
- setStyle : function(prop, value){\r
- var tmp, \r
- style,\r
- camel;\r
- if (!Ext.isObject(prop)) {\r
- tmp = {};\r
- tmp[prop] = value; \r
- prop = tmp;\r
- }\r
- for (style in prop) {\r
- value = prop[style]; \r
- style == 'opacity' ? \r
- this.setOpacity(value) : \r
- this.dom.style[chkCache(style)] = value;\r
- }\r
- return this;\r
- },\r
- \r
- /**\r
- * Set the opacity of the element\r
- * @param {Float} opacity The new opacity. 0 = transparent, .5 = 50% visibile, 1 = fully visible, etc\r
- * @param {Boolean/Object} animate (optional) a standard Element animation config object or <tt>true</tt> for\r
- * the default animation (<tt>{duration: .35, easing: 'easeIn'}</tt>)\r
- * @return {Ext.Element} this\r
- */\r
- setOpacity : function(opacity, animate){\r
- var me = this,\r
- s = me.dom.style;\r
- \r
- if(!animate || !me.anim){ \r
- if(Ext.isIE){\r
- var opac = opacity < 1 ? 'alpha(opacity=' + opacity * 100 + ')' : '', \r
- val = s.filter.replace(opacityRe, '').replace(trimRe, '');\r
-\r
- s.zoom = 1;\r
- s.filter = val + (val.length > 0 ? ' ' : '') + opac;\r
- }else{\r
- s.opacity = opacity;\r
- }\r
- }else{\r
- me.anim({opacity: {to: opacity}}, me.preanim(arguments, 1), null, .35, 'easeIn');\r
- }\r
- return me;\r
- },\r
- \r
- /**\r
- * Clears any opacity settings from this element. Required in some cases for IE.\r
- * @return {Ext.Element} this\r
- */\r
- clearOpacity : function(){\r
- var style = this.dom.style;\r
- if(Ext.isIE){\r
- if(!Ext.isEmpty(style.filter)){\r
- style.filter = style.filter.replace(opacityRe, '').replace(trimRe, '');\r
- }\r
- }else{\r
- style.opacity = style['-moz-opacity'] = style['-khtml-opacity'] = '';\r
- }\r
- return this;\r
- },\r
- \r
- /**\r
- * Returns the offset height of the element\r
- * @param {Boolean} contentHeight (optional) true to get the height minus borders and padding\r
- * @return {Number} The element's height\r
- */\r
- getHeight : function(contentHeight){\r
- var me = this,\r
- dom = me.dom,\r
- h = MATH.max(dom.offsetHeight, dom.clientHeight) || 0;\r
- h = !contentHeight ? h : h - me.getBorderWidth("tb") - me.getPadding("tb");\r
- return h < 0 ? 0 : h;\r
- },\r
- \r
- /**\r
- * Returns the offset width of the element\r
- * @param {Boolean} contentWidth (optional) true to get the width minus borders and padding\r
- * @return {Number} The element's width\r
- */\r
- getWidth : function(contentWidth){\r
- var me = this,\r
- dom = me.dom,\r
- w = MATH.max(dom.offsetWidth, dom.clientWidth) || 0;\r
- w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");\r
- return w < 0 ? 0 : w;\r
- },\r
- \r
- /**\r
- * Set the width of this Element.\r
- * @param {Mixed} width The new width. This may be one of:<div class="mdetail-params"><ul>\r
- * <li>A Number specifying the new width in this Element's {@link #defaultUnit}s (by default, pixels).</li>\r
- * <li>A String used to set the CSS width style. Animation may <b>not</b> be used.\r
- * </ul></div>\r
- * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object\r
- * @return {Ext.Element} this\r
- */\r
- setWidth : function(width, animate){\r
- var me = this;\r
- width = me.adjustWidth(width);\r
- !animate || !me.anim ? \r
- me.dom.style.width = me.addUnits(width) :\r
- me.anim({width : {to : width}}, me.preanim(arguments, 1));\r
- return me;\r
- },\r
- \r
- /**\r
- * Set the height of this Element.\r
- * <pre><code>\r
-// change the height to 200px and animate with default configuration\r
-Ext.fly('elementId').setHeight(200, true);\r
-\r
-// change the height to 150px and animate with a custom configuration\r
-Ext.fly('elId').setHeight(150, {\r
- duration : .5, // animation will have a duration of .5 seconds\r
- // will change the content to "finished"\r
- callback: function(){ this.{@link #update}("finished"); } \r
-});\r
- * </code></pre>\r
- * @param {Mixed} height The new height. This may be one of:<div class="mdetail-params"><ul>\r
- * <li>A Number specifying the new height in this Element's {@link #defaultUnit}s (by default, pixels.)</li>\r
- * <li>A String used to set the CSS height style. Animation may <b>not</b> be used.</li>\r
- * </ul></div>\r
- * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object\r
- * @return {Ext.Element} this\r
- */\r
- setHeight : function(height, animate){\r
- var me = this;\r
- height = me.adjustHeight(height);\r
- !animate || !me.anim ? \r
- me.dom.style.height = me.addUnits(height) :\r
- me.anim({height : {to : height}}, me.preanim(arguments, 1));\r
- return me;\r
- },\r
- \r
- /**\r
- * Gets the width of the border(s) for the specified side(s)\r
- * @param {String} side Can be t, l, r, b or any combination of those to add multiple values. For example,\r
- * passing <tt>'lr'</tt> would get the border <b><u>l</u></b>eft width + the border <b><u>r</u></b>ight width.\r
- * @return {Number} The width of the sides passed added together\r
- */\r
- getBorderWidth : function(side){\r
- return addStyles.call(this, side, borders);\r
- },\r
- \r
- /**\r
- * Gets the width of the padding(s) for the specified side(s)\r
- * @param {String} side Can be t, l, r, b or any combination of those to add multiple values. For example,\r
- * passing <tt>'lr'</tt> would get the padding <b><u>l</u></b>eft + the padding <b><u>r</u></b>ight.\r
- * @return {Number} The padding of the sides passed added together\r
- */\r
- getPadding : function(side){\r
- return addStyles.call(this, side, paddings);\r
- },\r
- \r
- /**\r
- * Store the current overflow setting and clip overflow on the element - use <tt>{@link #unclip}</tt> to remove\r
- * @return {Ext.Element} this\r
- */\r
- clip : function(){\r
- var me = this,\r
- dom = me.dom;\r
- \r
- if(!data(dom, ISCLIPPED)){\r
- data(dom, ISCLIPPED, true);\r
- data(dom, ORIGINALCLIP, {\r
- o: me.getStyle(OVERFLOW),\r
- x: me.getStyle(OVERFLOWX),\r
- y: me.getStyle(OVERFLOWY)\r
- });\r
- me.setStyle(OVERFLOW, HIDDEN);\r
- me.setStyle(OVERFLOWX, HIDDEN);\r
- me.setStyle(OVERFLOWY, HIDDEN);\r
- }\r
- return me;\r
- },\r
- \r
- /**\r
- * Return clipping (overflow) to original clipping before <tt>{@link #clip}</tt> was called\r
- * @return {Ext.Element} this\r
- */\r
- unclip : function(){\r
- var me = this,\r
- dom = me.dom;\r
- \r
- if(data(dom, ISCLIPPED)){\r
- data(dom, ISCLIPPED, false);\r
- var o = data(dom, ORIGINALCLIP);\r
- if(o.o){\r
- me.setStyle(OVERFLOW, o.o);\r
- }\r
- if(o.x){\r
- me.setStyle(OVERFLOWX, o.x);\r
- }\r
- if(o.y){\r
- me.setStyle(OVERFLOWY, o.y);\r
- }\r
- }\r
- return me;\r
- },\r
- \r
- addStyles : addStyles,\r
- margins : margins\r
- }\r
-}() \r
-);/**\r
- * @class Ext.Element\r
- */\r
-\r
-// special markup used throughout Ext when box wrapping elements\r
-Ext.Element.boxMarkup = '<div class="{0}-tl"><div class="{0}-tr"><div class="{0}-tc"></div></div></div><div class="{0}-ml"><div class="{0}-mr"><div class="{0}-mc"></div></div></div><div class="{0}-bl"><div class="{0}-br"><div class="{0}-bc"></div></div></div>';\r
-\r
-Ext.Element.addMethods(function(){\r
- var INTERNAL = "_internal";\r
- return {\r
- /**\r
- * More flexible version of {@link #setStyle} for setting style properties.\r
- * @param {String/Object/Function} styles A style specification string, e.g. "width:100px", or object in the form {width:"100px"}, or\r
- * a function which returns such a specification.\r
- * @return {Ext.Element} this\r
- */\r
- applyStyles : function(style){\r
- Ext.DomHelper.applyStyles(this.dom, style);\r
- return this;\r
- },\r
-\r
- /**\r
- * Returns an object with properties matching the styles requested.\r
- * For example, el.getStyles('color', 'font-size', 'width') might return\r
- * {'color': '#FFFFFF', 'font-size': '13px', 'width': '100px'}.\r
- * @param {String} style1 A style name\r
- * @param {String} style2 A style name\r
- * @param {String} etc.\r
- * @return {Object} The style object\r
- */\r
- getStyles : function(){\r
- var ret = {};\r
- Ext.each(arguments, function(v) {\r
- ret[v] = this.getStyle(v);\r
- },\r
- this);\r
- return ret;\r
- },\r
-\r
- getStyleSize : function(){\r
- var me = this,\r
- w,\r
- h,\r
- d = this.dom,\r
- s = d.style;\r
- if(s.width && s.width != 'auto'){\r
- w = parseInt(s.width, 10);\r
- if(me.isBorderBox()){\r
- w -= me.getFrameWidth('lr');\r
- }\r
- }\r
- if(s.height && s.height != 'auto'){\r
- h = parseInt(s.height, 10);\r
- if(me.isBorderBox()){\r
- h -= me.getFrameWidth('tb');\r
- }\r
- }\r
- return {width: w || me.getWidth(true), height: h || me.getHeight(true)};\r
- },\r
-\r
- // private ==> used by ext full\r
- setOverflow : function(v){\r
- var dom = this.dom;\r
- if(v=='auto' && Ext.isMac && Ext.isGecko2){ // work around stupid FF 2.0/Mac scroll bar bug\r
- dom.style.overflow = 'hidden';\r
- (function(){dom.style.overflow = 'auto';}).defer(1);\r
- }else{\r
- dom.style.overflow = v;\r
- }\r
- },\r
-\r
- /**\r
- * <p>Wraps the specified element with a special 9 element markup/CSS block that renders by default as\r
- * a gray container with a gradient background, rounded corners and a 4-way shadow.</p>\r
- * <p>This special markup is used throughout Ext when box wrapping elements ({@link Ext.Button},\r
- * {@link Ext.Panel} when <tt>{@link Ext.Panel#frame frame=true}</tt>, {@link Ext.Window}). The markup\r
- * is of this form:</p>\r
- * <pre><code>\r
-Ext.Element.boxMarkup =\r
- '<div class="{0}-tl"><div class="{0}-tr"><div class="{0}-tc"></div></div></div>\r
- <div class="{0}-ml"><div class="{0}-mr"><div class="{0}-mc"></div></div></div>\r
- <div class="{0}-bl"><div class="{0}-br"><div class="{0}-bc"></div></div></div>';\r
- * </code></pre>\r
- * <p>Example usage:</p>\r
- * <pre><code>\r
-// Basic box wrap\r
-Ext.get("foo").boxWrap();\r
-\r
-// You can also add a custom class and use CSS inheritance rules to customize the box look.\r
-// 'x-box-blue' is a built-in alternative -- look at the related CSS definitions as an example\r
-// for how to create a custom box wrap style.\r
-Ext.get("foo").boxWrap().addClass("x-box-blue");\r
- * </code></pre>\r
- * @param {String} class (optional) A base CSS class to apply to the containing wrapper element\r
- * (defaults to <tt>'x-box'</tt>). Note that there are a number of CSS rules that are dependent on\r
- * this name to make the overall effect work, so if you supply an alternate base class, make sure you\r
- * also supply all of the necessary rules.\r
- * @return {Ext.Element} this\r
- */\r
- boxWrap : function(cls){\r
- cls = cls || 'x-box';\r
- var el = Ext.get(this.insertHtml("beforeBegin", "<div class='" + cls + "'>" + String.format(Ext.Element.boxMarkup, cls) + "</div>")); //String.format('<div class="{0}">'+Ext.Element.boxMarkup+'</div>', cls)));\r
- Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom);\r
- return el;\r
- },\r
-\r
- /**\r
- * Set the size of this Element. If animation is true, both width and height will be animated concurrently.\r
- * @param {Mixed} width The new width. This may be one of:<div class="mdetail-params"><ul>\r
- * <li>A Number specifying the new width in this Element's {@link #defaultUnit}s (by default, pixels).</li>\r
- * <li>A String used to set the CSS width style. Animation may <b>not</b> be used.\r
- * <li>A size object in the format <code>{width: widthValue, height: heightValue}</code>.</li>\r
- * </ul></div>\r
- * @param {Mixed} height The new height. This may be one of:<div class="mdetail-params"><ul>\r
- * <li>A Number specifying the new height in this Element's {@link #defaultUnit}s (by default, pixels).</li>\r
- * <li>A String used to set the CSS height style. Animation may <b>not</b> be used.</li>\r
- * </ul></div>\r
- * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object\r
- * @return {Ext.Element} this\r
- */\r
- setSize : function(width, height, animate){\r
- var me = this;\r
- if(Ext.isObject(width)){ // in case of object from getSize()\r
- height = width.height;\r
- width = width.width;\r
- }\r
- width = me.adjustWidth(width);\r
- height = me.adjustHeight(height);\r
- if(!animate || !me.anim){\r
- me.dom.style.width = me.addUnits(width);\r
- me.dom.style.height = me.addUnits(height);\r
- }else{\r
- me.anim({width: {to: width}, height: {to: height}}, me.preanim(arguments, 2));\r
- }\r
- return me;\r
- },\r
-\r
- /**\r
- * Returns either the offsetHeight or the height of this element based on CSS height adjusted by padding or borders\r
- * when needed to simulate offsetHeight when offsets aren't available. This may not work on display:none elements\r
- * if a height has not been set using CSS.\r
- * @return {Number}\r
- */\r
- getComputedHeight : function(){\r
- var me = this,\r
- h = Math.max(me.dom.offsetHeight, me.dom.clientHeight);\r
- if(!h){\r
- h = parseInt(me.getStyle('height'), 10) || 0;\r
- if(!me.isBorderBox()){\r
- h += me.getFrameWidth('tb');\r
- }\r
- }\r
- return h;\r
- },\r
-\r
- /**\r
- * Returns either the offsetWidth or the width of this element based on CSS width adjusted by padding or borders\r
- * when needed to simulate offsetWidth when offsets aren't available. This may not work on display:none elements\r
- * if a width has not been set using CSS.\r
- * @return {Number}\r
- */\r
- getComputedWidth : function(){\r
- var w = Math.max(this.dom.offsetWidth, this.dom.clientWidth);\r
- if(!w){\r
- w = parseInt(this.getStyle('width'), 10) || 0;\r
- if(!this.isBorderBox()){\r
- w += this.getFrameWidth('lr');\r
- }\r
- }\r
- return w;\r
- },\r
-\r
- /**\r
- * Returns the sum width of the padding and borders for the passed "sides". See getBorderWidth()\r
- for more information about the sides.\r
- * @param {String} sides\r
- * @return {Number}\r
- */\r
- getFrameWidth : function(sides, onlyContentBox){\r
- return onlyContentBox && this.isBorderBox() ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides));\r
- },\r
-\r
- /**\r
- * Sets up event handlers to add and remove a css class when the mouse is over this element\r
- * @param {String} className\r
- * @return {Ext.Element} this\r
- */\r
- addClassOnOver : function(className){\r
- this.hover(\r
- function(){\r
- Ext.fly(this, INTERNAL).addClass(className);\r
- },\r
- function(){\r
- Ext.fly(this, INTERNAL).removeClass(className);\r
- }\r
- );\r
- return this;\r
- },\r
-\r
- /**\r
- * Sets up event handlers to add and remove a css class when this element has the focus\r
- * @param {String} className\r
- * @return {Ext.Element} this\r
- */\r
- addClassOnFocus : function(className){\r
- this.on("focus", function(){\r
- Ext.fly(this, INTERNAL).addClass(className);\r
- }, this.dom);\r
- this.on("blur", function(){\r
- Ext.fly(this, INTERNAL).removeClass(className);\r
- }, this.dom);\r
- return this;\r
- },\r
-\r
- /**\r
- * Sets up event handlers to add and remove a css class when the mouse is down and then up on this element (a click effect)\r
- * @param {String} className\r
- * @return {Ext.Element} this\r
- */\r
- addClassOnClick : function(className){\r
- var dom = this.dom;\r
- this.on("mousedown", function(){\r
- Ext.fly(dom, INTERNAL).addClass(className);\r
- var d = Ext.getDoc(),\r
- fn = function(){\r
- Ext.fly(dom, INTERNAL).removeClass(className);\r
- d.removeListener("mouseup", fn);\r
- };\r
- d.on("mouseup", fn);\r
- });\r
- return this;\r
- },\r
-\r
- /**\r
- * Returns the width and height of the viewport.\r
- * <pre><code>\r
- var vpSize = Ext.getBody().getViewSize();\r
-\r
- // all Windows created afterwards will have a default value of 90% height and 95% width\r
- Ext.Window.override({\r
- width: vpSize.width * 0.9,\r
- height: vpSize.height * 0.95\r
- });\r
- // To handle window resizing you would have to hook onto onWindowResize.\r
- </code></pre>\r
- * @return {Object} An object containing the viewport's size {width: (viewport width), height: (viewport height)}\r
- */\r
- getViewSize : function(){\r
- var doc = document,\r
- d = this.dom,\r
- extdom = Ext.lib.Dom,\r
- isDoc = (d == doc || d == doc.body);\r
- return { width : (isDoc ? extdom.getViewWidth() : d.clientWidth),\r
- height : (isDoc ? extdom.getViewHeight() : d.clientHeight) };\r
- },\r
-\r
- /**\r
- * Returns the size of the element.\r
- * @param {Boolean} contentSize (optional) true to get the width/size minus borders and padding\r
- * @return {Object} An object containing the element's size {width: (element width), height: (element height)}\r
- */\r
- getSize : function(contentSize){\r
- return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)};\r
- },\r
-\r
- /**\r
- * Forces the browser to repaint this element\r
- * @return {Ext.Element} this\r
- */\r
- repaint : function(){\r
- var dom = this.dom;\r
- this.addClass("x-repaint");\r
- setTimeout(function(){\r
- Ext.fly(dom).removeClass("x-repaint");\r
- }, 1);\r
- return this;\r
- },\r
-\r
- /**\r
- * Disables text selection for this element (normalized across browsers)\r
- * @return {Ext.Element} this\r
- */\r
- unselectable : function(){\r
- this.dom.unselectable = "on";\r
- return this.swallowEvent("selectstart", true).\r
- applyStyles("-moz-user-select:none;-khtml-user-select:none;").\r
- addClass("x-unselectable");\r
- },\r
-\r
- /**\r
- * Returns an object with properties top, left, right and bottom representing the margins of this element unless sides is passed,\r
- * then it returns the calculated width of the sides (see getPadding)\r
- * @param {String} sides (optional) Any combination of l, r, t, b to get the sum of those sides\r
- * @return {Object/Number}\r
- */\r
- getMargins : function(side){\r
- var me = this,\r
- key,\r
- hash = {t:"top", l:"left", r:"right", b: "bottom"},\r
- o = {};\r
-\r
- if (!side) {\r
- for (key in me.margins){\r
- o[hash[key]] = parseInt(me.getStyle(me.margins[key]), 10) || 0;\r
- }\r
- return o;\r
- } else {\r
- return me.addStyles.call(me, side, me.margins);\r
- }\r
- }\r
- };\r
-}());/**\r
- * @class Ext.Element\r
- */\r
-(function(){\r
-var D = Ext.lib.Dom,\r
- LEFT = "left",\r
- RIGHT = "right",\r
- TOP = "top",\r
- BOTTOM = "bottom",\r
- POSITION = "position",\r
- STATIC = "static",\r
- RELATIVE = "relative",\r
- AUTO = "auto",\r
- ZINDEX = "z-index";\r
-\r
-function animTest(args, animate, i) {\r
- return this.preanim && !!animate ? this.preanim(args, i) : false \r
-}\r
-\r
-Ext.Element.addMethods({\r
- /**\r
- * Gets the current X position of the element based on page coordinates. Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).\r
- * @return {Number} The X position of the element\r
- */\r
- getX : function(){\r
- return D.getX(this.dom);\r
- },\r
-\r
- /**\r
- * Gets the current Y position of the element based on page coordinates. Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).\r
- * @return {Number} The Y position of the element\r
- */\r
- getY : function(){\r
- return D.getY(this.dom);\r
- },\r
-\r
- /**\r
- * Gets the current position of the element based on page coordinates. Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).\r
- * @return {Array} The XY position of the element\r
- */\r
- getXY : function(){\r
- return D.getXY(this.dom);\r
- },\r
-\r
- /**\r
- * Returns the offsets of this element from the passed element. Both element must be part of the DOM tree and not have display:none to have page coordinates.\r
- * @param {Mixed} element The element to get the offsets from.\r
- * @return {Array} The XY page offsets (e.g. [100, -200])\r
- */\r
- getOffsetsTo : function(el){\r
- var o = this.getXY(),\r
- e = Ext.fly(el, '_internal').getXY();\r
- return [o[0]-e[0],o[1]-e[1]];\r
- },\r
-\r
- /**\r
- * Sets the X position of the element based on page coordinates. Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).\r
- * @param {Number} The X position of the element\r
- * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object\r
- * @return {Ext.Element} this\r
- */\r
- setX : function(x, animate){ \r
- return this.setXY([x, this.getY()], animTest.call(this, arguments, animate, 1));\r
- },\r
-\r
- /**\r
- * Sets the Y position of the element based on page coordinates. Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).\r
- * @param {Number} The Y position of the element\r
- * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object\r
- * @return {Ext.Element} this\r
- */\r
- setY : function(y, animate){ \r
- return this.setXY([this.getX(), y], animTest.call(this, arguments, animate, 1));\r
- },\r
-\r
- /**\r
- * Sets the element's left position directly using CSS style (instead of {@link #setX}).\r
- * @param {String} left The left CSS property value\r
- * @return {Ext.Element} this\r
- */\r
- setLeft : function(left){\r
- this.setStyle(LEFT, this.addUnits(left));\r
- return this;\r
- },\r
-\r
- /**\r
- * Sets the element's top position directly using CSS style (instead of {@link #setY}).\r
- * @param {String} top The top CSS property value\r
- * @return {Ext.Element} this\r
- */\r
- setTop : function(top){\r
- this.setStyle(TOP, this.addUnits(top));\r
- return this;\r
- },\r
-\r
- /**\r
- * Sets the element's CSS right style.\r
- * @param {String} right The right CSS property value\r
- * @return {Ext.Element} this\r
- */\r
- setRight : function(right){\r
- this.setStyle(RIGHT, this.addUnits(right));\r
- return this;\r
- },\r
-\r
- /**\r
- * Sets the element's CSS bottom style.\r
- * @param {String} bottom The bottom CSS property value\r
- * @return {Ext.Element} this\r
- */\r
- setBottom : function(bottom){\r
- this.setStyle(BOTTOM, this.addUnits(bottom));\r
- return this;\r
- },\r
-\r
- /**\r
- * Sets the position of the element in page coordinates, regardless of how the element is positioned.\r
- * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).\r
- * @param {Array} pos Contains X & Y [x, y] values for new position (coordinates are page-based)\r
- * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object\r
- * @return {Ext.Element} this\r
- */\r
- setXY : function(pos, animate){\r
- var me = this;\r
- if(!animate || !me.anim){\r
- D.setXY(me.dom, pos);\r
- }else{\r
- me.anim({points: {to: pos}}, me.preanim(arguments, 1), 'motion');\r
- }\r
- return me;\r
- },\r
-\r
- /**\r
- * Sets the position of the element in page coordinates, regardless of how the element is positioned.\r
- * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).\r
- * @param {Number} x X value for new position (coordinates are page-based)\r
- * @param {Number} y Y value for new position (coordinates are page-based)\r
- * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object\r
- * @return {Ext.Element} this\r
- */\r
- setLocation : function(x, y, animate){\r
- return this.setXY([x, y], animTest.call(this, arguments, animate, 2));\r
- },\r
-\r
- /**\r
- * Sets the position of the element in page coordinates, regardless of how the element is positioned.\r
- * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).\r
- * @param {Number} x X value for new position (coordinates are page-based)\r
- * @param {Number} y Y value for new position (coordinates are page-based)\r
- * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object\r
- * @return {Ext.Element} this\r
- */\r
- moveTo : function(x, y, animate){\r
- return this.setXY([x, y], animTest.call(this, arguments, animate, 2)); \r
- }, \r
- \r
- /**\r
- * Gets the left X coordinate\r
- * @param {Boolean} local True to get the local css position instead of page coordinate\r
- * @return {Number}\r
- */\r
- getLeft : function(local){\r
- return !local ? this.getX() : parseInt(this.getStyle(LEFT), 10) || 0;\r
- },\r
-\r
- /**\r
- * Gets the right X coordinate of the element (element X position + element width)\r
- * @param {Boolean} local True to get the local css position instead of page coordinate\r
- * @return {Number}\r
- */\r
- getRight : function(local){\r
- var me = this;\r
- return !local ? me.getX() + me.getWidth() : (me.getLeft(true) + me.getWidth()) || 0;\r
- },\r
-\r
- /**\r
- * Gets the top Y coordinate\r
- * @param {Boolean} local True to get the local css position instead of page coordinate\r
- * @return {Number}\r
- */\r
- getTop : function(local) {\r
- return !local ? this.getY() : parseInt(this.getStyle(TOP), 10) || 0;\r
- },\r
-\r
- /**\r
- * Gets the bottom Y coordinate of the element (element Y position + element height)\r
- * @param {Boolean} local True to get the local css position instead of page coordinate\r
- * @return {Number}\r
- */\r
- getBottom : function(local){\r
- var me = this;\r
- return !local ? me.getY() + me.getHeight() : (me.getTop(true) + me.getHeight()) || 0;\r
- },\r
-\r
- /**\r
- * Initializes positioning on this element. If a desired position is not passed, it will make the\r
- * the element positioned relative IF it is not already positioned.\r
- * @param {String} pos (optional) Positioning to use "relative", "absolute" or "fixed"\r
- * @param {Number} zIndex (optional) The zIndex to apply\r
- * @param {Number} x (optional) Set the page X position\r
- * @param {Number} y (optional) Set the page Y position\r
- */\r
- position : function(pos, zIndex, x, y){\r
- var me = this;\r
- \r
- if(!pos && me.isStyle(POSITION, STATIC)){ \r
- me.setStyle(POSITION, RELATIVE); \r
- } else if(pos) {\r
- me.setStyle(POSITION, pos);\r
- }\r
- if(zIndex){\r
- me.setStyle(ZINDEX, zIndex);\r
- }\r
- if(x || y) me.setXY([x || false, y || false]);\r
- },\r
-\r
- /**\r
- * Clear positioning back to the default when the document was loaded\r
- * @param {String} value (optional) The value to use for the left,right,top,bottom, defaults to '' (empty string). You could use 'auto'.\r
- * @return {Ext.Element} this\r
- */\r
- clearPositioning : function(value){\r
- value = value || '';\r
- this.setStyle({\r
- left : value,\r
- right : value,\r
- top : value,\r
- bottom : value,\r
- "z-index" : "",\r
- position : STATIC\r
- });\r
- return this;\r
- },\r
-\r
- /**\r
- * Gets an object with all CSS positioning properties. Useful along with setPostioning to get\r
- * snapshot before performing an update and then restoring the element.\r
- * @return {Object}\r
- */\r
- getPositioning : function(){\r
- var l = this.getStyle(LEFT);\r
- var t = this.getStyle(TOP);\r
- return {\r
- "position" : this.getStyle(POSITION),\r
- "left" : l,\r
- "right" : l ? "" : this.getStyle(RIGHT),\r
- "top" : t,\r
- "bottom" : t ? "" : this.getStyle(BOTTOM),\r
- "z-index" : this.getStyle(ZINDEX)\r
- };\r
- },\r
- \r
- /**\r
- * Set positioning with an object returned by getPositioning().\r
- * @param {Object} posCfg\r
- * @return {Ext.Element} this\r
- */\r
- setPositioning : function(pc){\r
- var me = this,\r
- style = me.dom.style;\r
- \r
- me.setStyle(pc);\r
- \r
- if(pc.right == AUTO){\r
- style.right = "";\r
- }\r
- if(pc.bottom == AUTO){\r
- style.bottom = "";\r
- }\r
- \r
- return me;\r
- }, \r
- \r
- /**\r
- * Translates the passed page coordinates into left/top css values for this element\r
- * @param {Number/Array} x The page x or an array containing [x, y]\r
- * @param {Number} y (optional) The page y, required if x is not an array\r
- * @return {Object} An object with left and top properties. e.g. {left: (value), top: (value)}\r
- */\r
- translatePoints : function(x, y){ \r
- y = isNaN(x[1]) ? y : x[1];\r
- x = isNaN(x[0]) ? x : x[0];\r
- var me = this,\r
- relative = me.isStyle(POSITION, RELATIVE),\r
- o = me.getXY(),\r
- l = parseInt(me.getStyle(LEFT), 10),\r
- t = parseInt(me.getStyle(TOP), 10);\r
- \r
- l = !isNaN(l) ? l : (relative ? 0 : me.dom.offsetLeft);\r
- t = !isNaN(t) ? t : (relative ? 0 : me.dom.offsetTop); \r
-\r
- return {left: (x - o[0] + l), top: (y - o[1] + t)}; \r
- },\r
- \r
- animTest : animTest\r
-});\r
-})();/**\r
- * @class Ext.Element\r
- */\r
-Ext.Element.addMethods({\r
- /**\r
- * Sets the element's box. Use getBox() on another element to get a box obj. If animate is true then width, height, x and y will be animated concurrently.\r
- * @param {Object} box The box to fill {x, y, width, height}\r
- * @param {Boolean} adjust (optional) Whether to adjust for box-model issues automatically\r
- * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object\r
- * @return {Ext.Element} this\r
- */\r
- setBox : function(box, adjust, animate){\r
- var me = this,\r
- w = box.width, \r
- h = box.height;\r
- if((adjust && !me.autoBoxAdjust) && !me.isBorderBox()){\r
- w -= (me.getBorderWidth("lr") + me.getPadding("lr"));\r
- h -= (me.getBorderWidth("tb") + me.getPadding("tb"));\r
- }\r
- me.setBounds(box.x, box.y, w, h, me.animTest.call(me, arguments, animate, 2));\r
- return me;\r
- },\r
- \r
- /**\r
- * Return a box {x, y, width, height} that can be used to set another elements\r
- * size/location to match this element.\r
- * @param {Boolean} contentBox (optional) If true a box for the content of the element is returned.\r
- * @param {Boolean} local (optional) If true the element's left and top are returned instead of page x/y.\r
- * @return {Object} box An object in the format {x, y, width, height}\r
- */\r
- getBox : function(contentBox, local) { \r
- var me = this,\r
- xy,\r
- left,\r
- top,\r
- getBorderWidth = me.getBorderWidth,\r
- getPadding = me.getPadding, \r
- l,\r
- r,\r
- t,\r
- b;\r
- if(!local){\r
- xy = me.getXY();\r
- }else{\r
- left = parseInt(me.getStyle("left"), 10) || 0;\r
- top = parseInt(me.getStyle("top"), 10) || 0;\r
- xy = [left, top];\r
- }\r
- var el = me.dom, w = el.offsetWidth, h = el.offsetHeight, bx;\r
- if(!contentBox){\r
- bx = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: w, height: h};\r
- }else{\r
- l = getBorderWidth.call(me, "l") + getPadding.call(me, "l");\r
- r = getBorderWidth.call(me, "r") + getPadding.call(me, "r");\r
- t = getBorderWidth.call(me, "t") + getPadding.call(me, "t");\r
- b = getBorderWidth.call(me, "b") + getPadding.call(me, "b");\r
- bx = {x: xy[0]+l, y: xy[1]+t, 0: xy[0]+l, 1: xy[1]+t, width: w-(l+r), height: h-(t+b)};\r
- }\r
- bx.right = bx.x + bx.width;\r
- bx.bottom = bx.y + bx.height;\r
- return bx;\r
- },\r
- \r
- /**\r
- * Move this element relative to its current position.\r
- * @param {String} direction Possible values are: "l" (or "left"), "r" (or "right"), "t" (or "top", or "up"), "b" (or "bottom", or "down").\r
- * @param {Number} distance How far to move the element in pixels\r
- * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object\r
- * @return {Ext.Element} this\r
- */\r
- move : function(direction, distance, animate){\r
- var me = this, \r
- xy = me.getXY(),\r
- x = xy[0],\r
- y = xy[1], \r
- left = [x - distance, y],\r
- right = [x + distance, y],\r
- top = [x, y - distance],\r
- bottom = [x, y + distance],\r
- hash = {\r
- l : left,\r
- left : left,\r
- r : right,\r
- right : right,\r
- t : top,\r
- top : top,\r
- up : top,\r
- b : bottom, \r
- bottom : bottom,\r
- down : bottom \r
- };\r
- \r
- direction = direction.toLowerCase(); \r
- me.moveTo(hash[direction][0], hash[direction][1], me.animTest.call(me, arguments, animate, 2));\r
- },\r
- \r
- /**\r
- * Quick set left and top adding default units\r
- * @param {String} left The left CSS property value\r
- * @param {String} top The top CSS property value\r
- * @return {Ext.Element} this\r
- */\r
- setLeftTop : function(left, top){\r
- var me = this,\r
- style = me.dom.style;\r
- style.left = me.addUnits(left);\r
- style.top = me.addUnits(top);\r
- return me;\r
- },\r
- \r
- /**\r
- * Returns the region of the given element.\r
- * The element must be part of the DOM tree to have a region (display:none or elements not appended return false).\r
- * @return {Region} A Ext.lib.Region containing "top, left, bottom, right" member data.\r
- */\r
- getRegion : function(){\r
- return Ext.lib.Dom.getRegion(this.dom);\r
- },\r
- \r
- /**\r
- * Sets the element's position and size in one shot. If animation is true then width, height, x and y will be animated concurrently.\r
- * @param {Number} x X value for new position (coordinates are page-based)\r
- * @param {Number} y Y value for new position (coordinates are page-based)\r
- * @param {Mixed} width The new width. This may be one of:<div class="mdetail-params"><ul>\r
- * <li>A Number specifying the new width in this Element's {@link #defaultUnit}s (by default, pixels)</li>\r
- * <li>A String used to set the CSS width style. Animation may <b>not</b> be used.\r
- * </ul></div>\r
- * @param {Mixed} height The new height. This may be one of:<div class="mdetail-params"><ul>\r
- * <li>A Number specifying the new height in this Element's {@link #defaultUnit}s (by default, pixels)</li>\r
- * <li>A String used to set the CSS height style. Animation may <b>not</b> be used.</li>\r
- * </ul></div>\r
- * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object\r
- * @return {Ext.Element} this\r
- */\r
- setBounds : function(x, y, width, height, animate){\r
- var me = this;\r
- if (!animate || !me.anim) {\r
- me.setSize(width, height);\r
- me.setLocation(x, y);\r
- } else {\r
- me.anim({points: {to: [x, y]}, \r
- width: {to: me.adjustWidth(width)}, \r
- height: {to: me.adjustHeight(height)}},\r
- me.preanim(arguments, 4), \r
- 'motion');\r
- }\r
- return me;\r
- },\r
-\r
- /**\r
- * Sets the element's position and size the specified region. If animation is true then width, height, x and y will be animated concurrently.\r
- * @param {Ext.lib.Region} region The region to fill\r
- * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object\r
- * @return {Ext.Element} this\r
- */\r
- setRegion : function(region, animate) {\r
- return this.setBounds(region.left, region.top, region.right-region.left, region.bottom-region.top, this.animTest.call(this, arguments, animate, 1));\r
- }\r
-});/**\r
- * @class Ext.Element\r
- */\r
-Ext.Element.addMethods({\r
- /**\r
- * Returns true if this element is scrollable.\r
- * @return {Boolean}\r
- */\r
- isScrollable : function(){\r
- var dom = this.dom;\r
- return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth;\r
- },\r
-\r
- /**\r
- * Scrolls this element the specified scroll point. It does NOT do bounds checking so if you scroll to a weird value it will try to do it. For auto bounds checking, use scroll().\r
- * @param {String} side Either "left" for scrollLeft values or "top" for scrollTop values.\r
- * @param {Number} value The new scroll value.\r
- * @return {Element} this\r
- */\r
- scrollTo : function(side, value){\r
- this.dom["scroll" + (/top/i.test(side) ? "Top" : "Left")] = value;\r
- return this;\r
- },\r
-\r
- /**\r
- * Returns the current scroll position of the element.\r
- * @return {Object} An object containing the scroll position in the format {left: (scrollLeft), top: (scrollTop)}\r
- */\r
- getScroll : function(){\r
- var d = this.dom, \r
- doc = document,\r
- body = doc.body,\r
- docElement = doc.documentElement,\r
- l,\r
- t,\r
- ret;\r
-\r
- if(d == doc || d == body){\r
- if(Ext.isIE && Ext.isStrict){\r
- l = docElement.scrollLeft; \r
- t = docElement.scrollTop;\r
- }else{\r
- l = window.pageXOffset;\r
- t = window.pageYOffset;\r
- }\r
- ret = {left: l || (body ? body.scrollLeft : 0), top: t || (body ? body.scrollTop : 0)};\r
- }else{\r
- ret = {left: d.scrollLeft, top: d.scrollTop};\r
- }\r
- return ret;\r
- }\r
-});/**\r
- * @class Ext.Element\r
- */\r
-Ext.Element.addMethods({\r
- /**\r
- * Scrolls this element the specified scroll point. It does NOT do bounds checking so if you scroll to a weird value it will try to do it. For auto bounds checking, use scroll().\r
- * @param {String} side Either "left" for scrollLeft values or "top" for scrollTop values.\r
- * @param {Number} value The new scroll value\r
- * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object\r
- * @return {Element} this\r
- */\r
- scrollTo : function(side, value, animate){\r
- var tester = /top/i,\r
- prop = "scroll" + (tester.test(side) ? "Top" : "Left"),\r
- me = this,\r
- dom = me.dom;\r
- if (!animate || !me.anim) {\r
- dom[prop] = value;\r
- } else {\r
- me.anim({scroll: {to: tester.test(prop) ? [dom[prop], value] : [value, dom[prop]]}},\r
- me.preanim(arguments, 2), 'scroll');\r
- }\r
- return me;\r
- },\r
- \r
- /**\r
- * Scrolls this element into view within the passed container.\r
- * @param {Mixed} container (optional) The container element to scroll (defaults to document.body). Should be a\r
- * string (id), dom node, or Ext.Element.\r
- * @param {Boolean} hscroll (optional) False to disable horizontal scroll (defaults to true)\r
- * @return {Ext.Element} this\r
- */\r
- scrollIntoView : function(container, hscroll){\r
- var c = Ext.getDom(container) || Ext.getBody().dom,\r
- el = this.dom,\r
- o = this.getOffsetsTo(c),\r
- l = o[0] + c.scrollLeft,\r
- t = o[1] + c.scrollTop,\r
- b = t + el.offsetHeight,\r
- r = l + el.offsetWidth,\r
- ch = c.clientHeight,\r
- ct = parseInt(c.scrollTop, 10),\r
- cl = parseInt(c.scrollLeft, 10),\r
- cb = ct + ch,\r
- cr = cl + c.clientWidth;\r
-\r
- if (el.offsetHeight > ch || t < ct) {\r
- c.scrollTop = t;\r
- } else if (b > cb){\r
- c.scrollTop = b-ch;\r
- }\r
- c.scrollTop = c.scrollTop; // corrects IE, other browsers will ignore\r
-\r
- if(hscroll !== false){\r
- if(el.offsetWidth > c.clientWidth || l < cl){\r
- c.scrollLeft = l;\r
- }else if(r > cr){\r
- c.scrollLeft = r - c.clientWidth;\r
- }\r
- c.scrollLeft = c.scrollLeft;\r
- }\r
- return this;\r
- },\r
-\r
- // private\r
- scrollChildIntoView : function(child, hscroll){\r
- Ext.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll);\r
- },\r
- \r
- /**\r
- * Scrolls this element the specified direction. Does bounds checking to make sure the scroll is\r
- * within this element's scrollable range.\r
- * @param {String} direction Possible values are: "l" (or "left"), "r" (or "right"), "t" (or "top", or "up"), "b" (or "bottom", or "down").\r
- * @param {Number} distance How far to scroll the element in pixels\r
- * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object\r
- * @return {Boolean} Returns true if a scroll was triggered or false if the element\r
- * was scrolled as far as it could go.\r
- */\r
- scroll : function(direction, distance, animate){\r
- if(!this.isScrollable()){\r
- return;\r
- }\r
- var el = this.dom,\r
- l = el.scrollLeft, t = el.scrollTop,\r
- w = el.scrollWidth, h = el.scrollHeight,\r
- cw = el.clientWidth, ch = el.clientHeight,\r
- scrolled = false, v,\r
- hash = {\r
- l: Math.min(l + distance, w-cw),\r
- r: v = Math.max(l - distance, 0),\r
- t: Math.max(t - distance, 0),\r
- b: Math.min(t + distance, h-ch)\r
- };\r
- hash.d = hash.b;\r
- hash.u = hash.t;\r
- \r
- direction = direction.substr(0, 1);\r
- if((v = hash[direction]) > -1){\r
- scrolled = true;\r
- this.scrollTo(direction == 'l' || direction == 'r' ? 'left' : 'top', v, this.preanim(arguments, 2));\r
- }\r
- return scrolled;\r
- }\r
-});/**\r
- * @class Ext.Element\r
- */\r
-/**\r
- * Visibility mode constant for use with {@link #setVisibilityMode}. Use visibility to hide element\r
- * @static\r
- * @type Number\r
- */\r
-Ext.Element.VISIBILITY = 1;\r
-/**\r
- * Visibility mode constant for use with {@link #setVisibilityMode}. Use display to hide element\r
- * @static\r
- * @type Number\r
- */\r
-Ext.Element.DISPLAY = 2;\r
-\r
-Ext.Element.addMethods(function(){\r
- var VISIBILITY = "visibility",\r
- DISPLAY = "display",\r
- HIDDEN = "hidden",\r
- NONE = "none", \r
- ORIGINALDISPLAY = 'originalDisplay',\r
- VISMODE = 'visibilityMode',\r
- ELDISPLAY = Ext.Element.DISPLAY,\r
- data = Ext.Element.data,\r
- getDisplay = function(dom){\r
- var d = data(dom, ORIGINALDISPLAY);\r
- if(d === undefined){\r
- data(dom, ORIGINALDISPLAY, d = '');\r
- }\r
- return d;\r
- },\r
- getVisMode = function(dom){\r
- var m = data(dom, VISMODE);\r
- if(m === undefined){\r
- data(dom, VISMODE, m = 1)\r
- }\r
- return m;\r
- };\r
- \r
- return {\r
- /**\r
- * The element's default display mode (defaults to "")\r
- * @type String\r
- */\r
- originalDisplay : "",\r
- visibilityMode : 1,\r
- \r
- /**\r
- * Sets the element's visibility mode. When setVisible() is called it\r
- * will use this to determine whether to set the visibility or the display property.\r
- * @param visMode Ext.Element.VISIBILITY or Ext.Element.DISPLAY\r
- * @return {Ext.Element} this\r
- */\r
- setVisibilityMode : function(visMode){ \r
- data(this.dom, VISMODE, visMode);\r
- return this;\r
- },\r
- \r
- /**\r
- * Perform custom animation on this element.\r
- * <div><ul class="mdetail-params">\r
- * <li><u>Animation Properties</u></li>\r
- * \r
- * <p>The Animation Control Object enables gradual transitions for any member of an\r
- * element's style object that takes a numeric value including but not limited to\r
- * these properties:</p><div><ul class="mdetail-params">\r
- * <li><tt>bottom, top, left, right</tt></li>\r
- * <li><tt>height, width</tt></li>\r
- * <li><tt>margin, padding</tt></li>\r
- * <li><tt>borderWidth</tt></li>\r
- * <li><tt>opacity</tt></li>\r
- * <li><tt>fontSize</tt></li>\r
- * <li><tt>lineHeight</tt></li>\r
- * </ul></div>\r
- * \r
- * \r
- * <li><u>Animation Property Attributes</u></li>\r
- * \r
- * <p>Each Animation Property is a config object with optional properties:</p>\r
- * <div><ul class="mdetail-params">\r
- * <li><tt>by</tt>* : relative change - start at current value, change by this value</li>\r
- * <li><tt>from</tt> : ignore current value, start from this value</li>\r
- * <li><tt>to</tt>* : start at current value, go to this value</li>\r
- * <li><tt>unit</tt> : any allowable unit specification</li>\r
- * <p>* do not specify both <tt>to</tt> and <tt>by</tt> for an animation property</p>\r
- * </ul></div>\r
- * \r
- * <li><u>Animation Types</u></li>\r
- * \r
- * <p>The supported animation types:</p><div><ul class="mdetail-params">\r
- * <li><tt>'run'</tt> : Default\r
- * <pre><code>\r
-var el = Ext.get('complexEl');\r
-el.animate(\r
- // animation control object\r
- {\r
- borderWidth: {to: 3, from: 0},\r
- opacity: {to: .3, from: 1},\r
- height: {to: 50, from: el.getHeight()},\r
- width: {to: 300, from: el.getWidth()},\r
- top : {by: - 100, unit: 'px'},\r
- },\r
- 0.35, // animation duration\r
- null, // callback\r
- 'easeOut', // easing method\r
- 'run' // animation type ('run','color','motion','scroll') \r
-);\r
- * </code></pre>\r
- * </li>\r
- * <li><tt>'color'</tt>\r
- * <p>Animates transition of background, text, or border colors.</p>\r
- * <pre><code>\r
-el.animate(\r
- // animation control object\r
- {\r
- color: { to: '#06e' },\r
- backgroundColor: { to: '#e06' }\r
- },\r
- 0.35, // animation duration\r
- null, // callback\r
- 'easeOut', // easing method\r
- 'color' // animation type ('run','color','motion','scroll') \r
-);\r
- * </code></pre> \r
- * </li>\r
- * \r
- * <li><tt>'motion'</tt>\r
- * <p>Animates the motion of an element to/from specific points using optional bezier\r
- * way points during transit.</p>\r
- * <pre><code>\r
-el.animate(\r
- // animation control object\r
- {\r
- borderWidth: {to: 3, from: 0},\r
- opacity: {to: .3, from: 1},\r
- height: {to: 50, from: el.getHeight()},\r
- width: {to: 300, from: el.getWidth()},\r
- top : {by: - 100, unit: 'px'},\r
- points: {\r
- to: [50, 100], // go to this point\r
- control: [ // optional bezier way points\r
- [ 600, 800],\r
- [-100, 200]\r
- ]\r
- }\r
- },\r
- 3000, // animation duration (milliseconds!)\r
- null, // callback\r
- 'easeOut', // easing method\r
- 'motion' // animation type ('run','color','motion','scroll') \r
-);\r
- * </code></pre> \r
- * </li>\r
- * <li><tt>'scroll'</tt>\r
- * <p>Animate horizontal or vertical scrolling of an overflowing page element.</p>\r
- * <pre><code>\r
-el.animate(\r
- // animation control object\r
- {\r
- scroll: {to: [400, 300]}\r
- },\r
- 0.35, // animation duration\r
- null, // callback\r
- 'easeOut', // easing method\r
- 'scroll' // animation type ('run','color','motion','scroll') \r
-);\r
- * </code></pre> \r
- * </li>\r
- * </ul></div>\r
- * \r
- * </ul></div>\r
- * \r
- * @param {Object} args The animation control args\r
- * @param {Float} duration (optional) How long the animation lasts in seconds (defaults to <tt>.35</tt>)\r
- * @param {Function} onComplete (optional) Function to call when animation completes\r
- * @param {String} easing (optional) {@link Ext.Fx#easing} method to use (defaults to <tt>'easeOut'</tt>)\r
- * @param {String} animType (optional) <tt>'run'</tt> is the default. Can also be <tt>'color'</tt>,\r
- * <tt>'motion'</tt>, or <tt>'scroll'</tt>\r
- * @return {Ext.Element} this\r
- */\r
- animate : function(args, duration, onComplete, easing, animType){ \r
- this.anim(args, {duration: duration, callback: onComplete, easing: easing}, animType);\r
- return this;\r
- },\r
- \r
- /*\r
- * @private Internal animation call\r
- */\r
- anim : function(args, opt, animType, defaultDur, defaultEase, cb){\r
- animType = animType || 'run';\r
- opt = opt || {};\r
- var me = this, \r
- anim = Ext.lib.Anim[animType](\r
- me.dom, \r
- args,\r
- (opt.duration || defaultDur) || .35,\r
- (opt.easing || defaultEase) || 'easeOut',\r
- function(){\r
- if(cb) cb.call(me);\r
- if(opt.callback) opt.callback.call(opt.scope || me, me, opt);\r
- },\r
- me\r
- );\r
- opt.anim = anim;\r
- return anim;\r
- },\r
- \r
- // private legacy anim prep\r
- preanim : function(a, i){\r
- return !a[i] ? false : (Ext.isObject(a[i]) ? a[i]: {duration: a[i+1], callback: a[i+2], easing: a[i+3]});\r
- },\r
- \r
- /**\r
- * Checks whether the element is currently visible using both visibility and display properties. \r
- * @return {Boolean} True if the element is currently visible, else false\r
- */\r
- isVisible : function() {\r
- return !this.isStyle(VISIBILITY, HIDDEN) && !this.isStyle(DISPLAY, NONE);\r
- },\r
- \r
- /**\r
- * Sets the visibility of the element (see details). If the visibilityMode is set to Element.DISPLAY, it will use\r
- * the display property to hide the element, otherwise it uses visibility. The default is to hide and show using the visibility property.\r
- * @param {Boolean} visible Whether the element is visible\r
- * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object\r
- * @return {Ext.Element} this\r
- */\r
- setVisible : function(visible, animate){\r
- var me = this,\r
- dom = me.dom,\r
- isDisplay = getVisMode(this.dom) == ELDISPLAY;\r
- \r
- if (!animate || !me.anim) {\r
- if(isDisplay){\r
- me.setDisplayed(visible);\r
- }else{\r
- me.fixDisplay();\r
- dom.style.visibility = visible ? "visible" : HIDDEN;\r
- }\r
- }else{\r
- // closure for composites \r
- if(visible){\r
- me.setOpacity(.01);\r
- me.setVisible(true);\r
- }\r
- me.anim({opacity: { to: (visible?1:0) }},\r
- me.preanim(arguments, 1),\r
- null,\r
- .35,\r
- 'easeIn',\r
- function(){\r
- if(!visible){\r
- dom.style[isDisplay ? DISPLAY : VISIBILITY] = (isDisplay) ? NONE : HIDDEN; \r
- Ext.fly(dom).setOpacity(1);\r
- }\r
- });\r
- }\r
- return me;\r
- },\r
- \r
- /**\r
- * Toggles the element's visibility or display, depending on visibility mode.\r
- * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object\r
- * @return {Ext.Element} this\r
- */\r
- toggle : function(animate){\r
- var me = this;\r
- me.setVisible(!me.isVisible(), me.preanim(arguments, 0));\r
- return me;\r
- },\r
- \r
- /**\r
- * Sets the CSS display property. Uses originalDisplay if the specified value is a boolean true.\r
- * @param {Mixed} value Boolean value to display the element using its default display, or a string to set the display directly.\r
- * @return {Ext.Element} this\r
- */\r
- setDisplayed : function(value) { \r
- if(typeof value == "boolean"){\r
- value = value ? getDisplay(this.dom) : NONE;\r
- }\r
- this.setStyle(DISPLAY, value);\r
- return this;\r
- },\r
- \r
- // private\r
- fixDisplay : function(){\r
- var me = this;\r
- if(me.isStyle(DISPLAY, NONE)){\r
- me.setStyle(VISIBILITY, HIDDEN);\r
- me.setStyle(DISPLAY, getDisplay(this.dom)); // first try reverting to default\r
- if(me.isStyle(DISPLAY, NONE)){ // if that fails, default to block\r
- me.setStyle(DISPLAY, "block");\r
- }\r
- }\r
- },\r
- \r
- /**\r
- * Hide this element - Uses display mode to determine whether to use "display" or "visibility". See {@link #setVisible}.\r
- * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object\r
- * @return {Ext.Element} this\r
- */\r
- hide : function(animate){\r
- this.setVisible(false, this.preanim(arguments, 0));\r
- return this;\r
- },\r
- \r
- /**\r
- * Show this element - Uses display mode to determine whether to use "display" or "visibility". See {@link #setVisible}.\r
- * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object\r
- * @return {Ext.Element} this\r
- */\r
- show : function(animate){\r
- this.setVisible(true, this.preanim(arguments, 0));\r
- return this;\r
- }\r
- }\r
-}());/**\r
- * @class Ext.Element\r
- */\r
-Ext.Element.addMethods(\r
-function(){\r
- var VISIBILITY = "visibility",\r
- DISPLAY = "display",\r
- HIDDEN = "hidden",\r
- NONE = "none",\r
- XMASKED = "x-masked",\r
- XMASKEDRELATIVE = "x-masked-relative",\r
- data = Ext.Element.data;\r
- \r
- return {\r
- /**\r
- * Checks whether the element is currently visible using both visibility and display properties.\r
- * @param {Boolean} deep (optional) True to walk the dom and see if parent elements are hidden (defaults to false)\r
- * @return {Boolean} True if the element is currently visible, else false\r
- */\r
- isVisible : function(deep) {\r
- var vis = !this.isStyle(VISIBILITY,HIDDEN) && !this.isStyle(DISPLAY,NONE),\r
- p = this.dom.parentNode;\r
- if(deep !== true || !vis){\r
- return vis;\r
- } \r
- while(p && !/body/i.test(p.tagName)){\r
- if(!Ext.fly(p, '_isVisible').isVisible()){\r
- return false;\r
- }\r
- p = p.parentNode;\r
- }\r
- return true;\r
- },\r
- \r
- /**\r
- * Returns true if display is not "none"\r
- * @return {Boolean}\r
- */\r
- isDisplayed : function() {\r
- return !this.isStyle(DISPLAY, NONE);\r
- },\r
- \r
- /**\r
- * Convenience method for setVisibilityMode(Element.DISPLAY)\r
- * @param {String} display (optional) What to set display to when visible\r
- * @return {Ext.Element} this\r
- */\r
- enableDisplayMode : function(display){ \r
- this.setVisibilityMode(Ext.Element.DISPLAY);\r
- if(!Ext.isEmpty(display)){\r
- data(this.dom, 'originalDisplay', display);\r
- }\r
- return this;\r
- },\r
- \r
- /**\r
- * Puts a mask over this element to disable user interaction. Requires core.css.\r
- * This method can only be applied to elements which accept child nodes.\r
- * @param {String} msg (optional) A message to display in the mask\r
- * @param {String} msgCls (optional) A css class to apply to the msg element\r
- * @return {Element} The mask element\r
- */\r
- mask : function(msg, msgCls){\r
- var me = this,\r
- dom = me.dom,\r
- dh = Ext.DomHelper,\r
- EXTELMASKMSG = "ext-el-mask-msg",\r
- el, \r
- mask;\r
- \r
- if(me.getStyle("position") == "static"){\r
- me.addClass(XMASKEDRELATIVE);\r
- }\r
- if((el = data(dom, 'maskMsg'))){\r
- el.remove();\r
- }\r
- if((el = data(dom, 'mask'))){\r
- el.remove();\r
- }\r
- \r
- mask = dh.append(dom, {cls : "ext-el-mask"}, true);\r
- data(dom, 'mask', mask);\r
- \r
- me.addClass(XMASKED);\r
- mask.setDisplayed(true);\r
- if(typeof msg == 'string'){\r
- var mm = dh.append(dom, {cls : EXTELMASKMSG, cn:{tag:'div'}}, true);\r
- data(dom, 'maskMsg', mm);\r
- mm.dom.className = msgCls ? EXTELMASKMSG + " " + msgCls : EXTELMASKMSG;\r
- mm.dom.firstChild.innerHTML = msg;\r
- mm.setDisplayed(true);\r
- mm.center(me);\r
- }\r
- if(Ext.isIE && !(Ext.isIE7 && Ext.isStrict) && me.getStyle('height') == 'auto'){ // ie will not expand full height automatically\r
- mask.setSize(undefined, me.getHeight());\r
- }\r
- return mask;\r
- },\r
- \r
- /**\r
- * Removes a previously applied mask.\r
- */\r
- unmask : function(){\r
- var me = this,\r
- dom = me.dom,\r
- mask = data(dom, 'mask'),\r
- maskMsg = data(dom, 'maskMsg');\r
- if(mask){\r
- if(maskMsg){\r
- maskMsg.remove();\r
- data(dom, 'maskMsg', undefined);\r
- }\r
- mask.remove();\r
- data(dom, 'mask', undefined);\r
- }\r
- me.removeClass([XMASKED, XMASKEDRELATIVE]);\r
- },\r
- \r
- /**\r
- * Returns true if this element is masked\r
- * @return {Boolean}\r
- */\r
- isMasked : function(){\r
- var m = data(this.dom, 'mask');\r
- return m && m.isVisible();\r
- },\r
- \r
- /**\r
- * Creates an iframe shim for this element to keep selects and other windowed objects from\r
- * showing through.\r
- * @return {Ext.Element} The new shim element\r
- */\r
- createShim : function(){\r
- var el = document.createElement('iframe'), \r
- shim;\r
- el.frameBorder = '0';\r
- el.className = 'ext-shim';\r
- if(Ext.isIE && Ext.isSecure){\r
- el.src = Ext.SSL_SECURE_URL;\r
- }\r
- shim = Ext.get(this.dom.parentNode.insertBefore(el, this.dom));\r
- shim.autoBoxAdjust = false;\r
- return shim;\r
- }\r
- };\r
-}());/**\r
- * @class Ext.Element\r
- */\r
-Ext.Element.addMethods({\r
- /**\r
- * Convenience method for constructing a KeyMap\r
- * @param {Number/Array/Object/String} key Either a string with the keys to listen for, the numeric key code, array of key codes or an object with the following options:\r
- * {key: (number or array), shift: (true/false), ctrl: (true/false), alt: (true/false)}\r
- * @param {Function} fn The function to call\r
- * @param {Object} scope (optional) The scope of the function\r
- * @return {Ext.KeyMap} The KeyMap created\r
- */\r
- addKeyListener : function(key, fn, scope){\r
- var config;\r
- if(!Ext.isObject(key) || Ext.isArray(key)){\r
- config = {\r
- key: key,\r
- fn: fn,\r
- scope: scope\r
- };\r
- }else{\r
- config = {\r
- key : key.key,\r
- shift : key.shift,\r
- ctrl : key.ctrl,\r
- alt : key.alt,\r
- fn: fn,\r
- scope: scope\r
- };\r
- }\r
- return new Ext.KeyMap(this, config);\r
- },\r
-\r
- /**\r
- * Creates a KeyMap for this element\r
- * @param {Object} config The KeyMap config. See {@link Ext.KeyMap} for more details\r
- * @return {Ext.KeyMap} The KeyMap created\r
- */\r
- addKeyMap : function(config){\r
- return new Ext.KeyMap(this, config);\r
- }\r
-});(function(){\r
- // contants\r
- var NULL = null,\r
- UNDEFINED = undefined,\r
- TRUE = true,\r
- FALSE = false,\r
- SETX = "setX",\r
- SETY = "setY",\r
- SETXY = "setXY",\r
- LEFT = "left",\r
- BOTTOM = "bottom",\r
- TOP = "top",\r
- RIGHT = "right",\r
- HEIGHT = "height",\r
- WIDTH = "width",\r
- POINTS = "points",\r
- HIDDEN = "hidden",\r
- ABSOLUTE = "absolute",\r
- VISIBLE = "visible",\r
- MOTION = "motion",\r
- POSITION = "position",\r
- EASEOUT = "easeOut",\r
- /*\r
- * Use a light flyweight here since we are using so many callbacks and are always assured a DOM element\r
- */\r
- flyEl = new Ext.Element.Flyweight(),\r
- queues = {},\r
- getObject = function(o){\r
- return o || {};\r
- },\r
- fly = function(dom){\r
- flyEl.dom = dom;\r
- flyEl.id = Ext.id(dom);\r
- return flyEl;\r
- },\r
- /*\r
- * Queueing now stored outside of the element due to closure issues\r
- */\r
- getQueue = function(id){\r
- if(!queues[id]){\r
- queues[id] = [];\r
- }\r
- return queues[id];\r
- },\r
- setQueue = function(id, value){\r
- queues[id] = value;\r
- };\r
- \r
-//Notifies Element that fx methods are available\r
-Ext.enableFx = TRUE;\r
-\r
-/**\r
- * @class Ext.Fx\r
- * <p>A class to provide basic animation and visual effects support. <b>Note:</b> This class is automatically applied\r
- * to the {@link Ext.Element} interface when included, so all effects calls should be performed via {@link Ext.Element}.\r
- * Conversely, since the effects are not actually defined in {@link Ext.Element}, Ext.Fx <b>must</b> be\r
- * {@link Ext#enableFx included} in order for the Element effects to work.</p><br/>\r
- * \r
- * <p><b><u>Method Chaining</u></b></p>\r
- * <p>It is important to note that although the Fx methods and many non-Fx Element methods support "method chaining" in that\r
- * they return the Element object itself as the method return value, it is not always possible to mix the two in a single\r
- * method chain. The Fx methods use an internal effects queue so that each effect can be properly timed and sequenced.\r
- * Non-Fx methods, on the other hand, have no such internal queueing and will always execute immediately. For this reason,\r
- * while it may be possible to mix certain Fx and non-Fx method calls in a single chain, it may not always provide the\r
- * expected results and should be done with care. Also see <tt>{@link #callback}</tt>.</p><br/>\r
- *\r
- * <p><b><u>Anchor Options for Motion Effects</u></b></p>\r
- * <p>Motion effects support 8-way anchoring, meaning that you can choose one of 8 different anchor points on the Element\r
- * that will serve as either the start or end point of the animation. Following are all of the supported anchor positions:</p>\r
-<pre>\r
-Value Description\r
------ -----------------------------\r
-tl The top left corner\r
-t The center of the top edge\r
-tr The top right corner\r
-l The center of the left edge\r
-r The center of the right edge\r
-bl The bottom left corner\r
-b The center of the bottom edge\r
-br The bottom right corner\r
-</pre>\r
- * <b>Note</b>: some Fx methods accept specific custom config parameters. The options shown in the Config Options\r
- * section below are common options that can be passed to any Fx method unless otherwise noted.</b>\r
- * \r
- * @cfg {Function} callback A function called when the effect is finished. Note that effects are queued internally by the\r
- * Fx class, so a callback is not required to specify another effect -- effects can simply be chained together\r
- * and called in sequence (see note for <b><u>Method Chaining</u></b> above), for example:<pre><code>\r
- * el.slideIn().highlight();\r
- * </code></pre>\r
- * The callback is intended for any additional code that should run once a particular effect has completed. The Element\r
- * being operated upon is passed as the first parameter.\r
- * \r
- * @cfg {Object} scope The scope of the <tt>{@link #callback}</tt> function\r
- * \r
- * @cfg {String} easing A valid Ext.lib.Easing value for the effect:</p><div class="mdetail-params"><ul>\r
- * <li><b><tt>backBoth</tt></b></li>\r
- * <li><b><tt>backIn</tt></b></li>\r
- * <li><b><tt>backOut</tt></b></li>\r
- * <li><b><tt>bounceBoth</tt></b></li>\r
- * <li><b><tt>bounceIn</tt></b></li>\r
- * <li><b><tt>bounceOut</tt></b></li>\r
- * <li><b><tt>easeBoth</tt></b></li>\r
- * <li><b><tt>easeBothStrong</tt></b></li>\r
- * <li><b><tt>easeIn</tt></b></li>\r
- * <li><b><tt>easeInStrong</tt></b></li>\r
- * <li><b><tt>easeNone</tt></b></li>\r
- * <li><b><tt>easeOut</tt></b></li>\r
- * <li><b><tt>easeOutStrong</tt></b></li>\r
- * <li><b><tt>elasticBoth</tt></b></li>\r
- * <li><b><tt>elasticIn</tt></b></li>\r
- * <li><b><tt>elasticOut</tt></b></li>\r
- * </ul></div>\r
- *\r
- * @cfg {String} afterCls A css class to apply after the effect\r
- * @cfg {Number} duration The length of time (in seconds) that the effect should last\r
- * \r
- * @cfg {Number} endOpacity Only applicable for {@link #fadeIn} or {@link #fadeOut}, a number between\r
- * <tt>0</tt> and <tt>1</tt> inclusive to configure the ending opacity value.\r
- * \r
- * @cfg {Boolean} remove Whether the Element should be removed from the DOM and destroyed after the effect finishes\r
- * @cfg {Boolean} useDisplay Whether to use the <i>display</i> CSS property instead of <i>visibility</i> when hiding Elements (only applies to \r
- * effects that end with the element being visually hidden, ignored otherwise)\r
- * @cfg {String/Object/Function} afterStyle A style specification string, e.g. <tt>"width:100px"</tt>, or an object\r
- * in the form <tt>{width:"100px"}</tt>, or a function which returns such a specification that will be applied to the\r
- * Element after the effect finishes.\r
- * @cfg {Boolean} block Whether the effect should block other effects from queueing while it runs\r
- * @cfg {Boolean} concurrent Whether to allow subsequently-queued effects to run at the same time as the current effect, or to ensure that they run in sequence\r
- * @cfg {Boolean} stopFx Whether preceding effects should be stopped and removed before running current effect (only applies to non blocking effects)\r
- */\r
-Ext.Fx = {\r
- \r
- // private - calls the function taking arguments from the argHash based on the key. Returns the return value of the function.\r
- // this is useful for replacing switch statements (for example).\r
- switchStatements : function(key, fn, argHash){\r
- return fn.apply(this, argHash[key]);\r
- },\r
- \r
- /**\r
- * Slides the element into view. An anchor point can be optionally passed to set the point of\r
- * origin for the slide effect. This function automatically handles wrapping the element with\r
- * a fixed-size container if needed. See the Fx class overview for valid anchor point options.\r
- * Usage:\r
- *<pre><code>\r
-// default: slide the element in from the top\r
-el.slideIn();\r
-\r
-// custom: slide the element in from the right with a 2-second duration\r
-el.slideIn('r', { duration: 2 });\r
-\r
-// common config options shown with default values\r
-el.slideIn('t', {\r
- easing: 'easeOut',\r
- duration: .5\r
-});\r
-</code></pre>\r
- * @param {String} anchor (optional) One of the valid Fx anchor positions (defaults to top: 't')\r
- * @param {Object} options (optional) Object literal with any of the Fx config options\r
- * @return {Ext.Element} The Element\r
- */\r
- slideIn : function(anchor, o){ \r
- o = getObject(o);\r
- var me = this,\r
- dom = me.dom,\r
- st = dom.style,\r
- xy,\r
- r,\r
- b, \r
- wrap, \r
- after,\r
- st,\r
- args, \r
- pt,\r
- bw,\r
- bh;\r
- \r
- anchor = anchor || "t";\r
-\r
- me.queueFx(o, function(){ \r
- xy = fly(dom).getXY();\r
- // fix display to visibility\r
- fly(dom).fixDisplay(); \r
- \r
- // restore values after effect\r
- r = fly(dom).getFxRestore(); \r
- b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight};\r
- b.right = b.x + b.width;\r
- b.bottom = b.y + b.height;\r
- \r
- // fixed size for slide\r
- fly(dom).setWidth(b.width).setHeight(b.height); \r
- \r
- // wrap if needed\r
- wrap = fly(dom).fxWrap(r.pos, o, HIDDEN);\r
- \r
- st.visibility = VISIBLE;\r
- st.position = ABSOLUTE;\r
- \r
- // clear out temp styles after slide and unwrap\r
- function after(){\r
- fly(dom).fxUnwrap(wrap, r.pos, o);\r
- st.width = r.width;\r
- st.height = r.height;\r
- fly(dom).afterFx(o);\r
- }\r
- \r
- // time to calculate the positions \r
- pt = {to: [b.x, b.y]}; \r
- bw = {to: b.width};\r
- bh = {to: b.height};\r
- \r
- function argCalc(wrap, style, ww, wh, sXY, sXYval, s1, s2, w, h, p){ \r
- var ret = {};\r
- fly(wrap).setWidth(ww).setHeight(wh);\r
- if(fly(wrap)[sXY]){\r
- fly(wrap)[sXY](sXYval); \r
- }\r
- style[s1] = style[s2] = "0"; \r
- if(w){\r
- ret.width = w\r
- };\r
- if(h){\r
- ret.height = h;\r
- }\r
- if(p){\r
- ret.points = p;\r
- }\r
- return ret;\r
- };\r
-\r
- args = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, {\r
- t : [wrap, st, b.width, 0, NULL, NULL, LEFT, BOTTOM, NULL, bh, NULL],\r
- l : [wrap, st, 0, b.height, NULL, NULL, RIGHT, TOP, bw, NULL, NULL],\r
- r : [wrap, st, b.width, b.height, SETX, b.right, LEFT, TOP, NULL, NULL, pt],\r
- b : [wrap, st, b.width, b.height, SETY, b.bottom, LEFT, TOP, NULL, bh, pt],\r
- tl : [wrap, st, 0, 0, NULL, NULL, RIGHT, BOTTOM, bw, bh, pt],\r
- bl : [wrap, st, 0, 0, SETY, b.y + b.height, RIGHT, TOP, bw, bh, pt],\r
- br : [wrap, st, 0, 0, SETXY, [b.right, b.bottom], LEFT, TOP, bw, bh, pt],\r
- tr : [wrap, st, 0, 0, SETX, b.x + b.width, LEFT, BOTTOM, bw, bh, pt]\r
- });\r
- \r
- st.visibility = VISIBLE;\r
- fly(wrap).show();\r
-\r
- arguments.callee.anim = fly(wrap).fxanim(args,\r
- o,\r
- MOTION,\r
- .5,\r
- EASEOUT, \r
- after);\r
- });\r
- return me;\r
- },\r
- \r
- /**\r
- * Slides the element out of view. An anchor point can be optionally passed to set the end point\r
- * for the slide effect. When the effect is completed, the element will be hidden (visibility = \r
- * 'hidden') but block elements will still take up space in the document. The element must be removed\r
- * from the DOM using the 'remove' config option if desired. This function automatically handles \r
- * wrapping the element with a fixed-size container if needed. See the Fx class overview for valid anchor point options.\r
- * Usage:\r
- *<pre><code>\r
-// default: slide the element out to the top\r
-el.slideOut();\r
-\r
-// custom: slide the element out to the right with a 2-second duration\r
-el.slideOut('r', { duration: 2 });\r
-\r
-// common config options shown with default values\r
-el.slideOut('t', {\r
- easing: 'easeOut',\r
- duration: .5,\r
- remove: false,\r
- useDisplay: false\r
-});\r
-</code></pre>\r
- * @param {String} anchor (optional) One of the valid Fx anchor positions (defaults to top: 't')\r
- * @param {Object} options (optional) Object literal with any of the Fx config options\r
- * @return {Ext.Element} The Element\r
- */\r
- slideOut : function(anchor, o){\r
- o = getObject(o);\r
- var me = this,\r
- dom = me.dom,\r
- st = dom.style,\r
- xy = me.getXY(),\r
- wrap,\r
- r,\r
- b,\r
- a,\r
- zero = {to: 0}; \r
- \r
- anchor = anchor || "t";\r
-\r
- me.queueFx(o, function(){\r
- \r
- // restore values after effect\r
- r = fly(dom).getFxRestore(); \r
- b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight};\r
- b.right = b.x + b.width;\r
- b.bottom = b.y + b.height;\r
- \r
- // fixed size for slide \r
- fly(dom).setWidth(b.width).setHeight(b.height);\r
-\r
- // wrap if needed\r
- wrap = fly(dom).fxWrap(r.pos, o, VISIBLE);\r
- \r
- st.visibility = VISIBLE;\r
- st.position = ABSOLUTE;\r
- fly(wrap).setWidth(b.width).setHeight(b.height); \r
-\r
- function after(){\r
- o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide(); \r
- fly(dom).fxUnwrap(wrap, r.pos, o);\r
- st.width = r.width;\r
- st.height = r.height;\r
- fly(dom).afterFx(o);\r
- } \r
- \r
- function argCalc(style, s1, s2, p1, v1, p2, v2, p3, v3){ \r
- var ret = {};\r
- \r
- style[s1] = style[s2] = "0";\r
- ret[p1] = v1; \r
- if(p2){\r
- ret[p2] = v2; \r
- }\r
- if(p3){\r
- ret[p3] = v3;\r
- }\r
- \r
- return ret;\r
- };\r
- \r
- a = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, {\r
- t : [st, LEFT, BOTTOM, HEIGHT, zero],\r
- l : [st, RIGHT, TOP, WIDTH, zero],\r
- r : [st, LEFT, TOP, WIDTH, zero, POINTS, {to : [b.right, b.y]}],\r
- b : [st, LEFT, TOP, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}],\r
- tl : [st, RIGHT, BOTTOM, WIDTH, zero, HEIGHT, zero],\r
- bl : [st, RIGHT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}],\r
- br : [st, LEFT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x + b.width, b.bottom]}],\r
- tr : [st, LEFT, BOTTOM, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.right, b.y]}]\r
- });\r
- \r
- arguments.callee.anim = fly(wrap).fxanim(a,\r
- o,\r
- MOTION,\r
- .5,\r
- EASEOUT, \r
- after);\r
- });\r
- return me;\r
- },\r
-\r
- /**\r
- * Fades the element out while slowly expanding it in all directions. When the effect is completed, the \r
- * element will be hidden (visibility = 'hidden') but block elements will still take up space in the document. \r
- * The element must be removed from the DOM using the 'remove' config option if desired.\r
- * Usage:\r
- *<pre><code>\r
-// default\r
-el.puff();\r
-\r
-// common config options shown with default values\r
-el.puff({\r
- easing: 'easeOut',\r
- duration: .5,\r
- remove: false,\r
- useDisplay: false\r
-});\r
-</code></pre>\r
- * @param {Object} options (optional) Object literal with any of the Fx config options\r
- * @return {Ext.Element} The Element\r
- */\r
- puff : function(o){\r
- o = getObject(o);\r
- var me = this,\r
- dom = me.dom,\r
- st = dom.style,\r
- width,\r
- height,\r
- r;\r
-\r
- me.queueFx(o, function(){\r
- width = fly(dom).getWidth();\r
- height = fly(dom).getHeight();\r
- fly(dom).clearOpacity();\r
- fly(dom).show();\r
-\r
- // restore values after effect\r
- r = fly(dom).getFxRestore(); \r
- \r
- function after(){\r
- o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide(); \r
- fly(dom).clearOpacity(); \r
- fly(dom).setPositioning(r.pos);\r
- st.width = r.width;\r
- st.height = r.height;\r
- st.fontSize = '';\r
- fly(dom).afterFx(o);\r
- } \r
-\r
- arguments.callee.anim = fly(dom).fxanim({\r
- width : {to : fly(dom).adjustWidth(width * 2)},\r
- height : {to : fly(dom).adjustHeight(height * 2)},\r
- points : {by : [-width * .5, -height * .5]},\r
- opacity : {to : 0},\r
- fontSize: {to : 200, unit: "%"}\r
- },\r
- o,\r
- MOTION,\r
- .5,\r
- EASEOUT,\r
- after);\r
- });\r
- return me;\r
- },\r
-\r
- /**\r
- * Blinks the element as if it was clicked and then collapses on its center (similar to switching off a television).\r
- * When the effect is completed, the element will be hidden (visibility = 'hidden') but block elements will still \r
- * take up space in the document. The element must be removed from the DOM using the 'remove' config option if desired.\r
- * Usage:\r
- *<pre><code>\r
-// default\r
-el.switchOff();\r
-\r
-// all config options shown with default values\r
-el.switchOff({\r
- easing: 'easeIn',\r
- duration: .3,\r
- remove: false,\r
- useDisplay: false\r
-});\r
-</code></pre>\r
- * @param {Object} options (optional) Object literal with any of the Fx config options\r
- * @return {Ext.Element} The Element\r
- */\r
- switchOff : function(o){\r
- o = getObject(o);\r
- var me = this,\r
- dom = me.dom,\r
- st = dom.style,\r
- r;\r
-\r
- me.queueFx(o, function(){\r
- fly(dom).clearOpacity();\r
- fly(dom).clip();\r
-\r
- // restore values after effect\r
- r = fly(dom).getFxRestore();\r
- \r
- function after(){\r
- o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide(); \r
- fly(dom).clearOpacity();\r
- fly(dom).setPositioning(r.pos);\r
- st.width = r.width;\r
- st.height = r.height; \r
- fly(dom).afterFx(o);\r
- };\r
-\r
- fly(dom).fxanim({opacity : {to : 0.3}}, \r
- NULL, \r
- NULL, \r
- .1, \r
- NULL, \r
- function(){ \r
- fly(dom).clearOpacity();\r
- (function(){ \r
- fly(dom).fxanim({\r
- height : {to : 1},\r
- points : {by : [0, fly(dom).getHeight() * .5]}\r
- }, \r
- o, \r
- MOTION, \r
- 0.3, \r
- 'easeIn', \r
- after);\r
- }).defer(100);\r
- });\r
- });\r
- return me;\r
- },\r
-\r
- /**\r
- * Highlights the Element by setting a color (applies to the background-color by default, but can be\r
- * changed using the "attr" config option) and then fading back to the original color. If no original\r
- * color is available, you should provide the "endColor" config option which will be cleared after the animation.\r
- * Usage:\r
-<pre><code>\r
-// default: highlight background to yellow\r
-el.highlight();\r
-\r
-// custom: highlight foreground text to blue for 2 seconds\r
-el.highlight("0000ff", { attr: 'color', duration: 2 });\r
-\r
-// common config options shown with default values\r
-el.highlight("ffff9c", {\r
- attr: "background-color", //can be any valid CSS property (attribute) that supports a color value\r
- endColor: (current color) or "ffffff",\r
- easing: 'easeIn',\r
- duration: 1\r
-});\r
-</code></pre>\r
- * @param {String} color (optional) The highlight color. Should be a 6 char hex color without the leading # (defaults to yellow: 'ffff9c')\r
- * @param {Object} options (optional) Object literal with any of the Fx config options\r
- * @return {Ext.Element} The Element\r
- */ \r
- highlight : function(color, o){\r
- o = getObject(o);\r
- var me = this,\r
- dom = me.dom,\r
- attr = o.attr || "backgroundColor",\r
- a = {},\r
- restore;\r
-\r
- me.queueFx(o, function(){\r
- fly(dom).clearOpacity();\r
- fly(dom).show();\r
-\r
- function after(){\r
- dom.style[attr] = restore;\r
- fly(dom).afterFx(o);\r
- } \r
- restore = dom.style[attr];\r
- a[attr] = {from: color || "ffff9c", to: o.endColor || fly(dom).getColor(attr) || "ffffff"};\r
- arguments.callee.anim = fly(dom).fxanim(a,\r
- o,\r
- 'color',\r
- 1,\r
- 'easeIn', \r
- after);\r
- });\r
- return me;\r
- },\r
-\r
- /**\r
- * Shows a ripple of exploding, attenuating borders to draw attention to an Element.\r
- * Usage:\r
-<pre><code>\r
-// default: a single light blue ripple\r
-el.frame();\r
-\r
-// custom: 3 red ripples lasting 3 seconds total\r
-el.frame("ff0000", 3, { duration: 3 });\r
-\r
-// common config options shown with default values\r
-el.frame("C3DAF9", 1, {\r
- duration: 1 //duration of each individual ripple.\r
- // Note: Easing is not configurable and will be ignored if included\r
-});\r
-</code></pre>\r
- * @param {String} color (optional) The color of the border. Should be a 6 char hex color without the leading # (defaults to light blue: 'C3DAF9').\r
- * @param {Number} count (optional) The number of ripples to display (defaults to 1)\r
- * @param {Object} options (optional) Object literal with any of the Fx config options\r
- * @return {Ext.Element} The Element\r
- */\r
- frame : function(color, count, o){\r
- o = getObject(o);\r
- var me = this,\r
- dom = me.dom,\r
- proxy,\r
- active;\r
-\r
- me.queueFx(o, function(){\r
- color = color || "#C3DAF9"\r
- if(color.length == 6){\r
- color = "#" + color;\r
- } \r
- count = count || 1;\r
- fly(dom).show();\r
-\r
- var xy = fly(dom).getXY(),\r
- b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight},\r
- queue = function(){\r
- proxy = fly(document.body || document.documentElement).createChild({\r
- style:{\r
- visbility: HIDDEN,\r
- position : ABSOLUTE,\r
- "z-index": 35000, // yee haw\r
- border : "0px solid " + color\r
- }\r
- });\r
- return proxy.queueFx({}, animFn);\r
- };\r
- \r
- \r
- arguments.callee.anim = {\r
- isAnimated: true,\r
- stop: function() {\r
- count = 0;\r
- proxy.stopFx();\r
- }\r
- };\r
- \r
- function animFn(){\r
- var scale = Ext.isBorderBox ? 2 : 1;\r
- active = proxy.anim({\r
- top : {from : b.y, to : b.y - 20},\r
- left : {from : b.x, to : b.x - 20},\r
- borderWidth : {from : 0, to : 10},\r
- opacity : {from : 1, to : 0},\r
- height : {from : b.height, to : b.height + 20 * scale},\r
- width : {from : b.width, to : b.width + 20 * scale}\r
- },{\r
- duration: o.duration || 1,\r
- callback: function() {\r
- proxy.remove();\r
- --count > 0 ? queue() : fly(dom).afterFx(o);\r
- }\r
- });\r
- arguments.callee.anim = {\r
- isAnimated: true,\r
- stop: function(){\r
- active.stop();\r
- }\r
- };\r
- };\r
- queue();\r
- });\r
- return me;\r
- },\r
-\r
- /**\r
- * Creates a pause before any subsequent queued effects begin. If there are\r
- * no effects queued after the pause it will have no effect.\r
- * Usage:\r
-<pre><code>\r
-el.pause(1);\r
-</code></pre>\r
- * @param {Number} seconds The length of time to pause (in seconds)\r
- * @return {Ext.Element} The Element\r
- */\r
- pause : function(seconds){ \r
- var dom = this.dom,\r
- t;\r
-\r
- this.queueFx({}, function(){\r
- t = setTimeout(function(){\r
- fly(dom).afterFx({});\r
- }, seconds * 1000);\r
- arguments.callee.anim = {\r
- isAnimated: true,\r
- stop: function(){\r
- clearTimeout(t);\r
- fly(dom).afterFx({});\r
- }\r
- };\r
- });\r
- return this;\r
- },\r
-\r
- /**\r
- * Fade an element in (from transparent to opaque). The ending opacity can be specified\r
- * using the <tt>{@link #endOpacity}</tt> config option.\r
- * Usage:\r
-<pre><code>\r
-// default: fade in from opacity 0 to 100%\r
-el.fadeIn();\r
-\r
-// custom: fade in from opacity 0 to 75% over 2 seconds\r
-el.fadeIn({ endOpacity: .75, duration: 2});\r
-\r
-// common config options shown with default values\r
-el.fadeIn({\r
- endOpacity: 1, //can be any value between 0 and 1 (e.g. .5)\r
- easing: 'easeOut',\r
- duration: .5\r
-});\r
-</code></pre>\r
- * @param {Object} options (optional) Object literal with any of the Fx config options\r
- * @return {Ext.Element} The Element\r
- */\r
- fadeIn : function(o){\r
- o = getObject(o);\r
- var me = this,\r
- dom = me.dom,\r
- to = o.endOpacity || 1;\r
- \r
- me.queueFx(o, function(){\r
- fly(dom).setOpacity(0);\r
- fly(dom).fixDisplay();\r
- dom.style.visibility = VISIBLE;\r
- arguments.callee.anim = fly(dom).fxanim({opacity:{to:to}},\r
- o, NULL, .5, EASEOUT, function(){\r
- if(to == 1){\r
- fly(dom).clearOpacity();\r
- }\r
- fly(dom).afterFx(o);\r
- });\r
- });\r
- return me;\r
- },\r
-\r
- /**\r
- * Fade an element out (from opaque to transparent). The ending opacity can be specified\r
- * using the <tt>{@link #endOpacity}</tt> config option. Note that IE may require\r
- * <tt>{@link #useDisplay}:true</tt> in order to redisplay correctly.\r
- * Usage:\r
-<pre><code>\r
-// default: fade out from the element's current opacity to 0\r
-el.fadeOut();\r
-\r
-// custom: fade out from the element's current opacity to 25% over 2 seconds\r
-el.fadeOut({ endOpacity: .25, duration: 2});\r
-\r
-// common config options shown with default values\r
-el.fadeOut({\r
- endOpacity: 0, //can be any value between 0 and 1 (e.g. .5)\r
- easing: 'easeOut',\r
- duration: .5,\r
- remove: false,\r
- useDisplay: false\r
-});\r
-</code></pre>\r
- * @param {Object} options (optional) Object literal with any of the Fx config options\r
- * @return {Ext.Element} The Element\r
- */\r
- fadeOut : function(o){\r
- o = getObject(o);\r
- var me = this,\r
- dom = me.dom,\r
- style = dom.style,\r
- to = o.endOpacity || 0; \r
- \r
- me.queueFx(o, function(){ \r
- arguments.callee.anim = fly(dom).fxanim({ \r
- opacity : {to : to}},\r
- o, \r
- NULL, \r
- .5, \r
- EASEOUT, \r
- function(){\r
- if(to == 0){\r
- Ext.Element.data(dom, 'visibilityMode') == Ext.Element.DISPLAY || o.useDisplay ? \r
- style.display = "none" :\r
- style.visibility = HIDDEN;\r
- \r
- fly(dom).clearOpacity();\r
- }\r
- fly(dom).afterFx(o);\r
- });\r
- });\r
- return me;\r
- },\r
-\r
- /**\r
- * Animates the transition of an element's dimensions from a starting height/width\r
- * to an ending height/width. This method is a convenience implementation of {@link shift}.\r
- * Usage:\r
-<pre><code>\r
-// change height and width to 100x100 pixels\r
-el.scale(100, 100);\r
-\r
-// common config options shown with default values. The height and width will default to\r
-// the element's existing values if passed as null.\r
-el.scale(\r
- [element's width],\r
- [element's height], {\r
- easing: 'easeOut',\r
- duration: .35\r
- }\r
-);\r
-</code></pre>\r
- * @param {Number} width The new width (pass undefined to keep the original width)\r
- * @param {Number} height The new height (pass undefined to keep the original height)\r
- * @param {Object} options (optional) Object literal with any of the Fx config options\r
- * @return {Ext.Element} The Element\r
- */\r
- scale : function(w, h, o){\r
- this.shift(Ext.apply({}, o, {\r
- width: w,\r
- height: h\r
- }));\r
- return this;\r
- },\r
-\r
- /**\r
- * Animates the transition of any combination of an element's dimensions, xy position and/or opacity.\r
- * Any of these properties not specified in the config object will not be changed. This effect \r
- * requires that at least one new dimension, position or opacity setting must be passed in on\r
- * the config object in order for the function to have any effect.\r
- * Usage:\r
-<pre><code>\r
-// slide the element horizontally to x position 200 while changing the height and opacity\r
-el.shift({ x: 200, height: 50, opacity: .8 });\r
-\r
-// common config options shown with default values.\r
-el.shift({\r
- width: [element's width],\r
- height: [element's height],\r
- x: [element's x position],\r
- y: [element's y position],\r
- opacity: [element's opacity],\r
- easing: 'easeOut',\r
- duration: .35\r
-});\r
-</code></pre>\r
- * @param {Object} options Object literal with any of the Fx config options\r
- * @return {Ext.Element} The Element\r
- */\r
- shift : function(o){\r
- o = getObject(o);\r
- var dom = this.dom,\r
- a = {};\r
- \r
- this.queueFx(o, function(){\r
- for (var prop in o) {\r
- if (o[prop] != UNDEFINED) { \r
- a[prop] = {to : o[prop]}; \r
- }\r
- } \r
- \r
- a.width ? a.width.to = fly(dom).adjustWidth(o.width) : a;\r
- a.height ? a.height.to = fly(dom).adjustWidth(o.height) : a; \r
- \r
- if (a.x || a.y || a.xy) {\r
- a.points = a.xy || \r
- {to : [ a.x ? a.x.to : fly(dom).getX(),\r
- a.y ? a.y.to : fly(dom).getY()]}; \r
- }\r
-\r
- arguments.callee.anim = fly(dom).fxanim(a,\r
- o, \r
- MOTION, \r
- .35, \r
- EASEOUT, \r
- function(){\r
- fly(dom).afterFx(o);\r
- });\r
- });\r
- return this;\r
- },\r
-\r
- /**\r
- * Slides the element while fading it out of view. An anchor point can be optionally passed to set the \r
- * ending point of the effect.\r
- * Usage:\r
- *<pre><code>\r
-// default: slide the element downward while fading out\r
-el.ghost();\r
-\r
-// custom: slide the element out to the right with a 2-second duration\r
-el.ghost('r', { duration: 2 });\r
-\r
-// common config options shown with default values\r
-el.ghost('b', {\r
- easing: 'easeOut',\r
- duration: .5,\r
- remove: false,\r
- useDisplay: false\r
-});\r
-</code></pre>\r
- * @param {String} anchor (optional) One of the valid Fx anchor positions (defaults to bottom: 'b')\r
- * @param {Object} options (optional) Object literal with any of the Fx config options\r
- * @return {Ext.Element} The Element\r
- */\r
- ghost : function(anchor, o){\r
- o = getObject(o);\r
- var me = this,\r
- dom = me.dom,\r
- st = dom.style,\r
- a = {opacity: {to: 0}, points: {}},\r
- pt = a.points,\r
- r,\r
- w,\r
- h;\r
- \r
- anchor = anchor || "b";\r
-\r
- me.queueFx(o, function(){\r
- // restore values after effect\r
- r = fly(dom).getFxRestore();\r
- w = fly(dom).getWidth();\r
- h = fly(dom).getHeight();\r
- \r
- function after(){\r
- o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide(); \r
- fly(dom).clearOpacity();\r
- fly(dom).setPositioning(r.pos);\r
- st.width = r.width;\r
- st.height = r.height;\r
- fly(dom).afterFx(o);\r
- }\r
- \r
- pt.by = fly(dom).switchStatements(anchor.toLowerCase(), function(v1,v2){ return [v1, v2];}, {\r
- t : [0, -h],\r
- l : [-w, 0],\r
- r : [w, 0],\r
- b : [0, h],\r
- tl : [-w, -h],\r
- bl : [-w, h],\r
- br : [w, h],\r
- tr : [w, -h] \r
- });\r
- \r
- arguments.callee.anim = fly(dom).fxanim(a,\r
- o,\r
- MOTION,\r
- .5,\r
- EASEOUT, after);\r
- });\r
- return me;\r
- },\r
-\r
- /**\r
- * Ensures that all effects queued after syncFx is called on the element are\r
- * run concurrently. This is the opposite of {@link #sequenceFx}.\r
- * @return {Ext.Element} The Element\r
- */\r
- syncFx : function(){\r
- var me = this;\r
- me.fxDefaults = Ext.apply(me.fxDefaults || {}, {\r
- block : FALSE,\r
- concurrent : TRUE,\r
- stopFx : FALSE\r
- });\r
- return me;\r
- },\r
-\r
- /**\r
- * Ensures that all effects queued after sequenceFx is called on the element are\r
- * run in sequence. This is the opposite of {@link #syncFx}.\r
- * @return {Ext.Element} The Element\r
- */\r
- sequenceFx : function(){\r
- var me = this;\r
- me.fxDefaults = Ext.apply(me.fxDefaults || {}, {\r
- block : FALSE,\r
- concurrent : FALSE,\r
- stopFx : FALSE\r
- });\r
- return me;\r
- },\r
-\r
- /* @private */\r
- nextFx : function(){ \r
- var ef = getQueue(this.dom.id)[0];\r
- if(ef){\r
- ef.call(this);\r
- }\r
- },\r
-\r
- /**\r
- * Returns true if the element has any effects actively running or queued, else returns false.\r
- * @return {Boolean} True if element has active effects, else false\r
- */\r
- hasActiveFx : function(){\r
- return getQueue(this.dom.id)[0];\r
- },\r
-\r
- /**\r
- * Stops any running effects and clears the element's internal effects queue if it contains\r
- * any additional effects that haven't started yet.\r
- * @return {Ext.Element} The Element\r
- */\r
- stopFx : function(finish){\r
- var me = this,\r
- id = me.dom.id;\r
- if(me.hasActiveFx()){\r
- var cur = getQueue(id)[0];\r
- if(cur && cur.anim){\r
- if(cur.anim.isAnimated){\r
- setQueue(id, [cur]); //clear\r
- cur.anim.stop(finish !== undefined ? finish : TRUE);\r
- }else{\r
- setQueue(id, []);\r
- }\r
- }\r
- }\r
- return me;\r
- },\r
-\r
- /* @private */\r
- beforeFx : function(o){\r
- if(this.hasActiveFx() && !o.concurrent){\r
- if(o.stopFx){\r
- this.stopFx();\r
- return TRUE;\r
- }\r
- return FALSE;\r
- }\r
- return TRUE;\r
- },\r
-\r
- /**\r
- * Returns true if the element is currently blocking so that no other effect can be queued\r
- * until this effect is finished, else returns false if blocking is not set. This is commonly\r
- * used to ensure that an effect initiated by a user action runs to completion prior to the\r
- * same effect being restarted (e.g., firing only one effect even if the user clicks several times).\r
- * @return {Boolean} True if blocking, else false\r
- */\r
- hasFxBlock : function(){\r
- var q = getQueue(this.dom.id);\r
- return q && q[0] && q[0].block;\r
- },\r
-\r
- /* @private */\r
- queueFx : function(o, fn){\r
- var me = this;\r
- if(!me.hasFxBlock()){\r
- Ext.applyIf(o, me.fxDefaults);\r
- if(!o.concurrent){\r
- var run = me.beforeFx(o);\r
- fn.block = o.block;\r
- getQueue(me.dom.id).push(fn);\r
- if(run){\r
- me.nextFx();\r
- }\r
- }else{\r
- fn.call(me);\r
- }\r
- }\r
- return me;\r
- },\r
-\r
- /* @private */\r
- fxWrap : function(pos, o, vis){ \r
- var dom = this.dom,\r
- wrap,\r
- wrapXY;\r
- if(!o.wrap || !(wrap = Ext.getDom(o.wrap))){ \r
- if(o.fixPosition){\r
- wrapXY = fly(dom).getXY();\r
- }\r
- var div = document.createElement("div");\r
- div.style.visibility = vis;\r
- wrap = dom.parentNode.insertBefore(div, dom);\r
- fly(wrap).setPositioning(pos);\r
- if(fly(wrap).isStyle(POSITION, "static")){\r
- fly(wrap).position("relative");\r
- }\r
- fly(dom).clearPositioning('auto');\r
- fly(wrap).clip();\r
- wrap.appendChild(dom);\r
- if(wrapXY){\r
- fly(wrap).setXY(wrapXY);\r
- }\r
- }\r
- return wrap;\r
- },\r
-\r
- /* @private */\r
- fxUnwrap : function(wrap, pos, o){ \r
- var dom = this.dom;\r
- fly(dom).clearPositioning();\r
- fly(dom).setPositioning(pos);\r
- if(!o.wrap){\r
- wrap.parentNode.insertBefore(dom, wrap);\r
- fly(wrap).remove();\r
- }\r
- },\r
-\r
- /* @private */\r
- getFxRestore : function(){\r
- var st = this.dom.style;\r
- return {pos: this.getPositioning(), width: st.width, height : st.height};\r
- },\r
-\r
- /* @private */\r
- afterFx : function(o){\r
- var dom = this.dom,\r
- id = dom.id,\r
- notConcurrent = !o.concurrent;\r
- if(o.afterStyle){\r
- fly(dom).setStyle(o.afterStyle); \r
- }\r
- if(o.afterCls){\r
- fly(dom).addClass(o.afterCls);\r
- }\r
- if(o.remove == TRUE){\r
- fly(dom).remove();\r
- }\r
- if(notConcurrent){\r
- getQueue(id).shift();\r
- }\r
- if(o.callback){\r
- o.callback.call(o.scope, fly(dom));\r
- }\r
- if(notConcurrent){\r
- fly(dom).nextFx();\r
- }\r
- },\r
-\r
- /* @private */\r
- fxanim : function(args, opt, animType, defaultDur, defaultEase, cb){\r
- animType = animType || 'run';\r
- opt = opt || {};\r
- var anim = Ext.lib.Anim[animType](\r
- this.dom, \r
- args,\r
- (opt.duration || defaultDur) || .35,\r
- (opt.easing || defaultEase) || EASEOUT,\r
- cb, \r
- this\r
- );\r
- opt.anim = anim;\r
- return anim;\r
- }\r
-};\r
-\r
-// backwards compat\r
-Ext.Fx.resize = Ext.Fx.scale;\r
-\r
-//When included, Ext.Fx is automatically applied to Element so that all basic\r
-//effects are available directly via the Element API\r
-Ext.Element.addMethods(Ext.Fx);\r
-})();/**\r
- * @class Ext.CompositeElementLite\r
- * Flyweight composite class. Reuses the same Ext.Element for element operations.\r
- <pre><code>\r
- var els = Ext.select("#some-el div.some-class");\r
- // or select directly from an existing element\r
- var el = Ext.get('some-el');\r
- el.select('div.some-class');\r
-\r
- els.setWidth(100); // all elements become 100 width\r
- els.hide(true); // all elements fade out and hide\r
- // or\r
- els.setWidth(100).hide(true);\r
- </code></pre><br><br>\r
- * <b>NOTE: Although they are not listed, this class supports all of the set/update methods of Ext.Element. All Ext.Element\r
- * actions will be performed on all the elements in this collection.</b>\r
- */\r
-Ext.CompositeElementLite = function(els, root){\r
- this.elements = [];\r
- this.add(els, root);\r
- this.el = new Ext.Element.Flyweight();\r
-};\r
-\r
-Ext.CompositeElementLite.prototype = {\r
- isComposite: true, \r
- /**\r
- * Returns the number of elements in this composite\r
- * @return Number\r
- */\r
- getCount : function(){\r
- return this.elements.length;\r
- }, \r
- add : function(els){\r
- if(els){\r
- if (Ext.isArray(els)) {\r
- this.elements = this.elements.concat(els);\r
- } else {\r
- var yels = this.elements; \r
- Ext.each(els, function(e) {\r
- yels.push(e);\r
- });\r
- }\r
- }\r
- return this;\r
- },\r
- invoke : function(fn, args){\r
- var els = this.elements,\r
- el = this.el; \r
- Ext.each(els, function(e) { \r
- el.dom = e;\r
- Ext.Element.prototype[fn].apply(el, args);\r
- });\r
- return this;\r
- },\r
- /**\r
- * Returns a flyweight Element of the dom element object at the specified index\r
- * @param {Number} index\r
- * @return {Ext.Element}\r
- */\r
- item : function(index){\r
- var me = this;\r
- if(!me.elements[index]){\r
- return null;\r
- }\r
- me.el.dom = me.elements[index];\r
- return me.el;\r
- },\r
-\r
- // fixes scope with flyweight\r
- addListener : function(eventName, handler, scope, opt){\r
- Ext.each(this.elements, function(e) {\r
- Ext.EventManager.on(e, eventName, handler, scope || e, opt);\r
- });\r
- return this;\r
- },\r
- /**\r
- * Calls the passed function passing (el, this, index) for each element in this composite. <b>The element\r
- * passed is the flyweight (shared) Ext.Element instance, so if you require a\r
- * a reference to the dom node, use el.dom.</b>\r
- * @param {Function} fn The function to call\r
- * @param {Object} scope (optional) The <i>this</i> object (defaults to the element)\r
- * @return {CompositeElement} this\r
- */\r
- each : function(fn, scope){ \r
- var me = this,\r
- el = me.el;\r
- \r
- Ext.each(me.elements, function(e,i) { \r
- el.dom = e;\r
- return fn.call(scope || el, el, me, i);\r
- });\r
- return me;\r
- },\r
- \r
- /**\r
- * Find the index of the passed element within the composite collection.\r
- * @param el {Mixed} The id of an element, or an Ext.Element, or an HtmlElement to find within the composite collection.\r
- * @return Number The index of the passed Ext.Element in the composite collection, or -1 if not found.\r
- */\r
- indexOf : function(el){\r
- return this.elements.indexOf(Ext.getDom(el));\r
- },\r
- \r
- /**\r
- * Replaces the specified element with the passed element.\r
- * @param {Mixed} el The id of an element, the Element itself, the index of the element in this composite\r
- * to replace.\r
- * @param {Mixed} replacement The id of an element or the Element itself.\r
- * @param {Boolean} domReplace (Optional) True to remove and replace the element in the document too.\r
- * @return {CompositeElement} this\r
- */ \r
- replaceElement : function(el, replacement, domReplace){\r
- var index = !isNaN(el) ? el : this.indexOf(el),\r
- d;\r
- if(index > -1){\r
- replacement = Ext.getDom(replacement);\r
- if(domReplace){\r
- d = this.elements[index];\r
- d.parentNode.insertBefore(replacement, d);\r
- Ext.removeNode(d);\r
- }\r
- this.elements.splice(index, 1, replacement);\r
- }\r
- return this;\r
- },\r
- \r
- /**\r
- * Removes all elements.\r
- */\r
- clear : function(){\r
- this.elements = [];\r
- }\r
-};\r
-\r
-Ext.CompositeElementLite.prototype.on = Ext.CompositeElementLite.prototype.addListener;\r
-\r
-(function(){\r
-var fnName,\r
- ElProto = Ext.Element.prototype,\r
- CelProto = Ext.CompositeElementLite.prototype;\r
- \r
-for(fnName in ElProto){\r
- if(Ext.isFunction(ElProto[fnName])){\r
- (function(fnName){ \r
- CelProto[fnName] = CelProto[fnName] || function(){\r
- return this.invoke(fnName, arguments);\r
- };\r
- }).call(CelProto, fnName);\r
- \r
- }\r
-}\r
-})();\r
-\r
-if(Ext.DomQuery){\r
- Ext.Element.selectorFunction = Ext.DomQuery.select;\r
-} \r
-\r
-/**\r
- * Selects elements based on the passed CSS selector to enable {@link Ext.Element Element} methods\r
- * to be applied to many related elements in one statement through the returned {@link Ext.CompositeElement CompositeElement} or\r
- * {@link Ext.CompositeElementLite CompositeElementLite} object.\r
- * @param {String/Array} selector The CSS selector or an array of elements\r
- * @param {Boolean} unique (optional) true to create a unique Ext.Element for each element (defaults to a shared flyweight object) <b>Not supported in core</b>\r
- * @param {HTMLElement/String} root (optional) The root element of the query or id of the root\r
- * @return {CompositeElementLite/CompositeElement}\r
- * @member Ext.Element\r
- * @method select\r
- */\r
-Ext.Element.select = function(selector, unique, root){\r
- var els;\r
- if(typeof selector == "string"){\r
- els = Ext.Element.selectorFunction(selector, root);\r
- }else if(selector.length !== undefined){\r
- els = selector;\r
- }else{\r
- throw "Invalid selector";\r
- }\r
- return new Ext.CompositeElementLite(els);\r
-};\r
-/**\r
- * Selects elements based on the passed CSS selector to enable {@link Ext.Element Element} methods\r
- * to be applied to many related elements in one statement through the returned {@link Ext.CompositeElement CompositeElement} or\r
- * {@link Ext.CompositeElementLite CompositeElementLite} object.\r
- * @param {String/Array} selector The CSS selector or an array of elements\r
- * @param {Boolean} unique (optional) true to create a unique Ext.Element for each element (defaults to a shared flyweight object)\r
- * @param {HTMLElement/String} root (optional) The root element of the query or id of the root\r
- * @return {CompositeElementLite/CompositeElement}\r
- * @member Ext\r
- * @method select\r
- */\r
-Ext.select = Ext.Element.select;/**\r
- * @class Ext.CompositeElementLite\r
- */\r
-Ext.apply(Ext.CompositeElementLite.prototype, { \r
- addElements : function(els, root){\r
- if(!els){\r
- return this;\r
- }\r
- if(typeof els == "string"){\r
- els = Ext.Element.selectorFunction(els, root);\r
- }\r
- var yels = this.elements; \r
- Ext.each(els, function(e) {\r
- yels.push(Ext.get(e));\r
- });\r
- return this;\r
- },\r
- \r
- /**\r
- * Clears this composite and adds the elements returned by the passed selector.\r
- * @param {String/Array} els A string CSS selector, an array of elements or an element\r
- * @return {CompositeElement} this\r
- */\r
- fill : function(els){\r
- this.elements = [];\r
- this.add(els);\r
- return this;\r
- },\r
- \r
- /**\r
- * Returns the first Element\r
- * @return {Ext.Element}\r
- */\r
- first : function(){\r
- return this.item(0);\r
- }, \r
- \r
- /**\r
- * Returns the last Element\r
- * @return {Ext.Element}\r
- */\r
- last : function(){\r
- return this.item(this.getCount()-1);\r
- },\r
- \r
- /**\r
- * Returns true if this composite contains the passed element\r
- * @param el {Mixed} The id of an element, or an Ext.Element, or an HtmlElement to find within the composite collection.\r
- * @return Boolean\r
- */\r
- contains : function(el){\r
- return this.indexOf(el) != -1;\r
- },\r
-\r
- /**\r
- * Filters this composite to only elements that match the passed selector.\r
- * @param {String} selector A string CSS selector\r
- * @return {CompositeElement} this\r
- */\r
- filter : function(selector){\r
- var els = [];\r
- this.each(function(el){\r
- if(el.is(selector)){\r
- els[els.length] = el.dom;\r
- }\r
- });\r
- this.fill(els);\r
- return this;\r
- },
-
- /**\r
- * Removes the specified element(s).\r
- * @param {Mixed} el The id of an element, the Element itself, the index of the element in this composite\r
- * or an array of any of those.\r
- * @param {Boolean} removeDom (optional) True to also remove the element from the document\r
- * @return {CompositeElement} this\r
- */\r
- removeElement : function(keys, removeDom){\r
- var me = this,\r
- els = this.elements, \r
- el; \r
- Ext.each(keys, function(val){\r
- if ((el = (els[val] || els[val = me.indexOf(val)]))) {\r
- if(removeDom){\r
- if(el.dom){\r
- el.remove();\r
- }else{\r
- Ext.removeNode(el);\r
- }\r
- }\r
- els.splice(val, 1); \r
- }\r
- });\r
- return this;\r
- } \r
-});
-/**\r
- * @class Ext.CompositeElement\r
- * @extends Ext.CompositeElementLite\r
- * Standard composite class. Creates a Ext.Element for every element in the collection.\r
- * <br><br>\r
- * <b>NOTE: Although they are not listed, this class supports all of the set/update methods of Ext.Element. All Ext.Element\r
- * actions will be performed on all the elements in this collection.</b>\r
- * <br><br>\r
- * All methods return <i>this</i> and can be chained.\r
- <pre><code>\r
- var els = Ext.select("#some-el div.some-class", true);\r
- // or select directly from an existing element\r
- var el = Ext.get('some-el');\r
- el.select('div.some-class', true);\r
-\r
- els.setWidth(100); // all elements become 100 width\r
- els.hide(true); // all elements fade out and hide\r
- // or\r
- els.setWidth(100).hide(true);\r
- </code></pre>\r
- */\r
-Ext.CompositeElement = function(els, root){\r
- this.elements = [];\r
- this.add(els, root);\r
-};\r
-\r
-Ext.extend(Ext.CompositeElement, Ext.CompositeElementLite, {\r
- invoke : function(fn, args){\r
- Ext.each(this.elements, function(e) {\r
- Ext.Element.prototype[fn].apply(e, args);\r
- });\r
- return this;\r
- },\r
- \r
- /**\r
- * Adds elements to this composite.\r
- * @param {String/Array} els A string CSS selector, an array of elements or an element\r
- * @return {CompositeElement} this\r
- */\r
- add : function(els, root){\r
- if(!els){\r
- return this;\r
- }\r
- if(typeof els == "string"){\r
- els = Ext.Element.selectorFunction(els, root);\r
- }\r
- var yels = this.elements; \r
- Ext.each(els, function(e) {\r
- yels.push(Ext.get(e));\r
- });\r
- return this;\r
- }, \r
- \r
- /**\r
- * Returns the Element object at the specified index\r
- * @param {Number} index\r
- * @return {Ext.Element}\r
- */\r
- item : function(index){\r
- return this.elements[index] || null;\r
- },\r
-\r
-\r
- indexOf : function(el){\r
- return this.elements.indexOf(Ext.get(el));\r
- },\r
- \r
- filter : function(selector){\r
- var me = this,\r
- out = [];\r
- \r
- Ext.each(me.elements, function(el) { \r
- if(el.is(selector)){\r
- out.push(Ext.get(el));\r
- }\r
- });\r
- me.elements = out;\r
- return me;\r
- },\r
- \r
- /**\r
- * Calls the passed function passing (el, this, index) for each element in this composite.\r
- * @param {Function} fn The function to call\r
- * @param {Object} scope (optional) The <i>this</i> object (defaults to the element)\r
- * @return {CompositeElement} this\r
- */\r
- each : function(fn, scope){ \r
- Ext.each(this.elements, function(e,i) {\r
- return fn.call(scope || e, e, this, i);\r
- }, this);\r
- return this;\r
- }\r
-});\r
-\r
-/**\r
- * Selects elements based on the passed CSS selector to enable {@link Ext.Element Element} methods\r
- * to be applied to many related elements in one statement through the returned {@link Ext.CompositeElement CompositeElement} or\r
- * {@link Ext.CompositeElementLite CompositeElementLite} object.\r
- * @param {String/Array} selector The CSS selector or an array of elements\r
- * @param {Boolean} unique (optional) true to create a unique Ext.Element for each element (defaults to a shared flyweight object)\r
- * @param {HTMLElement/String} root (optional) The root element of the query or id of the root\r
- * @return {CompositeElementLite/CompositeElement}\r
- * @member Ext.Element\r
- * @method select\r
- */\r
-Ext.Element.select = function(selector, unique, root){\r
- var els;\r
- if(typeof selector == "string"){\r
- els = Ext.Element.selectorFunction(selector, root);\r
- }else if(selector.length !== undefined){\r
- els = selector;\r
- }else{\r
- throw "Invalid selector";\r
- }\r
-\r
- return (unique === true) ? new Ext.CompositeElement(els) : new Ext.CompositeElementLite(els);\r
-};
-\r
-/**\r
- * Selects elements based on the passed CSS selector to enable {@link Ext.Element Element} methods\r
- * to be applied to many related elements in one statement through the returned {@link Ext.CompositeElement CompositeElement} or\r
- * {@link Ext.CompositeElementLite CompositeElementLite} object.\r
- * @param {String/Array} selector The CSS selector or an array of elements\r
- * @param {Boolean} unique (optional) true to create a unique Ext.Element for each element (defaults to a shared flyweight object)\r
- * @param {HTMLElement/String} root (optional) The root element of the query or id of the root\r
- * @return {CompositeElementLite/CompositeElement}\r
- * @member Ext.Element\r
- * @method select\r
- */\r
-Ext.select = Ext.Element.select;(function(){\r
- var BEFOREREQUEST = "beforerequest",\r
- REQUESTCOMPLETE = "requestcomplete",\r
- REQUESTEXCEPTION = "requestexception",\r
- UNDEFINED = undefined,\r
- LOAD = 'load',\r
- POST = 'POST',\r
- GET = 'GET',\r
- WINDOW = window;\r
- \r
- /**\r
- * @class Ext.data.Connection\r
- * @extends Ext.util.Observable\r
- * <p>The class encapsulates a connection to the page's originating domain, allowing requests to be made\r
- * either to a configured URL, or to a URL specified at request time.</p>\r
- * <p>Requests made by this class are asynchronous, and will return immediately. No data from\r
- * the server will be available to the statement immediately following the {@link #request} call.\r
- * To process returned data, use a\r
- * <a href="#request-option-success" ext:member="request-option-success" ext:cls="Ext.data.Connection">success callback</a>\r
- * in the request options object,\r
- * or an {@link #requestcomplete event listener}.</p>\r
- * <p><h3>File Uploads</h3><a href="#request-option-isUpload" ext:member="request-option-isUpload" ext:cls="Ext.data.Connection">File uploads</a> are not performed using normal "Ajax" techniques, that\r
- * is they are <b>not</b> performed using XMLHttpRequests. Instead the form is submitted in the standard\r
- * manner with the DOM <tt><form></tt> element temporarily modified to have its\r
- * <a href="http://www.w3.org/TR/REC-html40/present/frames.html#adef-target">target</a> set to refer\r
- * to a dynamically generated, hidden <tt><iframe></tt> which is inserted into the document\r
- * but removed after the return data has been gathered.</p>\r
- * <p>The server response is parsed by the browser to create the document for the IFRAME. If the\r
- * server is using JSON to send the return object, then the\r
- * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17">Content-Type</a> header\r
- * must be set to "text/html" in order to tell the browser to insert the text unchanged into the document body.</p>\r
- * <p>Characters which are significant to an HTML parser must be sent as HTML entities, so encode\r
- * "<" as "&lt;", "&" as "&amp;" etc.</p>\r
- * <p>The response text is retrieved from the document, and a fake XMLHttpRequest object\r
- * is created containing a <tt>responseText</tt> property in order to conform to the\r
- * requirements of event handlers and callbacks.</p>\r
- * <p>Be aware that file upload packets are sent with the content type <a href="http://www.faqs.org/rfcs/rfc2388.html">multipart/form</a>\r
- * and some server technologies (notably JEE) may require some custom processing in order to\r
- * retrieve parameter names and parameter values from the packet content.</p>\r
- * @constructor\r
- * @param {Object} config a configuration object.\r
- */\r
- Ext.data.Connection = function(config){ \r
- Ext.apply(this, config);\r
- this.addEvents(\r
- /**\r
- * @event beforerequest\r
- * Fires before a network request is made to retrieve a data object.\r
- * @param {Connection} conn This Connection object.\r
- * @param {Object} options The options config object passed to the {@link #request} method.\r
- */\r
- BEFOREREQUEST,\r
- /**\r
- * @event requestcomplete\r
- * Fires if the request was successfully completed.\r
- * @param {Connection} conn This Connection object.\r
- * @param {Object} response The XHR object containing the response data.\r
- * See <a href="http://www.w3.org/TR/XMLHttpRequest/">The XMLHttpRequest Object</a>\r
- * for details.\r
- * @param {Object} options The options config object passed to the {@link #request} method.\r
- */\r
- REQUESTCOMPLETE,\r
- /**\r
- * @event requestexception\r
- * Fires if an error HTTP status was returned from the server.\r
- * See <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">HTTP Status Code Definitions</a>\r
- * for details of HTTP status codes.\r
- * @param {Connection} conn This Connection object.\r
- * @param {Object} response The XHR object containing the response data.\r
- * See <a href="http://www.w3.org/TR/XMLHttpRequest/">The XMLHttpRequest Object</a>\r
- * for details.\r
- * @param {Object} options The options config object passed to the {@link #request} method.\r
- */\r
- REQUESTEXCEPTION\r
- );\r
- Ext.data.Connection.superclass.constructor.call(this);\r
- };\r
-\r
- // private\r
- function handleResponse(response){\r
- this.transId = false;\r
- var options = response.argument.options;\r
- response.argument = options ? options.argument : null;\r
- this.fireEvent(REQUESTCOMPLETE, this, response, options);\r
- if(options.success){\r
- options.success.call(options.scope, response, options);\r
- }\r
- if(options.callback){\r
- options.callback.call(options.scope, options, true, response);\r
- }\r
- }\r
-\r
- // private\r
- function handleFailure(response, e){\r
- this.transId = false;\r
- var options = response.argument.options;\r
- response.argument = options ? options.argument : null;\r
- this.fireEvent(REQUESTEXCEPTION, this, response, options, e);\r
- if(options.failure){\r
- options.failure.call(options.scope, response, options);\r
- }\r
- if(options.callback){\r
- options.callback.call(options.scope, options, false, response);\r
- }\r
- }\r
-\r
- // private\r
- function doFormUpload(o, ps, url){\r
- var id = Ext.id(),\r
- doc = document,\r
- frame = doc.createElement('iframe'),\r
- form = Ext.getDom(o.form),\r
- hiddens = [],\r
- hd,\r
- encoding = 'multipart/form-data',\r
- buf = {\r
- target: form.target,\r
- method: form.method,\r
- encoding: form.encoding,\r
- enctype: form.enctype,\r
- action: form.action\r
- };\r
- \r
- Ext.apply(frame, {\r
- id: id,\r
- name: id,\r
- className: 'x-hidden',\r
- src: Ext.SSL_SECURE_URL // for IE\r
- }); \r
- doc.body.appendChild(frame);\r
- \r
- // This is required so that IE doesn't pop the response up in a new window.\r
- if(Ext.isIE){\r
- document.frames[id].name = id;\r
- }\r
- \r
- Ext.apply(form, {\r
- target: id,\r
- method: POST,\r
- enctype: encoding,\r
- encoding: encoding,\r
- action: url || buf.action\r
- });\r
- \r
- // add dynamic params \r
- ps = Ext.urlDecode(ps, false);\r
- for(var k in ps){\r
- if(ps.hasOwnProperty(k)){\r
- hd = doc.createElement('input');\r
- hd.type = 'hidden'; \r
- hd.value = ps[hd.name = k];\r
- form.appendChild(hd);\r
- hiddens.push(hd);\r
- }\r
- } \r
-\r
- function cb(){\r
- var me = this,\r
- // bogus response object\r
- r = {responseText : '',\r
- responseXML : null,\r
- argument : o.argument},\r
- doc,\r
- firstChild;\r
-\r
- try{ \r
- doc = frame.contentWindow.document || frame.contentDocument || WINDOW.frames[id].document;\r
- if(doc){\r
- if(doc.body){\r
- if(/textarea/i.test((firstChild = doc.body.firstChild || {}).tagName)){ // json response wrapped in textarea \r
- r.responseText = firstChild.value;\r
- }else{\r
- r.responseText = doc.body.innerHTML;\r
- }\r
- }\r
- //in IE the document may still have a body even if returns XML.\r
- r.responseXML = doc.XMLDocument || doc;\r
- }\r
- }\r
- catch(e) {}\r
-\r
- Ext.EventManager.removeListener(frame, LOAD, cb, me);\r
-\r
- me.fireEvent(REQUESTCOMPLETE, me, r, o);\r
- \r
- function runCallback(fn, scope, args){\r
- if(Ext.isFunction(fn)){\r
- fn.apply(scope, args);\r
- }\r
- }\r
-\r
- runCallback(o.success, o.scope, [r, o]);\r
- runCallback(o.callback, o.scope, [o, true, r]);\r
-\r
- if(!me.debugUploads){\r
- setTimeout(function(){Ext.removeNode(frame);}, 100);\r
- }\r
- }\r
-\r
- Ext.EventManager.on(frame, LOAD, cb, this);\r
- form.submit();\r
- \r
- Ext.apply(form, buf);\r
- Ext.each(hiddens, function(h) {\r
- Ext.removeNode(h);\r
- });\r
- }\r
-\r
- Ext.extend(Ext.data.Connection, Ext.util.Observable, {\r
- /**\r
- * @cfg {String} url (Optional) <p>The default URL to be used for requests to the server. Defaults to undefined.</p>\r
- * <p>The <code>url</code> config may be a function which <i>returns</i> the URL to use for the Ajax request. The scope\r
- * (<code><b>this</b></code> reference) of the function is the <code>scope</code> option passed to the {@link #request} method.</p>\r
- */\r
- /**\r
- * @cfg {Object} extraParams (Optional) An object containing properties which are used as\r
- * extra parameters to each request made by this object. (defaults to undefined)\r
- */\r
- /**\r
- * @cfg {Object} defaultHeaders (Optional) An object containing request headers which are added\r
- * to each request made by this object. (defaults to undefined)\r
- */\r
- /**\r
- * @cfg {String} method (Optional) The default HTTP method to be used for requests.\r
- * (defaults to undefined; if not set, but {@link #request} params are present, POST will be used;\r
- * otherwise, GET will be used.)\r
- */\r
- /**\r
- * @cfg {Number} timeout (Optional) The timeout in milliseconds to be used for requests. (defaults to 30000)\r
- */\r
- timeout : 30000,\r
- /**\r
- * @cfg {Boolean} autoAbort (Optional) Whether this request should abort any pending requests. (defaults to false)\r
- * @type Boolean\r
- */\r
- autoAbort:false,\r
- \r
- /**\r
- * @cfg {Boolean} disableCaching (Optional) True to add a unique cache-buster param to GET requests. (defaults to true)\r
- * @type Boolean\r
- */\r
- disableCaching: true,\r
- \r
- /**\r
- * @cfg {String} disableCachingParam (Optional) Change the parameter which is sent went disabling caching\r
- * through a cache buster. Defaults to '_dc'\r
- * @type String\r
- */\r
- disableCachingParam: '_dc',\r
- \r
- /**\r
- * <p>Sends an HTTP request to a remote server.</p>\r
- * <p><b>Important:</b> Ajax server requests are asynchronous, and this call will\r
- * return before the response has been received. Process any returned data\r
- * in a callback function.</p>\r
- * <pre><code>\r
-Ext.Ajax.request({\r
- url: 'ajax_demo/sample.json',\r
- success: function(response, opts) {\r
- var obj = Ext.decode(response.responseText);\r
- console.dir(obj);\r
- },\r
- failure: function(response, opts) {\r
- console.log('server-side failure with status code ' + response.status);\r
- }\r
-});\r
- * </code></pre>\r
- * <p>To execute a callback function in the correct scope, use the <tt>scope</tt> option.</p>\r
- * @param {Object} options An object which may contain the following properties:<ul>\r
- * <li><b>url</b> : String/Function (Optional)<div class="sub-desc">The URL to\r
- * which to send the request, or a function to call which returns a URL string. The scope of the\r
- * function is specified by the <tt>scope</tt> option. Defaults to the configured\r
- * <tt>{@link #url}</tt>.</div></li>\r
- * <li><b>params</b> : Object/String/Function (Optional)<div class="sub-desc">\r
- * An object containing properties which are used as parameters to the\r
- * request, a url encoded string or a function to call to get either. The scope of the function\r
- * is specified by the <tt>scope</tt> option.</div></li>\r
- * <li><b>method</b> : String (Optional)<div class="sub-desc">The HTTP method to use\r
- * for the request. Defaults to the configured method, or if no method was configured,\r
- * "GET" if no parameters are being sent, and "POST" if parameters are being sent. Note that\r
- * the method name is case-sensitive and should be all caps.</div></li>\r
- * <li><b>callback</b> : Function (Optional)<div class="sub-desc">The\r
- * function to be called upon receipt of the HTTP response. The callback is\r
- * called regardless of success or failure and is passed the following\r
- * parameters:<ul>\r
- * <li><b>options</b> : Object<div class="sub-desc">The parameter to the request call.</div></li>\r
- * <li><b>success</b> : Boolean<div class="sub-desc">True if the request succeeded.</div></li>\r
- * <li><b>response</b> : Object<div class="sub-desc">The XMLHttpRequest object containing the response data. \r
- * See <a href="http://www.w3.org/TR/XMLHttpRequest/">http://www.w3.org/TR/XMLHttpRequest/</a> for details about \r
- * accessing elements of the response.</div></li>\r
- * </ul></div></li>\r
- * <li><a id="request-option-success"></a><b>success</b> : Function (Optional)<div class="sub-desc">The function\r
- * to be called upon success of the request. The callback is passed the following\r
- * parameters:<ul>\r
- * <li><b>response</b> : Object<div class="sub-desc">The XMLHttpRequest object containing the response data.</div></li>\r
- * <li><b>options</b> : Object<div class="sub-desc">The parameter to the request call.</div></li>\r
- * </ul></div></li>\r
- * <li><b>failure</b> : Function (Optional)<div class="sub-desc">The function\r
- * to be called upon failure of the request. The callback is passed the\r
- * following parameters:<ul>\r
- * <li><b>response</b> : Object<div class="sub-desc">The XMLHttpRequest object containing the response data.</div></li>\r
- * <li><b>options</b> : Object<div class="sub-desc">The parameter to the request call.</div></li>\r
- * </ul></div></li>\r
- * <li><b>scope</b> : Object (Optional)<div class="sub-desc">The scope in\r
- * which to execute the callbacks: The "this" object for the callback function. If the <tt>url</tt>, or <tt>params</tt> options were\r
- * specified as functions from which to draw values, then this also serves as the scope for those function calls.\r
- * Defaults to the browser window.</div></li>\r
- * <li><b>timeout</b> : Number (Optional)<div class="sub-desc">The timeout in milliseconds to be used for this request. Defaults to 30 seconds.</div></li>\r
- * <li><b>form</b> : Element/HTMLElement/String (Optional)<div class="sub-desc">The <tt><form></tt>\r
- * Element or the id of the <tt><form></tt> to pull parameters from.</div></li>\r
- * <li><a id="request-option-isUpload"></a><b>isUpload</b> : Boolean (Optional)<div class="sub-desc"><b>Only meaningful when used \r
- * with the <tt>form</tt> option</b>.\r
- * <p>True if the form object is a file upload (will be set automatically if the form was\r
- * configured with <b><tt>enctype</tt></b> "multipart/form-data").</p>\r
- * <p>File uploads are not performed using normal "Ajax" techniques, that is they are <b>not</b>\r
- * performed using XMLHttpRequests. Instead the form is submitted in the standard manner with the\r
- * DOM <tt><form></tt> element temporarily modified to have its\r
- * <a href="http://www.w3.org/TR/REC-html40/present/frames.html#adef-target">target</a> set to refer\r
- * to a dynamically generated, hidden <tt><iframe></tt> which is inserted into the document\r
- * but removed after the return data has been gathered.</p>\r
- * <p>The server response is parsed by the browser to create the document for the IFRAME. If the\r
- * server is using JSON to send the return object, then the\r
- * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17">Content-Type</a> header\r
- * must be set to "text/html" in order to tell the browser to insert the text unchanged into the document body.</p>\r
- * <p>The response text is retrieved from the document, and a fake XMLHttpRequest object\r
- * is created containing a <tt>responseText</tt> property in order to conform to the\r
- * requirements of event handlers and callbacks.</p>\r
- * <p>Be aware that file upload packets are sent with the content type <a href="http://www.faqs.org/rfcs/rfc2388.html">multipart/form</a>\r
- * and some server technologies (notably JEE) may require some custom processing in order to\r
- * retrieve parameter names and parameter values from the packet content.</p>\r
- * </div></li>\r
- * <li><b>headers</b> : Object (Optional)<div class="sub-desc">Request\r
- * headers to set for the request.</div></li>\r
- * <li><b>xmlData</b> : Object (Optional)<div class="sub-desc">XML document\r
- * to use for the post. Note: This will be used instead of params for the post\r
- * data. Any params will be appended to the URL.</div></li>\r
- * <li><b>jsonData</b> : Object/String (Optional)<div class="sub-desc">JSON\r
- * data to use as the post. Note: This will be used instead of params for the post\r
- * data. Any params will be appended to the URL.</div></li>\r
- * <li><b>disableCaching</b> : Boolean (Optional)<div class="sub-desc">True\r
- * to add a unique cache-buster param to GET requests.</div></li>\r
- * </ul></p>\r
- * <p>The options object may also contain any other property which might be needed to perform\r
- * postprocessing in a callback because it is passed to callback functions.</p>\r
- * @return {Number} transactionId The id of the server transaction. This may be used\r
- * to cancel the request.\r
- */\r
- request : function(o){\r
- var me = this;\r
- if(me.fireEvent(BEFOREREQUEST, me, o)){\r
- if (o.el) {\r
- if(!Ext.isEmpty(o.indicatorText)){\r
- me.indicatorText = '<div class="loading-indicator">'+o.indicatorText+"</div>";\r
- }\r
- if(me.indicatorText) {\r
- Ext.getDom(o.el).innerHTML = me.indicatorText; \r
- }\r
- o.success = (Ext.isFunction(o.success) ? o.success : function(){}).createInterceptor(function(response) {\r
- Ext.getDom(o.el).innerHTML = response.responseText;\r
- });\r
- }\r
- \r
- var p = o.params,\r
- url = o.url || me.url, \r
- method,\r
- cb = {success: handleResponse,\r
- failure: handleFailure,\r
- scope: me,\r
- argument: {options: o},\r
- timeout : o.timeout || me.timeout\r
- },\r
- form, \r
- serForm; \r
- \r
- \r
- if (Ext.isFunction(p)) {\r
- p = p.call(o.scope||WINDOW, o);\r
- }\r
- \r
- p = Ext.urlEncode(me.extraParams, Ext.isObject(p) ? Ext.urlEncode(p) : p); \r
- \r
- if (Ext.isFunction(url)) {\r
- url = url.call(o.scope || WINDOW, o);\r
- }\r
- \r
- if((form = Ext.getDom(o.form))){\r
- url = url || form.action;\r
- if(o.isUpload || /multipart\/form-data/i.test(form.getAttribute("enctype"))) { \r
- return doFormUpload.call(me, o, p, url);\r
- }\r
- serForm = Ext.lib.Ajax.serializeForm(form); \r
- p = p ? (p + '&' + serForm) : serForm;\r
- }\r
- \r
- method = o.method || me.method || ((p || o.xmlData || o.jsonData) ? POST : GET);\r
- \r
- if(method === GET && (me.disableCaching && o.disableCaching !== false) || o.disableCaching === true){\r
- var dcp = o.disableCachingParam || me.disableCachingParam;\r
- url = Ext.urlAppend(url, dcp + '=' + (new Date().getTime()));\r
- }\r
- \r
- o.headers = Ext.apply(o.headers || {}, me.defaultHeaders || {});\r
- \r
- if(o.autoAbort === true || me.autoAbort) {\r
- me.abort();\r
- }\r
- \r
- if((method == GET || o.xmlData || o.jsonData) && p){\r
- url = Ext.urlAppend(url, p); \r
- p = '';\r
- }\r
- return (me.transId = Ext.lib.Ajax.request(method, url, cb, p, o));\r
- }else{ \r
- return o.callback ? o.callback.apply(o.scope, [o,UNDEFINED,UNDEFINED]) : null;\r
- }\r
- },\r
- \r
- /**\r
- * Determine whether this object has a request outstanding.\r
- * @param {Number} transactionId (Optional) defaults to the last transaction\r
- * @return {Boolean} True if there is an outstanding request.\r
- */\r
- isLoading : function(transId){\r
- return transId ? Ext.lib.Ajax.isCallInProgress(transId) : !! this.transId; \r
- },\r
- \r
- /**\r
- * Aborts any outstanding request.\r
- * @param {Number} transactionId (Optional) defaults to the last transaction\r
- */\r
- abort : function(transId){\r
- if(transId || this.isLoading()){\r
- Ext.lib.Ajax.abort(transId || this.transId);\r
- }\r
- }\r
- });\r
-})();\r
-\r
-/**\r
- * @class Ext.Ajax\r
- * @extends Ext.data.Connection\r
- * <p>The global Ajax request class that provides a simple way to make Ajax requests\r
- * with maximum flexibility.</p>\r
- * <p>Since Ext.Ajax is a singleton, you can set common properties/events for it once\r
- * and override them at the request function level only if necessary.</p>\r
- * <p>Common <b>Properties</b> you may want to set are:<div class="mdetail-params"><ul>\r
- * <li><b><tt>{@link #method}</tt></b><p class="sub-desc"></p></li>\r
- * <li><b><tt>{@link #extraParams}</tt></b><p class="sub-desc"></p></li>\r
- * <li><b><tt>{@link #url}</tt></b><p class="sub-desc"></p></li>\r
- * </ul></div>\r
- * <pre><code>\r
-// Default headers to pass in every request\r
-Ext.Ajax.defaultHeaders = {\r
- 'Powered-By': 'Ext'\r
-};\r
- * </code></pre> \r
- * </p>\r
- * <p>Common <b>Events</b> you may want to set are:<div class="mdetail-params"><ul>\r
- * <li><b><tt>{@link Ext.data.Connection#beforerequest beforerequest}</tt></b><p class="sub-desc"></p></li>\r
- * <li><b><tt>{@link Ext.data.Connection#requestcomplete requestcomplete}</tt></b><p class="sub-desc"></p></li>\r
- * <li><b><tt>{@link Ext.data.Connection#requestexception requestexception}</tt></b><p class="sub-desc"></p></li>\r
- * </ul></div>\r
- * <pre><code>\r
-// Example: show a spinner during all Ajax requests\r
-Ext.Ajax.on('beforerequest', this.showSpinner, this);\r
-Ext.Ajax.on('requestcomplete', this.hideSpinner, this);\r
-Ext.Ajax.on('requestexception', this.hideSpinner, this);\r
- * </code></pre> \r
- * </p>\r
- * <p>An example request:</p>\r
- * <pre><code>\r
-// Basic request\r
-Ext.Ajax.{@link Ext.data.Connection#request request}({\r
- url: 'foo.php',\r
- success: someFn,\r
- failure: otherFn,\r
- headers: {\r
- 'my-header': 'foo'\r
- },\r
- params: { foo: 'bar' }\r
-});\r
-\r
-// Simple ajax form submission\r
-Ext.Ajax.{@link Ext.data.Connection#request request}({\r
- form: 'some-form',\r
- params: 'foo=bar'\r
-});\r
- * </code></pre> \r
- * </p>\r
- * @singleton\r
- */\r
-Ext.Ajax = new Ext.data.Connection({\r
- /**\r
- * @cfg {String} url @hide\r
- */\r
- /**\r
- * @cfg {Object} extraParams @hide\r
- */\r
- /**\r
- * @cfg {Object} defaultHeaders @hide\r
- */\r
- /**\r
- * @cfg {String} method (Optional) @hide\r
- */\r
- /**\r
- * @cfg {Number} timeout (Optional) @hide\r
- */\r
- /**\r
- * @cfg {Boolean} autoAbort (Optional) @hide\r
- */\r
-\r
- /**\r
- * @cfg {Boolean} disableCaching (Optional) @hide\r
- */\r
-\r
- /**\r
- * @property disableCaching\r
- * True to add a unique cache-buster param to GET requests. (defaults to true)\r
- * @type Boolean\r
- */\r
- /**\r
- * @property url\r
- * The default URL to be used for requests to the server. (defaults to undefined)\r
- * If the server receives all requests through one URL, setting this once is easier than\r
- * entering it on every request.\r
- * @type String\r
- */\r
- /**\r
- * @property extraParams\r
- * An object containing properties which are used as extra parameters to each request made\r
- * by this object (defaults to undefined). Session information and other data that you need\r
- * to pass with each request are commonly put here.\r
- * @type Object\r
- */\r
- /**\r
- * @property defaultHeaders\r
- * An object containing request headers which are added to each request made by this object\r
- * (defaults to undefined).\r
- * @type Object\r
- */\r
- /**\r
- * @property method\r
- * The default HTTP method to be used for requests. Note that this is case-sensitive and\r
- * should be all caps (defaults to undefined; if not set but params are present will use\r
- * <tt>"POST"</tt>, otherwise will use <tt>"GET"</tt>.)\r
- * @type String\r
- */\r
- /**\r
- * @property timeout\r
- * The timeout in milliseconds to be used for requests. (defaults to 30000)\r
- * @type Number\r
- */\r
-\r
- /**\r
- * @property autoAbort\r
- * Whether a new request should abort any pending requests. (defaults to false)\r
- * @type Boolean\r
- */\r
- autoAbort : false,\r
-\r
- /**\r
- * Serialize the passed form into a url encoded string\r
- * @param {String/HTMLElement} form\r
- * @return {String}\r
- */\r
- serializeForm : function(form){\r
- return Ext.lib.Ajax.serializeForm(form);\r
- }\r
-});\r
-/**
- * @class Ext.Updater
- * @extends Ext.util.Observable
- * Provides AJAX-style update capabilities for Element objects. Updater can be used to {@link #update}
- * an {@link Ext.Element} once, or you can use {@link #startAutoRefresh} to set up an auto-updating
- * {@link Ext.Element Element} on a specific interval.<br><br>
- * Usage:<br>
- * <pre><code>
- * var el = Ext.get("foo"); // Get Ext.Element object
- * var mgr = el.getUpdater();
- * mgr.update({
- url: "http://myserver.com/index.php",
- params: {
- param1: "foo",
- param2: "bar"
- }
- * });
- * ...
- * mgr.formUpdate("myFormId", "http://myserver.com/index.php");
- * <br>
- * // or directly (returns the same Updater instance)
- * var mgr = new Ext.Updater("myElementId");
- * mgr.startAutoRefresh(60, "http://myserver.com/index.php");
- * mgr.on("update", myFcnNeedsToKnow);
- * <br>
- * // short handed call directly from the element object
- * Ext.get("foo").load({
- url: "bar.php",
- scripts: true,
- params: "param1=foo&param2=bar",
- text: "Loading Foo..."
- * });
- * </code></pre>
- * @constructor
- * Create new Updater directly.
- * @param {Mixed} el The element to update
- * @param {Boolean} forceNew (optional) By default the constructor checks to see if the passed element already
- * has an Updater and if it does it returns the same instance. This will skip that check (useful for extending this class).
- */
-Ext.UpdateManager = Ext.Updater = Ext.extend(Ext.util.Observable,
-function() {
- var BEFOREUPDATE = "beforeupdate",
- UPDATE = "update",
- FAILURE = "failure";
-
- // private
- function processSuccess(response){
- var me = this;
- me.transaction = null;
- if (response.argument.form && response.argument.reset) {
- try { // put in try/catch since some older FF releases had problems with this
- response.argument.form.reset();
- } catch(e){}
- }
- if (me.loadScripts) {
- me.renderer.render(me.el, response, me,
- updateComplete.createDelegate(me, [response]));
- } else {
- me.renderer.render(me.el, response, me);
- updateComplete.call(me, response);
- }
- }
-
- // private
- function updateComplete(response, type, success){
- this.fireEvent(type || UPDATE, this.el, response);
- if(Ext.isFunction(response.argument.callback)){
- response.argument.callback.call(response.argument.scope, this.el, Ext.isEmpty(success) ? true : false, response, response.argument.options);
- }
- }
-
- // private
- function processFailure(response){
- updateComplete.call(this, response, FAILURE, !!(this.transaction = null));
- }
-
- return {
- constructor: function(el, forceNew){
- var me = this;
- el = Ext.get(el);
- if(!forceNew && el.updateManager){
- return el.updateManager;
- }
- /**
- * The Element object
- * @type Ext.Element
- */
- me.el = el;
- /**
- * Cached url to use for refreshes. Overwritten every time update() is called unless "discardUrl" param is set to true.
- * @type String
- */
- me.defaultUrl = null;
-
- me.addEvents(
- /**
- * @event beforeupdate
- * Fired before an update is made, return false from your handler and the update is cancelled.
- * @param {Ext.Element} el
- * @param {String/Object/Function} url
- * @param {String/Object} params
- */
- BEFOREUPDATE,
- /**
- * @event update
- * Fired after successful update is made.
- * @param {Ext.Element} el
- * @param {Object} oResponseObject The response Object
- */
- UPDATE,
- /**
- * @event failure
- * Fired on update failure.
- * @param {Ext.Element} el
- * @param {Object} oResponseObject The response Object
- */
- FAILURE
- );
-
- Ext.apply(me, Ext.Updater.defaults);
- /**
- * Blank page URL to use with SSL file uploads (defaults to {@link Ext.Updater.defaults#sslBlankUrl}).
- * @property sslBlankUrl
- * @type String
- */
- /**
- * Whether to append unique parameter on get request to disable caching (defaults to {@link Ext.Updater.defaults#disableCaching}).
- * @property disableCaching
- * @type Boolean
- */
- /**
- * Text for loading indicator (defaults to {@link Ext.Updater.defaults#indicatorText}).
- * @property indicatorText
- * @type String
- */
- /**
- * Whether to show indicatorText when loading (defaults to {@link Ext.Updater.defaults#showLoadIndicator}).
- * @property showLoadIndicator
- * @type String
- */
- /**
- * Timeout for requests or form posts in seconds (defaults to {@link Ext.Updater.defaults#timeout}).
- * @property timeout
- * @type Number
- */
- /**
- * True to process scripts in the output (defaults to {@link Ext.Updater.defaults#loadScripts}).
- * @property loadScripts
- * @type Boolean
- */
-
- /**
- * Transaction object of the current executing transaction, or null if there is no active transaction.
- */
- me.transaction = null;
- /**
- * Delegate for refresh() prebound to "this", use myUpdater.refreshDelegate.createCallback(arg1, arg2) to bind arguments
- * @type Function
- */
- me.refreshDelegate = me.refresh.createDelegate(me);
- /**
- * Delegate for update() prebound to "this", use myUpdater.updateDelegate.createCallback(arg1, arg2) to bind arguments
- * @type Function
- */
- me.updateDelegate = me.update.createDelegate(me);
- /**
- * Delegate for formUpdate() prebound to "this", use myUpdater.formUpdateDelegate.createCallback(arg1, arg2) to bind arguments
- * @type Function
- */
- me.formUpdateDelegate = (me.formUpdate || function(){}).createDelegate(me);
-
- /**
- * The renderer for this Updater (defaults to {@link Ext.Updater.BasicRenderer}).
- */
- me.renderer = me.renderer || me.getDefaultRenderer();
-
- Ext.Updater.superclass.constructor.call(me);
- },
-
- /**
- * Sets the content renderer for this Updater. See {@link Ext.Updater.BasicRenderer#render} for more details.
- * @param {Object} renderer The object implementing the render() method
- */
- setRenderer : function(renderer){
- this.renderer = renderer;
- },
-
- /**
- * Returns the current content renderer for this Updater. See {@link Ext.Updater.BasicRenderer#render} for more details.
- * @return {Object}
- */
- getRenderer : function(){
- return this.renderer;
- },
-
- /**
- * This is an overrideable method which returns a reference to a default
- * renderer class if none is specified when creating the Ext.Updater.
- * Defaults to {@link Ext.Updater.BasicRenderer}
- */
- getDefaultRenderer: function() {
- return new Ext.Updater.BasicRenderer();
- },
-
- /**
- * Sets the default URL used for updates.
- * @param {String/Function} defaultUrl The url or a function to call to get the url
- */
- setDefaultUrl : function(defaultUrl){
- this.defaultUrl = defaultUrl;
- },
-
- /**
- * Get the Element this Updater is bound to
- * @return {Ext.Element} The element
- */
- getEl : function(){
- return this.el;
- },
-
- /**
- * Performs an <b>asynchronous</b> request, updating this element with the response.
- * If params are specified it uses POST, otherwise it uses GET.<br><br>
- * <b>Note:</b> Due to the asynchronous nature of remote server requests, the Element
- * will not have been fully updated when the function returns. To post-process the returned
- * data, use the callback option, or an <b><tt>update</tt></b> event handler.
- * @param {Object} options A config object containing any of the following options:<ul>
- * <li>url : <b>String/Function</b><p class="sub-desc">The URL to request or a function which
- * <i>returns</i> the URL (defaults to the value of {@link Ext.Ajax#url} if not specified).</p></li>
- * <li>method : <b>String</b><p class="sub-desc">The HTTP method to
- * use. Defaults to POST if the <tt>params</tt> argument is present, otherwise GET.</p></li>
- * <li>params : <b>String/Object/Function</b><p class="sub-desc">The
- * parameters to pass to the server (defaults to none). These may be specified as a url-encoded
- * string, or as an object containing properties which represent parameters,
- * or as a function, which returns such an object.</p></li>
- * <li>scripts : <b>Boolean</b><p class="sub-desc">If <tt>true</tt>
- * any <script> tags embedded in the response text will be extracted
- * and executed (defaults to {@link Ext.Updater.defaults#loadScripts}). If this option is specified,
- * the callback will be called <i>after</i> the execution of the scripts.</p></li>
- * <li>callback : <b>Function</b><p class="sub-desc">A function to
- * be called when the response from the server arrives. The following
- * parameters are passed:<ul>
- * <li><b>el</b> : Ext.Element<p class="sub-desc">The Element being updated.</p></li>
- * <li><b>success</b> : Boolean<p class="sub-desc">True for success, false for failure.</p></li>
- * <li><b>response</b> : XMLHttpRequest<p class="sub-desc">The XMLHttpRequest which processed the update.</p></li>
- * <li><b>options</b> : Object<p class="sub-desc">The config object passed to the update call.</p></li></ul>
- * </p></li>
- * <li>scope : <b>Object</b><p class="sub-desc">The scope in which
- * to execute the callback (The callback's <tt>this</tt> reference.) If the
- * <tt>params</tt> argument is a function, this scope is used for that function also.</p></li>
- * <li>discardUrl : <b>Boolean</b><p class="sub-desc">By default, the URL of this request becomes
- * the default URL for this Updater object, and will be subsequently used in {@link #refresh}
- * calls. To bypass this behavior, pass <tt>discardUrl:true</tt> (defaults to false).</p></li>
- * <li>timeout : <b>Number</b><p class="sub-desc">The number of seconds to wait for a response before
- * timing out (defaults to {@link Ext.Updater.defaults#timeout}).</p></li>
- * <li>text : <b>String</b><p class="sub-desc">The text to use as the innerHTML of the
- * {@link Ext.Updater.defaults#indicatorText} div (defaults to 'Loading...'). To replace the entire div, not
- * just the text, override {@link Ext.Updater.defaults#indicatorText} directly.</p></li>
- * <li>nocache : <b>Boolean</b><p class="sub-desc">Only needed for GET
- * requests, this option causes an extra, auto-generated parameter to be appended to the request
- * to defeat caching (defaults to {@link Ext.Updater.defaults#disableCaching}).</p></li></ul>
- * <p>
- * For example:
- <pre><code>
- um.update({
- url: "your-url.php",
- params: {param1: "foo", param2: "bar"}, // or a URL encoded string
- callback: yourFunction,
- scope: yourObject, //(optional scope)
- discardUrl: true,
- nocache: true,
- text: "Loading...",
- timeout: 60,
- scripts: false // Save time by avoiding RegExp execution.
- });
- </code></pre>
- */
- update : function(url, params, callback, discardUrl){
- var me = this,
- cfg,
- callerScope;
-
- if(me.fireEvent(BEFOREUPDATE, me.el, url, params) !== false){
- if(Ext.isObject(url)){ // must be config object
- cfg = url;
- url = cfg.url;
- params = params || cfg.params;
- callback = callback || cfg.callback;
- discardUrl = discardUrl || cfg.discardUrl;
- callerScope = cfg.scope;
- if(!Ext.isEmpty(cfg.nocache)){me.disableCaching = cfg.nocache;};
- if(!Ext.isEmpty(cfg.text)){me.indicatorText = '<div class="loading-indicator">'+cfg.text+"</div>";};
- if(!Ext.isEmpty(cfg.scripts)){me.loadScripts = cfg.scripts;};
- if(!Ext.isEmpty(cfg.timeout)){me.timeout = cfg.timeout;};
- }
- me.showLoading();
-
- if(!discardUrl){
- me.defaultUrl = url;
- }
- if(Ext.isFunction(url)){
- url = url.call(me);
- }
-
- var o = Ext.apply({}, {
- url : url,
- params: (Ext.isFunction(params) && callerScope) ? params.createDelegate(callerScope) : params,
- success: processSuccess,
- failure: processFailure,
- scope: me,
- callback: undefined,
- timeout: (me.timeout*1000),
- disableCaching: me.disableCaching,
- argument: {
- "options": cfg,
- "url": url,
- "form": null,
- "callback": callback,
- "scope": callerScope || window,
- "params": params
- }
- }, cfg);
-
- me.transaction = Ext.Ajax.request(o);
- }
- },
-
- /**
- * <p>Performs an async form post, updating this element with the response. If the form has the attribute
- * enctype="<a href="http://www.faqs.org/rfcs/rfc2388.html">multipart/form-data</a>", it assumes it's a file upload.
- * Uses this.sslBlankUrl for SSL file uploads to prevent IE security warning.</p>
- * <p>File uploads are not performed using normal "Ajax" techniques, that is they are <b>not</b>
- * performed using XMLHttpRequests. Instead the form is submitted in the standard manner with the
- * DOM <tt><form></tt> element temporarily modified to have its
- * <a href="http://www.w3.org/TR/REC-html40/present/frames.html#adef-target">target</a> set to refer
- * to a dynamically generated, hidden <tt><iframe></tt> which is inserted into the document
- * but removed after the return data has been gathered.</p>
- * <p>Be aware that file upload packets, sent with the content type <a href="http://www.faqs.org/rfcs/rfc2388.html">multipart/form-data</a>
- * and some server technologies (notably JEE) may require some custom processing in order to
- * retrieve parameter names and parameter values from the packet content.</p>
- * @param {String/HTMLElement} form The form Id or form element
- * @param {String} url (optional) The url to pass the form to. If omitted the action attribute on the form will be used.
- * @param {Boolean} reset (optional) Whether to try to reset the form after the update
- * @param {Function} callback (optional) Callback when transaction is complete. The following
- * parameters are passed:<ul>
- * <li><b>el</b> : Ext.Element<p class="sub-desc">The Element being updated.</p></li>
- * <li><b>success</b> : Boolean<p class="sub-desc">True for success, false for failure.</p></li>
- * <li><b>response</b> : XMLHttpRequest<p class="sub-desc">The XMLHttpRequest which processed the update.</p></li></ul>
- */
- formUpdate : function(form, url, reset, callback){
- var me = this;
- if(me.fireEvent(BEFOREUPDATE, me.el, form, url) !== false){
- if(Ext.isFunction(url)){
- url = url.call(me);
- }
- form = Ext.getDom(form)
- me.transaction = Ext.Ajax.request({
- form: form,
- url:url,
- success: processSuccess,
- failure: processFailure,
- scope: me,
- timeout: (me.timeout*1000),
- argument: {
- "url": url,
- "form": form,
- "callback": callback,
- "reset": reset
- }
- });
- me.showLoading.defer(1, me);
- }
- },
-
- /**
- * Set this element to auto refresh. Can be canceled by calling {@link #stopAutoRefresh}.
- * @param {Number} interval How often to update (in seconds).
- * @param {String/Object/Function} url (optional) The url for this request, a config object in the same format
- * supported by {@link #load}, or a function to call to get the url (defaults to the last used url). Note that while
- * the url used in a load call can be reused by this method, other load config options will not be reused and must be
- * sepcified as part of a config object passed as this paramter if needed.
- * @param {String/Object} params (optional) The parameters to pass as either a url encoded string
- * "¶m1=1¶m2=2" or as an object {param1: 1, param2: 2}
- * @param {Function} callback (optional) Callback when transaction is complete - called with signature (oElement, bSuccess)
- * @param {Boolean} refreshNow (optional) Whether to execute the refresh now, or wait the interval
- */
- startAutoRefresh : function(interval, url, params, callback, refreshNow){
- var me = this;
- if(refreshNow){
- me.update(url || me.defaultUrl, params, callback, true);
- }
- if(me.autoRefreshProcId){
- clearInterval(me.autoRefreshProcId);
- }
- me.autoRefreshProcId = setInterval(me.update.createDelegate(me, [url || me.defaultUrl, params, callback, true]), interval * 1000);
- },
-
- /**
- * Stop auto refresh on this element.
- */
- stopAutoRefresh : function(){
- if(this.autoRefreshProcId){
- clearInterval(this.autoRefreshProcId);
- delete this.autoRefreshProcId;
- }
- },
-
- /**
- * Returns true if the Updater is currently set to auto refresh its content (see {@link #startAutoRefresh}), otherwise false.
- */
- isAutoRefreshing : function(){
- return !!this.autoRefreshProcId;
- },
-
- /**
- * Display the element's "loading" state. By default, the element is updated with {@link #indicatorText}. This
- * method may be overridden to perform a custom action while this Updater is actively updating its contents.
- */
- showLoading : function(){
- if(this.showLoadIndicator){
- this.el.dom.innerHTML = this.indicatorText;
- }
- },
-
- /**
- * Aborts the currently executing transaction, if any.
- */
- abort : function(){
- if(this.transaction){
- Ext.Ajax.abort(this.transaction);
- }
- },
-
- /**
- * Returns true if an update is in progress, otherwise false.
- * @return {Boolean}
- */
- isUpdating : function(){
- return this.transaction ? Ext.Ajax.isLoading(this.transaction) : false;
- },
-
- /**
- * Refresh the element with the last used url or defaultUrl. If there is no url, it returns immediately
- * @param {Function} callback (optional) Callback when transaction is complete - called with signature (oElement, bSuccess)
- */
- refresh : function(callback){
- if(this.defaultUrl){
- this.update(this.defaultUrl, null, callback, true);
- }
- }
- }
-}());
-
-/**
- * @class Ext.Updater.defaults
- * The defaults collection enables customizing the default properties of Updater
- */
-Ext.Updater.defaults = {
- /**
- * Timeout for requests or form posts in seconds (defaults to 30 seconds).
- * @type Number
- */
- timeout : 30,
- /**
- * True to append a unique parameter to GET requests to disable caching (defaults to false).
- * @type Boolean
- */
- disableCaching : false,
- /**
- * Whether or not to show {@link #indicatorText} during loading (defaults to true).
- * @type Boolean
- */
- showLoadIndicator : true,
- /**
- * Text for loading indicator (defaults to '<div class="loading-indicator">Loading...</div>').
- * @type String
- */
- indicatorText : '<div class="loading-indicator">Loading...</div>',
- /**
- * True to process scripts by default (defaults to false).
- * @type Boolean
- */
- loadScripts : false,
- /**
- * Blank page URL to use with SSL file uploads (defaults to {@link Ext#SSL_SECURE_URL} if set, or "javascript:false").
- * @type String
- */
- sslBlankUrl : (Ext.SSL_SECURE_URL || "javascript:false")
-};
-
-
-/**
- * Static convenience method. <b>This method is deprecated in favor of el.load({url:'foo.php', ...})</b>.
- * Usage:
- * <pre><code>Ext.Updater.updateElement("my-div", "stuff.php");</code></pre>
- * @param {Mixed} el The element to update
- * @param {String} url The url
- * @param {String/Object} params (optional) Url encoded param string or an object of name/value pairs
- * @param {Object} options (optional) A config object with any of the Updater properties you want to set - for
- * example: {disableCaching:true, indicatorText: "Loading data..."}
- * @static
- * @deprecated
- * @member Ext.Updater
- */
-Ext.Updater.updateElement = function(el, url, params, options){
- var um = Ext.get(el).getUpdater();
- Ext.apply(um, options);
- um.update(url, params, options ? options.callback : null);
-};
-
-/**
- * @class Ext.Updater.BasicRenderer
- * Default Content renderer. Updates the elements innerHTML with the responseText.
- */
-Ext.Updater.BasicRenderer = function(){};
-
-Ext.Updater.BasicRenderer.prototype = {
- /**
- * This is called when the transaction is completed and it's time to update the element - The BasicRenderer
- * updates the elements innerHTML with the responseText - To perform a custom render (i.e. XML or JSON processing),
- * create an object with a "render(el, response)" method and pass it to setRenderer on the Updater.
- * @param {Ext.Element} el The element being rendered
- * @param {Object} response The XMLHttpRequest object
- * @param {Updater} updateManager The calling update manager
- * @param {Function} callback A callback that will need to be called if loadScripts is true on the Updater
- */
- render : function(el, response, updateManager, callback){
- el.update(response.responseText, updateManager.loadScripts, callback);
- }
-};/**
- * @class Date
- *
- * The date parsing and formatting syntax contains a subset of
- * <a href="http://www.php.net/date">PHP's date() function</a>, and the formats that are
- * supported will provide results equivalent to their PHP versions.
- *
- * The following is a list of all currently supported formats:
- * <pre>
-Format Description Example returned values
------- ----------------------------------------------------------------------- -----------------------
- d Day of the month, 2 digits with leading zeros 01 to 31
- D A short textual representation of the day of the week Mon to Sun
- j Day of the month without leading zeros 1 to 31
- l A full textual representation of the day of the week Sunday to Saturday
- N ISO-8601 numeric representation of the day of the week 1 (for Monday) through 7 (for Sunday)
- S English ordinal suffix for the day of the month, 2 characters st, nd, rd or th. Works well with j
- w Numeric representation of the day of the week 0 (for Sunday) to 6 (for Saturday)
- z The day of the year (starting from 0) 0 to 364 (365 in leap years)
- W ISO-8601 week number of year, weeks starting on Monday 01 to 53
- F A full textual representation of a month, such as January or March January to December
- m Numeric representation of a month, with leading zeros 01 to 12
- M A short textual representation of a month Jan to Dec
- n Numeric representation of a month, without leading zeros 1 to 12
- t Number of days in the given month 28 to 31
- L Whether it's a leap year 1 if it is a leap year, 0 otherwise.
- o ISO-8601 year number (identical to (Y), but if the ISO week number (W) Examples: 1998 or 2004
- belongs to the previous or next year, that year is used instead)
- Y A full numeric representation of a year, 4 digits Examples: 1999 or 2003
- y A two digit representation of a year Examples: 99 or 03
- a Lowercase Ante meridiem and Post meridiem am or pm
- A Uppercase Ante meridiem and Post meridiem AM or PM
- g 12-hour format of an hour without leading zeros 1 to 12
- G 24-hour format of an hour without leading zeros 0 to 23
- h 12-hour format of an hour with leading zeros 01 to 12
- H 24-hour format of an hour with leading zeros 00 to 23
- i Minutes, with leading zeros 00 to 59
- s Seconds, with leading zeros 00 to 59
- u Decimal fraction of a second Examples:
- (minimum 1 digit, arbitrary number of digits allowed) 001 (i.e. 0.001s) or
- 100 (i.e. 0.100s) or
- 999 (i.e. 0.999s) or
- 999876543210 (i.e. 0.999876543210s)
- O Difference to Greenwich time (GMT) in hours and minutes Example: +1030
- P Difference to Greenwich time (GMT) with colon between hours and minutes Example: -08:00
- T Timezone abbreviation of the machine running the code Examples: EST, MDT, PDT ...
- Z Timezone offset in seconds (negative if west of UTC, positive if east) -43200 to 50400
- c ISO 8601 date
- Notes: Examples:
- 1) If unspecified, the month / day defaults to the current month / day, 1991 or
- the time defaults to midnight, while the timezone defaults to the 1992-10 or
- browser's timezone. If a time is specified, it must include both hours 1993-09-20 or
- and minutes. The "T" delimiter, seconds, milliseconds and timezone 1994-08-19T16:20+01:00 or
- are optional. 1995-07-18T17:21:28-02:00 or
- 2) The decimal fraction of a second, if specified, must contain at 1996-06-17T18:22:29.98765+03:00 or
- least 1 digit (there is no limit to the maximum number 1997-05-16T19:23:30,12345-0400 or
- of digits allowed), and may be delimited by either a '.' or a ',' 1998-04-15T20:24:31.2468Z or
- Refer to the examples on the right for the various levels of 1999-03-14T20:24:32Z or
- date-time granularity which are supported, or see 2000-02-13T21:25:33
- http://www.w3.org/TR/NOTE-datetime for more info. 2001-01-12 22:26:34
- U Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) 1193432466 or -2138434463
- M$ Microsoft AJAX serialized dates \/Date(1238606590509)\/ (i.e. UTC milliseconds since epoch) or
- \/Date(1238606590509+0800)\/
-</pre>
- *
- * Example usage (note that you must escape format specifiers with '\\' to render them as character literals):
- * <pre><code>
-// Sample date:
-// 'Wed Jan 10 2007 15:05:01 GMT-0600 (Central Standard Time)'
-
-var dt = new Date('1/10/2007 03:05:01 PM GMT-0600');
-document.write(dt.format('Y-m-d')); // 2007-01-10
-document.write(dt.format('F j, Y, g:i a')); // January 10, 2007, 3:05 pm
-document.write(dt.format('l, \\t\\he jS \\of F Y h:i:s A')); // Wednesday, the 10th of January 2007 03:05:01 PM
-</code></pre>
- *
- * Here are some standard date/time patterns that you might find helpful. They
- * are not part of the source of Date.js, but to use them you can simply copy this
- * block of code into any script that is included after Date.js and they will also become
- * globally available on the Date object. Feel free to add or remove patterns as needed in your code.
- * <pre><code>
-Date.patterns = {
- ISO8601Long:"Y-m-d H:i:s",
- ISO8601Short:"Y-m-d",
- ShortDate: "n/j/Y",
- LongDate: "l, F d, Y",
- FullDateTime: "l, F d, Y g:i:s A",
- MonthDay: "F d",
- ShortTime: "g:i A",
- LongTime: "g:i:s A",
- SortableDateTime: "Y-m-d\\TH:i:s",
- UniversalSortableDateTime: "Y-m-d H:i:sO",
- YearMonth: "F, Y"
-};
-</code></pre>
- *
- * Example usage:
- * <pre><code>
-var dt = new Date();
-document.write(dt.format(Date.patterns.ShortDate));
-</code></pre>
- * <p>Developer-written, custom formats may be used by supplying both a formatting and a parsing function
- * which perform to specialized requirements. The functions are stored in {@link #parseFunctions} and {@link #formatFunctions}.</p>
- */
-
-/*
- * Most of the date-formatting functions below are the excellent work of Baron Schwartz.
- * (see http://www.xaprb.com/blog/2005/12/12/javascript-closures-for-runtime-efficiency/)
- * They generate precompiled functions from format patterns instead of parsing and
- * processing each pattern every time a date is formatted. These functions are available
- * on every Date object.
- */
-
-(function() {
-
-/**
- * Global flag which determines if strict date parsing should be used.
- * Strict date parsing will not roll-over invalid dates, which is the
- * default behaviour of javascript Date objects.
- * (see {@link #parseDate} for more information)
- * Defaults to <tt>false</tt>.
- * @static
- * @type Boolean
-*/
-Date.useStrict = false;
-
-
-// create private copy of Ext's String.format() method
-// - to remove unnecessary dependency
-// - to resolve namespace conflict with M$-Ajax's implementation
-function xf(format) {
- var args = Array.prototype.slice.call(arguments, 1);
- return format.replace(/\{(\d+)\}/g, function(m, i) {
- return args[i];
- });
-}
-
-
-// private
-Date.formatCodeToRegex = function(character, currentGroup) {
- // Note: currentGroup - position in regex result array (see notes for Date.parseCodes below)
- var p = Date.parseCodes[character];
-
- if (p) {
- p = typeof p == 'function'? p() : p;
- Date.parseCodes[character] = p; // reassign function result to prevent repeated execution
- }
-
- return p? Ext.applyIf({
- c: p.c? xf(p.c, currentGroup || "{0}") : p.c
- }, p) : {
- g:0,
- c:null,
- s:Ext.escapeRe(character) // treat unrecognised characters as literals
- }
-}
-
-// private shorthand for Date.formatCodeToRegex since we'll be using it fairly often
-var $f = Date.formatCodeToRegex;
-
-Ext.apply(Date, {
- /**
- * <p>An object hash in which each property is a date parsing function. The property name is the
- * format string which that function parses.</p>
- * <p>This object is automatically populated with date parsing functions as
- * date formats are requested for Ext standard formatting strings.</p>
- * <p>Custom parsing functions may be inserted into this object, keyed by a name which from then on
- * may be used as a format string to {@link #parseDate}.<p>
- * <p>Example:</p><pre><code>
-Date.parseFunctions['x-date-format'] = myDateParser;
-</code></pre>
- * <p>A parsing function should return a Date object, and is passed the following parameters:<div class="mdetail-params"><ul>
- * <li><code>date</code> : String<div class="sub-desc">The date string to parse.</div></li>
- * <li><code>strict</code> : Boolean<div class="sub-desc">True to validate date strings while parsing
- * (i.e. prevent javascript Date "rollover") (The default must be false).
- * Invalid date strings should return null when parsed.</div></li>
- * </ul></div></p>
- * <p>To enable Dates to also be <i>formatted</i> according to that format, a corresponding
- * formatting function must be placed into the {@link #formatFunctions} property.
- * @property parseFunctions
- * @static
- * @type Object
- */
- parseFunctions: {
- "M$": function(input, strict) {
- // note: the timezone offset is ignored since the M$ Ajax server sends
- // a UTC milliseconds-since-Unix-epoch value (negative values are allowed)
- var re = new RegExp('\\/Date\\(([-+])?(\\d+)(?:[+-]\\d{4})?\\)\\/');
- var r = (input || '').match(re);
- return r? new Date(((r[1] || '') + r[2]) * 1) : null;
- }
- },
- parseRegexes: [],
-
- /**
- * <p>An object hash in which each property is a date formatting function. The property name is the
- * format string which corresponds to the produced formatted date string.</p>
- * <p>This object is automatically populated with date formatting functions as
- * date formats are requested for Ext standard formatting strings.</p>
- * <p>Custom formatting functions may be inserted into this object, keyed by a name which from then on
- * may be used as a format string to {@link #format}. Example:</p><pre><code>
-Date.formatFunctions['x-date-format'] = myDateFormatter;
-</code></pre>
- * <p>A formatting function should return a string repesentation of the passed Date object:<div class="mdetail-params"><ul>
- * <li><code>date</code> : Date<div class="sub-desc">The Date to format.</div></li>
- * </ul></div></p>
- * <p>To enable date strings to also be <i>parsed</i> according to that format, a corresponding
- * parsing function must be placed into the {@link #parseFunctions} property.
- * @property formatFunctions
- * @static
- * @type Object
- */
- formatFunctions: {
- "M$": function() {
- // UTC milliseconds since Unix epoch (M$-AJAX serialized date format (MRSF))
- return '\\/Date(' + this.getTime() + ')\\/';
- }
- },
-
- y2kYear : 50,
-
- /**
- * Date interval constant
- * @static
- * @type String
- */
- MILLI : "ms",
-
- /**
- * Date interval constant
- * @static
- * @type String
- */
- SECOND : "s",
-
- /**
- * Date interval constant
- * @static
- * @type String
- */
- MINUTE : "mi",
-
- /** Date interval constant
- * @static
- * @type String
- */
- HOUR : "h",
-
- /**
- * Date interval constant
- * @static
- * @type String
- */
- DAY : "d",
-
- /**
- * Date interval constant
- * @static
- * @type String
- */
- MONTH : "mo",
-
- /**
- * Date interval constant
- * @static
- * @type String
- */
- YEAR : "y",
-
- /**
- * <p>An object hash containing default date values used during date parsing.</p>
- * <p>The following properties are available:<div class="mdetail-params"><ul>
- * <li><code>y</code> : Number<div class="sub-desc">The default year value. (defaults to undefined)</div></li>
- * <li><code>m</code> : Number<div class="sub-desc">The default 1-based month value. (defaults to undefined)</div></li>
- * <li><code>d</code> : Number<div class="sub-desc">The default day value. (defaults to undefined)</div></li>
- * <li><code>h</code> : Number<div class="sub-desc">The default hour value. (defaults to undefined)</div></li>
- * <li><code>i</code> : Number<div class="sub-desc">The default minute value. (defaults to undefined)</div></li>
- * <li><code>s</code> : Number<div class="sub-desc">The default second value. (defaults to undefined)</div></li>
- * <li><code>ms</code> : Number<div class="sub-desc">The default millisecond value. (defaults to undefined)</div></li>
- * </ul></div></p>
- * <p>Override these properties to customize the default date values used by the {@link #parseDate} method.</p>
- * <p><b>Note: In countries which experience Daylight Saving Time (i.e. DST), the <tt>h</tt>, <tt>i</tt>, <tt>s</tt>
- * and <tt>ms</tt> properties may coincide with the exact time in which DST takes effect.
- * It is the responsiblity of the developer to account for this.</b></p>
- * Example Usage:
- * <pre><code>
-// set default day value to the first day of the month
-Date.defaults.d = 1;
-
-// parse a February date string containing only year and month values.
-// setting the default day value to 1 prevents weird date rollover issues
-// when attempting to parse the following date string on, for example, March 31st 2009.
-Date.parseDate('2009-02', 'Y-m'); // returns a Date object representing February 1st 2009
-</code></pre>
- * @property defaults
- * @static
- * @type Object
- */
- defaults: {},
-
- /**
- * An array of textual day names.
- * Override these values for international dates.
- * Example:
- * <pre><code>
-Date.dayNames = [
- 'SundayInYourLang',
- 'MondayInYourLang',
- ...
-];
-</code></pre>
- * @type Array
- * @static
- */
- dayNames : [
- "Sunday",
- "Monday",
- "Tuesday",
- "Wednesday",
- "Thursday",
- "Friday",
- "Saturday"
- ],
-
- /**
- * An array of textual month names.
- * Override these values for international dates.
- * Example:
- * <pre><code>
-Date.monthNames = [
- 'JanInYourLang',
- 'FebInYourLang',
- ...
-];
-</code></pre>
- * @type Array
- * @static
- */
- monthNames : [
- "January",
- "February",
- "March",
- "April",
- "May",
- "June",
- "July",
- "August",
- "September",
- "October",
- "November",
- "December"
- ],
-
- /**
- * An object hash of zero-based javascript month numbers (with short month names as keys. note: keys are case-sensitive).
- * Override these values for international dates.
- * Example:
- * <pre><code>
-Date.monthNumbers = {
- 'ShortJanNameInYourLang':0,
- 'ShortFebNameInYourLang':1,
- ...
-};
-</code></pre>
- * @type Object
- * @static
- */
- monthNumbers : {
- Jan:0,
- Feb:1,
- Mar:2,
- Apr:3,
- May:4,
- Jun:5,
- Jul:6,
- Aug:7,
- Sep:8,
- Oct:9,
- Nov:10,
- Dec:11
- },
-
- /**
- * Get the short month name for the given month number.
- * Override this function for international dates.
- * @param {Number} month A zero-based javascript month number.
- * @return {String} The short month name.
- * @static
- */
- getShortMonthName : function(month) {
- return Date.monthNames[month].substring(0, 3);
- },
-
- /**
- * Get the short day name for the given day number.
- * Override this function for international dates.
- * @param {Number} day A zero-based javascript day number.
- * @return {String} The short day name.
- * @static
- */
- getShortDayName : function(day) {
- return Date.dayNames[day].substring(0, 3);
- },
-
- /**
- * Get the zero-based javascript month number for the given short/full month name.
- * Override this function for international dates.
- * @param {String} name The short/full month name.
- * @return {Number} The zero-based javascript month number.
- * @static
- */
- getMonthNumber : function(name) {
- // handle camel casing for english month names (since the keys for the Date.monthNumbers hash are case sensitive)
- return Date.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()];
- },
-
- /**
- * The base format-code to formatting-function hashmap used by the {@link #format} method.
- * Formatting functions are strings (or functions which return strings) which
- * will return the appropriate value when evaluated in the context of the Date object
- * from which the {@link #format} method is called.
- * Add to / override these mappings for custom date formatting.
- * Note: Date.format() treats characters as literals if an appropriate mapping cannot be found.
- * Example:
- * <pre><code>
-Date.formatCodes.x = "String.leftPad(this.getDate(), 2, '0')";
-(new Date()).format("X"); // returns the current day of the month
-</code></pre>
- * @type Object
- * @static
- */
- formatCodes : {
- d: "String.leftPad(this.getDate(), 2, '0')",
- D: "Date.getShortDayName(this.getDay())", // get localised short day name
- j: "this.getDate()",
- l: "Date.dayNames[this.getDay()]",
- N: "(this.getDay() ? this.getDay() : 7)",
- S: "this.getSuffix()",
- w: "this.getDay()",
- z: "this.getDayOfYear()",
- W: "String.leftPad(this.getWeekOfYear(), 2, '0')",
- F: "Date.monthNames[this.getMonth()]",
- m: "String.leftPad(this.getMonth() + 1, 2, '0')",
- M: "Date.getShortMonthName(this.getMonth())", // get localised short month name
- n: "(this.getMonth() + 1)",
- t: "this.getDaysInMonth()",
- L: "(this.isLeapYear() ? 1 : 0)",
- o: "(this.getFullYear() + (this.getWeekOfYear() == 1 && this.getMonth() > 0 ? +1 : (this.getWeekOfYear() >= 52 && this.getMonth() < 11 ? -1 : 0)))",
- Y: "this.getFullYear()",
- y: "('' + this.getFullYear()).substring(2, 4)",
- a: "(this.getHours() < 12 ? 'am' : 'pm')",
- A: "(this.getHours() < 12 ? 'AM' : 'PM')",
- g: "((this.getHours() % 12) ? this.getHours() % 12 : 12)",
- G: "this.getHours()",
- h: "String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0')",
- H: "String.leftPad(this.getHours(), 2, '0')",
- i: "String.leftPad(this.getMinutes(), 2, '0')",
- s: "String.leftPad(this.getSeconds(), 2, '0')",
- u: "String.leftPad(this.getMilliseconds(), 3, '0')",
- O: "this.getGMTOffset()",
- P: "this.getGMTOffset(true)",
- T: "this.getTimezone()",
- Z: "(this.getTimezoneOffset() * -60)",
-
- c: function() { // ISO-8601 -- GMT format
- for (var c = "Y-m-dTH:i:sP", code = [], i = 0, l = c.length; i < l; ++i) {
- var e = c.charAt(i);
- code.push(e == "T" ? "'T'" : Date.getFormatCode(e)); // treat T as a character literal
- }
- return code.join(" + ");
- },
- /*
- c: function() { // ISO-8601 -- UTC format
- return [
- "this.getUTCFullYear()", "'-'",
- "String.leftPad(this.getUTCMonth() + 1, 2, '0')", "'-'",
- "String.leftPad(this.getUTCDate(), 2, '0')",
- "'T'",
- "String.leftPad(this.getUTCHours(), 2, '0')", "':'",
- "String.leftPad(this.getUTCMinutes(), 2, '0')", "':'",
- "String.leftPad(this.getUTCSeconds(), 2, '0')",
- "'Z'"
- ].join(" + ");
- },
- */
-
- U: "Math.round(this.getTime() / 1000)"
- },
-
- /**
- * Checks if the passed Date parameters will cause a javascript Date "rollover".
- * @param {Number} year 4-digit year
- * @param {Number} month 1-based month-of-year
- * @param {Number} day Day of month
- * @param {Number} hour (optional) Hour
- * @param {Number} minute (optional) Minute
- * @param {Number} second (optional) Second
- * @param {Number} millisecond (optional) Millisecond
- * @return {Boolean} true if the passed parameters do not cause a Date "rollover", false otherwise.
- * @static
- */
- isValid : function(y, m, d, h, i, s, ms) {
- // setup defaults
- h = h || 0;
- i = i || 0;
- s = s || 0;
- ms = ms || 0;
-
- var dt = new Date(y, m - 1, d, h, i, s, ms);
-
- return y == dt.getFullYear() &&
- m == dt.getMonth() + 1 &&
- d == dt.getDate() &&
- h == dt.getHours() &&
- i == dt.getMinutes() &&
- s == dt.getSeconds() &&
- ms == dt.getMilliseconds();
- },
-
- /**
- * Parses the passed string using the specified date format.
- * Note that this function expects normal calendar dates, meaning that months are 1-based (i.e. 1 = January).
- * The {@link #defaults} hash will be used for any date value (i.e. year, month, day, hour, minute, second or millisecond)
- * which cannot be found in the passed string. If a corresponding default date value has not been specified in the {@link #defaults} hash,
- * the current date's year, month, day or DST-adjusted zero-hour time value will be used instead.
- * Keep in mind that the input date string must precisely match the specified format string
- * in order for the parse operation to be successful (failed parse operations return a null value).
- * <p>Example:</p><pre><code>
-//dt = Fri May 25 2007 (current date)
-var dt = new Date();
-
-//dt = Thu May 25 2006 (today's month/day in 2006)
-dt = Date.parseDate("2006", "Y");
-
-//dt = Sun Jan 15 2006 (all date parts specified)
-dt = Date.parseDate("2006-01-15", "Y-m-d");
-
-//dt = Sun Jan 15 2006 15:20:01
-dt = Date.parseDate("2006-01-15 3:20:01 PM", "Y-m-d g:i:s A");
-
-// attempt to parse Sun Feb 29 2006 03:20:01 in strict mode
-dt = Date.parseDate("2006-02-29 03:20:01", "Y-m-d H:i:s", true); // returns null
-</code></pre>
- * @param {String} input The raw date string.
- * @param {String} format The expected date string format.
- * @param {Boolean} strict (optional) True to validate date strings while parsing (i.e. prevents javascript Date "rollover")
- (defaults to false). Invalid date strings will return null when parsed.
- * @return {Date} The parsed Date.
- * @static
- */
- parseDate : function(input, format, strict) {
- var p = Date.parseFunctions;
- if (p[format] == null) {
- Date.createParser(format);
- }
- return p[format](input, Ext.isDefined(strict) ? strict : Date.useStrict);
- },
-
- // private
- getFormatCode : function(character) {
- var f = Date.formatCodes[character];
-
- if (f) {
- f = typeof f == 'function'? f() : f;
- Date.formatCodes[character] = f; // reassign function result to prevent repeated execution
- }
-
- // note: unknown characters are treated as literals
- return f || ("'" + String.escape(character) + "'");
- },
-
- // private
- createFormat : function(format) {
- var code = [],
- special = false,
- ch = '';
-
- for (var i = 0; i < format.length; ++i) {
- ch = format.charAt(i);
- if (!special && ch == "\\") {
- special = true;
- } else if (special) {
- special = false;
- code.push("'" + String.escape(ch) + "'");
- } else {
- code.push(Date.getFormatCode(ch))
- }
- }
- Date.formatFunctions[format] = new Function("return " + code.join('+'));
- },
-
- // private
- createParser : function() {
- var code = [
- "var dt, y, m, d, h, i, s, ms, o, z, zz, u, v,",
- "def = Date.defaults,",
- "results = String(input).match(Date.parseRegexes[{0}]);", // either null, or an array of matched strings
-
- "if(results){",
- "{1}",
-
- "if(u != null){", // i.e. unix time is defined
- "v = new Date(u * 1000);", // give top priority to UNIX time
- "}else{",
- // create Date object representing midnight of the current day;
- // this will provide us with our date defaults
- // (note: clearTime() handles Daylight Saving Time automatically)
- "dt = (new Date()).clearTime();",
-
- // date calculations (note: these calculations create a dependency on Ext.num())
- "y = y >= 0? y : Ext.num(def.y, dt.getFullYear());",
- "m = m >= 0? m : Ext.num(def.m - 1, dt.getMonth());",
- "d = d >= 0? d : Ext.num(def.d, dt.getDate());",
-
- // time calculations (note: these calculations create a dependency on Ext.num())
- "h = h || Ext.num(def.h, dt.getHours());",
- "i = i || Ext.num(def.i, dt.getMinutes());",
- "s = s || Ext.num(def.s, dt.getSeconds());",
- "ms = ms || Ext.num(def.ms, dt.getMilliseconds());",
-
- "if(z >= 0 && y >= 0){",
- // both the year and zero-based day of year are defined and >= 0.
- // these 2 values alone provide sufficient info to create a full date object
-
- // create Date object representing January 1st for the given year
- "v = new Date(y, 0, 1, h, i, s, ms);",
-
- // then add day of year, checking for Date "rollover" if necessary
- "v = !strict? v : (strict === true && (z <= 364 || (v.isLeapYear() && z <= 365))? v.add(Date.DAY, z) : null);",
- "}else if(strict === true && !Date.isValid(y, m + 1, d, h, i, s, ms)){", // check for Date "rollover"
- "v = null;", // invalid date, so return null
- "}else{",
- // plain old Date object
- "v = new Date(y, m, d, h, i, s, ms);",
- "}",
- "}",
- "}",
-
- "if(v){",
- // favour UTC offset over GMT offset
- "if(zz != null){",
- // reset to UTC, then add offset
- "v = v.add(Date.SECOND, -v.getTimezoneOffset() * 60 - zz);",
- "}else if(o){",
- // reset to GMT, then add offset
- "v = v.add(Date.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));",
- "}",
- "}",
-
- "return v;"
- ].join('\n');
-
- return function(format) {
- var regexNum = Date.parseRegexes.length,
- currentGroup = 1,
- calc = [],
- regex = [],
- special = false,
- ch = "";
-
- for (var i = 0; i < format.length; ++i) {
- ch = format.charAt(i);
- if (!special && ch == "\\") {
- special = true;
- } else if (special) {
- special = false;
- regex.push(String.escape(ch));
- } else {
- var obj = $f(ch, currentGroup);
- currentGroup += obj.g;
- regex.push(obj.s);
- if (obj.g && obj.c) {
- calc.push(obj.c);
- }
- }
- }
-
- Date.parseRegexes[regexNum] = new RegExp("^" + regex.join('') + "$", "i");
- Date.parseFunctions[format] = new Function("input", "strict", xf(code, regexNum, calc.join('')));
- }
- }(),
-
- // private
- parseCodes : {
- /*
- * Notes:
- * g = {Number} calculation group (0 or 1. only group 1 contributes to date calculations.)
- * c = {String} calculation method (required for group 1. null for group 0. {0} = currentGroup - position in regex result array)
- * s = {String} regex pattern. all matches are stored in results[], and are accessible by the calculation mapped to 'c'
- */
- d: {
- g:1,
- c:"d = parseInt(results[{0}], 10);\n",
- s:"(\\d{2})" // day of month with leading zeroes (01 - 31)
- },
- j: {
- g:1,
- c:"d = parseInt(results[{0}], 10);\n",
- s:"(\\d{1,2})" // day of month without leading zeroes (1 - 31)
- },
- D: function() {
- for (var a = [], i = 0; i < 7; a.push(Date.getShortDayName(i)), ++i); // get localised short day names
- return {
- g:0,
- c:null,
- s:"(?:" + a.join("|") +")"
- }
- },
- l: function() {
- return {
- g:0,
- c:null,
- s:"(?:" + Date.dayNames.join("|") + ")"
- }
- },
- N: {
- g:0,
- c:null,
- s:"[1-7]" // ISO-8601 day number (1 (monday) - 7 (sunday))
- },
- S: {
- g:0,
- c:null,
- s:"(?:st|nd|rd|th)"
- },
- w: {
- g:0,
- c:null,
- s:"[0-6]" // javascript day number (0 (sunday) - 6 (saturday))
- },
- z: {
- g:1,
- c:"z = parseInt(results[{0}], 10);\n",
- s:"(\\d{1,3})" // day of the year (0 - 364 (365 in leap years))
- },
- W: {
- g:0,
- c:null,
- s:"(?:\\d{2})" // ISO-8601 week number (with leading zero)
- },
- F: function() {
- return {
- g:1,
- c:"m = parseInt(Date.getMonthNumber(results[{0}]), 10);\n", // get localised month number
- s:"(" + Date.monthNames.join("|") + ")"
- }
- },
- M: function() {
- for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i); // get localised short month names
- return Ext.applyIf({
- s:"(" + a.join("|") + ")"
- }, $f("F"));
- },
- m: {
- g:1,
- c:"m = parseInt(results[{0}], 10) - 1;\n",
- s:"(\\d{2})" // month number with leading zeros (01 - 12)
- },
- n: {
- g:1,
- c:"m = parseInt(results[{0}], 10) - 1;\n",
- s:"(\\d{1,2})" // month number without leading zeros (1 - 12)
- },
- t: {
- g:0,
- c:null,
- s:"(?:\\d{2})" // no. of days in the month (28 - 31)
- },
- L: {
- g:0,
- c:null,
- s:"(?:1|0)"
- },
- o: function() {
- return $f("Y");
- },
- Y: {
- g:1,
- c:"y = parseInt(results[{0}], 10);\n",
- s:"(\\d{4})" // 4-digit year
- },
- y: {
- g:1,
- c:"var ty = parseInt(results[{0}], 10);\n"
- + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n", // 2-digit year
- s:"(\\d{1,2})"
- },
- a: {
- g:1,
- c:"if (results[{0}] == 'am') {\n"
- + "if (h == 12) { h = 0; }\n"
- + "} else { if (h < 12) { h += 12; }}",
- s:"(am|pm)"
- },
- A: {
- g:1,
- c:"if (results[{0}] == 'AM') {\n"
- + "if (h == 12) { h = 0; }\n"
- + "} else { if (h < 12) { h += 12; }}",
- s:"(AM|PM)"
- },
- g: function() {
- return $f("G");
- },
- G: {
- g:1,
- c:"h = parseInt(results[{0}], 10);\n",
- s:"(\\d{1,2})" // 24-hr format of an hour without leading zeroes (0 - 23)
- },
- h: function() {
- return $f("H");
- },
- H: {
- g:1,
- c:"h = parseInt(results[{0}], 10);\n",
- s:"(\\d{2})" // 24-hr format of an hour with leading zeroes (00 - 23)
- },
- i: {
- g:1,
- c:"i = parseInt(results[{0}], 10);\n",
- s:"(\\d{2})" // minutes with leading zeros (00 - 59)
- },
- s: {
- g:1,
- c:"s = parseInt(results[{0}], 10);\n",
- s:"(\\d{2})" // seconds with leading zeros (00 - 59)
- },
- u: {
- g:1,
- c:"ms = results[{0}]; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n",
- s:"(\\d+)" // decimal fraction of a second (minimum = 1 digit, maximum = unlimited)
- },
- O: {
- g:1,
- c:[
- "o = results[{0}];",
- "var sn = o.substring(0,1),", // get + / - sign
- "hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60),", // get hours (performs minutes-to-hour conversion also, just in case)
- "mn = o.substring(3,5) % 60;", // get minutes
- "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n" // -12hrs <= GMT offset <= 14hrs
- ].join("\n"),
- s: "([+\-]\\d{4})" // GMT offset in hrs and mins
- },
- P: {
- g:1,
- c:[
- "o = results[{0}];",
- "var sn = o.substring(0,1),", // get + / - sign
- "hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60),", // get hours (performs minutes-to-hour conversion also, just in case)
- "mn = o.substring(4,6) % 60;", // get minutes
- "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n" // -12hrs <= GMT offset <= 14hrs
- ].join("\n"),
- s: "([+\-]\\d{2}:\\d{2})" // GMT offset in hrs and mins (with colon separator)
- },
- T: {
- g:0,
- c:null,
- s:"[A-Z]{1,4}" // timezone abbrev. may be between 1 - 4 chars
- },
- Z: {
- g:1,
- c:"zz = results[{0}] * 1;\n" // -43200 <= UTC offset <= 50400
- + "zz = (-43200 <= zz && zz <= 50400)? zz : null;\n",
- s:"([+\-]?\\d{1,5})" // leading '+' sign is optional for UTC offset
- },
- c: function() {
- var calc = [],
- arr = [
- $f("Y", 1), // year
- $f("m", 2), // month
- $f("d", 3), // day
- $f("h", 4), // hour
- $f("i", 5), // minute
- $f("s", 6), // second
- {c:"ms = results[7] || '0'; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n"}, // decimal fraction of a second (minimum = 1 digit, maximum = unlimited)
- {c:[ // allow either "Z" (i.e. UTC) or "-0530" or "+08:00" (i.e. UTC offset) timezone delimiters. assumes local timezone if no timezone is specified
- "if(results[8]) {", // timezone specified
- "if(results[8] == 'Z'){",
- "zz = 0;", // UTC
- "}else if (results[8].indexOf(':') > -1){",
- $f("P", 8).c, // timezone offset with colon separator
- "}else{",
- $f("O", 8).c, // timezone offset without colon separator
- "}",
- "}"
- ].join('\n')}
- ];
-
- for (var i = 0, l = arr.length; i < l; ++i) {
- calc.push(arr[i].c);
- }
-
- return {
- g:1,
- c:calc.join(""),
- s:[
- arr[0].s, // year (required)
- "(?:", "-", arr[1].s, // month (optional)
- "(?:", "-", arr[2].s, // day (optional)
- "(?:",
- "(?:T| )?", // time delimiter -- either a "T" or a single blank space
- arr[3].s, ":", arr[4].s, // hour AND minute, delimited by a single colon (optional). MUST be preceded by either a "T" or a single blank space
- "(?::", arr[5].s, ")?", // seconds (optional)
- "(?:(?:\\.|,)(\\d+))?", // decimal fraction of a second (e.g. ",12345" or ".98765") (optional)
- "(Z|(?:[-+]\\d{2}(?::)?\\d{2}))?", // "Z" (UTC) or "-0530" (UTC offset without colon delimiter) or "+08:00" (UTC offset with colon delimiter) (optional)
- ")?",
- ")?",
- ")?"
- ].join("")
- }
- },
- U: {
- g:1,
- c:"u = parseInt(results[{0}], 10);\n",
- s:"(-?\\d+)" // leading minus sign indicates seconds before UNIX epoch
- }
- }
-});
-
-}());
-
-Ext.apply(Date.prototype, {
- // private
- dateFormat : function(format) {
- if (Date.formatFunctions[format] == null) {
- Date.createFormat(format);
- }
- return Date.formatFunctions[format].call(this);
- },
-
- /**
- * Get the timezone abbreviation of the current date (equivalent to the format specifier 'T').
- *
- * Note: The date string returned by the javascript Date object's toString() method varies
- * between browsers (e.g. FF vs IE) and system region settings (e.g. IE in Asia vs IE in America).
- * For a given date string e.g. "Thu Oct 25 2007 22:55:35 GMT+0800 (Malay Peninsula Standard Time)",
- * getTimezone() first tries to get the timezone abbreviation from between a pair of parentheses
- * (which may or may not be present), failing which it proceeds to get the timezone abbreviation
- * from the GMT offset portion of the date string.
- * @return {String} The abbreviated timezone name (e.g. 'CST', 'PDT', 'EDT', 'MPST' ...).
- */
- getTimezone : function() {
- // the following list shows the differences between date strings from different browsers on a WinXP SP2 machine from an Asian locale:
- //
- // Opera : "Thu, 25 Oct 2007 22:53:45 GMT+0800" -- shortest (weirdest) date string of the lot
- // Safari : "Thu Oct 25 2007 22:55:35 GMT+0800 (Malay Peninsula Standard Time)" -- value in parentheses always gives the correct timezone (same as FF)
- // FF : "Thu Oct 25 2007 22:55:35 GMT+0800 (Malay Peninsula Standard Time)" -- value in parentheses always gives the correct timezone
- // IE : "Thu Oct 25 22:54:35 UTC+0800 2007" -- (Asian system setting) look for 3-4 letter timezone abbrev
- // IE : "Thu Oct 25 17:06:37 PDT 2007" -- (American system setting) look for 3-4 letter timezone abbrev
- //
- // this crazy regex attempts to guess the correct timezone abbreviation despite these differences.
- // step 1: (?:\((.*)\) -- find timezone in parentheses
- // step 2: ([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?) -- if nothing was found in step 1, find timezone from timezone offset portion of date string
- // step 3: remove all non uppercase characters found in step 1 and 2
- return this.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, "");
- },
-
- /**
- * Get the offset from GMT of the current date (equivalent to the format specifier 'O').
- * @param {Boolean} colon (optional) true to separate the hours and minutes with a colon (defaults to false).
- * @return {String} The 4-character offset string prefixed with + or - (e.g. '-0600').
- */
- getGMTOffset : function(colon) {
- return (this.getTimezoneOffset() > 0 ? "-" : "+")
- + String.leftPad(Math.floor(Math.abs(this.getTimezoneOffset()) / 60), 2, "0")
- + (colon ? ":" : "")
- + String.leftPad(Math.abs(this.getTimezoneOffset() % 60), 2, "0");
- },
-
- /**
- * Get the numeric day number of the year, adjusted for leap year.
- * @return {Number} 0 to 364 (365 in leap years).
- */
- getDayOfYear: function() {
- var i = 0,
- num = 0,
- d = this.clone(),
- m = this.getMonth();
-
- for (i = 0, d.setMonth(0); i < m; d.setMonth(++i)) {
- num += d.getDaysInMonth();
- }
- return num + this.getDate() - 1;
- },
-
- /**
- * Get the numeric ISO-8601 week number of the year.
- * (equivalent to the format specifier 'W', but without a leading zero).
- * @return {Number} 1 to 53
- */
- getWeekOfYear : function() {
- // adapted from http://www.merlyn.demon.co.uk/weekcalc.htm
- var ms1d = 864e5, // milliseconds in a day
- ms7d = 7 * ms1d; // milliseconds in a week
-
- return function() { // return a closure so constants get calculated only once
- var DC3 = Date.UTC(this.getFullYear(), this.getMonth(), this.getDate() + 3) / ms1d, // an Absolute Day Number
- AWN = Math.floor(DC3 / 7), // an Absolute Week Number
- Wyr = new Date(AWN * ms7d).getUTCFullYear();
-
- return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
- }
- }(),
-
- /**
- * Checks if the current date falls within a leap year.
- * @return {Boolean} True if the current date falls within a leap year, false otherwise.
- */
- isLeapYear : function() {
- var year = this.getFullYear();
- return !!((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
- },
-
- /**
- * Get the first day of the current month, adjusted for leap year. The returned value
- * is the numeric day index within the week (0-6) which can be used in conjunction with
- * the {@link #monthNames} array to retrieve the textual day name.
- * Example:
- * <pre><code>
-var dt = new Date('1/10/2007');
-document.write(Date.dayNames[dt.getFirstDayOfMonth()]); //output: 'Monday'
-</code></pre>
- * @return {Number} The day number (0-6).
- */
- getFirstDayOfMonth : function() {
- var day = (this.getDay() - (this.getDate() - 1)) % 7;
- return (day < 0) ? (day + 7) : day;
- },
-
- /**
- * Get the last day of the current month, adjusted for leap year. The returned value
- * is the numeric day index within the week (0-6) which can be used in conjunction with
- * the {@link #monthNames} array to retrieve the textual day name.
- * Example:
- * <pre><code>
-var dt = new Date('1/10/2007');
-document.write(Date.dayNames[dt.getLastDayOfMonth()]); //output: 'Wednesday'
-</code></pre>
- * @return {Number} The day number (0-6).
- */
- getLastDayOfMonth : function() {
- return this.getLastDateOfMonth().getDay();
- },
-
-
- /**
- * Get the date of the first day of the month in which this date resides.
- * @return {Date}
- */
- getFirstDateOfMonth : function() {
- return new Date(this.getFullYear(), this.getMonth(), 1);
- },
-
- /**
- * Get the date of the last day of the month in which this date resides.
- * @return {Date}
- */
- getLastDateOfMonth : function() {
- return new Date(this.getFullYear(), this.getMonth(), this.getDaysInMonth());
- },
-
- /**
- * Get the number of days in the current month, adjusted for leap year.
- * @return {Number} The number of days in the month.
- */
- getDaysInMonth: function() {
- var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
-
- return function() { // return a closure for efficiency
- var m = this.getMonth();
-
- return m == 1 && this.isLeapYear() ? 29 : daysInMonth[m];
- }
- }(),
-
- /**
- * Get the English ordinal suffix of the current day (equivalent to the format specifier 'S').
- * @return {String} 'st, 'nd', 'rd' or 'th'.
- */
- getSuffix : function() {
- switch (this.getDate()) {
- case 1:
- case 21:
- case 31:
- return "st";
- case 2:
- case 22:
- return "nd";
- case 3:
- case 23:
- return "rd";
- default:
- return "th";
- }
- },
-
- /**
- * Creates and returns a new Date instance with the exact same date value as the called instance.
- * Dates are copied and passed by reference, so if a copied date variable is modified later, the original
- * variable will also be changed. When the intention is to create a new variable that will not
- * modify the original instance, you should create a clone.
- *
- * Example of correctly cloning a date:
- * <pre><code>
-//wrong way:
-var orig = new Date('10/1/2006');
-var copy = orig;
-copy.setDate(5);
-document.write(orig); //returns 'Thu Oct 05 2006'!
-
-//correct way:
-var orig = new Date('10/1/2006');
-var copy = orig.clone();
-copy.setDate(5);
-document.write(orig); //returns 'Thu Oct 01 2006'
-</code></pre>
- * @return {Date} The new Date instance.
- */
- clone : function() {
- return new Date(this.getTime());
- },
-
- /**
- * Checks if the current date is affected by Daylight Saving Time (DST).
- * @return {Boolean} True if the current date is affected by DST.
- */
- isDST : function() {
- // adapted from http://extjs.com/forum/showthread.php?p=247172#post247172
- // courtesy of @geoffrey.mcgill
- return new Date(this.getFullYear(), 0, 1).getTimezoneOffset() != this.getTimezoneOffset();
- },
-
- /**
- * Attempts to clear all time information from this Date by setting the time to midnight of the same day,
- * automatically adjusting for Daylight Saving Time (DST) where applicable.
- * (note: DST timezone information for the browser's host operating system is assumed to be up-to-date)
- * @param {Boolean} clone true to create a clone of this date, clear the time and return it (defaults to false).
- * @return {Date} this or the clone.
- */
- clearTime : function(clone) {
- if (clone) {
- return this.clone().clearTime();
- }
-
- // get current date before clearing time
- var d = this.getDate();
-
- // clear time
- this.setHours(0);
- this.setMinutes(0);
- this.setSeconds(0);
- this.setMilliseconds(0);
-
- if (this.getDate() != d) { // account for DST (i.e. day of month changed when setting hour = 0)
- // note: DST adjustments are assumed to occur in multiples of 1 hour (this is almost always the case)
- // refer to http://www.timeanddate.com/time/aboutdst.html for the (rare) exceptions to this rule
-
- // increment hour until cloned date == current date
- for (var hr = 1, c = this.add(Date.HOUR, hr); c.getDate() != d; hr++, c = this.add(Date.HOUR, hr));
-
- this.setDate(d);
- this.setHours(c.getHours());
- }
-
- return this;
- },
-
- /**
- * Provides a convenient method for performing basic date arithmetic. This method
- * does not modify the Date instance being called - it creates and returns
- * a new Date instance containing the resulting date value.
- *
- * Examples:
- * <pre><code>
-// Basic usage:
-var dt = new Date('10/29/2006').add(Date.DAY, 5);
-document.write(dt); //returns 'Fri Nov 03 2006 00:00:00'
-
-// Negative values will be subtracted:
-var dt2 = new Date('10/1/2006').add(Date.DAY, -5);
-document.write(dt2); //returns 'Tue Sep 26 2006 00:00:00'
-
-// You can even chain several calls together in one line:
-var dt3 = new Date('10/1/2006').add(Date.DAY, 5).add(Date.HOUR, 8).add(Date.MINUTE, -30);
-document.write(dt3); //returns 'Fri Oct 06 2006 07:30:00'
-</code></pre>
- *
- * @param {String} interval A valid date interval enum value.
- * @param {Number} value The amount to add to the current date.
- * @return {Date} The new Date instance.
- */
- add : function(interval, value) {
- var d = this.clone();
- if (!interval || value === 0) return d;
-
- switch(interval.toLowerCase()) {
- case Date.MILLI:
- d.setMilliseconds(this.getMilliseconds() + value);
- break;
- case Date.SECOND:
- d.setSeconds(this.getSeconds() + value);
- break;
- case Date.MINUTE:
- d.setMinutes(this.getMinutes() + value);
- break;
- case Date.HOUR:
- d.setHours(this.getHours() + value);
- break;
- case Date.DAY:
- d.setDate(this.getDate() + value);
- break;
- case Date.MONTH:
- var day = this.getDate();
- if (day > 28) {
- day = Math.min(day, this.getFirstDateOfMonth().add('mo', value).getLastDateOfMonth().getDate());
- }
- d.setDate(day);
- d.setMonth(this.getMonth() + value);
- break;
- case Date.YEAR:
- d.setFullYear(this.getFullYear() + value);
- break;
- }
- return d;
- },
-
- /**
- * Checks if this date falls on or between the given start and end dates.
- * @param {Date} start Start date
- * @param {Date} end End date
- * @return {Boolean} true if this date falls on or between the given start and end dates.
- */
- between : function(start, end) {
- var t = this.getTime();
- return start.getTime() <= t && t <= end.getTime();
- }
-});
-
-
-/**
- * Formats a date given the supplied format string.
- * @param {String} format The format string.
- * @return {String} The formatted date.
- * @method format
- */
-Date.prototype.format = Date.prototype.dateFormat;
-
-
-// private
-if (Ext.isSafari && (navigator.userAgent.match(/WebKit\/(\d+)/)[1] || NaN) < 420) {
- Ext.apply(Date.prototype, {
- _xMonth : Date.prototype.setMonth,
- _xDate : Date.prototype.setDate,
-
- // Bug in Safari 1.3, 2.0 (WebKit build < 420)
- // Date.setMonth does not work consistently if iMonth is not 0-11
- setMonth : function(num) {
- if (num <= -1) {
- var n = Math.ceil(-num),
- back_year = Math.ceil(n / 12),
- month = (n % 12) ? 12 - n % 12 : 0;
-
- this.setFullYear(this.getFullYear() - back_year);
-
- return this._xMonth(month);
- } else {
- return this._xMonth(num);
- }
- },
-
- // Bug in setDate() method (resolved in WebKit build 419.3, so to be safe we target Webkit builds < 420)
- // The parameter for Date.setDate() is converted to a signed byte integer in Safari
- // http://brianary.blogspot.com/2006/03/safari-date-bug.html
- setDate : function(d) {
- // use setTime() to workaround setDate() bug
- // subtract current day of month in milliseconds, then add desired day of month in milliseconds
- return this.setTime(this.getTime() - (this.getDate() - d) * 864e5);
- }
- });
-}
-
-
-
-/* Some basic Date tests... (requires Firebug)
-
-Date.parseDate('', 'c'); // call Date.parseDate() once to force computation of regex string so we can console.log() it
-console.log('Insane Regex for "c" format: %o', Date.parseCodes.c.s); // view the insane regex for the "c" format specifier
-
-// standard tests
-console.group('Standard Date.parseDate() Tests');
- console.log('Date.parseDate("2009-01-05T11:38:56", "c") = %o', Date.parseDate("2009-01-05T11:38:56", "c")); // assumes browser's timezone setting
- console.log('Date.parseDate("2009-02-04T12:37:55.001000", "c") = %o', Date.parseDate("2009-02-04T12:37:55.001000", "c")); // assumes browser's timezone setting
- console.log('Date.parseDate("2009-03-03T13:36:54,101000Z", "c") = %o', Date.parseDate("2009-03-03T13:36:54,101000Z", "c")); // UTC
- console.log('Date.parseDate("2009-04-02T14:35:53.901000-0530", "c") = %o', Date.parseDate("2009-04-02T14:35:53.901000-0530", "c")); // GMT-0530
- console.log('Date.parseDate("2009-05-01T15:34:52,9876000+08:00", "c") = %o', Date.parseDate("2009-05-01T15:34:52,987600+08:00", "c")); // GMT+08:00
-console.groupEnd();
-
-// ISO-8601 format as specified in http://www.w3.org/TR/NOTE-datetime
-// -- accepts ALL 6 levels of date-time granularity
-console.group('ISO-8601 Granularity Test (see http://www.w3.org/TR/NOTE-datetime)');
- console.log('Date.parseDate("1997", "c") = %o', Date.parseDate("1997", "c")); // YYYY (e.g. 1997)
- console.log('Date.parseDate("1997-07", "c") = %o', Date.parseDate("1997-07", "c")); // YYYY-MM (e.g. 1997-07)
- console.log('Date.parseDate("1997-07-16", "c") = %o', Date.parseDate("1997-07-16", "c")); // YYYY-MM-DD (e.g. 1997-07-16)
- console.log('Date.parseDate("1997-07-16T19:20+01:00", "c") = %o', Date.parseDate("1997-07-16T19:20+01:00", "c")); // YYYY-MM-DDThh:mmTZD (e.g. 1997-07-16T19:20+01:00)
- console.log('Date.parseDate("1997-07-16T19:20:30+01:00", "c") = %o', Date.parseDate("1997-07-16T19:20:30+01:00", "c")); // YYYY-MM-DDThh:mm:ssTZD (e.g. 1997-07-16T19:20:30+01:00)
- console.log('Date.parseDate("1997-07-16T19:20:30.45+01:00", "c") = %o', Date.parseDate("1997-07-16T19:20:30.45+01:00", "c")); // YYYY-MM-DDThh:mm:ss.sTZD (e.g. 1997-07-16T19:20:30.45+01:00)
- console.log('Date.parseDate("1997-07-16 19:20:30.45+01:00", "c") = %o', Date.parseDate("1997-07-16 19:20:30.45+01:00", "c")); // YYYY-MM-DD hh:mm:ss.sTZD (e.g. 1997-07-16T19:20:30.45+01:00)
- console.log('Date.parseDate("1997-13-16T19:20:30.45+01:00", "c", true)= %o', Date.parseDate("1997-13-16T19:20:30.45+01:00", "c", true)); // strict date parsing with invalid month value
-console.groupEnd();
-
-//*//**
- * @class Ext.util.DelayedTask
- * <p> The DelayedTask class provides a convenient way to "buffer" the execution of a method,
- * performing setTimeout where a new timeout cancels the old timeout. When called, the
- * task will wait the specified time period before executing. If durng that time period,
- * the task is called again, the original call will be cancelled. This continues so that
- * the function is only called a single time for each iteration.</p>
- * <p>This method is especially useful for things like detecting whether a user has finished
- * typing in a text field. An example would be performing validation on a keypress. You can
- * use this class to buffer the keypress events for a certain number of milliseconds, and
- * perform only if they stop for that amount of time. Usage:</p><pre><code>
-var task = new Ext.util.DelayedTask(function(){
- alert(Ext.getDom('myInputField').value.length);
-});
-// Wait 500ms before calling our function. If the user presses another key
-// during that 500ms, it will be cancelled and we'll wait another 500ms.
-Ext.get('myInputField').on('keypress', function(){
- task.{@link #delay}(500);
-});
- * </code></pre>
- * <p>Note that we are using a DelayedTask here to illustrate a point. The configuration
- * option <tt>buffer</tt> for {@link Ext.util.Observable#addListener addListener/on} will
- * also setup a delayed task for you to buffer events.</p>
- * @constructor The parameters to this constructor serve as defaults and are not required.
- * @param {Function} fn (optional) The default function to timeout
- * @param {Object} scope (optional) The default scope of that timeout
- * @param {Array} args (optional) The default Array of arguments
- */
-Ext.util.DelayedTask = function(fn, scope, args){
- var me = this,
- id,
- call = function(){
- clearInterval(id);
- id = null;
- fn.apply(scope, args || []);
- };
-
- /**
- * Cancels any pending timeout and queues a new one
- * @param {Number} delay The milliseconds to delay
- * @param {Function} newFn (optional) Overrides function passed to constructor
- * @param {Object} newScope (optional) Overrides scope passed to constructor
- * @param {Array} newArgs (optional) Overrides args passed to constructor
- */
- me.delay = function(delay, newFn, newScope, newArgs){
- me.cancel();
- fn = newFn || fn;
- scope = newScope || scope;
- args = newArgs || args;
- id = setInterval(call, delay);
- };
-
- /**
- * Cancel the last queued timeout
- */
- me.cancel = function(){
- if(id){
- clearInterval(id);
- id = null;
- }
- };
-};/**\r
- * @class Ext.util.MixedCollection\r
- * @extends Ext.util.Observable\r
- * A Collection class that maintains both numeric indexes and keys and exposes events.\r
- * @constructor\r
- * @param {Boolean} allowFunctions True if the addAll function should add function references to the\r
- * collection (defaults to false)\r
- * @param {Function} keyFn A function that can accept an item of the type(s) stored in this MixedCollection\r
- * and return the key value for that item. This is used when available to look up the key on items that\r
- * were passed without an explicit key parameter to a MixedCollection method. Passing this parameter is\r
- * equivalent to providing an implementation for the {@link #getKey} method.\r
- */\r
-Ext.util.MixedCollection = function(allowFunctions, keyFn){\r
- this.items = [];\r
- this.map = {};\r
- this.keys = [];\r
- this.length = 0;\r
- this.addEvents(\r
- /**\r
- * @event clear\r
- * Fires when the collection is cleared.\r
- */\r
- "clear",\r
- /**\r
- * @event add\r
- * Fires when an item is added to the collection.\r
- * @param {Number} index The index at which the item was added.\r
- * @param {Object} o The item added.\r
- * @param {String} key The key associated with the added item.\r
- */\r
- "add",\r
- /**\r
- * @event replace\r
- * Fires when an item is replaced in the collection.\r
- * @param {String} key he key associated with the new added.\r
- * @param {Object} old The item being replaced.\r
- * @param {Object} new The new item.\r
- */\r
- "replace",\r
- /**\r
- * @event remove\r
- * Fires when an item is removed from the collection.\r
- * @param {Object} o The item being removed.\r
- * @param {String} key (optional) The key associated with the removed item.\r
- */\r
- "remove",\r
- "sort"\r
- );\r
- this.allowFunctions = allowFunctions === true;\r
- if(keyFn){\r
- this.getKey = keyFn;\r
- }\r
- Ext.util.MixedCollection.superclass.constructor.call(this);\r
-};\r
-\r
-Ext.extend(Ext.util.MixedCollection, Ext.util.Observable, {\r
- allowFunctions : false,\r
-\r
-/**\r
- * Adds an item to the collection. Fires the {@link #add} event when complete.\r
- * @param {String} key <p>The key to associate with the item, or the new item.</p>\r
- * <p>If you supplied a {@link #getKey} implementation for this MixedCollection, or if the key\r
- * of your stored items is in a property called <tt><b>id</b></tt>, then the MixedCollection\r
- * will be able to <i>derive</i> the key for the new item. In this case just pass the new item in\r
- * this parameter.</p>\r
- * @param {Object} o The item to add.\r
- * @return {Object} The item added.\r
- */\r
- add: function(key, o){\r
- if(arguments.length == 1){\r
- o = arguments[0];\r
- key = this.getKey(o);\r
- }\r
- if(typeof key != 'undefined' && key !== null){\r
- var old = this.map[key];\r
- if(typeof old != 'undefined'){\r
- return this.replace(key, o);\r
- }\r
- this.map[key] = o;\r
- }\r
- this.length++;\r
- this.items.push(o);\r
- this.keys.push(key);\r
- this.fireEvent('add', this.length-1, o, key);\r
- return o;\r
- },\r
-\r
-/**\r
- * MixedCollection has a generic way to fetch keys if you implement getKey. The default implementation\r
- * simply returns <tt style="font-weight:bold;">item.id</tt> but you can provide your own implementation\r
- * to return a different value as in the following examples:\r
-<pre><code>\r
-// normal way\r
-var mc = new Ext.util.MixedCollection();\r
-mc.add(someEl.dom.id, someEl);\r
-mc.add(otherEl.dom.id, otherEl);\r
-//and so on\r
-\r
-// using getKey\r
-var mc = new Ext.util.MixedCollection();\r
-mc.getKey = function(el){\r
- return el.dom.id;\r
-};\r
-mc.add(someEl);\r
-mc.add(otherEl);\r
-\r
-// or via the constructor\r
-var mc = new Ext.util.MixedCollection(false, function(el){\r
- return el.dom.id;\r
-});\r
-mc.add(someEl);\r
-mc.add(otherEl);\r
-</code></pre>\r
- * @param {Object} item The item for which to find the key.\r
- * @return {Object} The key for the passed item.\r
- */\r
- getKey : function(o){\r
- return o.id;\r
- },\r
-\r
-/**\r
- * Replaces an item in the collection. Fires the {@link #replace} event when complete.\r
- * @param {String} key <p>The key associated with the item to replace, or the replacement item.</p>\r
- * <p>If you supplied a {@link #getKey} implementation for this MixedCollection, or if the key\r
- * of your stored items is in a property called <tt><b>id</b></tt>, then the MixedCollection\r
- * will be able to <i>derive</i> the key of the replacement item. If you want to replace an item\r
- * with one having the same key value, then just pass the replacement item in this parameter.</p>\r
- * @param o {Object} o (optional) If the first parameter passed was a key, the item to associate\r
- * with that key.\r
- * @return {Object} The new item.\r
- */\r
- replace : function(key, o){\r
- if(arguments.length == 1){\r
- o = arguments[0];\r
- key = this.getKey(o);\r
- }\r
- var old = this.map[key];\r
- if(typeof key == "undefined" || key === null || typeof old == "undefined"){\r
- return this.add(key, o);\r
- }\r
- var index = this.indexOfKey(key);\r
- this.items[index] = o;\r
- this.map[key] = o;\r
- this.fireEvent("replace", key, old, o);\r
- return o;\r
- },\r
-\r
-/**\r
- * Adds all elements of an Array or an Object to the collection.\r
- * @param {Object/Array} objs An Object containing properties which will be added to the collection, or\r
- * an Array of values, each of which are added to the collection.\r
- */\r
- addAll : function(objs){\r
- if(arguments.length > 1 || Ext.isArray(objs)){\r
- var args = arguments.length > 1 ? arguments : objs;\r
- for(var i = 0, len = args.length; i < len; i++){\r
- this.add(args[i]);\r
- }\r
- }else{\r
- for(var key in objs){\r
- if(this.allowFunctions || typeof objs[key] != "function"){\r
- this.add(key, objs[key]);\r
- }\r
- }\r
- }\r
- },\r
-\r
-/**\r
- * Executes the specified function once for every item in the collection, passing the following arguments:\r
- * <div class="mdetail-params"><ul>\r
- * <li><b>item</b> : Mixed<p class="sub-desc">The collection item</p></li>\r
- * <li><b>index</b> : Number<p class="sub-desc">The item's index</p></li>\r
- * <li><b>length</b> : Number<p class="sub-desc">The total number of items in the collection</p></li>\r
- * </ul></div>\r
- * The function should return a boolean value. Returning false from the function will stop the iteration.\r
- * @param {Function} fn The function to execute for each item.\r
- * @param {Object} scope (optional) The scope in which to execute the function.\r
- */\r
- each : function(fn, scope){\r
- var items = [].concat(this.items); // each safe for removal\r
- for(var i = 0, len = items.length; i < len; i++){\r
- if(fn.call(scope || items[i], items[i], i, len) === false){\r
- break;\r
- }\r
- }\r
- },\r
-\r
-/**\r
- * Executes the specified function once for every key in the collection, passing each\r
- * key, and its associated item as the first two parameters.\r
- * @param {Function} fn The function to execute for each item.\r
- * @param {Object} scope (optional) The scope in which to execute the function.\r
- */\r
- eachKey : function(fn, scope){\r
- for(var i = 0, len = this.keys.length; i < len; i++){\r
- fn.call(scope || window, this.keys[i], this.items[i], i, len);\r
- }\r
- },\r
-\r
- /**\r
- * Returns the first item in the collection which elicits a true return value from the\r
- * passed selection function.\r
- * @param {Function} fn The selection function to execute for each item.\r
- * @param {Object} scope (optional) The scope in which to execute the function.\r
- * @return {Object} The first item in the collection which returned true from the selection function.\r
- */\r
- find : function(fn, scope){\r
- for(var i = 0, len = this.items.length; i < len; i++){\r
- if(fn.call(scope || window, this.items[i], this.keys[i])){\r
- return this.items[i];\r
- }\r
- }\r
- return null;\r
- },\r
-\r
-/**\r
- * Inserts an item at the specified index in the collection. Fires the {@link #add} event when complete.\r
- * @param {Number} index The index to insert the item at.\r
- * @param {String} key The key to associate with the new item, or the item itself.\r
- * @param {Object} o (optional) If the second parameter was a key, the new item.\r
- * @return {Object} The item inserted.\r
- */\r
- insert : function(index, key, o){\r
- if(arguments.length == 2){\r
- o = arguments[1];\r
- key = this.getKey(o);\r
- }\r
- if(this.containsKey(key)){\r
- this.suspendEvents();\r
- this.removeKey(key);\r
- this.resumeEvents();\r
- }\r
- if(index >= this.length){\r
- return this.add(key, o);\r
- }\r
- this.length++;\r
- this.items.splice(index, 0, o);\r
- if(typeof key != "undefined" && key !== null){\r
- this.map[key] = o;\r
- }\r
- this.keys.splice(index, 0, key);\r
- this.fireEvent("add", index, o, key);\r
- return o;\r
- },\r
-\r
-/**\r
- * Remove an item from the collection.\r
- * @param {Object} o The item to remove.\r
- * @return {Object} The item removed or false if no item was removed.\r
- */\r
- remove : function(o){\r
- return this.removeAt(this.indexOf(o));\r
- },\r
-\r
-/**\r
- * Remove an item from a specified index in the collection. Fires the {@link #remove} event when complete.\r
- * @param {Number} index The index within the collection of the item to remove.\r
- * @return {Object} The item removed or false if no item was removed.\r
- */\r
- removeAt : function(index){\r
- if(index < this.length && index >= 0){\r
- this.length--;\r
- var o = this.items[index];\r
- this.items.splice(index, 1);\r
- var key = this.keys[index];\r
- if(typeof key != "undefined"){\r
- delete this.map[key];\r
- }\r
- this.keys.splice(index, 1);\r
- this.fireEvent("remove", o, key);\r
- return o;\r
- }\r
- return false;\r
- },\r
-\r
-/**\r
- * Removed an item associated with the passed key fom the collection.\r
- * @param {String} key The key of the item to remove.\r
- * @return {Object} The item removed or false if no item was removed.\r
- */\r
- removeKey : function(key){\r
- return this.removeAt(this.indexOfKey(key));\r
- },\r
-\r
-/**\r
- * Returns the number of items in the collection.\r
- * @return {Number} the number of items in the collection.\r
- */\r
- getCount : function(){\r
- return this.length;\r
- },\r
-\r
-/**\r
- * Returns index within the collection of the passed Object.\r
- * @param {Object} o The item to find the index of.\r
- * @return {Number} index of the item. Returns -1 if not found.\r
- */\r
- indexOf : function(o){\r
- return this.items.indexOf(o);\r
- },\r
-\r
-/**\r
- * Returns index within the collection of the passed key.\r
- * @param {String} key The key to find the index of.\r
- * @return {Number} index of the key.\r
- */\r
- indexOfKey : function(key){\r
- return this.keys.indexOf(key);\r
- },\r
-\r
-/**\r
- * Returns the item associated with the passed key OR index. Key has priority over index. This is the equivalent\r
- * of calling {@link #key} first, then if nothing matched calling {@link #itemAt}.\r
- * @param {String/Number} key The key or index of the item.\r
- * @return {Object} If the item is found, returns the item. If the item was not found, returns <tt>undefined</tt>.\r
- * If an item was found, but is a Class, returns <tt>null</tt>.\r
- */\r
- item : function(key){\r
- var mk = this.map[key],\r
- item = mk !== undefined ? mk : (typeof key == 'number') ? this.items[key] : undefined;\r
- return !Ext.isFunction(item) || this.allowFunctions ? item : null; // for prototype!\r
- },\r
-\r
-/**\r
- * Returns the item at the specified index.\r
- * @param {Number} index The index of the item.\r
- * @return {Object} The item at the specified index.\r
- */\r
- itemAt : function(index){\r
- return this.items[index];\r
- },\r
-\r
-/**\r
- * Returns the item associated with the passed key.\r
- * @param {String/Number} key The key of the item.\r
- * @return {Object} The item associated with the passed key.\r
- */\r
- key : function(key){\r
- return this.map[key];\r
- },\r
-\r
-/**\r
- * Returns true if the collection contains the passed Object as an item.\r
- * @param {Object} o The Object to look for in the collection.\r
- * @return {Boolean} True if the collection contains the Object as an item.\r
- */\r
- contains : function(o){\r
- return this.indexOf(o) != -1;\r
- },\r
-\r
-/**\r
- * Returns true if the collection contains the passed Object as a key.\r
- * @param {String} key The key to look for in the collection.\r
- * @return {Boolean} True if the collection contains the Object as a key.\r
- */\r
- containsKey : function(key){\r
- return typeof this.map[key] != "undefined";\r
- },\r
-\r
-/**\r
- * Removes all items from the collection. Fires the {@link #clear} event when complete.\r
- */\r
- clear : function(){\r
- this.length = 0;\r
- this.items = [];\r
- this.keys = [];\r
- this.map = {};\r
- this.fireEvent("clear");\r
- },\r
-\r
-/**\r
- * Returns the first item in the collection.\r
- * @return {Object} the first item in the collection..\r
- */\r
- first : function(){\r
- return this.items[0];\r
- },\r
-\r
-/**\r
- * Returns the last item in the collection.\r
- * @return {Object} the last item in the collection..\r
- */\r
- last : function(){\r
- return this.items[this.length-1];\r
- },\r
-\r
- // private\r
- _sort : function(property, dir, fn){\r
- var i,\r
- len,\r
- dsc = String(dir).toUpperCase() == "DESC" ? -1 : 1,\r
- c = [], k = this.keys, items = this.items;\r
- \r
- fn = fn || function(a, b){\r
- return a-b;\r
- };\r
- for(i = 0, len = items.length; i < len; i++){\r
- c[c.length] = {key: k[i], value: items[i], index: i};\r
- }\r
- c.sort(function(a, b){\r
- var v = fn(a[property], b[property]) * dsc;\r
- if(v === 0){\r
- v = (a.index < b.index ? -1 : 1);\r
- }\r
- return v;\r
- });\r
- for(i = 0, len = c.length; i < len; i++){\r
- items[i] = c[i].value;\r
- k[i] = c[i].key;\r
- }\r
- this.fireEvent("sort", this);\r
- },\r
-\r
- /**\r
- * Sorts this collection with the passed comparison function\r
- * @param {String} direction (optional) "ASC" or "DESC"\r
- * @param {Function} fn (optional) comparison function\r
- */\r
- sort : function(dir, fn){\r
- this._sort("value", dir, fn);\r
- },\r
-\r
- /**\r
- * Sorts this collection by keys\r
- * @param {String} direction (optional) "ASC" or "DESC"\r
- * @param {Function} fn (optional) a comparison function (defaults to case insensitive string)\r
- */\r
- keySort : function(dir, fn){\r
- this._sort("key", dir, fn || function(a, b){\r
- var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase();\r
- return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);\r
- });\r
- },\r
-\r
- /**\r
- * Returns a range of items in this collection\r
- * @param {Number} startIndex (optional) defaults to 0\r
- * @param {Number} endIndex (optional) default to the last item\r
- * @return {Array} An array of items\r
- */\r
- getRange : function(start, end){\r
- var items = this.items;\r
- if(items.length < 1){\r
- return [];\r
- }\r
- start = start || 0;\r
- end = Math.min(typeof end == "undefined" ? this.length-1 : end, this.length-1);\r
- var i, r = [];\r
- if(start <= end){\r
- for(i = start; i <= end; i++) {\r
- r[r.length] = items[i];\r
- }\r
- }else{\r
- for(i = start; i >= end; i--) {\r
- r[r.length] = items[i];\r
- }\r
- }\r
- return r;\r
- },\r
-\r
- /**\r
- * Filter the <i>objects</i> in this collection by a specific property.\r
- * Returns a new collection that has been filtered.\r
- * @param {String} property A property on your objects\r
- * @param {String/RegExp} value Either string that the property values\r
- * should start with or a RegExp to test against the property\r
- * @param {Boolean} anyMatch (optional) True to match any part of the string, not just the beginning\r
- * @param {Boolean} caseSensitive (optional) True for case sensitive comparison (defaults to False).\r
- * @return {MixedCollection} The new filtered collection\r
- */\r
- filter : function(property, value, anyMatch, caseSensitive){\r
- if(Ext.isEmpty(value, false)){\r
- return this.clone();\r
- }\r
- value = this.createValueMatcher(value, anyMatch, caseSensitive);\r
- return this.filterBy(function(o){\r
- return o && value.test(o[property]);\r
- });\r
- },\r
-\r
- /**\r
- * Filter by a function. Returns a <i>new</i> collection that has been filtered.\r
- * The passed function will be called with each object in the collection.\r
- * If the function returns true, the value is included otherwise it is filtered.\r
- * @param {Function} fn The function to be called, it will receive the args o (the object), k (the key)\r
- * @param {Object} scope (optional) The scope of the function (defaults to this)\r
- * @return {MixedCollection} The new filtered collection\r
- */\r
- filterBy : function(fn, scope){\r
- var r = new Ext.util.MixedCollection();\r
- r.getKey = this.getKey;\r
- var k = this.keys, it = this.items;\r
- for(var i = 0, len = it.length; i < len; i++){\r
- if(fn.call(scope||this, it[i], k[i])){\r
- r.add(k[i], it[i]);\r
- }\r
- }\r
- return r;\r
- },\r
-\r
- /**\r
- * Finds the index of the first matching object in this collection by a specific property/value.\r
- * @param {String} property The name of a property on your objects.\r
- * @param {String/RegExp} value A string that the property values\r
- * should start with or a RegExp to test against the property.\r
- * @param {Number} start (optional) The index to start searching at (defaults to 0).\r
- * @param {Boolean} anyMatch (optional) True to match any part of the string, not just the beginning.\r
- * @param {Boolean} caseSensitive (optional) True for case sensitive comparison.\r
- * @return {Number} The matched index or -1\r
- */\r
- findIndex : function(property, value, start, anyMatch, caseSensitive){\r
- if(Ext.isEmpty(value, false)){\r
- return -1;\r
- }\r
- value = this.createValueMatcher(value, anyMatch, caseSensitive);\r
- return this.findIndexBy(function(o){\r
- return o && value.test(o[property]);\r
- }, null, start);\r
- },\r
-\r
- /**\r
- * Find the index of the first matching object in this collection by a function.\r
- * If the function returns <i>true</i> it is considered a match.\r
- * @param {Function} fn The function to be called, it will receive the args o (the object), k (the key).\r
- * @param {Object} scope (optional) The scope of the function (defaults to this).\r
- * @param {Number} start (optional) The index to start searching at (defaults to 0).\r
- * @return {Number} The matched index or -1\r
- */\r
- findIndexBy : function(fn, scope, start){\r
- var k = this.keys, it = this.items;\r
- for(var i = (start||0), len = it.length; i < len; i++){\r
- if(fn.call(scope||this, it[i], k[i])){\r
- return i;\r
- }\r
- }\r
- return -1;\r
- },\r
-\r
- // private\r
- createValueMatcher : function(value, anyMatch, caseSensitive){\r
- if(!value.exec){ // not a regex\r
- value = String(value);\r
- value = new RegExp((anyMatch === true ? '' : '^') + Ext.escapeRe(value), caseSensitive ? '' : 'i');\r
- }\r
- return value;\r
- },\r
-\r
- /**\r
- * Creates a shallow copy of this collection\r
- * @return {MixedCollection}\r
- */\r
- clone : function(){\r
- var r = new Ext.util.MixedCollection();\r
- var k = this.keys, it = this.items;\r
- for(var i = 0, len = it.length; i < len; i++){\r
- r.add(k[i], it[i]);\r
- }\r
- r.getKey = this.getKey;\r
- return r;\r
- }\r
-});\r
-/**\r
- * This method calls {@link #item item()}.\r
- * Returns the item associated with the passed key OR index. Key has priority over index. This is the equivalent\r
- * of calling {@link #key} first, then if nothing matched calling {@link #itemAt}.\r
- * @param {String/Number} key The key or index of the item.\r
- * @return {Object} If the item is found, returns the item. If the item was not found, returns <tt>undefined</tt>.\r
- * If an item was found, but is a Class, returns <tt>null</tt>.\r
- */\r
-Ext.util.MixedCollection.prototype.get = Ext.util.MixedCollection.prototype.item;/**
- * @class Ext.util.JSON
- * Modified version of Douglas Crockford"s json.js that doesn"t
- * mess with the Object prototype
- * http://www.json.org/js.html
- * @singleton
- */
-Ext.util.JSON = new (function(){
- var useHasOwn = !!{}.hasOwnProperty,
- isNative = function() {
- var useNative = null;
-
- return function() {
- if (useNative === null) {
- useNative = Ext.USE_NATIVE_JSON && window.JSON && JSON.toString() == '[object JSON]';
- }
-
- return useNative;
- };
- }(),
- pad = function(n) {
- return n < 10 ? "0" + n : n;
- },
- doDecode = function(json){
- return eval("(" + json + ')');
- },
- doEncode = function(o){
- if(typeof o == "undefined" || o === null){
- return "null";
- }else if(Ext.isArray(o)){
- return encodeArray(o);
- }else if(Object.prototype.toString.apply(o) === '[object Date]'){
- return Ext.util.JSON.encodeDate(o);
- }else if(typeof o == "string"){
- return encodeString(o);
- }else if(typeof o == "number"){
- return isFinite(o) ? String(o) : "null";
- }else if(typeof o == "boolean"){
- return String(o);
- }else {
- var a = ["{"], b, i, v;
- for (i in o) {
- if(!useHasOwn || o.hasOwnProperty(i)) {
- v = o[i];
- switch (typeof v) {
- case "undefined":
- case "function":
- case "unknown":
- break;
- default:
- if(b){
- a.push(',');
- }
- a.push(doEncode(i), ":",
- v === null ? "null" : doEncode(v));
- b = true;
- }
- }
- }
- a.push("}");
- return a.join("");
- }
- },
- m = {
- "\b": '\\b',
- "\t": '\\t',
- "\n": '\\n',
- "\f": '\\f',
- "\r": '\\r',
- '"' : '\\"',
- "\\": '\\\\'
- },
- encodeString = function(s){
- if (/["\\\x00-\x1f]/.test(s)) {
- return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) {
- var c = m[b];
- if(c){
- return c;
- }
- c = b.charCodeAt();
- return "\\u00" +
- Math.floor(c / 16).toString(16) +
- (c % 16).toString(16);
- }) + '"';
- }
- return '"' + s + '"';
- },
- encodeArray = function(o){
- var a = ["["], b, i, l = o.length, v;
- for (i = 0; i < l; i += 1) {
- v = o[i];
- switch (typeof v) {
- case "undefined":
- case "function":
- case "unknown":
- break;
- default:
- if (b) {
- a.push(',');
- }
- a.push(v === null ? "null" : Ext.util.JSON.encode(v));
- b = true;
- }
- }
- a.push("]");
- return a.join("");
- };
-
- this.encodeDate = function(o){
- return '"' + o.getFullYear() + "-" +
- pad(o.getMonth() + 1) + "-" +
- pad(o.getDate()) + "T" +
- pad(o.getHours()) + ":" +
- pad(o.getMinutes()) + ":" +
- pad(o.getSeconds()) + '"';
- };
-
- /**
- * Encodes an Object, Array or other value
- * @param {Mixed} o The variable to encode
- * @return {String} The JSON string
- */
- this.encode = function() {
- var ec;
- return function(o) {
- if (!ec) {
- // setup encoding function on first access
- ec = isNative() ? JSON.stringify : doEncode;
- }
- return ec(o);
- };
- }();
-
-
- /**
- * Decodes (parses) a JSON string to an object. If the JSON is invalid, this function throws a SyntaxError unless the safe option is set.
- * @param {String} json The JSON string
- * @return {Object} The resulting object
- */
- this.decode = function() {
- var dc;
- return function(json) {
- if (!dc) {
- // setup decoding function on first access
- dc = isNative() ? JSON.parse : doDecode;
- }
- return dc(json);
- };
- }();
-
-})();
-/**
- * Shorthand for {@link Ext.util.JSON#encode}
- * @param {Mixed} o The variable to encode
- * @return {String} The JSON string
- * @member Ext
- * @method encode
- */
-Ext.encode = Ext.util.JSON.encode;
-/**
- * Shorthand for {@link Ext.util.JSON#decode}
- * @param {String} json The JSON string
- * @param {Boolean} safe (optional) Whether to return null or throw an exception if the JSON is invalid.
- * @return {Object} The resulting object
- * @member Ext
- * @method decode
- */
-Ext.decode = Ext.util.JSON.decode;
-/**\r
- * @class Ext.util.Format\r
- * Reusable data formatting functions\r
- * @singleton\r
- */\r
-Ext.util.Format = function(){\r
- var trimRe = /^\s+|\s+$/g;\r
- return {\r
- /**\r
- * Truncate a string and add an ellipsis ('...') to the end if it exceeds the specified length\r
- * @param {String} value The string to truncate\r
- * @param {Number} length The maximum length to allow before truncating\r
- * @param {Boolean} word True to try to find a common work break\r
- * @return {String} The converted text\r
- */\r
- ellipsis : function(value, len, word){\r
- if(value && value.length > len){\r
- if(word){\r
- var vs = value.substr(0, len - 2);\r
- var index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?'));\r
- if(index == -1 || index < (len - 15)){\r
- return value.substr(0, len - 3) + "...";\r
- }else{\r
- return vs.substr(0, index) + "...";\r
- }\r
- } else{\r
- return value.substr(0, len - 3) + "...";\r
- }\r
- }\r
- return value;\r
- },\r
-\r
- /**\r
- * Checks a reference and converts it to empty string if it is undefined\r
- * @param {Mixed} value Reference to check\r
- * @return {Mixed} Empty string if converted, otherwise the original value\r
- */\r
- undef : function(value){\r
- return value !== undefined ? value : "";\r
- },\r
-\r
- /**\r
- * Checks a reference and converts it to the default value if it's empty\r
- * @param {Mixed} value Reference to check\r
- * @param {String} defaultValue The value to insert of it's undefined (defaults to "")\r
- * @return {String}\r
- */\r
- defaultValue : function(value, defaultValue){\r
- return value !== undefined && value !== '' ? value : defaultValue;\r
- },\r
-\r
- /**\r
- * Convert certain characters (&, <, >, and ') to their HTML character equivalents for literal display in web pages.\r
- * @param {String} value The string to encode\r
- * @return {String} The encoded text\r
- */\r
- htmlEncode : function(value){\r
- return !value ? value : String(value).replace(/&/g, "&").replace(/>/g, ">").replace(/</g, "<").replace(/"/g, """);\r
- },\r
-\r
- /**\r
- * Convert certain characters (&, <, >, and ') from their HTML character equivalents.\r
- * @param {String} value The string to decode\r
- * @return {String} The decoded text\r
- */\r
- htmlDecode : function(value){\r
- return !value ? value : String(value).replace(/>/g, ">").replace(/</g, "<").replace(/"/g, '"').replace(/&/g, "&");\r
- },\r
-\r
- /**\r
- * Trims any whitespace from either side of a string\r
- * @param {String} value The text to trim\r
- * @return {String} The trimmed text\r
- */\r
- trim : function(value){\r
- return String(value).replace(trimRe, "");\r
- },\r
-\r
- /**\r
- * Returns a substring from within an original string\r
- * @param {String} value The original text\r
- * @param {Number} start The start index of the substring\r
- * @param {Number} length The length of the substring\r
- * @return {String} The substring\r
- */\r
- substr : function(value, start, length){\r
- return String(value).substr(start, length);\r
- },\r
-\r
- /**\r
- * Converts a string to all lower case letters\r
- * @param {String} value The text to convert\r
- * @return {String} The converted text\r
- */\r
- lowercase : function(value){\r
- return String(value).toLowerCase();\r
- },\r
-\r
- /**\r
- * Converts a string to all upper case letters\r
- * @param {String} value The text to convert\r
- * @return {String} The converted text\r
- */\r
- uppercase : function(value){\r
- return String(value).toUpperCase();\r
- },\r
-\r
- /**\r
- * Converts the first character only of a string to upper case\r
- * @param {String} value The text to convert\r
- * @return {String} The converted text\r
- */\r
- capitalize : function(value){\r
- return !value ? value : value.charAt(0).toUpperCase() + value.substr(1).toLowerCase();\r
- },\r
-\r
- // private\r
- call : function(value, fn){\r
- if(arguments.length > 2){\r
- var args = Array.prototype.slice.call(arguments, 2);\r
- args.unshift(value);\r
- return eval(fn).apply(window, args);\r
- }else{\r
- return eval(fn).call(window, value);\r
- }\r
- },\r
-\r
- /**\r
- * Format a number as US currency\r
- * @param {Number/String} value The numeric value to format\r
- * @return {String} The formatted currency string\r
- */\r
- usMoney : function(v){\r
- v = (Math.round((v-0)*100))/100;\r
- v = (v == Math.floor(v)) ? v + ".00" : ((v*10 == Math.floor(v*10)) ? v + "0" : v);\r
- v = String(v);\r
- var ps = v.split('.');\r
- var whole = ps[0];\r
- var sub = ps[1] ? '.'+ ps[1] : '.00';\r
- var r = /(\d+)(\d{3})/;\r
- while (r.test(whole)) {\r
- whole = whole.replace(r, '$1' + ',' + '$2');\r
- }\r
- v = whole + sub;\r
- if(v.charAt(0) == '-'){\r
- return '-$' + v.substr(1);\r
- }\r
- return "$" + v;\r
- },\r
-\r
- /**\r
- * Parse a value into a formatted date using the specified format pattern.\r
- * @param {String/Date} value The value to format (Strings must conform to the format expected by the javascript Date object's <a href="http://www.w3schools.com/jsref/jsref_parse.asp">parse()</a> method)\r
- * @param {String} format (optional) Any valid date format string (defaults to 'm/d/Y')\r
- * @return {String} The formatted date string\r
- */\r
- date : function(v, format){\r
- if(!v){\r
- return "";\r
- }\r
- if(!Ext.isDate(v)){\r
- v = new Date(Date.parse(v));\r
- }\r
- return v.dateFormat(format || "m/d/Y");\r
- },\r
-\r
- /**\r
- * Returns a date rendering function that can be reused to apply a date format multiple times efficiently\r
- * @param {String} format Any valid date format string\r
- * @return {Function} The date formatting function\r
- */\r
- dateRenderer : function(format){\r
- return function(v){\r
- return Ext.util.Format.date(v, format);\r
- };\r
- },\r
-\r
- // private\r
- stripTagsRE : /<\/?[^>]+>/gi,\r
- \r
- /**\r
- * Strips all HTML tags\r
- * @param {Mixed} value The text from which to strip tags\r
- * @return {String} The stripped text\r
- */\r
- stripTags : function(v){\r
- return !v ? v : String(v).replace(this.stripTagsRE, "");\r
- },\r
-\r
- stripScriptsRe : /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,\r
-\r
- /**\r
- * Strips all script tags\r
- * @param {Mixed} value The text from which to strip script tags\r
- * @return {String} The stripped text\r
- */\r
- stripScripts : function(v){\r
- return !v ? v : String(v).replace(this.stripScriptsRe, "");\r
- },\r
-\r
- /**\r
- * Simple format for a file size (xxx bytes, xxx KB, xxx MB)\r
- * @param {Number/String} size The numeric value to format\r
- * @return {String} The formatted file size\r
- */\r
- fileSize : function(size){\r
- if(size < 1024) {\r
- return size + " bytes";\r
- } else if(size < 1048576) {\r
- return (Math.round(((size*10) / 1024))/10) + " KB";\r
- } else {\r
- return (Math.round(((size*10) / 1048576))/10) + " MB";\r
- }\r
- },\r
-\r
- /**\r
- * It does simple math for use in a template, for example:<pre><code>\r
- * var tpl = new Ext.Template('{value} * 10 = {value:math("* 10")}');\r
- * </code></pre>\r
- * @return {Function} A function that operates on the passed value.\r
- */\r
- math : function(){\r
- var fns = {};\r
- return function(v, a){\r
- if(!fns[a]){\r
- fns[a] = new Function('v', 'return v ' + a + ';');\r
- }\r
- return fns[a](v);\r
- }\r
- }(),\r
-\r
- /**\r
- * Rounds the passed number to the required decimal precision.\r
- * @param {Number/String} value The numeric value to round.\r
- * @param {Number} precision The number of decimal places to which to round the first parameter's value.\r
- * @return {Number} The rounded value.\r
- */\r
- round : function(value, precision) {\r
- var result = Number(value);\r
- if (typeof precision == 'number') {\r
- precision = Math.pow(10, precision);\r
- result = Math.round(value * precision) / precision;\r
- }\r
- return result;\r
- },\r
-\r
- /**\r
- * Formats the number according to the format string.\r
- * <div style="margin-left:40px">examples (123456.789):\r
- * <div style="margin-left:10px">\r
- * 0 - (123456) show only digits, no precision<br>\r
- * 0.00 - (123456.78) show only digits, 2 precision<br>\r
- * 0.0000 - (123456.7890) show only digits, 4 precision<br>\r
- * 0,000 - (123,456) show comma and digits, no precision<br>\r
- * 0,000.00 - (123,456.78) show comma and digits, 2 precision<br>\r
- * 0,0.00 - (123,456.78) shortcut method, show comma and digits, 2 precision<br>\r
- * To reverse the grouping (,) and decimal (.) for international numbers, add /i to the end.\r
- * For example: 0.000,00/i\r
- * </div></div>\r
- * @param {Number} v The number to format.\r
- * @param {String} format The way you would like to format this text.\r
- * @return {String} The formatted number.\r
- */\r
- number: function(v, format) {\r
- if(!format){\r
- return v;\r
- }\r
- v = Ext.num(v, NaN);\r
- if (isNaN(v)){\r
- return '';\r
- }\r
- var comma = ',',\r
- dec = '.',\r
- i18n = false,\r
- neg = v < 0;\r
- \r
- v = Math.abs(v);\r
- if(format.substr(format.length - 2) == '/i'){\r
- format = format.substr(0, format.length - 2);\r
- i18n = true;\r
- comma = '.';\r
- dec = ',';\r
- }\r
- \r
- var hasComma = format.indexOf(comma) != -1, \r
- psplit = (i18n ? format.replace(/[^\d\,]/g, '') : format.replace(/[^\d\.]/g, '')).split(dec);\r
- \r
- if(1 < psplit.length){\r
- v = v.toFixed(psplit[1].length);\r
- }else if(2 < psplit.length){\r
- throw ('NumberFormatException: invalid format, formats should have no more than 1 period: ' + format);\r
- }else{\r
- v = v.toFixed(0);\r
- }\r
- \r
- var fnum = v.toString();\r
- if(hasComma){\r
- psplit = fnum.split('.');\r
- \r
- var cnum = psplit[0], parr = [], j = cnum.length, m = Math.floor(j / 3), n = cnum.length % 3 || 3;\r
- \r
- for(var i = 0; i < j; i += n){\r
- if(i != 0){\r
- n = 3;\r
- }\r
- parr[parr.length] = cnum.substr(i, n);\r
- m -= 1;\r
- }\r
- fnum = parr.join(comma);\r
- if(psplit[1]){\r
- fnum += dec + psplit[1];\r
- }\r
- }\r
- \r
- return (neg ? '-' : '') + format.replace(/[\d,?\.?]+/, fnum);\r
- },\r
-\r
- /**\r
- * Returns a number rendering function that can be reused to apply a number format multiple times efficiently\r
- * @param {String} format Any valid number format string for {@link #number}\r
- * @return {Function} The number formatting function\r
- */\r
- numberRenderer : function(format){\r
- return function(v){\r
- return Ext.util.Format.number(v, format);\r
- };\r
- },\r
-\r
- /**\r
- * Selectively do a plural form of a word based on a numeric value. For example, in a template,\r
- * {commentCount:plural("Comment")} would result in "1 Comment" if commentCount was 1 or would be "x Comments"\r
- * if the value is 0 or greater than 1.\r
- * @param {Number} value The value to compare against\r
- * @param {String} singular The singular form of the word\r
- * @param {String} plural (optional) The plural form of the word (defaults to the singular with an "s")\r
- */\r
- plural : function(v, s, p){\r
- return v +' ' + (v == 1 ? s : (p ? p : s+'s'));\r
- },\r
- \r
- /**\r
- * Converts newline characters to the HTML tag <br/>\r
- * @param {String} The string value to format.\r
- * @return {String} The string with embedded <br/> tags in place of newlines.\r
- */\r
- nl2br : function(v){\r
- return v === undefined || v === null ? '' : v.replace(/\n/g, '<br/>');\r
- }\r
- }\r
-}();/**
- * @class Ext.XTemplate
- * @extends Ext.Template
- * <p>A template class that supports advanced functionality like autofilling arrays, conditional processing with
- * basic comparison operators, sub-templates, basic math function support, special built-in template variables,
- * inline code execution and more. XTemplate also provides the templating mechanism built into {@link Ext.DataView}.</p>
- * <p>XTemplate supports many special tags and built-in operators that aren't defined as part of the API, but are
- * supported in the templates that can be created. The following examples demonstrate all of the supported features.
- * This is the data object used for reference in each code example:</p>
- * <pre><code>
-var data = {
- name: 'Jack Slocum',
- title: 'Lead Developer',
- company: 'Ext JS, LLC',
- email: 'jack@extjs.com',
- address: '4 Red Bulls Drive',
- city: 'Cleveland',
- state: 'Ohio',
- zip: '44102',
- drinks: ['Red Bull', 'Coffee', 'Water'],
- kids: [{
- name: 'Sara Grace',
- age:3
- },{
- name: 'Zachary',
- age:2
- },{
- name: 'John James',
- age:0
- }]
-};
- * </code></pre>
- * <p><b>Auto filling of arrays</b><br/>The <tt>tpl</tt> tag and the <tt>for</tt> operator are used
- * to process the provided data object. If <tt>for="."</tt> is specified, the data object provided
- * is examined. If the variable in <tt>for</tt> is an array, it will auto-fill, repeating the template
- * block inside the <tt>tpl</tt> tag for each item in the array:</p>
- * <pre><code>
-var tpl = new Ext.XTemplate(
- '<p>Kids: ',
- '<tpl for=".">',
- '<p>{name}</p>',
- '</tpl></p>'
-);
-tpl.overwrite(panel.body, data.kids); // pass the kids property of the data object
- * </code></pre>
- * <p><b>Scope switching</b><br/>The <tt>for</tt> property can be leveraged to access specified members
- * of the provided data object to populate the template:</p>
- * <pre><code>
-var tpl = new Ext.XTemplate(
- '<p>Name: {name}</p>',
- '<p>Title: {title}</p>',
- '<p>Company: {company}</p>',
- '<p>Kids: ',
- '<tpl <b>for="kids"</b>>', // interrogate the kids property within the data
- '<p>{name}</p>',
- '</tpl></p>'
-);
-tpl.overwrite(panel.body, data);
- * </code></pre>
- * <p><b>Access to parent object from within sub-template scope</b><br/>When processing a sub-template, for example while
- * looping through a child array, you can access the parent object's members via the <tt>parent</tt> object:</p>
- * <pre><code>
-var tpl = new Ext.XTemplate(
- '<p>Name: {name}</p>',
- '<p>Kids: ',
- '<tpl for="kids">',
- '<tpl if="age &gt; 1">', // <-- Note that the > is encoded
- '<p>{name}</p>',
- '<p>Dad: {parent.name}</p>',
- '</tpl>',
- '</tpl></p>'
-);
-tpl.overwrite(panel.body, data);
-</code></pre>
- * <p><b>Array item index and basic math support</b> <br/>While processing an array, the special variable <tt>{#}</tt>
- * will provide the current array index + 1 (starts at 1, not 0). Templates also support the basic math operators
- * + - * and / that can be applied directly on numeric data values:</p>
- * <pre><code>
-var tpl = new Ext.XTemplate(
- '<p>Name: {name}</p>',
- '<p>Kids: ',
- '<tpl for="kids">',
- '<tpl if="age &gt; 1">', // <-- Note that the > is encoded
- '<p>{#}: {name}</p>', // <-- Auto-number each item
- '<p>In 5 Years: {age+5}</p>', // <-- Basic math
- '<p>Dad: {parent.name}</p>',
- '</tpl>',
- '</tpl></p>'
-);
-tpl.overwrite(panel.body, data);
-</code></pre>
- * <p><b>Auto-rendering of flat arrays</b> <br/>Flat arrays that contain values (and not objects) can be auto-rendered
- * using the special <tt>{.}</tt> variable inside a loop. This variable will represent the value of
- * the array at the current index:</p>
- * <pre><code>
-var tpl = new Ext.XTemplate(
- '<p>{name}\'s favorite beverages:</p>',
- '<tpl for="drinks">',
- '<div> - {.}</div>',
- '</tpl>'
-);
-tpl.overwrite(panel.body, data);
-</code></pre>
- * <p><b>Basic conditional logic</b> <br/>Using the <tt>tpl</tt> tag and the <tt>if</tt>
- * operator you can provide conditional checks for deciding whether or not to render specific parts of the template.
- * Note that there is no <tt>else</tt> operator — if needed, you should use two opposite <tt>if</tt> statements.
- * Properly-encoded attributes are required as seen in the following example:</p>
- * <pre><code>
-var tpl = new Ext.XTemplate(
- '<p>Name: {name}</p>',
- '<p>Kids: ',
- '<tpl for="kids">',
- '<tpl if="age &gt; 1">', // <-- Note that the > is encoded
- '<p>{name}</p>',
- '</tpl>',
- '</tpl></p>'
-);
-tpl.overwrite(panel.body, data);
-</code></pre>
- * <p><b>Ability to execute arbitrary inline code</b> <br/>In an XTemplate, anything between {[ ... ]} is considered
- * code to be executed in the scope of the template. There are some special variables available in that code:
- * <ul>
- * <li><b><tt>values</tt></b>: The values in the current scope. If you are using scope changing sub-templates, you
- * can change what <tt>values</tt> is.</li>
- * <li><b><tt>parent</tt></b>: The scope (values) of the ancestor template.</li>
- * <li><b><tt>xindex</tt></b>: If you are in a looping template, the index of the loop you are in (1-based).</li>
- * <li><b><tt>xcount</tt></b>: If you are in a looping template, the total length of the array you are looping.</li>
- * <li><b><tt>fm</tt></b>: An alias for <tt>Ext.util.Format</tt>.</li>
- * </ul>
- * This example demonstrates basic row striping using an inline code block and the <tt>xindex</tt> variable:</p>
- * <pre><code>
-var tpl = new Ext.XTemplate(
- '<p>Name: {name}</p>',
- '<p>Company: {[values.company.toUpperCase() + ", " + values.title]}</p>',
- '<p>Kids: ',
- '<tpl for="kids">',
- '<div class="{[xindex % 2 === 0 ? "even" : "odd"]}">',
- '{name}',
- '</div>',
- '</tpl></p>'
-);
-tpl.overwrite(panel.body, data);
-</code></pre>
- * <p><b>Template member functions</b> <br/>One or more member functions can be defined directly on the config
- * object passed into the XTemplate constructor for more complex processing:</p>
- * <pre><code>
-var tpl = new Ext.XTemplate(
- '<p>Name: {name}</p>',
- '<p>Kids: ',
- '<tpl for="kids">',
- '<tpl if="this.isGirl(name)">',
- '<p>Girl: {name} - {age}</p>',
- '</tpl>',
- '<tpl if="this.isGirl(name) == false">',
- '<p>Boy: {name} - {age}</p>',
- '</tpl>',
- '<tpl if="this.isBaby(age)">',
- '<p>{name} is a baby!</p>',
- '</tpl>',
- '</tpl></p>', {
- isGirl: function(name){
- return name == 'Sara Grace';
- },
- isBaby: function(age){
- return age < 1;
- }
-});
-tpl.overwrite(panel.body, data);
-</code></pre>
- * @constructor
- * @param {String/Array/Object} parts The HTML fragment or an array of fragments to join(""), or multiple arguments
- * to join("") that can also include a config object
- */
-Ext.XTemplate = function(){
- Ext.XTemplate.superclass.constructor.apply(this, arguments);
-
- var me = this,
- s = me.html,
- re = /<tpl\b[^>]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/,
- nameRe = /^<tpl\b[^>]*?for="(.*?)"/,
- ifRe = /^<tpl\b[^>]*?if="(.*?)"/,
- execRe = /^<tpl\b[^>]*?exec="(.*?)"/,
- m,
- id = 0,
- tpls = [],
- VALUES = 'values',
- PARENT = 'parent',
- XINDEX = 'xindex',
- XCOUNT = 'xcount',
- RETURN = 'return ',
- WITHVALUES = 'with(values){ ';
-
- s = ['<tpl>', s, '</tpl>'].join('');
-
- while((m = s.match(re))){
- var m2 = m[0].match(nameRe),
- m3 = m[0].match(ifRe),
- m4 = m[0].match(execRe),
- exp = null,
- fn = null,
- exec = null,
- name = m2 && m2[1] ? m2[1] : '';
-
- if (m3) {
- exp = m3 && m3[1] ? m3[1] : null;
- if(exp){
- fn = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + RETURN +(Ext.util.Format.htmlDecode(exp))+'; }');
- }
- }
- if (m4) {
- exp = m4 && m4[1] ? m4[1] : null;
- if(exp){
- exec = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES +(Ext.util.Format.htmlDecode(exp))+'; }');
- }
- }
- if(name){
- switch(name){
- case '.': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + VALUES + '; }'); break;
- case '..': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + PARENT + '; }'); break;
- default: name = new Function(VALUES, PARENT, WITHVALUES + RETURN + name + '; }');
- }
- }
- tpls.push({
- id: id,
- target: name,
- exec: exec,
- test: fn,
- body: m[1]||''
- });
- s = s.replace(m[0], '{xtpl'+ id + '}');
- ++id;
- }
- Ext.each(tpls, function(t) {
- me.compileTpl(t);
- });
- me.master = tpls[tpls.length-1];
- me.tpls = tpls;
-};
-Ext.extend(Ext.XTemplate, Ext.Template, {
- // private
- re : /\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\\]\s?[\d\.\+\-\*\\\(\)]+)?\}/g,
- // private
- codeRe : /\{\[((?:\\\]|.|\n)*?)\]\}/g,
-
- // private
- applySubTemplate : function(id, values, parent, xindex, xcount){
- var me = this,
- len,
- t = me.tpls[id],
- vs,
- buf = [];
- if ((t.test && !t.test.call(me, values, parent, xindex, xcount)) ||
- (t.exec && t.exec.call(me, values, parent, xindex, xcount))) {
- return '';
- }
- vs = t.target ? t.target.call(me, values, parent) : values;
- len = vs.length;
- parent = t.target ? values : parent;
- if(t.target && Ext.isArray(vs)){
- Ext.each(vs, function(v, i) {
- buf[buf.length] = t.compiled.call(me, v, parent, i+1, len);
- });
- return buf.join('');
- }
- return t.compiled.call(me, vs, parent, xindex, xcount);
- },
-
- // private
- compileTpl : function(tpl){
- var fm = Ext.util.Format,
- useF = this.disableFormats !== true,
- sep = Ext.isGecko ? "+" : ",",
- body;
-
- function fn(m, name, format, args, math){
- if(name.substr(0, 4) == 'xtpl'){
- return "'"+ sep +'this.applySubTemplate('+name.substr(4)+', values, parent, xindex, xcount)'+sep+"'";
- }
- var v;
- if(name === '.'){
- v = 'values';
- }else if(name === '#'){
- v = 'xindex';
- }else if(name.indexOf('.') != -1){
- v = name;
- }else{
- v = "values['" + name + "']";
- }
- if(math){
- v = '(' + v + math + ')';
- }
- if (format && useF) {
- args = args ? ',' + args : "";
- if(format.substr(0, 5) != "this."){
- format = "fm." + format + '(';
- }else{
- format = 'this.call("'+ format.substr(5) + '", ';
- args = ", values";
- }
- } else {
- args= ''; format = "("+v+" === undefined ? '' : ";
- }
- return "'"+ sep + format + v + args + ")"+sep+"'";
- }
-
- function codeFn(m, code){
- return "'"+ sep +'('+code+')'+sep+"'";
- }
-
- // branched to use + in gecko and [].join() in others
- if(Ext.isGecko){
- body = "tpl.compiled = function(values, parent, xindex, xcount){ return '" +
- tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn) +
- "';};";
- }else{
- body = ["tpl.compiled = function(values, parent, xindex, xcount){ return ['"];
- body.push(tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn));
- body.push("'].join('');};");
- body = body.join('');
- }
- eval(body);
- return this;
- },
-
- /**
- * Returns an HTML fragment of this template with the specified values applied.
- * @param {Object} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
- * @return {String} The HTML fragment
- */
- applyTemplate : function(values){
- return this.master.compiled.call(this, values, {}, 1, 1);
- },
-
- /**
- * Compile the template to a function for optimized performance. Recommended if the template will be used frequently.
- * @return {Function} The compiled function
- */
- compile : function(){return this;}
-
- /**
- * @property re
- * @hide
- */
- /**
- * @property disableFormats
- * @hide
- */
- /**
- * @method set
- * @hide
- */
-
-});
-/**
- * Alias for {@link #applyTemplate}
- * Returns an HTML fragment of this template with the specified values applied.
- * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
- * @return {String} The HTML fragment
- * @member Ext.XTemplate
- * @method apply
- */
-Ext.XTemplate.prototype.apply = Ext.XTemplate.prototype.applyTemplate;
-
-/**
- * Creates a template from the passed element's value (<i>display:none</i> textarea, preferred) or innerHTML.
- * @param {String/HTMLElement} el A DOM element or its id
- * @return {Ext.Template} The created template
- * @static
- */
-Ext.XTemplate.from = function(el){
- el = Ext.getDom(el);
- return new Ext.XTemplate(el.value || el.innerHTML);
-};/**\r
- * @class Ext.util.CSS\r
- * Utility class for manipulating CSS rules\r
- * @singleton\r
- */\r
-Ext.util.CSS = function(){\r
- var rules = null;\r
- var doc = document;\r
-\r
- var camelRe = /(-[a-z])/gi;\r
- var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };\r
-\r
- return {\r
- /**\r
- * Creates a stylesheet from a text blob of rules.\r
- * These rules will be wrapped in a STYLE tag and appended to the HEAD of the document.\r
- * @param {String} cssText The text containing the css rules\r
- * @param {String} id An id to add to the stylesheet for later removal\r
- * @return {StyleSheet}\r
- */\r
- createStyleSheet : function(cssText, id){\r
- var ss;\r
- var head = doc.getElementsByTagName("head")[0];\r
- var rules = doc.createElement("style");\r
- rules.setAttribute("type", "text/css");\r
- if(id){\r
- rules.setAttribute("id", id);\r
- }\r
- if(Ext.isIE){\r
- head.appendChild(rules);\r
- ss = rules.styleSheet;\r
- ss.cssText = cssText;\r
- }else{\r
- try{\r
- rules.appendChild(doc.createTextNode(cssText));\r
- }catch(e){\r
- rules.cssText = cssText;\r
- }\r
- head.appendChild(rules);\r
- ss = rules.styleSheet ? rules.styleSheet : (rules.sheet || doc.styleSheets[doc.styleSheets.length-1]);\r
- }\r
- this.cacheStyleSheet(ss);\r
- return ss;\r
- },\r
-\r
- /**\r
- * Removes a style or link tag by id\r
- * @param {String} id The id of the tag\r
- */\r
- removeStyleSheet : function(id){\r
- var existing = doc.getElementById(id);\r
- if(existing){\r
- existing.parentNode.removeChild(existing);\r
- }\r
- },\r
-\r
- /**\r
- * Dynamically swaps an existing stylesheet reference for a new one\r
- * @param {String} id The id of an existing link tag to remove\r
- * @param {String} url The href of the new stylesheet to include\r
- */\r
- swapStyleSheet : function(id, url){\r
- this.removeStyleSheet(id);\r
- var ss = doc.createElement("link");\r
- ss.setAttribute("rel", "stylesheet");\r
- ss.setAttribute("type", "text/css");\r
- ss.setAttribute("id", id);\r
- ss.setAttribute("href", url);\r
- doc.getElementsByTagName("head")[0].appendChild(ss);\r
- },\r
- \r
- /**\r
- * Refresh the rule cache if you have dynamically added stylesheets\r
- * @return {Object} An object (hash) of rules indexed by selector\r
- */\r
- refreshCache : function(){\r
- return this.getRules(true);\r
- },\r
-\r
- // private\r
- cacheStyleSheet : function(ss){\r
- if(!rules){\r
- rules = {};\r
- }\r
- try{// try catch for cross domain access issue\r
- var ssRules = ss.cssRules || ss.rules;\r
- for(var j = ssRules.length-1; j >= 0; --j){\r
- rules[ssRules[j].selectorText] = ssRules[j];\r
- }\r
- }catch(e){}\r
- },\r
- \r
- /**\r
- * Gets all css rules for the document\r
- * @param {Boolean} refreshCache true to refresh the internal cache\r
- * @return {Object} An object (hash) of rules indexed by selector\r
- */\r
- getRules : function(refreshCache){\r
- if(rules === null || refreshCache){\r
- rules = {};\r
- var ds = doc.styleSheets;\r
- for(var i =0, len = ds.length; i < len; i++){\r
- try{\r
- this.cacheStyleSheet(ds[i]);\r
- }catch(e){} \r
- }\r
- }\r
- return rules;\r
- },\r
- \r
- /**\r
- * Gets an an individual CSS rule by selector(s)\r
- * @param {String/Array} selector The CSS selector or an array of selectors to try. The first selector that is found is returned.\r
- * @param {Boolean} refreshCache true to refresh the internal cache if you have recently updated any rules or added styles dynamically\r
- * @return {CSSRule} The CSS rule or null if one is not found\r
- */\r
- getRule : function(selector, refreshCache){\r
- var rs = this.getRules(refreshCache);\r
- if(!Ext.isArray(selector)){\r
- return rs[selector];\r
- }\r
- for(var i = 0; i < selector.length; i++){\r
- if(rs[selector[i]]){\r
- return rs[selector[i]];\r
- }\r
- }\r
- return null;\r
- },\r
- \r
- \r
- /**\r
- * Updates a rule property\r
- * @param {String/Array} selector If it's an array it tries each selector until it finds one. Stops immediately once one is found.\r
- * @param {String} property The css property\r
- * @param {String} value The new value for the property\r
- * @return {Boolean} true If a rule was found and updated\r
- */\r
- updateRule : function(selector, property, value){\r
- if(!Ext.isArray(selector)){\r
- var rule = this.getRule(selector);\r
- if(rule){\r
- rule.style[property.replace(camelRe, camelFn)] = value;\r
- return true;\r
- }\r
- }else{\r
- for(var i = 0; i < selector.length; i++){\r
- if(this.updateRule(selector[i], property, value)){\r
- return true;\r
- }\r
- }\r
- }\r
- return false;\r
- }\r
- }; \r
-}();/**
- @class Ext.util.ClickRepeater
- @extends Ext.util.Observable
-
- A wrapper class which can be applied to any element. Fires a "click" event while the
- mouse is pressed. The interval between firings may be specified in the config but
- defaults to 20 milliseconds.
-
- Optionally, a CSS class may be applied to the element during the time it is pressed.
-
- @cfg {Mixed} el The element to act as a button.
- @cfg {Number} delay The initial delay before the repeating event begins firing.
- Similar to an autorepeat key delay.
- @cfg {Number} interval The interval between firings of the "click" event. Default 20 ms.
- @cfg {String} pressClass A CSS class name to be applied to the element while pressed.
- @cfg {Boolean} accelerate True if autorepeating should start slowly and accelerate.
- "interval" and "delay" are ignored.
- @cfg {Boolean} preventDefault True to prevent the default click event
- @cfg {Boolean} stopDefault True to stop the default click event
-
- @history
- 2007-02-02 jvs Original code contributed by Nige "Animal" White
- 2007-02-02 jvs Renamed to ClickRepeater
- 2007-02-03 jvs Modifications for FF Mac and Safari
-
- @constructor
- @param {Mixed} el The element to listen on
- @param {Object} config
- */
-Ext.util.ClickRepeater = function(el, config)
-{
- this.el = Ext.get(el);
- this.el.unselectable();
-
- Ext.apply(this, config);
-
- this.addEvents(
- /**
- * @event mousedown
- * Fires when the mouse button is depressed.
- * @param {Ext.util.ClickRepeater} this
- */
- "mousedown",
- /**
- * @event click
- * Fires on a specified interval during the time the element is pressed.
- * @param {Ext.util.ClickRepeater} this
- */
- "click",
- /**
- * @event mouseup
- * Fires when the mouse key is released.
- * @param {Ext.util.ClickRepeater} this
- */
- "mouseup"
- );
-
- if(!this.disabled){
- this.disabled = true;
- this.enable();
- }
-
- // allow inline handler
- if(this.handler){
- this.on("click", this.handler, this.scope || this);
- }
-
- Ext.util.ClickRepeater.superclass.constructor.call(this);
-};
-
-Ext.extend(Ext.util.ClickRepeater, Ext.util.Observable, {
- interval : 20,
- delay: 250,
- preventDefault : true,
- stopDefault : false,
- timer : 0,
-
- /**
- * Enables the repeater and allows events to fire.
- */
- enable: function(){
- if(this.disabled){
- this.el.on('mousedown', this.handleMouseDown, this);
- if(this.preventDefault || this.stopDefault){
- this.el.on('click', this.eventOptions, this);
- }
- }
- this.disabled = false;
- },
-
- /**
- * Disables the repeater and stops events from firing.
- */
- disable: function(/* private */ force){
- if(force || !this.disabled){
- clearTimeout(this.timer);
- if(this.pressClass){
- this.el.removeClass(this.pressClass);
- }
- Ext.getDoc().un('mouseup', this.handleMouseUp, this);
- this.el.removeAllListeners();
- }
- this.disabled = true;
- },
-
- /**
- * Convenience function for setting disabled/enabled by boolean.
- * @param {Boolean} disabled
- */
- setDisabled: function(disabled){
- this[disabled ? 'disable' : 'enable']();
- },
-
- eventOptions: function(e){
- if(this.preventDefault){
- e.preventDefault();
- }
- if(this.stopDefault){
- e.stopEvent();
- }
- },
-
- // private
- destroy : function() {
- this.disable(true);
- Ext.destroy(this.el);
- this.purgeListeners();
- },
-
- // private
- handleMouseDown : function(){
- clearTimeout(this.timer);
- this.el.blur();
- if(this.pressClass){
- this.el.addClass(this.pressClass);
- }
- this.mousedownTime = new Date();
-
- Ext.getDoc().on("mouseup", this.handleMouseUp, this);
- this.el.on("mouseout", this.handleMouseOut, this);
-
- this.fireEvent("mousedown", this);
- this.fireEvent("click", this);
-
-// Do not honor delay or interval if acceleration wanted.
- if (this.accelerate) {
- this.delay = 400;
- }
- this.timer = this.click.defer(this.delay || this.interval, this);
- },
-
- // private
- click : function(){
- this.fireEvent("click", this);
- this.timer = this.click.defer(this.accelerate ?
- this.easeOutExpo(this.mousedownTime.getElapsed(),
- 400,
- -390,
- 12000) :
- this.interval, this);
- },
-
- easeOutExpo : function (t, b, c, d) {
- return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
- },
-
- // private
- handleMouseOut : function(){
- clearTimeout(this.timer);
- if(this.pressClass){
- this.el.removeClass(this.pressClass);
- }
- this.el.on("mouseover", this.handleMouseReturn, this);
- },
-
- // private
- handleMouseReturn : function(){
- this.el.un("mouseover", this.handleMouseReturn, this);
- if(this.pressClass){
- this.el.addClass(this.pressClass);
- }
- this.click();
- },
-
- // private
- handleMouseUp : function(){
- clearTimeout(this.timer);
- this.el.un("mouseover", this.handleMouseReturn, this);
- this.el.un("mouseout", this.handleMouseOut, this);
- Ext.getDoc().un("mouseup", this.handleMouseUp, this);
- this.el.removeClass(this.pressClass);
- this.fireEvent("mouseup", this);
- }
-});/**
- * @class Ext.KeyNav
- * <p>Provides a convenient wrapper for normalized keyboard navigation. KeyNav allows you to bind
- * navigation keys to function calls that will get called when the keys are pressed, providing an easy
- * way to implement custom navigation schemes for any UI component.</p>
- * <p>The following are all of the possible keys that can be implemented: enter, left, right, up, down, tab, esc,
- * pageUp, pageDown, del, home, end. Usage:</p>
- <pre><code>
-var nav = new Ext.KeyNav("my-element", {
- "left" : function(e){
- this.moveLeft(e.ctrlKey);
- },
- "right" : function(e){
- this.moveRight(e.ctrlKey);
- },
- "enter" : function(e){
- this.save();
- },
- scope : this
-});
-</code></pre>
- * @constructor
- * @param {Mixed} el The element to bind to
- * @param {Object} config The config
- */
-Ext.KeyNav = function(el, config){
- this.el = Ext.get(el);
- Ext.apply(this, config);
- if(!this.disabled){
- this.disabled = true;
- this.enable();
- }
-};
-
-Ext.KeyNav.prototype = {
- /**
- * @cfg {Boolean} disabled
- * True to disable this KeyNav instance (defaults to false)
- */
- disabled : false,
- /**
- * @cfg {String} defaultEventAction
- * The method to call on the {@link Ext.EventObject} after this KeyNav intercepts a key. Valid values are
- * {@link Ext.EventObject#stopEvent}, {@link Ext.EventObject#preventDefault} and
- * {@link Ext.EventObject#stopPropagation} (defaults to 'stopEvent')
- */
- defaultEventAction: "stopEvent",
- /**
- * @cfg {Boolean} forceKeyDown
- * Handle the keydown event instead of keypress (defaults to false). KeyNav automatically does this for IE since
- * IE does not propagate special keys on keypress, but setting this to true will force other browsers to also
- * handle keydown instead of keypress.
- */
- forceKeyDown : false,
-
- // private
- prepareEvent : function(e){
- var k = e.getKey();
- var h = this.keyToHandler[k];
- if(Ext.isSafari2 && h && k >= 37 && k <= 40){
- e.stopEvent();
- }
- },
-
- // private
- relay : function(e){
- var k = e.getKey();
- var h = this.keyToHandler[k];
- if(h && this[h]){
- if(this.doRelay(e, this[h], h) !== true){
- e[this.defaultEventAction]();
- }
- }
- },
-
- // private
- doRelay : function(e, h, hname){
- return h.call(this.scope || this, e);
- },
-
- // possible handlers
- enter : false,
- left : false,
- right : false,
- up : false,
- down : false,
- tab : false,
- esc : false,
- pageUp : false,
- pageDown : false,
- del : false,
- home : false,
- end : false,
-
- // quick lookup hash
- keyToHandler : {
- 37 : "left",
- 39 : "right",
- 38 : "up",
- 40 : "down",
- 33 : "pageUp",
- 34 : "pageDown",
- 46 : "del",
- 36 : "home",
- 35 : "end",
- 13 : "enter",
- 27 : "esc",
- 9 : "tab"
- },
-
- /**
- * Enable this KeyNav
- */
- enable: function(){
- if(this.disabled){
- // ie won't do special keys on keypress, no one else will repeat keys with keydown
- // the EventObject will normalize Safari automatically
- if(this.isKeydown()){
- this.el.on("keydown", this.relay, this);
- }else{
- this.el.on("keydown", this.prepareEvent, this);
- this.el.on("keypress", this.relay, this);
- }
- this.disabled = false;
- }
- },
-
- /**
- * Disable this KeyNav
- */
- disable: function(){
- if(!this.disabled){
- if(this.isKeydown()){
- this.el.un("keydown", this.relay, this);
- }else{
- this.el.un("keydown", this.prepareEvent, this);
- this.el.un("keypress", this.relay, this);
- }
- this.disabled = true;
- }
- },
-
- /**
- * Convenience function for setting disabled/enabled by boolean.
- * @param {Boolean} disabled
- */
- setDisabled : function(disabled){
- this[disabled ? "disable" : "enable"]();
- },
-
- // private
- isKeydown: function(){
- return this.forceKeyDown || Ext.EventManager.useKeydown;
- }
-};
-/**\r
- * @class Ext.KeyMap\r
- * Handles mapping keys to actions for an element. One key map can be used for multiple actions.\r
- * The constructor accepts the same config object as defined by {@link #addBinding}.\r
- * If you bind a callback function to a KeyMap, anytime the KeyMap handles an expected key\r
- * combination it will call the function with this signature (if the match is a multi-key\r
- * combination the callback will still be called only once): (String key, Ext.EventObject e)\r
- * A KeyMap can also handle a string representation of keys.<br />\r
- * Usage:\r
- <pre><code>\r
-// map one key by key code\r
-var map = new Ext.KeyMap("my-element", {\r
- key: 13, // or Ext.EventObject.ENTER\r
- fn: myHandler,\r
- scope: myObject\r
-});\r
-\r
-// map multiple keys to one action by string\r
-var map = new Ext.KeyMap("my-element", {\r
- key: "a\r\n\t",\r
- fn: myHandler,\r
- scope: myObject\r
-});\r
-\r
-// map multiple keys to multiple actions by strings and array of codes\r
-var map = new Ext.KeyMap("my-element", [\r
- {\r
- key: [10,13],\r
- fn: function(){ alert("Return was pressed"); }\r
- }, {\r
- key: "abc",\r
- fn: function(){ alert('a, b or c was pressed'); }\r
- }, {\r
- key: "\t",\r
- ctrl:true,\r
- shift:true,\r
- fn: function(){ alert('Control + shift + tab was pressed.'); }\r
- }\r
-]);\r
-</code></pre>\r
- * <b>Note: A KeyMap starts enabled</b>\r
- * @constructor\r
- * @param {Mixed} el The element to bind to\r
- * @param {Object} config The config (see {@link #addBinding})\r
- * @param {String} eventName (optional) The event to bind to (defaults to "keydown")\r
- */\r
-Ext.KeyMap = function(el, config, eventName){\r
- this.el = Ext.get(el);\r
- this.eventName = eventName || "keydown";\r
- this.bindings = [];\r
- if(config){\r
- this.addBinding(config);\r
- }\r
- this.enable();\r
-};\r
-\r
-Ext.KeyMap.prototype = {\r
- /**\r
- * True to stop the event from bubbling and prevent the default browser action if the\r
- * key was handled by the KeyMap (defaults to false)\r
- * @type Boolean\r
- */\r
- stopEvent : false,\r
-\r
- /**\r
- * Add a new binding to this KeyMap. The following config object properties are supported:\r
- * <pre>\r
-Property Type Description\r
----------- --------------- ----------------------------------------------------------------------\r
-key String/Array A single keycode or an array of keycodes to handle\r
-shift Boolean True to handle key only when shift is pressed, False to handle the key only when shift is not pressed (defaults to undefined)\r
-ctrl Boolean True to handle key only when ctrl is pressed, False to handle the key only when ctrl is not pressed (defaults to undefined)\r
-alt Boolean True to handle key only when alt is pressed, False to handle the key only when alt is not pressed (defaults to undefined)\r
-handler Function The function to call when KeyMap finds the expected key combination\r
-fn Function Alias of handler (for backwards-compatibility)\r
-scope Object The scope of the callback function\r
-stopEvent Boolean True to stop the event from bubbling and prevent the default browser action if the key was handled by the KeyMap (defaults to false)\r
-</pre>\r
- *\r
- * Usage:\r
- * <pre><code>\r
-// Create a KeyMap\r
-var map = new Ext.KeyMap(document, {\r
- key: Ext.EventObject.ENTER,\r
- fn: handleKey,\r
- scope: this\r
-});\r
-\r
-//Add a new binding to the existing KeyMap later\r
-map.addBinding({\r
- key: 'abc',\r
- shift: true,\r
- fn: handleKey,\r
- scope: this\r
-});\r
-</code></pre>\r
- * @param {Object/Array} config A single KeyMap config or an array of configs\r
- */\r
- addBinding : function(config){\r
- if(Ext.isArray(config)){\r
- Ext.each(config, function(c){\r
- this.addBinding(c);\r
- }, this);\r
- return;\r
- }\r
- var keyCode = config.key,\r
- fn = config.fn || config.handler,\r
- scope = config.scope;\r
-\r
- if (config.stopEvent) {\r
- this.stopEvent = config.stopEvent; \r
- } \r
-\r
- if(typeof keyCode == "string"){\r
- var ks = [];\r
- var keyString = keyCode.toUpperCase();\r
- for(var j = 0, len = keyString.length; j < len; j++){\r
- ks.push(keyString.charCodeAt(j));\r
- }\r
- keyCode = ks;\r
- }\r
- var keyArray = Ext.isArray(keyCode);\r
- \r
- var handler = function(e){\r
- if(this.checkModifiers(config, e)){\r
- var k = e.getKey();\r
- if(keyArray){\r
- for(var i = 0, len = keyCode.length; i < len; i++){\r
- if(keyCode[i] == k){\r
- if(this.stopEvent){\r
- e.stopEvent();\r
- }\r
- fn.call(scope || window, k, e);\r
- return;\r
- }\r
- }\r
- }else{\r
- if(k == keyCode){\r
- if(this.stopEvent){\r
- e.stopEvent();\r
- }\r
- fn.call(scope || window, k, e);\r
- }\r
- }\r
- }\r
- };\r
- this.bindings.push(handler);\r
- },\r
- \r
- // private\r
- checkModifiers: function(config, e){\r
- var val, key, keys = ['shift', 'ctrl', 'alt'];\r
- for (var i = 0, len = keys.length; i < len; ++i){\r
- key = keys[i];\r
- val = config[key];\r
- if(!(val === undefined || (val === e[key + 'Key']))){\r
- return false;\r
- }\r
- }\r
- return true;\r
- },\r
-\r
- /**\r
- * Shorthand for adding a single key listener\r
- * @param {Number/Array/Object} key Either the numeric key code, array of key codes or an object with the\r
- * following options:\r
- * {key: (number or array), shift: (true/false), ctrl: (true/false), alt: (true/false)}\r
- * @param {Function} fn The function to call\r
- * @param {Object} scope (optional) The scope of the function\r
- */\r
- on : function(key, fn, scope){\r
- var keyCode, shift, ctrl, alt;\r
- if(typeof key == "object" && !Ext.isArray(key)){\r
- keyCode = key.key;\r
- shift = key.shift;\r
- ctrl = key.ctrl;\r
- alt = key.alt;\r
- }else{\r
- keyCode = key;\r
- }\r
- this.addBinding({\r
- key: keyCode,\r
- shift: shift,\r
- ctrl: ctrl,\r
- alt: alt,\r
- fn: fn,\r
- scope: scope\r
- });\r
- },\r
-\r
- // private\r
- handleKeyDown : function(e){\r
- if(this.enabled){ //just in case\r
- var b = this.bindings;\r
- for(var i = 0, len = b.length; i < len; i++){\r
- b[i].call(this, e);\r
- }\r
- }\r
- },\r
-\r
- /**\r
- * Returns true if this KeyMap is enabled\r
- * @return {Boolean}\r
- */\r
- isEnabled : function(){\r
- return this.enabled;\r
- },\r
-\r
- /**\r
- * Enables this KeyMap\r
- */\r
- enable: function(){\r
- if(!this.enabled){\r
- this.el.on(this.eventName, this.handleKeyDown, this);\r
- this.enabled = true;\r
- }\r
- },\r
-\r
- /**\r
- * Disable this KeyMap\r
- */\r
- disable: function(){\r
- if(this.enabled){\r
- this.el.removeListener(this.eventName, this.handleKeyDown, this);\r
- this.enabled = false;\r
- }\r
- },\r
- \r
- /**\r
- * Convenience function for setting disabled/enabled by boolean.\r
- * @param {Boolean} disabled\r
- */\r
- setDisabled : function(disabled){\r
- this[disabled ? "disable" : "enable"]();\r
- }\r
-};/**
- * @class Ext.util.TextMetrics
- * Provides precise pixel measurements for blocks of text so that you can determine exactly how high and
- * wide, in pixels, a given block of text will be. Note that when measuring text, it should be plain text and
- * should not contain any HTML, otherwise it may not be measured correctly.
- * @singleton
- */
-Ext.util.TextMetrics = function(){
- var shared;
- return {
- /**
- * Measures the size of the specified text
- * @param {String/HTMLElement} el The element, dom node or id from which to copy existing CSS styles
- * that can affect the size of the rendered text
- * @param {String} text The text to measure
- * @param {Number} fixedWidth (optional) If the text will be multiline, you have to set a fixed width
- * in order to accurately measure the text height
- * @return {Object} An object containing the text's size {width: (width), height: (height)}
- */
- measure : function(el, text, fixedWidth){
- if(!shared){
- shared = Ext.util.TextMetrics.Instance(el, fixedWidth);
- }
- shared.bind(el);
- shared.setFixedWidth(fixedWidth || 'auto');
- return shared.getSize(text);
- },
-
- /**
- * Return a unique TextMetrics instance that can be bound directly to an element and reused. This reduces
- * the overhead of multiple calls to initialize the style properties on each measurement.
- * @param {String/HTMLElement} el The element, dom node or id that the instance will be bound to
- * @param {Number} fixedWidth (optional) If the text will be multiline, you have to set a fixed width
- * in order to accurately measure the text height
- * @return {Ext.util.TextMetrics.Instance} instance The new instance
- */
- createInstance : function(el, fixedWidth){
- return Ext.util.TextMetrics.Instance(el, fixedWidth);
- }
- };
-}();
-
-Ext.util.TextMetrics.Instance = function(bindTo, fixedWidth){
- var ml = new Ext.Element(document.createElement('div'));
- document.body.appendChild(ml.dom);
- ml.position('absolute');
- ml.setLeftTop(-1000, -1000);
- ml.hide();
-
- if(fixedWidth){
- ml.setWidth(fixedWidth);
- }
-
- var instance = {
- /**
- * Returns the size of the specified text based on the internal element's style and width properties
- * @param {String} text The text to measure
- * @return {Object} An object containing the text's size {width: (width), height: (height)}
- */
- getSize : function(text){
- ml.update(text);
- var s = ml.getSize();
- ml.update('');
- return s;
- },
-
- /**
- * Binds this TextMetrics instance to an element from which to copy existing CSS styles
- * that can affect the size of the rendered text
- * @param {String/HTMLElement} el The element, dom node or id
- */
- bind : function(el){
- ml.setStyle(
- Ext.fly(el).getStyles('font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing')
- );
- },
-
- /**
- * Sets a fixed width on the internal measurement element. If the text will be multiline, you have
- * to set a fixed width in order to accurately measure the text height.
- * @param {Number} width The width to set on the element
- */
- setFixedWidth : function(width){
- ml.setWidth(width);
- },
-
- /**
- * Returns the measured width of the specified text
- * @param {String} text The text to measure
- * @return {Number} width The width in pixels
- */
- getWidth : function(text){
- ml.dom.style.width = 'auto';
- return this.getSize(text).width;
- },
-
- /**
- * Returns the measured height of the specified text. For multiline text, be sure to call
- * {@link #setFixedWidth} if necessary.
- * @param {String} text The text to measure
- * @return {Number} height The height in pixels
- */
- getHeight : function(text){
- return this.getSize(text).height;
- }
- };
-
- instance.bind(bindTo);
-
- return instance;
-};
-
-Ext.Element.addMethods({
- /**
- * Returns the width in pixels of the passed text, or the width of the text in this Element.
- * @param {String} text The text to measure. Defaults to the innerHTML of the element.
- * @param {Number} min (Optional) The minumum value to return.
- * @param {Number} max (Optional) The maximum value to return.
- * @return {Number} The text width in pixels.
- * @member Ext.Element getTextWidth
- */
- getTextWidth : function(text, min, max){
- return (Ext.util.TextMetrics.measure(this.dom, Ext.value(text, this.dom.innerHTML, true)).width).constrain(min || 0, max || 1000000);
- }
-});
-/**\r
- * @class Ext.util.Cookies\r
- * Utility class for managing and interacting with cookies.\r
- * @singleton\r
- */\r
-Ext.util.Cookies = {\r
- /**\r
- * Create a cookie with the specified name and value. Additional settings\r
- * for the cookie may be optionally specified (for example: expiration,\r
- * access restriction, SSL).\r
- * @param {Object} name\r
- * @param {Object} value\r
- * @param {Object} expires (Optional) Specify an expiration date the\r
- * cookie is to persist until. Note that the specified Date object will\r
- * be converted to Greenwich Mean Time (GMT). \r
- * @param {String} path (Optional) Setting a path on the cookie restricts\r
- * access to pages that match that path. Defaults to all pages (<tt>'/'</tt>). \r
- * @param {String} domain (Optional) Setting a domain restricts access to\r
- * pages on a given domain (typically used to allow cookie access across\r
- * subdomains). For example, "extjs.com" will create a cookie that can be\r
- * accessed from any subdomain of extjs.com, including www.extjs.com,\r
- * support.extjs.com, etc.\r
- * @param {Boolean} secure (Optional) Specify true to indicate that the cookie\r
- * should only be accessible via SSL on a page using the HTTPS protocol.\r
- * Defaults to <tt>false</tt>. Note that this will only work if the page\r
- * calling this code uses the HTTPS protocol, otherwise the cookie will be\r
- * created with default options.\r
- */\r
- set : function(name, value){\r
- var argv = arguments;\r
- var argc = arguments.length;\r
- var expires = (argc > 2) ? argv[2] : null;\r
- var path = (argc > 3) ? argv[3] : '/';\r
- var domain = (argc > 4) ? argv[4] : null;\r
- var secure = (argc > 5) ? argv[5] : false;\r
- document.cookie = name + "=" + escape(value) + ((expires === null) ? "" : ("; expires=" + expires.toGMTString())) + ((path === null) ? "" : ("; path=" + path)) + ((domain === null) ? "" : ("; domain=" + domain)) + ((secure === true) ? "; secure" : "");\r
- },\r
-\r
- /**\r
- * Retrieves cookies that are accessible by the current page. If a cookie\r
- * does not exist, <code>get()</code> returns <tt>null</tt>. The following\r
- * example retrieves the cookie called "valid" and stores the String value\r
- * in the variable <tt>validStatus</tt>.\r
- * <pre><code>\r
- * var validStatus = Ext.util.Cookies.get("valid");\r
- * </code></pre>\r
- * @param {Object} name The name of the cookie to get\r
- * @return {Mixed} Returns the cookie value for the specified name;\r
- * null if the cookie name does not exist.\r
- */\r
- get : function(name){\r
- var arg = name + "=";\r
- var alen = arg.length;\r
- var clen = document.cookie.length;\r
- var i = 0;\r
- var j = 0;\r
- while(i < clen){\r
- j = i + alen;\r
- if(document.cookie.substring(i, j) == arg){\r
- return Ext.util.Cookies.getCookieVal(j);\r
- }\r
- i = document.cookie.indexOf(" ", i) + 1;\r
- if(i === 0){\r
- break;\r
- }\r
- }\r
- return null;\r
- },\r
-\r
- /**\r
- * Removes a cookie with the provided name from the browser\r
- * if found.\r
- * @param {Object} name The name of the cookie to remove\r
- */\r
- clear : function(name){\r
- if(Ext.util.Cookies.get(name)){\r
- document.cookie = name + "=" + "; expires=Thu, 01-Jan-70 00:00:01 GMT";\r
- }\r
- },\r
- /**\r
- * @private\r
- */\r
- getCookieVal : function(offset){\r
- var endstr = document.cookie.indexOf(";", offset);\r
- if(endstr == -1){\r
- endstr = document.cookie.length;\r
- }\r
- return unescape(document.cookie.substring(offset, endstr));\r
- }\r
-};/**
- * Framework-wide error-handler. Developers can override this method to provide
- * custom exception-handling. Framework errors will often extend from the base
- * Ext.Error class.
- * @param {Object/Error} e The thrown exception object.
- */
-Ext.handleError = function(e) {
- throw e;
-};
-
-/**
- * @class Ext.Error
- * @extends Error
- * <p>A base error class. Future implementations are intended to provide more
- * robust error handling throughout the framework (<b>in the debug build only</b>)
- * to check for common errors and problems. The messages issued by this class
- * will aid error checking. Error checks will be automatically removed in the
- * production build so that performance is not negatively impacted.</p>
- * <p>Some sample messages currently implemented:</p><pre>
-"DataProxy attempted to execute an API-action but found an undefined
-url / function. Please review your Proxy url/api-configuration."
- * </pre><pre>
-"Could not locate your "root" property in your server response.
-Please review your JsonReader config to ensure the config-property
-"root" matches the property your server-response. See the JsonReader
-docs for additional assistance."
- * </pre>
- * <p>An example of the code used for generating error messages:</p><pre><code>
-try {
- generateError({
- foo: 'bar'
- });
-}
-catch (e) {
- console.error(e);
-}
-function generateError(data) {
- throw new Ext.Error('foo-error', data);
-}
- * </code></pre>
- * @param {String} message
- */
-Ext.Error = function(message) {
- // Try to read the message from Ext.Error.lang
- this.message = (this.lang[message]) ? this.lang[message] : message;
-}
-Ext.Error.prototype = new Error();
-Ext.apply(Ext.Error.prototype, {
- // protected. Extensions place their error-strings here.
- lang: {},
-
- name: 'Ext.Error',
- /**
- * getName
- * @return {String}
- */
- getName : function() {
- return this.name;
- },
- /**
- * getMessage
- * @return {String}
- */
- getMessage : function() {
- return this.message;
- },
- /**
- * toJson
- * @return {String}
- */
- toJson : function() {
- return Ext.encode(this);
- }
-});
-
-/**
- * @class Ext.ComponentMgr
- * <p>Provides a registry of all Components (instances of {@link Ext.Component} or any subclass
- * thereof) on a page so that they can be easily accessed by {@link Ext.Component component}
- * {@link Ext.Component#id id} (see {@link #get}, or the convenience method {@link Ext#getCmp Ext.getCmp}).</p>
- * <p>This object also provides a registry of available Component <i>classes</i>
- * indexed by a mnemonic code known as the Component's {@link Ext.Component#xtype xtype}.
- * The <tt>{@link Ext.Component#xtype xtype}</tt> provides a way to avoid instantiating child Components
- * when creating a full, nested config object for a complete Ext page.</p>
- * <p>A child Component may be specified simply as a <i>config object</i>
- * as long as the correct <tt>{@link Ext.Component#xtype xtype}</tt> is specified so that if and when the Component
- * needs rendering, the correct type can be looked up for lazy instantiation.</p>
- * <p>For a list of all available <tt>{@link Ext.Component#xtype xtypes}</tt>, see {@link Ext.Component}.</p>
- * @singleton
- */
-Ext.ComponentMgr = function(){
- var all = new Ext.util.MixedCollection();
- var types = {};
- var ptypes = {};
-
- return {
- /**
- * Registers a component.
- * @param {Ext.Component} c The component
- */
- register : function(c){
- all.add(c);
- },
-
- /**
- * Unregisters a component.
- * @param {Ext.Component} c The component
- */
- unregister : function(c){
- all.remove(c);
- },
-
- /**
- * Returns a component by {@link Ext.Component#id id}.
- * For additional details see {@link Ext.util.MixedCollection#get}.
- * @param {String} id The component {@link Ext.Component#id id}
- * @return Ext.Component The Component, <tt>undefined</tt> if not found, or <tt>null</tt> if a
- * Class was found.
- */
- get : function(id){
- return all.get(id);
- },
-
- /**
- * Registers a function that will be called when a specified component is added to ComponentMgr
- * @param {String} id The component {@link Ext.Component#id id}
- * @param {Function} fn The callback function
- * @param {Object} scope The scope of the callback
- */
- onAvailable : function(id, fn, scope){
- all.on("add", function(index, o){
- if(o.id == id){
- fn.call(scope || o, o);
- all.un("add", fn, scope);
- }
- });
- },
-
- /**
- * The MixedCollection used internally for the component cache. An example usage may be subscribing to
- * events on the MixedCollection to monitor addition or removal. Read-only.
- * @type {MixedCollection}
- */
- all : all,
-
- /**
- * Checks if a Component type is registered.
- * @param {Ext.Component} xtype The mnemonic string by which the Component class may be looked up
- * @return {Boolean} Whether the type is registered.
- */
- isRegistered : function(xtype){
- return types[xtype] !== undefined;
- },
-
- /**
- * <p>Registers a new Component constructor, keyed by a new
- * {@link Ext.Component#xtype}.</p>
- * <p>Use this method (or its alias {@link Ext#reg Ext.reg}) to register new
- * subclasses of {@link Ext.Component} so that lazy instantiation may be used when specifying
- * child Components.
- * see {@link Ext.Container#items}</p>
- * @param {String} xtype The mnemonic string by which the Component class may be looked up.
- * @param {Constructor} cls The new Component class.
- */
- registerType : function(xtype, cls){
- types[xtype] = cls;
- cls.xtype = xtype;
- },
-
- /**
- * Creates a new Component from the specified config object using the
- * config object's {@link Ext.component#xtype xtype} to determine the class to instantiate.
- * @param {Object} config A configuration object for the Component you wish to create.
- * @param {Constructor} defaultType The constructor to provide the default Component type if
- * the config object does not contain a <tt>xtype</tt>. (Optional if the config contains a <tt>xtype</tt>).
- * @return {Ext.Component} The newly instantiated Component.
- */
- create : function(config, defaultType){
- return config.render ? config : new types[config.xtype || defaultType](config);
- },
-
- /**
- * <p>Registers a new Plugin constructor, keyed by a new
- * {@link Ext.Component#ptype}.</p>
- * <p>Use this method (or its alias {@link Ext#preg Ext.preg}) to register new
- * plugins for {@link Ext.Component}s so that lazy instantiation may be used when specifying
- * Plugins.</p>
- * @param {String} ptype The mnemonic string by which the Plugin class may be looked up.
- * @param {Constructor} cls The new Plugin class.
- */
- registerPlugin : function(ptype, cls){
- ptypes[ptype] = cls;
- cls.ptype = ptype;
- },
-
- /**
- * Creates a new Plugin from the specified config object using the
- * config object's {@link Ext.component#ptype ptype} to determine the class to instantiate.
- * @param {Object} config A configuration object for the Plugin you wish to create.
- * @param {Constructor} defaultType The constructor to provide the default Plugin type if
- * the config object does not contain a <tt>ptype</tt>. (Optional if the config contains a <tt>ptype</tt>).
- * @return {Ext.Component} The newly instantiated Plugin.
- */
- createPlugin : function(config, defaultType){
- return new ptypes[config.ptype || defaultType](config);
- }
- };
-}();
-
-/**
- * Shorthand for {@link Ext.ComponentMgr#registerType}
- * @param {String} xtype The {@link Ext.component#xtype mnemonic string} by which the Component class
- * may be looked up.
- * @param {Constructor} cls The new Component class.
- * @member Ext
- * @method reg
- */
-Ext.reg = Ext.ComponentMgr.registerType; // this will be called a lot internally, shorthand to keep the bytes down
-/**
- * Shorthand for {@link Ext.ComponentMgr#registerPlugin}
- * @param {String} ptype The {@link Ext.component#ptype mnemonic string} by which the Plugin class
- * may be looked up.
- * @param {Constructor} cls The new Plugin class.
- * @member Ext
- * @method preg
- */
-Ext.preg = Ext.ComponentMgr.registerPlugin;
-Ext.create = Ext.ComponentMgr.create;
-/**
- * @class Ext.Component
- * @extends Ext.util.Observable
- * <p>Base class for all Ext components. All subclasses of Component may participate in the automated
- * Ext component lifecycle of creation, rendering and destruction which is provided by the {@link Ext.Container Container} class.
- * Components may be added to a Container through the {@link Ext.Container#items items} config option at the time the Container is created,
- * or they may be added dynamically via the {@link Ext.Container#add add} method.</p>
- * <p>The Component base class has built-in support for basic hide/show and enable/disable behavior.</p>
- * <p>All Components are registered with the {@link Ext.ComponentMgr} on construction so that they can be referenced at any time via
- * {@link Ext#getCmp}, passing the {@link #id}.</p>
- * <p>All user-developed visual widgets that are required to participate in automated lifecycle and size management should subclass Component (or
- * {@link Ext.BoxComponent} if managed box model handling is required, ie height and width management).</p>
- * <p>See the <a href="http://extjs.com/learn/Tutorial:Creating_new_UI_controls">Creating new UI controls</a> tutorial for details on how
- * and to either extend or augment ExtJs base classes to create custom Components.</p>
- * <p>Every component has a specific xtype, which is its Ext-specific type name, along with methods for checking the
- * xtype like {@link #getXType} and {@link #isXType}. This is the list of all valid xtypes:</p>
- * <pre>
-xtype Class
-------------- ------------------
-box {@link Ext.BoxComponent}
-button {@link Ext.Button}
-buttongroup {@link Ext.ButtonGroup}
-colorpalette {@link Ext.ColorPalette}
-component {@link Ext.Component}
-container {@link Ext.Container}
-cycle {@link Ext.CycleButton}
-dataview {@link Ext.DataView}
-datepicker {@link Ext.DatePicker}
-editor {@link Ext.Editor}
-editorgrid {@link Ext.grid.EditorGridPanel}
-flash {@link Ext.FlashComponent}
-grid {@link Ext.grid.GridPanel}
-listview {@link Ext.ListView}
-panel {@link Ext.Panel}
-progress {@link Ext.ProgressBar}
-propertygrid {@link Ext.grid.PropertyGrid}
-slider {@link Ext.Slider}
-spacer {@link Ext.Spacer}
-splitbutton {@link Ext.SplitButton}
-tabpanel {@link Ext.TabPanel}
-treepanel {@link Ext.tree.TreePanel}
-viewport {@link Ext.ViewPort}
-window {@link Ext.Window}
-
-Toolbar components
----------------------------------------
-paging {@link Ext.PagingToolbar}
-toolbar {@link Ext.Toolbar}
-tbbutton {@link Ext.Toolbar.Button} (deprecated; use button)
-tbfill {@link Ext.Toolbar.Fill}
-tbitem {@link Ext.Toolbar.Item}
-tbseparator {@link Ext.Toolbar.Separator}
-tbspacer {@link Ext.Toolbar.Spacer}
-tbsplit {@link Ext.Toolbar.SplitButton} (deprecated; use splitbutton)
-tbtext {@link Ext.Toolbar.TextItem}
-
-Menu components
----------------------------------------
-menu {@link Ext.menu.Menu}
-colormenu {@link Ext.menu.ColorMenu}
-datemenu {@link Ext.menu.DateMenu}
-menubaseitem {@link Ext.menu.BaseItem}
-menucheckitem {@link Ext.menu.CheckItem}
-menuitem {@link Ext.menu.Item}
-menuseparator {@link Ext.menu.Separator}
-menutextitem {@link Ext.menu.TextItem}
-
-Form components
----------------------------------------
-form {@link Ext.FormPanel}
-checkbox {@link Ext.form.Checkbox}
-checkboxgroup {@link Ext.form.CheckboxGroup}
-combo {@link Ext.form.ComboBox}
-datefield {@link Ext.form.DateField}
-displayfield {@link Ext.form.DisplayField}
-field {@link Ext.form.Field}
-fieldset {@link Ext.form.FieldSet}
-hidden {@link Ext.form.Hidden}
-htmleditor {@link Ext.form.HtmlEditor}
-label {@link Ext.form.Label}
-numberfield {@link Ext.form.NumberField}
-radio {@link Ext.form.Radio}
-radiogroup {@link Ext.form.RadioGroup}
-textarea {@link Ext.form.TextArea}
-textfield {@link Ext.form.TextField}
-timefield {@link Ext.form.TimeField}
-trigger {@link Ext.form.TriggerField}
-
-Chart components
----------------------------------------
-chart {@link Ext.chart.Chart}
-barchart {@link Ext.chart.BarChart}
-cartesianchart {@link Ext.chart.CartesianChart}
-columnchart {@link Ext.chart.ColumnChart}
-linechart {@link Ext.chart.LineChart}
-piechart {@link Ext.chart.PieChart}
-
-Store xtypes
----------------------------------------
-arraystore {@link Ext.data.ArrayStore}
-directstore {@link Ext.data.DirectStore}
-groupingstore {@link Ext.data.GroupingStore}
-jsonstore {@link Ext.data.JsonStore}
-simplestore {@link Ext.data.SimpleStore} (deprecated; use arraystore)
-store {@link Ext.data.Store}
-xmlstore {@link Ext.data.XmlStore}
-</pre>
- * @constructor
- * @param {Ext.Element/String/Object} config The configuration options may be specified as either:
- * <div class="mdetail-params"><ul>
- * <li><b>an element</b> :
- * <p class="sub-desc">it is set as the internal element and its id used as the component id</p></li>
- * <li><b>a string</b> :
- * <p class="sub-desc">it is assumed to be the id of an existing element and is used as the component id</p></li>
- * <li><b>anything else</b> :
- * <p class="sub-desc">it is assumed to be a standard config object and is applied to the component</p></li>
- * </ul></div>
- */
-Ext.Component = function(config){
- config = config || {};
- if(config.initialConfig){
- if(config.isAction){ // actions
- this.baseAction = config;
- }
- config = config.initialConfig; // component cloning / action set up
- }else if(config.tagName || config.dom || Ext.isString(config)){ // element object
- config = {applyTo: config, id: config.id || config};
- }
-
- /**
- * This Component's initial configuration specification. Read-only.
- * @type Object
- * @property initialConfig
- */
- this.initialConfig = config;
-
- Ext.apply(this, config);
- this.addEvents(
- /**
- * @event disable
- * Fires after the component is disabled.
- * @param {Ext.Component} this
- */
- 'disable',
- /**
- * @event enable
- * Fires after the component is enabled.
- * @param {Ext.Component} this
- */
- 'enable',
- /**
- * @event beforeshow
- * Fires before the component is shown by calling the {@link #show} method.
- * Return false from an event handler to stop the show.
- * @param {Ext.Component} this
- */
- 'beforeshow',
- /**
- * @event show
- * Fires after the component is shown when calling the {@link #show} method.
- * @param {Ext.Component} this
- */
- 'show',
- /**
- * @event beforehide
- * Fires before the component is hidden by calling the {@link #hide} method.
- * Return false from an event handler to stop the hide.
- * @param {Ext.Component} this
- */
- 'beforehide',
- /**
- * @event hide
- * Fires after the component is hidden.
- * Fires after the component is hidden when calling the {@link #hide} method.
- * @param {Ext.Component} this
- */
- 'hide',
- /**
- * @event beforerender
- * Fires before the component is {@link #rendered}. Return false from an
- * event handler to stop the {@link #render}.
- * @param {Ext.Component} this
- */
- 'beforerender',
- /**
- * @event render
- * Fires after the component markup is {@link #rendered}.
- * @param {Ext.Component} this
- */
- 'render',
- /**
- * @event afterrender
- * <p>Fires after the component rendering is finished.</p>
- * <p>The afterrender event is fired after this Component has been {@link #rendered}, been postprocesed
- * by any afterRender method defined for the Component, and, if {@link #stateful}, after state
- * has been restored.</p>
- * @param {Ext.Component} this
- */
- 'afterrender',
- /**
- * @event beforedestroy
- * Fires before the component is {@link #destroy}ed. Return false from an event handler to stop the {@link #destroy}.
- * @param {Ext.Component} this
- */
- 'beforedestroy',
- /**
- * @event destroy
- * Fires after the component is {@link #destroy}ed.
- * @param {Ext.Component} this
- */
- 'destroy',
- /**
- * @event beforestaterestore
- * Fires before the state of the component is restored. Return false from an event handler to stop the restore.
- * @param {Ext.Component} this
- * @param {Object} state The hash of state values returned from the StateProvider. If this
- * event is not vetoed, then the state object is passed to <b><tt>applyState</tt></b>. By default,
- * that simply copies property values into this Component. The method maybe overriden to
- * provide custom state restoration.
- */
- 'beforestaterestore',
- /**
- * @event staterestore
- * Fires after the state of the component is restored.
- * @param {Ext.Component} this
- * @param {Object} state The hash of state values returned from the StateProvider. This is passed
- * to <b><tt>applyState</tt></b>. By default, that simply copies property values into this
- * Component. The method maybe overriden to provide custom state restoration.
- */
- 'staterestore',
- /**
- * @event beforestatesave
- * Fires before the state of the component is saved to the configured state provider. Return false to stop the save.
- * @param {Ext.Component} this
- * @param {Object} state The hash of state values. This is determined by calling
- * <b><tt>getState()</tt></b> on the Component. This method must be provided by the
- * developer to return whetever representation of state is required, by default, Ext.Component
- * has a null implementation.
- */
- 'beforestatesave',
- /**
- * @event statesave
- * Fires after the state of the component is saved to the configured state provider.
- * @param {Ext.Component} this
- * @param {Object} state The hash of state values. This is determined by calling
- * <b><tt>getState()</tt></b> on the Component. This method must be provided by the
- * developer to return whetever representation of state is required, by default, Ext.Component
- * has a null implementation.
- */
- 'statesave'
- );
- this.getId();
- Ext.ComponentMgr.register(this);
- Ext.Component.superclass.constructor.call(this);
-
- if(this.baseAction){
- this.baseAction.addComponent(this);
- }
-
- this.initComponent();
-
- if(this.plugins){
- if(Ext.isArray(this.plugins)){
- for(var i = 0, len = this.plugins.length; i < len; i++){
- this.plugins[i] = this.initPlugin(this.plugins[i]);
- }
- }else{
- this.plugins = this.initPlugin(this.plugins);
- }
- }
-
- if(this.stateful !== false){
- this.initState(config);
- }
-
- if(this.applyTo){
- this.applyToMarkup(this.applyTo);
- delete this.applyTo;
- }else if(this.renderTo){
- this.render(this.renderTo);
- delete this.renderTo;
- }
-};
-
-// private
-Ext.Component.AUTO_ID = 1000;
-
-Ext.extend(Ext.Component, Ext.util.Observable, {
- // Configs below are used for all Components when rendered by FormLayout.
- /**
- * @cfg {String} fieldLabel <p>The label text to display next to this Component (defaults to '').</p>
- * <br><p><b>Note</b>: this config is only used when this Component is rendered by a Container which
- * has been configured to use the <b>{@link Ext.layout.FormLayout FormLayout}</b> layout manager (e.g.
- * {@link Ext.form.FormPanel} or specifying <tt>layout:'form'</tt>).</p><br>
- * <p>Also see <tt>{@link #hideLabel}</tt> and
- * {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl}.</p>
- * Example use:<pre><code>
-new Ext.FormPanel({
- height: 100,
- renderTo: Ext.getBody(),
- items: [{
- xtype: 'textfield',
- fieldLabel: 'Name'
- }]
-});
-</code></pre>
- */
- /**
- * @cfg {String} labelStyle <p>A CSS style specification string to apply directly to this field's
- * label. Defaults to the container's labelStyle value if set (e.g.,
- * <tt>{@link Ext.layout.FormLayout#labelStyle}</tt> , or '').</p>
- * <br><p><b>Note</b>: see the note for <code>{@link #clearCls}</code>.</p><br>
- * <p>Also see <code>{@link #hideLabel}</code> and
- * <code>{@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl}.</code></p>
- * Example use:<pre><code>
-new Ext.FormPanel({
- height: 100,
- renderTo: Ext.getBody(),
- items: [{
- xtype: 'textfield',
- fieldLabel: 'Name',
- labelStyle: 'font-weight:bold;'
- }]
-});
-</code></pre>
- */
- /**
- * @cfg {String} labelSeparator <p>The separator to display after the text of each
- * <tt>{@link #fieldLabel}</tt>. This property may be configured at various levels.
- * The order of precedence is:
- * <div class="mdetail-params"><ul>
- * <li>field / component level</li>
- * <li>container level</li>
- * <li>{@link Ext.layout.FormLayout#labelSeparator layout level} (defaults to colon <tt>':'</tt>)</li>
- * </ul></div>
- * To display no separator for this field's label specify empty string ''.</p>
- * <br><p><b>Note</b>: see the note for <tt>{@link #clearCls}</tt>.</p><br>
- * <p>Also see <tt>{@link #hideLabel}</tt> and
- * {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl}.</p>
- * Example use:<pre><code>
-new Ext.FormPanel({
- height: 100,
- renderTo: Ext.getBody(),
- layoutConfig: {
- labelSeparator: '~' // layout config has lowest priority (defaults to ':')
- },
- {@link Ext.layout.FormLayout#labelSeparator labelSeparator}: '>>', // config at container level
- items: [{
- xtype: 'textfield',
- fieldLabel: 'Field 1',
- labelSeparator: '...' // field/component level config supersedes others
- },{
- xtype: 'textfield',
- fieldLabel: 'Field 2' // labelSeparator will be '='
- }]
-});
-</code></pre>
- */
- /**
- * @cfg {Boolean} hideLabel <p><tt>true</tt> to completely hide the label element
- * ({@link #fieldLabel label} and {@link #labelSeparator separator}). Defaults to <tt>false</tt>.
- * By default, even if you do not specify a <tt>{@link #fieldLabel}</tt> the space will still be
- * reserved so that the field will line up with other fields that do have labels.
- * Setting this to <tt>true</tt> will cause the field to not reserve that space.</p>
- * <br><p><b>Note</b>: see the note for <tt>{@link #clearCls}</tt>.</p><br>
- * Example use:<pre><code>
-new Ext.FormPanel({
- height: 100,
- renderTo: Ext.getBody(),
- items: [{
- xtype: 'textfield'
- hideLabel: true
- }]
-});
-</code></pre>
- */
- /**
- * @cfg {String} clearCls <p>The CSS class used to to apply to the special clearing div rendered
- * directly after each form field wrapper to provide field clearing (defaults to
- * <tt>'x-form-clear-left'</tt>).</p>
- * <br><p><b>Note</b>: this config is only used when this Component is rendered by a Container
- * which has been configured to use the <b>{@link Ext.layout.FormLayout FormLayout}</b> layout
- * manager (e.g. {@link Ext.form.FormPanel} or specifying <tt>layout:'form'</tt>) and either a
- * <tt>{@link #fieldLabel}</tt> is specified or <tt>isFormField=true</tt> is specified.</p><br>
- * <p>See {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl} also.</p>
- */
- /**
- * @cfg {String} itemCls <p>An additional CSS class to apply to the div wrapping the form item
- * element of this field. If supplied, <tt>itemCls</tt> at the <b>field</b> level will override
- * the default <tt>itemCls</tt> supplied at the <b>container</b> level. The value specified for
- * <tt>itemCls</tt> will be added to the default class (<tt>'x-form-item'</tt>).</p>
- * <p>Since it is applied to the item wrapper (see
- * {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl}), it allows
- * you to write standard CSS rules that can apply to the field, the label (if specified), or
- * any other element within the markup for the field.</p>
- * <br><p><b>Note</b>: see the note for <tt>{@link #fieldLabel}</tt>.</p><br>
- * Example use:<pre><code>
-// Apply a style to the field's label:
-<style>
- .required .x-form-item-label {font-weight:bold;color:red;}
-</style>
-
-new Ext.FormPanel({
- height: 100,
- renderTo: Ext.getBody(),
- items: [{
- xtype: 'textfield',
- fieldLabel: 'Name',
- itemCls: 'required' //this label will be styled
- },{
- xtype: 'textfield',
- fieldLabel: 'Favorite Color'
- }]
-});
-</code></pre>
- */
-
- // Configs below are used for all Components when rendered by AnchorLayout.
- /**
- * @cfg {String} anchor <p><b>Note</b>: this config is only used when this Component is rendered
- * by a Container which has been configured to use an <b>{@link Ext.layout.AnchorLayout AnchorLayout}</b>
- * based layout manager, for example:<div class="mdetail-params"><ul>
- * <li>{@link Ext.form.FormPanel}</li>
- * <li>specifying <code>layout: 'anchor' // or 'form', or 'absolute'</code></li>
- * </ul></div></p>
- * <p>See {@link Ext.layout.AnchorLayout}.{@link Ext.layout.AnchorLayout#anchor anchor} also.</p>
- */
-
- /**
- * @cfg {String} id
- * <p>The <b>unique</b> id of this component (defaults to an {@link #getId auto-assigned id}).
- * You should assign an id if you need to be able to access the component later and you do
- * not have an object reference available (e.g., using {@link Ext}.{@link Ext#getCmp getCmp}).</p>
- * <p>Note that this id will also be used as the element id for the containing HTML element
- * that is rendered to the page for this component. This allows you to write id-based CSS
- * rules to style the specific instance of this component uniquely, and also to select
- * sub-elements using this component's id as the parent.</p>
- * <p><b>Note</b>: to avoid complications imposed by a unique <tt>id</tt> also see
- * <code>{@link #itemId}</code> and <code>{@link #ref}</code>.</p>
- * <p><b>Note</b>: to access the container of an item see <code>{@link #ownerCt}</code>.</p>
- */
- /**
- * @cfg {String} itemId
- * <p>An <tt>itemId</tt> can be used as an alternative way to get a reference to a component
- * when no object reference is available. Instead of using an <code>{@link #id}</code> with
- * {@link Ext}.{@link Ext#getCmp getCmp}, use <code>itemId</code> with
- * {@link Ext.Container}.{@link Ext.Container#getComponent getComponent} which will retrieve
- * <code>itemId</code>'s or <tt>{@link #id}</tt>'s. Since <code>itemId</code>'s are an index to the
- * container's internal MixedCollection, the <code>itemId</code> is scoped locally to the container --
- * avoiding potential conflicts with {@link Ext.ComponentMgr} which requires a <b>unique</b>
- * <code>{@link #id}</code>.</p>
- * <pre><code>
-var c = new Ext.Panel({ //
- {@link Ext.BoxComponent#height height}: 300,
- {@link #renderTo}: document.body,
- {@link Ext.Container#layout layout}: 'auto',
- {@link Ext.Container#items items}: [
- {
- itemId: 'p1',
- {@link Ext.Panel#title title}: 'Panel 1',
- {@link Ext.BoxComponent#height height}: 150
- },
- {
- itemId: 'p2',
- {@link Ext.Panel#title title}: 'Panel 2',
- {@link Ext.BoxComponent#height height}: 150
- }
- ]
-})
-p1 = c.{@link Ext.Container#getComponent getComponent}('p1'); // not the same as {@link Ext#getCmp Ext.getCmp()}
-p2 = p1.{@link #ownerCt}.{@link Ext.Container#getComponent getComponent}('p2'); // reference via a sibling
- * </code></pre>
- * <p>Also see <tt>{@link #id}</tt> and <code>{@link #ref}</code>.</p>
- * <p><b>Note</b>: to access the container of an item see <tt>{@link #ownerCt}</tt>.</p>
- */
- /**
- * @cfg {String} xtype
- * The registered <tt>xtype</tt> to create. This config option is not used when passing
- * a config object into a constructor. This config option is used only when
- * lazy instantiation is being used, and a child item of a Container is being
- * specified not as a fully instantiated Component, but as a <i>Component config
- * object</i>. The <tt>xtype</tt> will be looked up at render time up to determine what
- * type of child Component to create.<br><br>
- * The predefined xtypes are listed {@link Ext.Component here}.
- * <br><br>
- * If you subclass Components to create your own Components, you may register
- * them using {@link Ext.ComponentMgr#registerType} in order to be able to
- * take advantage of lazy instantiation and rendering.
- */
- /**
- * @cfg {String} ptype
- * The registered <tt>ptype</tt> to create. This config option is not used when passing
- * a config object into a constructor. This config option is used only when
- * lazy instantiation is being used, and a Plugin is being
- * specified not as a fully instantiated Component, but as a <i>Component config
- * object</i>. The <tt>ptype</tt> will be looked up at render time up to determine what
- * type of Plugin to create.<br><br>
- * If you create your own Plugins, you may register them using
- * {@link Ext.ComponentMgr#registerPlugin} in order to be able to
- * take advantage of lazy instantiation and rendering.
- */
- /**
- * @cfg {String} cls
- * An optional extra CSS class that will be added to this component's Element (defaults to ''). This can be
- * useful for adding customized styles to the component or any of its children using standard CSS rules.
- */
- /**
- * @cfg {String} overCls
- * An optional extra CSS class that will be added to this component's Element when the mouse moves
- * over the Element, and removed when the mouse moves out. (defaults to ''). This can be
- * useful for adding customized 'active' or 'hover' styles to the component or any of its children using standard CSS rules.
- */
- /**
- * @cfg {String} style
- * A custom style specification to be applied to this component's Element. Should be a valid argument to
- * {@link Ext.Element#applyStyles}.
- * <pre><code>
-new Ext.Panel({
- title: 'Some Title',
- renderTo: Ext.getBody(),
- width: 400, height: 300,
- layout: 'form',
- items: [{
- xtype: 'textarea',
- style: {
- width: '95%',
- marginBottom: '10px'
- }
- },
- new Ext.Button({
- text: 'Send',
- minWidth: '100',
- style: {
- marginBottom: '10px'
- }
- })
- ]
-});
- * </code></pre>
- */
- /**
- * @cfg {String} ctCls
- * <p>An optional extra CSS class that will be added to this component's container. This can be useful for
- * adding customized styles to the container or any of its children using standard CSS rules. See
- * {@link Ext.layout.ContainerLayout}.{@link Ext.layout.ContainerLayout#extraCls extraCls} also.</p>
- * <p><b>Note</b>: <tt>ctCls</tt> defaults to <tt>''</tt> except for the following class
- * which assigns a value by default:
- * <div class="mdetail-params"><ul>
- * <li>{@link Ext.layout.Box Box Layout} : <tt>'x-box-layout-ct'</tt></li>
- * </ul></div>
- * To configure the above Class with an extra CSS class append to the default. For example,
- * for BoxLayout (Hbox and Vbox):<pre><code>
- * ctCls: 'x-box-layout-ct custom-class'
- * </code></pre>
- * </p>
- */
- /**
- * @cfg {Boolean} disabled
- * Render this component disabled (default is false).
- */
- disabled : false,
- /**
- * @cfg {Boolean} hidden
- * Render this component hidden (default is false). If <tt>true</tt>, the
- * {@link #hide} method will be called internally.
- */
- hidden : false,
- /**
- * @cfg {Object/Array} plugins
- * An object or array of objects that will provide custom functionality for this component. The only
- * requirement for a valid plugin is that it contain an init method that accepts a reference of type Ext.Component.
- * When a component is created, if any plugins are available, the component will call the init method on each
- * plugin, passing a reference to itself. Each plugin can then call methods or respond to events on the
- * component as needed to provide its functionality.
- */
- /**
- * @cfg {Mixed} applyTo
- * <p>Specify the id of the element, a DOM element or an existing Element corresponding to a DIV
- * that is already present in the document that specifies some structural markup for this
- * component.</p><div><ul>
- * <li><b>Description</b> : <ul>
- * <div class="sub-desc">When <tt>applyTo</tt> is used, constituent parts of the component can also be specified
- * by id or CSS class name within the main element, and the component being created may attempt
- * to create its subcomponents from that markup if applicable.</div>
- * </ul></li>
- * <li><b>Notes</b> : <ul>
- * <div class="sub-desc">When using this config, a call to render() is not required.</div>
- * <div class="sub-desc">If applyTo is specified, any value passed for {@link #renderTo} will be ignored and the target
- * element's parent node will automatically be used as the component's container.</div>
- * </ul></li>
- * </ul></div>
- */
- /**
- * @cfg {Mixed} renderTo
- * <p>Specify the id of the element, a DOM element or an existing Element that this component
- * will be rendered into.</p><div><ul>
- * <li><b>Notes</b> : <ul>
- * <div class="sub-desc">Do <u>not</u> use this option if the Component is to be a child item of
- * a {@link Ext.Container Container}. It is the responsibility of the
- * {@link Ext.Container Container}'s {@link Ext.Container#layout layout manager}
- * to render and manage its child items.</div>
- * <div class="sub-desc">When using this config, a call to render() is not required.</div>
- * </ul></li>
- * </ul></div>
- * <p>See <tt>{@link #render}</tt> also.</p>
- */
- /**
- * @cfg {Boolean} stateful
- * <p>A flag which causes the Component to attempt to restore the state of
- * internal properties from a saved state on startup. The component must have
- * either a <code>{@link #stateId}</code> or <code>{@link #id}</code> assigned
- * for state to be managed. Auto-generated ids are not guaranteed to be stable
- * across page loads and cannot be relied upon to save and restore the same
- * state for a component.<p>
- * <p>For state saving to work, the state manager's provider must have been
- * set to an implementation of {@link Ext.state.Provider} which overrides the
- * {@link Ext.state.Provider#set set} and {@link Ext.state.Provider#get get}
- * methods to save and recall name/value pairs. A built-in implementation,
- * {@link Ext.state.CookieProvider} is available.</p>
- * <p>To set the state provider for the current page:</p>
- * <pre><code>
-Ext.state.Manager.setProvider(new Ext.state.CookieProvider({
- expires: new Date(new Date().getTime()+(1000*60*60*24*7)), //7 days from now
-}));
- * </code></pre>
- * <p>A stateful Component attempts to save state when one of the events
- * listed in the <code>{@link #stateEvents}</code> configuration fires.</p>
- * <p>To save state, a stateful Component first serializes its state by
- * calling <b><code>getState</code></b>. By default, this function does
- * nothing. The developer must provide an implementation which returns an
- * object hash which represents the Component's restorable state.</p>
- * <p>The value yielded by getState is passed to {@link Ext.state.Manager#set}
- * which uses the configured {@link Ext.state.Provider} to save the object
- * keyed by the Component's <code>{@link stateId}</code>, or, if that is not
- * specified, its <code>{@link #id}</code>.</p>
- * <p>During construction, a stateful Component attempts to <i>restore</i>
- * its state by calling {@link Ext.state.Manager#get} passing the
- * <code>{@link #stateId}</code>, or, if that is not specified, the
- * <code>{@link #id}</code>.</p>
- * <p>The resulting object is passed to <b><code>applyState</code></b>.
- * The default implementation of <code>applyState</code> simply copies
- * properties into the object, but a developer may override this to support
- * more behaviour.</p>
- * <p>You can perform extra processing on state save and restore by attaching
- * handlers to the {@link #beforestaterestore}, {@link #staterestore},
- * {@link #beforestatesave} and {@link #statesave} events.</p>
- */
- /**
- * @cfg {String} stateId
- * The unique id for this component to use for state management purposes
- * (defaults to the component id if one was set, otherwise null if the
- * component is using a generated id).
- * <p>See <code>{@link #stateful}</code> for an explanation of saving and
- * restoring Component state.</p>
- */
- /**
- * @cfg {Array} stateEvents
- * <p>An array of events that, when fired, should trigger this component to
- * save its state (defaults to none). <code>stateEvents</code> may be any type
- * of event supported by this component, including browser or custom events
- * (e.g., <tt>['click', 'customerchange']</tt>).</p>
- * <p>See <code>{@link #stateful}</code> for an explanation of saving and
- * restoring Component state.</p>
- */
- /**
- * @cfg {Mixed} autoEl
- * <p>A tag name or {@link Ext.DomHelper DomHelper} spec used to create the {@link #getEl Element} which will
- * encapsulate this Component.</p>
- * <p>You do not normally need to specify this. For the base classes {@link Ext.Component}, {@link Ext.BoxComponent},
- * and {@link Ext.Container}, this defaults to <b><tt>'div'</tt></b>. The more complex Ext classes use a more complex
- * DOM structure created by their own onRender methods.</p>
- * <p>This is intended to allow the developer to create application-specific utility Components encapsulated by
- * different DOM elements. Example usage:</p><pre><code>
-{
- xtype: 'box',
- autoEl: {
- tag: 'img',
- src: 'http://www.example.com/example.jpg'
- }
-}, {
- xtype: 'box',
- autoEl: {
- tag: 'blockquote',
- html: 'autoEl is cool!'
- }
-}, {
- xtype: 'container',
- autoEl: 'ul',
- cls: 'ux-unordered-list',
- items: {
- xtype: 'box',
- autoEl: 'li',
- html: 'First list item'
- }
-}
-</code></pre>
- */
- autoEl : 'div',
-
- /**
- * @cfg {String} disabledClass
- * CSS class added to the component when it is disabled (defaults to 'x-item-disabled').
- */
- disabledClass : 'x-item-disabled',
- /**
- * @cfg {Boolean} allowDomMove
- * Whether the component can move the Dom node when rendering (defaults to true).
- */
- allowDomMove : true,
- /**
- * @cfg {Boolean} autoShow
- * True if the component should check for hidden classes (e.g. 'x-hidden' or 'x-hide-display') and remove
- * them on render (defaults to false).
- */
- autoShow : false,
- /**
- * @cfg {String} hideMode
- * <p>How this component should be hidden. Supported values are <tt>'visibility'</tt>
- * (css visibility), <tt>'offsets'</tt> (negative offset position) and <tt>'display'</tt>
- * (css display).</p>
- * <br><p><b>Note</b>: the default of <tt>'display'</tt> is generally preferred
- * since items are automatically laid out when they are first shown (no sizing
- * is done while hidden).</p>
- */
- hideMode : 'display',
- /**
- * @cfg {Boolean} hideParent
- * True to hide and show the component's container when hide/show is called on the component, false to hide
- * and show the component itself (defaults to false). For example, this can be used as a shortcut for a hide
- * button on a window by setting hide:true on the button when adding it to its parent container.
- */
- hideParent : false,
- /**
- * <p>The {@link Ext.Element} which encapsulates this Component. Read-only.</p>
- * <p>This will <i>usually</i> be a <DIV> element created by the class's onRender method, but
- * that may be overridden using the <code>{@link #autoEl}</code> config.</p>
- * <br><p><b>Note</b>: this element will not be available until this Component has been rendered.</p><br>
- * <p>To add listeners for <b>DOM events</b> to this Component (as opposed to listeners
- * for this Component's own Observable events), see the {@link Ext.util.Observable#listeners listeners}
- * config for a suggestion, or use a render listener directly:</p><pre><code>
-new Ext.Panel({
- title: 'The Clickable Panel',
- listeners: {
- render: function(p) {
- // Append the Panel to the click handler's argument list.
- p.getEl().on('click', handlePanelClick.createDelegate(null, [p], true));
- },
- single: true // Remove the listener after first invocation
- }
-});
-</code></pre>
- * <p>See also <tt>{@link #getEl getEl}</p>
- * @type Ext.Element
- * @property el
- */
- /**
- * The component's owner {@link Ext.Container} (defaults to undefined, and is set automatically when
- * the component is added to a container). Read-only.
- * <p><b>Note</b>: to access items within the container see <tt>{@link #itemId}</tt>.</p>
- * @type Ext.Container
- * @property ownerCt
- */
- /**
- * True if this component is hidden. Read-only.
- * @type Boolean
- * @property
- */
- /**
- * True if this component is disabled. Read-only.
- * @type Boolean
- * @property
- */
- /**
- * True if this component has been rendered. Read-only.
- * @type Boolean
- * @property
- */
- rendered : false,
-
- // private
- ctype : 'Ext.Component',
-
- // private
- actionMode : 'el',
-
- // private
- getActionEl : function(){
- return this[this.actionMode];
- },
-
- initPlugin : function(p){
- if(p.ptype && !Ext.isFunction(p.init)){
- p = Ext.ComponentMgr.createPlugin(p);
- }else if(Ext.isString(p)){
- p = Ext.ComponentMgr.createPlugin({
- ptype: p
- });
- }
- p.init(this);
- return p;
- },
-
- /* // protected
- * Function to be implemented by Component subclasses to be part of standard component initialization flow (it is empty by default).
- * <pre><code>
-// Traditional constructor:
-Ext.Foo = function(config){
- // call superclass constructor:
- Ext.Foo.superclass.constructor.call(this, config);
-
- this.addEvents({
- // add events
- });
-};
-Ext.extend(Ext.Foo, Ext.Bar, {
- // class body
-}
-
-// initComponent replaces the constructor:
-Ext.Foo = Ext.extend(Ext.Bar, {
- initComponent : function(){
- // call superclass initComponent
- Ext.Container.superclass.initComponent.call(this);
-
- this.addEvents({
- // add events
- });
- }
-}
-</code></pre>
- */
- initComponent : Ext.emptyFn,
-
- /**
- * <p>Render this Component into the passed HTML element.</p>
- * <p><b>If you are using a {@link Ext.Container Container} object to house this Component, then
- * do not use the render method.</b></p>
- * <p>A Container's child Components are rendered by that Container's
- * {@link Ext.Container#layout layout} manager when the Container is first rendered.</p>
- * <p>Certain layout managers allow dynamic addition of child components. Those that do
- * include {@link Ext.layout.CardLayout}, {@link Ext.layout.AnchorLayout},
- * {@link Ext.layout.FormLayout}, {@link Ext.layout.TableLayout}.</p>
- * <p>If the Container is already rendered when a new child Component is added, you may need to call
- * the Container's {@link Ext.Container#doLayout doLayout} to refresh the view which causes any
- * unrendered child Components to be rendered. This is required so that you can add multiple
- * child components if needed while only refreshing the layout once.</p>
- * <p>When creating complex UIs, it is important to remember that sizing and positioning
- * of child items is the responsibility of the Container's {@link Ext.Container#layout layout} manager.
- * If you expect child items to be sized in response to user interactions, you must
- * configure the Container with a layout manager which creates and manages the type of layout you
- * have in mind.</p>
- * <p><b>Omitting the Container's {@link Ext.Container#layout layout} config means that a basic
- * layout manager is used which does nothing but render child components sequentially into the
- * Container. No sizing or positioning will be performed in this situation.</b></p>
- * @param {Element/HTMLElement/String} container (optional) The element this Component should be
- * rendered into. If it is being created from existing markup, this should be omitted.
- * @param {String/Number} position (optional) The element ID or DOM node index within the container <b>before</b>
- * which this component will be inserted (defaults to appending to the end of the container)
- */
- render : function(container, position){
- if(!this.rendered && this.fireEvent('beforerender', this) !== false){
- if(!container && this.el){
- this.el = Ext.get(this.el);
- container = this.el.dom.parentNode;
- this.allowDomMove = false;
- }
- this.container = Ext.get(container);
- if(this.ctCls){
- this.container.addClass(this.ctCls);
- }
- this.rendered = true;
- if(position !== undefined){
- if(Ext.isNumber(position)){
- position = this.container.dom.childNodes[position];
- }else{
- position = Ext.getDom(position);
- }
- }
- this.onRender(this.container, position || null);
- if(this.autoShow){
- this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]);
- }
- if(this.cls){
- this.el.addClass(this.cls);
- delete this.cls;
- }
- if(this.style){
- this.el.applyStyles(this.style);
- delete this.style;
- }
- if(this.overCls){
- this.el.addClassOnOver(this.overCls);
- }
- this.fireEvent('render', this);
- this.afterRender(this.container);
- if(this.hidden){
- // call this so we don't fire initial hide events.
- this.doHide();
- }
- if(this.disabled){
- // pass silent so the event doesn't fire the first time.
- this.disable(true);
- }
-
- if(this.stateful !== false){
- this.initStateEvents();
- }
- this.initRef();
- this.fireEvent('afterrender', this);
- }
- return this;
- },
-
- initRef : function(){
- /**
- * @cfg {String} ref
- * <p>A path specification, relative to the Component's {@link #ownerCt} specifying into which
- * ancestor Container to place a named reference to this Component.</p>
- * <p>The ancestor axis can be traversed by using '/' characters in the path.
- * For example, to put a reference to a Toolbar Button into <i>the Panel which owns the Toolbar</i>:</p><pre><code>
-var myGrid = new Ext.grid.EditorGridPanel({
- title: 'My EditorGridPanel',
- store: myStore,
- colModel: myColModel,
- tbar: [{
- text: 'Save',
- handler: saveChanges,
- disabled: true,
- ref: '../saveButton'
- }],
- listeners: {
- afteredit: function() {
-// The button reference is in the GridPanel
- myGrid.saveButton.enable();
- }
- }
-});
-</code></pre>
- * <p>In the code above, if the ref had been <code>'saveButton'</code> the reference would
- * have been placed into the Toolbar. Each '/' in the ref moves up one level from the
- * Component's {@link #ownerCt}.</p>
- */
- if(this.ref){
- var levels = this.ref.split('/');
- var last = levels.length, i = 0;
- var t = this;
- while(i < last){
- if(t.ownerCt){
- t = t.ownerCt;
- }
- i++;
- }
- t[levels[--i]] = this;
- }
- },
-
- // private
- initState : function(config){
- if(Ext.state.Manager){
- var id = this.getStateId();
- if(id){
- var state = Ext.state.Manager.get(id);
- if(state){
- if(this.fireEvent('beforestaterestore', this, state) !== false){
- this.applyState(state);
- this.fireEvent('staterestore', this, state);
- }
- }
- }
- }
- },
-
- // private
- getStateId : function(){
- return this.stateId || ((this.id.indexOf('ext-comp-') == 0 || this.id.indexOf('ext-gen') == 0) ? null : this.id);
- },
-
- // private
- initStateEvents : function(){
- if(this.stateEvents){
- for(var i = 0, e; e = this.stateEvents[i]; i++){
- this.on(e, this.saveState, this, {delay:100});
- }
- }
- },
-
- // private
- applyState : function(state, config){
- if(state){
- Ext.apply(this, state);
- }
- },
-
- // private
- getState : function(){
- return null;
- },
-
- // private
- saveState : function(){
- if(Ext.state.Manager && this.stateful !== false){
- var id = this.getStateId();
- if(id){
- var state = this.getState();
- if(this.fireEvent('beforestatesave', this, state) !== false){
- Ext.state.Manager.set(id, state);
- this.fireEvent('statesave', this, state);
- }
- }
- }
- },
-
- /**
- * Apply this component to existing markup that is valid. With this function, no call to render() is required.
- * @param {String/HTMLElement} el
- */
- applyToMarkup : function(el){
- this.allowDomMove = false;
- this.el = Ext.get(el);
- this.render(this.el.dom.parentNode);
- },
-
- /**
- * Adds a CSS class to the component's underlying element.
- * @param {string} cls The CSS class name to add
- * @return {Ext.Component} this
- */
- addClass : function(cls){
- if(this.el){
- this.el.addClass(cls);
- }else{
- this.cls = this.cls ? this.cls + ' ' + cls : cls;
- }
- return this;
- },
-
- /**
- * Removes a CSS class from the component's underlying element.
- * @param {string} cls The CSS class name to remove
- * @return {Ext.Component} this
- */
- removeClass : function(cls){
- if(this.el){
- this.el.removeClass(cls);
- }else if(this.cls){
- this.cls = this.cls.split(' ').remove(cls).join(' ');
- }
- return this;
- },
-
- // private
- // default function is not really useful
- onRender : function(ct, position){
- if(!this.el && this.autoEl){
- if(Ext.isString(this.autoEl)){
- this.el = document.createElement(this.autoEl);
- }else{
- var div = document.createElement('div');
- Ext.DomHelper.overwrite(div, this.autoEl);
- this.el = div.firstChild;
- }
- if (!this.el.id) {
- this.el.id = this.getId();
- }
- }
- if(this.el){
- this.el = Ext.get(this.el);
- if(this.allowDomMove !== false){
- ct.dom.insertBefore(this.el.dom, position);
- }
- }
- },
-
- // private
- getAutoCreate : function(){
- var cfg = Ext.isObject(this.autoCreate) ?
- this.autoCreate : Ext.apply({}, this.defaultAutoCreate);
- if(this.id && !cfg.id){
- cfg.id = this.id;
- }
- return cfg;
- },
-
- // private
- afterRender : Ext.emptyFn,
-
- /**
- * Destroys this component by purging any event listeners, removing the component's element from the DOM,
- * removing the component from its {@link Ext.Container} (if applicable) and unregistering it from
- * {@link Ext.ComponentMgr}. Destruction is generally handled automatically by the framework and this method
- * should usually not need to be called directly.
- *
- */
- destroy : function(){
- if(this.fireEvent('beforedestroy', this) !== false){
- this.beforeDestroy();
- if(this.rendered){
- this.el.removeAllListeners();
- this.el.remove();
- if(this.actionMode == 'container' || this.removeMode == 'container'){
- this.container.remove();
- }
- }
- this.onDestroy();
- Ext.ComponentMgr.unregister(this);
- this.fireEvent('destroy', this);
- this.purgeListeners();
- }
- },
-
- // private
- beforeDestroy : Ext.emptyFn,
-
- // private
- onDestroy : Ext.emptyFn,
-
- /**
- * <p>Returns the {@link Ext.Element} which encapsulates this Component.</p>
- * <p>This will <i>usually</i> be a <DIV> element created by the class's onRender method, but
- * that may be overridden using the {@link #autoEl} config.</p>
- * <br><p><b>Note</b>: this element will not be available until this Component has been rendered.</p><br>
- * <p>To add listeners for <b>DOM events</b> to this Component (as opposed to listeners
- * for this Component's own Observable events), see the {@link #listeners} config for a suggestion,
- * or use a render listener directly:</p><pre><code>
-new Ext.Panel({
- title: 'The Clickable Panel',
- listeners: {
- render: function(p) {
- // Append the Panel to the click handler's argument list.
- p.getEl().on('click', handlePanelClick.createDelegate(null, [p], true));
- },
- single: true // Remove the listener after first invocation
- }
-});
-</code></pre>
- * @return {Ext.Element} The Element which encapsulates this Component.
- */
- getEl : function(){
- return this.el;
- },
-
- /**
- * Returns the <code>id</code> of this component or automatically generates and
- * returns an <code>id</code> if an <code>id</code> is not defined yet:<pre><code>
- * 'ext-comp-' + (++Ext.Component.AUTO_ID)
- * </code></pre>
- * @return {String} id
- */
- getId : function(){
- return this.id || (this.id = 'ext-comp-' + (++Ext.Component.AUTO_ID));
- },
-
- /**
- * Returns the <code>{@link #itemId}</code> of this component. If an
- * <code>{@link #itemId}</code> was not assigned through configuration the
- * <code>id</code> is returned using <code>{@link #getId}</code>.
- * @return {String}
- */
- getItemId : function(){
- return this.itemId || this.getId();
- },
-
- /**
- * Try to focus this component.
- * @param {Boolean} selectText (optional) If applicable, true to also select the text in this component
- * @param {Boolean/Number} delay (optional) Delay the focus this number of milliseconds (true for 10 milliseconds)
- * @return {Ext.Component} this
- */
- focus : function(selectText, delay){
- if(delay){
- this.focus.defer(Ext.isNumber(delay) ? delay : 10, this, [selectText, false]);
- return;
- }
- if(this.rendered){
- this.el.focus();
- if(selectText === true){
- this.el.dom.select();
- }
- }
- return this;
- },
-
- // private
- blur : function(){
- if(this.rendered){
- this.el.blur();
- }
- return this;
- },
-
- /**
- * Disable this component and fire the 'disable' event.
- * @return {Ext.Component} this
- */
- disable : function(/* private */ silent){
- if(this.rendered){
- this.onDisable();
- }
- this.disabled = true;
- if(silent !== true){
- this.fireEvent('disable', this);
- }
- return this;
- },
-
- // private
- onDisable : function(){
- this.getActionEl().addClass(this.disabledClass);
- this.el.dom.disabled = true;
- },
-
- /**
- * Enable this component and fire the 'enable' event.
- * @return {Ext.Component} this
- */
- enable : function(){
- if(this.rendered){
- this.onEnable();
- }
- this.disabled = false;
- this.fireEvent('enable', this);
- return this;
- },
-
- // private
- onEnable : function(){
- this.getActionEl().removeClass(this.disabledClass);
- this.el.dom.disabled = false;
- },
-
- /**
- * Convenience function for setting disabled/enabled by boolean.
- * @param {Boolean} disabled
- * @return {Ext.Component} this
- */
- setDisabled : function(disabled){
- return this[disabled ? 'disable' : 'enable']();
- },
-
- /**
- * Show this component. Listen to the '{@link #beforeshow}' event and return
- * <tt>false</tt> to cancel showing the component. Fires the '{@link #show}'
- * event after showing the component.
- * @return {Ext.Component} this
- */
- show : function(){
- if(this.fireEvent('beforeshow', this) !== false){
- this.hidden = false;
- if(this.autoRender){
- this.render(Ext.isBoolean(this.autoRender) ? Ext.getBody() : this.autoRender);
- }
- if(this.rendered){
- this.onShow();
- }
- this.fireEvent('show', this);
- }
- return this;
- },
-
- // private
- onShow : function(){
- this.getVisibiltyEl().removeClass('x-hide-' + this.hideMode);
- },
-
- /**
- * Hide this component. Listen to the '{@link #beforehide}' event and return
- * <tt>false</tt> to cancel hiding the component. Fires the '{@link #hide}'
- * event after hiding the component. Note this method is called internally if
- * the component is configured to be <code>{@link #hidden}</code>.
- * @return {Ext.Component} this
- */
- hide : function(){
- if(this.fireEvent('beforehide', this) !== false){
- this.doHide();
- this.fireEvent('hide', this);
- }
- return this;
- },
-
- // private
- doHide: function(){
- this.hidden = true;
- if(this.rendered){
- this.onHide();
- }
- },
-
- // private
- onHide : function(){
- this.getVisibiltyEl().addClass('x-hide-' + this.hideMode);
- },
-
- // private
- getVisibiltyEl : function(){
- return this.hideParent ? this.container : this.getActionEl();
- },
-
- /**
- * Convenience function to hide or show this component by boolean.
- * @param {Boolean} visible True to show, false to hide
- * @return {Ext.Component} this
- */
- setVisible : function(visible){
- return this[visible ? 'show' : 'hide']();
- },
-
- /**
- * Returns true if this component is visible.
- * @return {Boolean} True if this component is visible, false otherwise.
- */
- isVisible : function(){
- return this.rendered && this.getVisibiltyEl().isVisible();
- },
-
- /**
- * Clone the current component using the original config values passed into this instance by default.
- * @param {Object} overrides A new config containing any properties to override in the cloned version.
- * An id property can be passed on this object, otherwise one will be generated to avoid duplicates.
- * @return {Ext.Component} clone The cloned copy of this component
- */
- cloneConfig : function(overrides){
- overrides = overrides || {};
- var id = overrides.id || Ext.id();
- var cfg = Ext.applyIf(overrides, this.initialConfig);
- cfg.id = id; // prevent dup id
- return new this.constructor(cfg);
- },
-
- /**
- * Gets the xtype for this component as registered with {@link Ext.ComponentMgr}. For a list of all
- * available xtypes, see the {@link Ext.Component} header. Example usage:
- * <pre><code>
-var t = new Ext.form.TextField();
-alert(t.getXType()); // alerts 'textfield'
-</code></pre>
- * @return {String} The xtype
- */
- getXType : function(){
- return this.constructor.xtype;
- },
-
- /**
- * <p>Tests whether or not this Component is of a specific xtype. This can test whether this Component is descended
- * from the xtype (default) or whether it is directly of the xtype specified (shallow = true).</p>
- * <p><b>If using your own subclasses, be aware that a Component must register its own xtype
- * to participate in determination of inherited xtypes.</b></p>
- * <p>For a list of all available xtypes, see the {@link Ext.Component} header.</p>
- * <p>Example usage:</p>
- * <pre><code>
-var t = new Ext.form.TextField();
-var isText = t.isXType('textfield'); // true
-var isBoxSubclass = t.isXType('box'); // true, descended from BoxComponent
-var isBoxInstance = t.isXType('box', true); // false, not a direct BoxComponent instance
-</code></pre>
- * @param {String} xtype The xtype to check for this Component
- * @param {Boolean} shallow (optional) False to check whether this Component is descended from the xtype (this is
- * the default), or true to check whether this Component is directly of the specified xtype.
- * @return {Boolean} True if this component descends from the specified xtype, false otherwise.
- */
- isXType : function(xtype, shallow){
- //assume a string by default
- if (Ext.isFunction(xtype)){
- xtype = xtype.xtype; //handle being passed the class, e.g. Ext.Component
- }else if (Ext.isObject(xtype)){
- xtype = xtype.constructor.xtype; //handle being passed an instance
- }
-
- return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 : this.constructor.xtype == xtype;
- },
-
- /**
- * <p>Returns this Component's xtype hierarchy as a slash-delimited string. For a list of all
- * available xtypes, see the {@link Ext.Component} header.</p>
- * <p><b>If using your own subclasses, be aware that a Component must register its own xtype
- * to participate in determination of inherited xtypes.</b></p>
- * <p>Example usage:</p>
- * <pre><code>
-var t = new Ext.form.TextField();
-alert(t.getXTypes()); // alerts 'component/box/field/textfield'
-</code></pre>
- * @return {String} The xtype hierarchy string
- */
- getXTypes : function(){
- var tc = this.constructor;
- if(!tc.xtypes){
- var c = [], sc = this;
- while(sc && sc.constructor.xtype){
- c.unshift(sc.constructor.xtype);
- sc = sc.constructor.superclass;
- }
- tc.xtypeChain = c;
- tc.xtypes = c.join('/');
- }
- return tc.xtypes;
- },
-
- /**
- * Find a container above this component at any level by a custom function. If the passed function returns
- * true, the container will be returned.
- * @param {Function} fn The custom function to call with the arguments (container, this component).
- * @return {Ext.Container} The first Container for which the custom function returns true
- */
- findParentBy : function(fn) {
- for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt);
- return p || null;
- },
-
- /**
- * Find a container above this component at any level by xtype or class
- * @param {String/Class} xtype The xtype string for a component, or the class of the component directly
- * @return {Ext.Container} The first Container which matches the given xtype or class
- */
- findParentByType : function(xtype) {
- return Ext.isFunction(xtype) ?
- this.findParentBy(function(p){
- return p.constructor === xtype;
- }) :
- this.findParentBy(function(p){
- return p.constructor.xtype === xtype;
- });
- },
-
- getDomPositionEl : function(){
- return this.getPositionEl ? this.getPositionEl() : this.getEl();
- },
-
- // private
- purgeListeners : function(){
- Ext.Component.superclass.purgeListeners.call(this);
- if(this.mons){
- this.on('beforedestroy', this.clearMons, this, {single: true});
- }
- },
-
- // private
- clearMons : function(){
- Ext.each(this.mons, function(m){
- m.item.un(m.ename, m.fn, m.scope);
- }, this);
- this.mons = [];
- },
-
- // internal function for auto removal of assigned event handlers on destruction
- mon : function(item, ename, fn, scope, opt){
- if(!this.mons){
- this.mons = [];
- this.on('beforedestroy', this.clearMons, this, {single: true});
- }
-
- if(Ext.isObject(ename)){
- var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
-
- var o = ename;
- for(var e in o){
- if(propRe.test(e)){
- continue;
- }
- if(Ext.isFunction(o[e])){
- // shared options
- this.mons.push({
- item: item, ename: e, fn: o[e], scope: o.scope
- });
- item.on(e, o[e], o.scope, o);
- }else{
- // individual options
- this.mons.push({
- item: item, ename: e, fn: o[e], scope: o.scope
- });
- item.on(e, o[e]);
- }
- }
- return;
- }
-
-
- this.mons.push({
- item: item, ename: ename, fn: fn, scope: scope
- });
- item.on(ename, fn, scope, opt);
- },
-
- // protected, opposite of mon
- mun : function(item, ename, fn, scope){
- var found, mon;
- for(var i = 0, len = this.mons.length; i < len; ++i){
- mon = this.mons[i];
- if(item === mon.item && ename == mon.ename && fn === mon.fn && scope === mon.scope){
- this.mons.splice(i, 1);
- item.un(ename, fn, scope);
- found = true;
- break;
- }
- }
- return found;
- },
-
- /**
- * Returns the next component in the owning container
- * @return Ext.Component
- */
- nextSibling : function(){
- if(this.ownerCt){
- var index = this.ownerCt.items.indexOf(this);
- if(index != -1 && index+1 < this.ownerCt.items.getCount()){
- return this.ownerCt.items.itemAt(index+1);
- }
- }
- return null;
- },
-
- /**
- * Returns the previous component in the owning container
- * @return Ext.Component
- */
- previousSibling : function(){
- if(this.ownerCt){
- var index = this.ownerCt.items.indexOf(this);
- if(index > 0){
- return this.ownerCt.items.itemAt(index-1);
- }
- }
- return null;
- },
-
- /**
- * Provides the link for Observable's fireEvent method to bubble up the ownership hierarchy.
- * @return {Ext.Container} the Container which owns this Component.
- */
- getBubbleTarget : function(){
- return this.ownerCt;
- }
-});
-
-Ext.reg('component', Ext.Component);
-/**\r
- * @class Ext.Action\r
- * <p>An Action is a piece of reusable functionality that can be abstracted out of any particular component so that it\r
- * can be usefully shared among multiple components. Actions let you share handlers, configuration options and UI\r
- * updates across any components that support the Action interface (primarily {@link Ext.Toolbar}, {@link Ext.Button}\r
- * and {@link Ext.menu.Menu} components).</p>\r
- * <p>Aside from supporting the config object interface, any component that needs to use Actions must also support\r
- * the following method list, as these will be called as needed by the Action class: setText(string), setIconCls(string),\r
- * setDisabled(boolean), setVisible(boolean) and setHandler(function).</p>\r
- * Example usage:<br>\r
- * <pre><code>\r
-// Define the shared action. Each component below will have the same\r
-// display text and icon, and will display the same message on click.\r
-var action = new Ext.Action({\r
- {@link #text}: 'Do something',\r
- {@link #handler}: function(){\r
- Ext.Msg.alert('Click', 'You did something.');\r
- },\r
- {@link #iconCls}: 'do-something',\r
- {@link #itemId}: 'myAction'\r
-});\r
-\r
-var panel = new Ext.Panel({\r
- title: 'Actions',\r
- width: 500,\r
- height: 300,\r
- tbar: [\r
- // Add the action directly to a toolbar as a menu button\r
- action,\r
- {\r
- text: 'Action Menu',\r
- // Add the action to a menu as a text item\r
- menu: [action]\r
- }\r
- ],\r
- items: [\r
- // Add the action to the panel body as a standard button\r
- new Ext.Button(action)\r
- ],\r
- renderTo: Ext.getBody()\r
-});\r
-\r
-// Change the text for all components using the action\r
-action.setText('Something else');\r
-\r
-// Reference an action through a container using the itemId\r
-var btn = panel.getComponent('myAction');\r
-var aRef = btn.baseAction;\r
-aRef.setText('New text');\r
-</code></pre>\r
- * @constructor\r
- * @param {Object} config The configuration options\r
- */\r
-Ext.Action = function(config){\r
- this.initialConfig = config;\r
- this.itemId = config.itemId = (config.itemId || config.id || Ext.id());\r
- this.items = [];\r
-}\r
-\r
-Ext.Action.prototype = {\r
- /**\r
- * @cfg {String} text The text to set for all components using this action (defaults to '').\r
- */\r
- /**\r
- * @cfg {String} iconCls\r
- * The CSS class selector that specifies a background image to be used as the header icon for\r
- * all components using this action (defaults to '').\r
- * <p>An example of specifying a custom icon class would be something like:\r
- * </p><pre><code>\r
-// specify the property in the config for the class:\r
- ...\r
- iconCls: 'do-something'\r
-\r
-// css class that specifies background image to be used as the icon image:\r
-.do-something { background-image: url(../images/my-icon.gif) 0 6px no-repeat !important; }\r
-</code></pre>\r
- */\r
- /**\r
- * @cfg {Boolean} disabled True to disable all components using this action, false to enable them (defaults to false).\r
- */\r
- /**\r
- * @cfg {Boolean} hidden True to hide all components using this action, false to show them (defaults to false).\r
- */\r
- /**\r
- * @cfg {Function} handler The function that will be invoked by each component tied to this action\r
- * when the component's primary event is triggered (defaults to undefined).\r
- */\r
- /**\r
- * @cfg {String} itemId\r
- * See {@link Ext.Component}.{@link Ext.Component#itemId itemId}.\r
- */\r
- /**\r
- * @cfg {Object} scope The scope in which the {@link #handler} function will execute.\r
- */\r
-\r
- // private\r
- isAction : true,\r
-\r
- /**\r
- * Sets the text to be displayed by all components using this action.\r
- * @param {String} text The text to display\r
- */\r
- setText : function(text){\r
- this.initialConfig.text = text;\r
- this.callEach('setText', [text]);\r
- },\r
-\r
- /**\r
- * Gets the text currently displayed by all components using this action.\r
- */\r
- getText : function(){\r
- return this.initialConfig.text;\r
- },\r
-\r
- /**\r
- * Sets the icon CSS class for all components using this action. The class should supply\r
- * a background image that will be used as the icon image.\r
- * @param {String} cls The CSS class supplying the icon image\r
- */\r
- setIconClass : function(cls){\r
- this.initialConfig.iconCls = cls;\r
- this.callEach('setIconClass', [cls]);\r
- },\r
-\r
- /**\r
- * Gets the icon CSS class currently used by all components using this action.\r
- */\r
- getIconClass : function(){\r
- return this.initialConfig.iconCls;\r
- },\r
-\r
- /**\r
- * Sets the disabled state of all components using this action. Shortcut method\r
- * for {@link #enable} and {@link #disable}.\r
- * @param {Boolean} disabled True to disable the component, false to enable it\r
- */\r
- setDisabled : function(v){\r
- this.initialConfig.disabled = v;\r
- this.callEach('setDisabled', [v]);\r
- },\r
-\r
- /**\r
- * Enables all components using this action.\r
- */\r
- enable : function(){\r
- this.setDisabled(false);\r
- },\r
-\r
- /**\r
- * Disables all components using this action.\r
- */\r
- disable : function(){\r
- this.setDisabled(true);\r
- },\r
-\r
- /**\r
- * Returns true if the components using this action are currently disabled, else returns false. \r
- */\r
- isDisabled : function(){\r
- return this.initialConfig.disabled;\r
- },\r
-\r
- /**\r
- * Sets the hidden state of all components using this action. Shortcut method\r
- * for <code>{@link #hide}</code> and <code>{@link #show}</code>.\r
- * @param {Boolean} hidden True to hide the component, false to show it\r
- */\r
- setHidden : function(v){\r
- this.initialConfig.hidden = v;\r
- this.callEach('setVisible', [!v]);\r
- },\r
-\r
- /**\r
- * Shows all components using this action.\r
- */\r
- show : function(){\r
- this.setHidden(false);\r
- },\r
-\r
- /**\r
- * Hides all components using this action.\r
- */\r
- hide : function(){\r
- this.setHidden(true);\r
- },\r
-\r
- /**\r
- * Returns true if the components using this action are currently hidden, else returns false. \r
- */\r
- isHidden : function(){\r
- return this.initialConfig.hidden;\r
- },\r
-\r
- /**\r
- * Sets the function that will be called by each component using this action when its primary event is triggered.\r
- * @param {Function} fn The function that will be invoked by the action's components. The function\r
- * will be called with no arguments.\r
- * @param {Object} scope The scope in which the function will execute\r
- */\r
- setHandler : function(fn, scope){\r
- this.initialConfig.handler = fn;\r
- this.initialConfig.scope = scope;\r
- this.callEach('setHandler', [fn, scope]);\r
- },\r
-\r
- /**\r
- * Executes the specified function once for each component currently tied to this action. The function passed\r
- * in should accept a single argument that will be an object that supports the basic Action config/method interface.\r
- * @param {Function} fn The function to execute for each component\r
- * @param {Object} scope The scope in which the function will execute\r
- */\r
- each : function(fn, scope){\r
- Ext.each(this.items, fn, scope);\r
- },\r
-\r
- // private\r
- callEach : function(fnName, args){\r
- var cs = this.items;\r
- for(var i = 0, len = cs.length; i < len; i++){\r
- cs[i][fnName].apply(cs[i], args);\r
- }\r
- },\r
-\r
- // private\r
- addComponent : function(comp){\r
- this.items.push(comp);\r
- comp.on('destroy', this.removeComponent, this);\r
- },\r
-\r
- // private\r
- removeComponent : function(comp){\r
- this.items.remove(comp);\r
- },\r
-\r
- /**\r
- * Executes this action manually using the handler function specified in the original config object\r
- * or the handler function set with <code>{@link #setHandler}</code>. Any arguments passed to this\r
- * function will be passed on to the handler function.\r
- * @param {Mixed} arg1 (optional) Variable number of arguments passed to the handler function\r
- * @param {Mixed} arg2 (optional)\r
- * @param {Mixed} etc... (optional)\r
- */\r
- execute : function(){\r
- this.initialConfig.handler.apply(this.initialConfig.scope || window, arguments);\r
- }\r
-};
-/**
- * @class Ext.Layer
- * @extends Ext.Element
- * An extended {@link Ext.Element} object that supports a shadow and shim, constrain to viewport and
- * automatic maintaining of shadow/shim positions.
- * @cfg {Boolean} shim False to disable the iframe shim in browsers which need one (defaults to true)
- * @cfg {String/Boolean} shadow True to automatically create an {@link Ext.Shadow}, or a string indicating the
- * shadow's display {@link Ext.Shadow#mode}. False to disable the shadow. (defaults to false)
- * @cfg {Object} dh DomHelper object config to create element with (defaults to {tag: 'div', cls: 'x-layer'}).
- * @cfg {Boolean} constrain False to disable constrain to viewport (defaults to true)
- * @cfg {String} cls CSS class to add to the element
- * @cfg {Number} zindex Starting z-index (defaults to 11000)
- * @cfg {Number} shadowOffset Number of pixels to offset the shadow (defaults to 4)
- * @cfg {Boolean} useDisplay
- * Defaults to use css offsets to hide the Layer. Specify <tt>true</tt>
- * to use css style <tt>'display:none;'</tt> to hide the Layer.
- * @constructor
- * @param {Object} config An object with config options.
- * @param {String/HTMLElement} existingEl (optional) Uses an existing DOM element. If the element is not found it creates it.
- */
-(function(){
-Ext.Layer = function(config, existingEl){
- config = config || {};
- var dh = Ext.DomHelper;
- var cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body;
- if(existingEl){
- this.dom = Ext.getDom(existingEl);
- }
- if(!this.dom){
- var o = config.dh || {tag: 'div', cls: 'x-layer'};
- this.dom = dh.append(pel, o);
- }
- if(config.cls){
- this.addClass(config.cls);
- }
- this.constrain = config.constrain !== false;
- this.setVisibilityMode(Ext.Element.VISIBILITY);
- if(config.id){
- this.id = this.dom.id = config.id;
- }else{
- this.id = Ext.id(this.dom);
- }
- this.zindex = config.zindex || this.getZIndex();
- this.position('absolute', this.zindex);
- if(config.shadow){
- this.shadowOffset = config.shadowOffset || 4;
- this.shadow = new Ext.Shadow({
- offset : this.shadowOffset,
- mode : config.shadow
- });
- }else{
- this.shadowOffset = 0;
- }
- this.useShim = config.shim !== false && Ext.useShims;
- this.useDisplay = config.useDisplay;
- this.hide();
-};
-
-var supr = Ext.Element.prototype;
-
-// shims are shared among layer to keep from having 100 iframes
-var shims = [];
-
-Ext.extend(Ext.Layer, Ext.Element, {
-
- getZIndex : function(){
- return this.zindex || parseInt((this.getShim() || this).getStyle('z-index'), 10) || 11000;
- },
-
- getShim : function(){
- if(!this.useShim){
- return null;
- }
- if(this.shim){
- return this.shim;
- }
- var shim = shims.shift();
- if(!shim){
- shim = this.createShim();
- shim.enableDisplayMode('block');
- shim.dom.style.display = 'none';
- shim.dom.style.visibility = 'visible';
- }
- var pn = this.dom.parentNode;
- if(shim.dom.parentNode != pn){
- pn.insertBefore(shim.dom, this.dom);
- }
- shim.setStyle('z-index', this.getZIndex()-2);
- this.shim = shim;
- return shim;
- },
-
- hideShim : function(){
- if(this.shim){
- this.shim.setDisplayed(false);
- shims.push(this.shim);
- delete this.shim;
- }
- },
-
- disableShadow : function(){
- if(this.shadow){
- this.shadowDisabled = true;
- this.shadow.hide();
- this.lastShadowOffset = this.shadowOffset;
- this.shadowOffset = 0;
- }
- },
-
- enableShadow : function(show){
- if(this.shadow){
- this.shadowDisabled = false;
- this.shadowOffset = this.lastShadowOffset;
- delete this.lastShadowOffset;
- if(show){
- this.sync(true);
- }
- }
- },
-
- // private
- // this code can execute repeatedly in milliseconds (i.e. during a drag) so
- // code size was sacrificed for effeciency (e.g. no getBox/setBox, no XY calls)
- sync : function(doShow){
- var sw = this.shadow;
- if(!this.updating && this.isVisible() && (sw || this.useShim)){
- var sh = this.getShim();
-
- var w = this.getWidth(),
- h = this.getHeight();
-
- var l = this.getLeft(true),
- t = this.getTop(true);
-
- if(sw && !this.shadowDisabled){
- if(doShow && !sw.isVisible()){
- sw.show(this);
- }else{
- sw.realign(l, t, w, h);
- }
- if(sh){
- if(doShow){
- sh.show();
- }
- // fit the shim behind the shadow, so it is shimmed too
- var a = sw.adjusts, s = sh.dom.style;
- s.left = (Math.min(l, l+a.l))+'px';
- s.top = (Math.min(t, t+a.t))+'px';
- s.width = (w+a.w)+'px';
- s.height = (h+a.h)+'px';
- }
- }else if(sh){
- if(doShow){
- sh.show();
- }
- sh.setSize(w, h);
- sh.setLeftTop(l, t);
- }
-
- }
- },
-
- // private
- destroy : function(){
- this.hideShim();
- if(this.shadow){
- this.shadow.hide();
- }
- this.removeAllListeners();
- Ext.removeNode(this.dom);
- Ext.Element.uncache(this.id);
- },
-
- remove : function(){
- this.destroy();
- },
-
- // private
- beginUpdate : function(){
- this.updating = true;
- },
-
- // private
- endUpdate : function(){
- this.updating = false;
- this.sync(true);
- },
-
- // private
- hideUnders : function(negOffset){
- if(this.shadow){
- this.shadow.hide();
- }
- this.hideShim();
- },
-
- // private
- constrainXY : function(){
- if(this.constrain){
- var vw = Ext.lib.Dom.getViewWidth(),
- vh = Ext.lib.Dom.getViewHeight();
- var s = Ext.getDoc().getScroll();
-
- var xy = this.getXY();
- var x = xy[0], y = xy[1];
- var so = this.shadowOffset;
- var w = this.dom.offsetWidth+so, h = this.dom.offsetHeight+so;
- // only move it if it needs it
- var moved = false;
- // first validate right/bottom
- if((x + w) > vw+s.left){
- x = vw - w - so;
- moved = true;
- }
- if((y + h) > vh+s.top){
- y = vh - h - so;
- moved = true;
- }
- // then make sure top/left isn't negative
- if(x < s.left){
- x = s.left;
- moved = true;
- }
- if(y < s.top){
- y = s.top;
- moved = true;
- }
- if(moved){
- if(this.avoidY){
- var ay = this.avoidY;
- if(y <= ay && (y+h) >= ay){
- y = ay-h-5;
- }
- }
- xy = [x, y];
- this.storeXY(xy);
- supr.setXY.call(this, xy);
- this.sync();
- }
- }
- return this;
- },
-
- isVisible : function(){
- return this.visible;
- },
-
- // private
- showAction : function(){
- this.visible = true; // track visibility to prevent getStyle calls
- if(this.useDisplay === true){
- this.setDisplayed('');
- }else if(this.lastXY){
- supr.setXY.call(this, this.lastXY);
- }else if(this.lastLT){
- supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]);
- }
- },
-
- // private
- hideAction : function(){
- this.visible = false;
- if(this.useDisplay === true){
- this.setDisplayed(false);
- }else{
- this.setLeftTop(-10000,-10000);
- }
- },
-
- // overridden Element method
- setVisible : function(v, a, d, c, e){
- if(v){
- this.showAction();
- }
- if(a && v){
- var cb = function(){
- this.sync(true);
- if(c){
- c();
- }
- }.createDelegate(this);
- supr.setVisible.call(this, true, true, d, cb, e);
- }else{
- if(!v){
- this.hideUnders(true);
- }
- var cb = c;
- if(a){
- cb = function(){
- this.hideAction();
- if(c){
- c();
- }
- }.createDelegate(this);
- }
- supr.setVisible.call(this, v, a, d, cb, e);
- if(v){
- this.sync(true);
- }else if(!a){
- this.hideAction();
- }
- }
- return this;
- },
-
- storeXY : function(xy){
- delete this.lastLT;
- this.lastXY = xy;
- },
-
- storeLeftTop : function(left, top){
- delete this.lastXY;
- this.lastLT = [left, top];
- },
-
- // private
- beforeFx : function(){
- this.beforeAction();
- return Ext.Layer.superclass.beforeFx.apply(this, arguments);
- },
-
- // private
- afterFx : function(){
- Ext.Layer.superclass.afterFx.apply(this, arguments);
- this.sync(this.isVisible());
- },
-
- // private
- beforeAction : function(){
- if(!this.updating && this.shadow){
- this.shadow.hide();
- }
- },
-
- // overridden Element method
- setLeft : function(left){
- this.storeLeftTop(left, this.getTop(true));
- supr.setLeft.apply(this, arguments);
- this.sync();
- return this;
- },
-
- setTop : function(top){
- this.storeLeftTop(this.getLeft(true), top);
- supr.setTop.apply(this, arguments);
- this.sync();
- return this;
- },
-
- setLeftTop : function(left, top){
- this.storeLeftTop(left, top);
- supr.setLeftTop.apply(this, arguments);
- this.sync();
- return this;
- },
-
- setXY : function(xy, a, d, c, e){
- this.fixDisplay();
- this.beforeAction();
- this.storeXY(xy);
- var cb = this.createCB(c);
- supr.setXY.call(this, xy, a, d, cb, e);
- if(!a){
- cb();
- }
- return this;
- },
-
- // private
- createCB : function(c){
- var el = this;
- return function(){
- el.constrainXY();
- el.sync(true);
- if(c){
- c();
- }
- };
- },
-
- // overridden Element method
- setX : function(x, a, d, c, e){
- this.setXY([x, this.getY()], a, d, c, e);
- return this;
- },
-
- // overridden Element method
- setY : function(y, a, d, c, e){
- this.setXY([this.getX(), y], a, d, c, e);
- return this;
- },
-
- // overridden Element method
- setSize : function(w, h, a, d, c, e){
- this.beforeAction();
- var cb = this.createCB(c);
- supr.setSize.call(this, w, h, a, d, cb, e);
- if(!a){
- cb();
- }
- return this;
- },
-
- // overridden Element method
- setWidth : function(w, a, d, c, e){
- this.beforeAction();
- var cb = this.createCB(c);
- supr.setWidth.call(this, w, a, d, cb, e);
- if(!a){
- cb();
- }
- return this;
- },
-
- // overridden Element method
- setHeight : function(h, a, d, c, e){
- this.beforeAction();
- var cb = this.createCB(c);
- supr.setHeight.call(this, h, a, d, cb, e);
- if(!a){
- cb();
- }
- return this;
- },
-
- // overridden Element method
- setBounds : function(x, y, w, h, a, d, c, e){
- this.beforeAction();
- var cb = this.createCB(c);
- if(!a){
- this.storeXY([x, y]);
- supr.setXY.call(this, [x, y]);
- supr.setSize.call(this, w, h, a, d, cb, e);
- cb();
- }else{
- supr.setBounds.call(this, x, y, w, h, a, d, cb, e);
- }
- return this;
- },
-
- /**
- * Sets the z-index of this layer and adjusts any shadow and shim z-indexes. The layer z-index is automatically
- * incremented by two more than the value passed in so that it always shows above any shadow or shim (the shadow
- * element, if any, will be assigned z-index + 1, and the shim element, if any, will be assigned the unmodified z-index).
- * @param {Number} zindex The new z-index to set
- * @return {this} The Layer
- */
- setZIndex : function(zindex){
- this.zindex = zindex;
- this.setStyle('z-index', zindex + 2);
- if(this.shadow){
- this.shadow.setZIndex(zindex + 1);
- }
- if(this.shim){
- this.shim.setStyle('z-index', zindex);
- }
- return this;
- }
-});
-})();/**
- * @class Ext.Shadow
- * Simple class that can provide a shadow effect for any element. Note that the element MUST be absolutely positioned,
- * and the shadow does not provide any shimming. This should be used only in simple cases -- for more advanced
- * functionality that can also provide the same shadow effect, see the {@link Ext.Layer} class.
- * @constructor
- * Create a new Shadow
- * @param {Object} config The config object
- */
-Ext.Shadow = function(config){
- Ext.apply(this, config);
- if(typeof this.mode != "string"){
- this.mode = this.defaultMode;
- }
- var o = this.offset, a = {h: 0};
- var rad = Math.floor(this.offset/2);
- switch(this.mode.toLowerCase()){ // all this hideous nonsense calculates the various offsets for shadows
- case "drop":
- a.w = 0;
- a.l = a.t = o;
- a.t -= 1;
- if(Ext.isIE){
- a.l -= this.offset + rad;
- a.t -= this.offset + rad;
- a.w -= rad;
- a.h -= rad;
- a.t += 1;
- }
- break;
- case "sides":
- a.w = (o*2);
- a.l = -o;
- a.t = o-1;
- if(Ext.isIE){
- a.l -= (this.offset - rad);
- a.t -= this.offset + rad;
- a.l += 1;
- a.w -= (this.offset - rad)*2;
- a.w -= rad + 1;
- a.h -= 1;
- }
- break;
- case "frame":
- a.w = a.h = (o*2);
- a.l = a.t = -o;
- a.t += 1;
- a.h -= 2;
- if(Ext.isIE){
- a.l -= (this.offset - rad);
- a.t -= (this.offset - rad);
- a.l += 1;
- a.w -= (this.offset + rad + 1);
- a.h -= (this.offset + rad);
- a.h += 1;
- }
- break;
- };
-
- this.adjusts = a;
-};
-
-Ext.Shadow.prototype = {
- /**
- * @cfg {String} mode
- * The shadow display mode. Supports the following options:<div class="mdetail-params"><ul>
- * <li><b><tt>sides</tt></b> : Shadow displays on both sides and bottom only</li>
- * <li><b><tt>frame</tt></b> : Shadow displays equally on all four sides</li>
- * <li><b><tt>drop</tt></b> : Traditional bottom-right drop shadow</li>
- * </ul></div>
- */
- /**
- * @cfg {String} offset
- * The number of pixels to offset the shadow from the element (defaults to <tt>4</tt>)
- */
- offset: 4,
-
- // private
- defaultMode: "drop",
-
- /**
- * Displays the shadow under the target element
- * @param {Mixed} targetEl The id or element under which the shadow should display
- */
- show : function(target){
- target = Ext.get(target);
- if(!this.el){
- this.el = Ext.Shadow.Pool.pull();
- if(this.el.dom.nextSibling != target.dom){
- this.el.insertBefore(target);
- }
- }
- this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10)-1);
- if(Ext.isIE){
- this.el.dom.style.filter="progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius="+(this.offset)+")";
- }
- this.realign(
- target.getLeft(true),
- target.getTop(true),
- target.getWidth(),
- target.getHeight()
- );
- this.el.dom.style.display = "block";
- },
-
- /**
- * Returns true if the shadow is visible, else false
- */
- isVisible : function(){
- return this.el ? true : false;
- },
-
- /**
- * Direct alignment when values are already available. Show must be called at least once before
- * calling this method to ensure it is initialized.
- * @param {Number} left The target element left position
- * @param {Number} top The target element top position
- * @param {Number} width The target element width
- * @param {Number} height The target element height
- */
- realign : function(l, t, w, h){
- if(!this.el){
- return;
- }
- var a = this.adjusts, d = this.el.dom, s = d.style;
- var iea = 0;
- s.left = (l+a.l)+"px";
- s.top = (t+a.t)+"px";
- var sw = (w+a.w), sh = (h+a.h), sws = sw +"px", shs = sh + "px";
- if(s.width != sws || s.height != shs){
- s.width = sws;
- s.height = shs;
- if(!Ext.isIE){
- var cn = d.childNodes;
- var sww = Math.max(0, (sw-12))+"px";
- cn[0].childNodes[1].style.width = sww;
- cn[1].childNodes[1].style.width = sww;
- cn[2].childNodes[1].style.width = sww;
- cn[1].style.height = Math.max(0, (sh-12))+"px";
- }
- }
- },
-
- /**
- * Hides this shadow
- */
- hide : function(){
- if(this.el){
- this.el.dom.style.display = "none";
- Ext.Shadow.Pool.push(this.el);
- delete this.el;
- }
- },
-
- /**
- * Adjust the z-index of this shadow
- * @param {Number} zindex The new z-index
- */
- setZIndex : function(z){
- this.zIndex = z;
- if(this.el){
- this.el.setStyle("z-index", z);
- }
- }
-};
-
-// Private utility class that manages the internal Shadow cache
-Ext.Shadow.Pool = function(){
- var p = [];
- var markup = Ext.isIE ?
- '<div class="x-ie-shadow"></div>' :
- '<div class="x-shadow"><div class="xst"><div class="xstl"></div><div class="xstc"></div><div class="xstr"></div></div><div class="xsc"><div class="xsml"></div><div class="xsmc"></div><div class="xsmr"></div></div><div class="xsb"><div class="xsbl"></div><div class="xsbc"></div><div class="xsbr"></div></div></div>';
- return {
- pull : function(){
- var sh = p.shift();
- if(!sh){
- sh = Ext.get(Ext.DomHelper.insertHtml("beforeBegin", document.body.firstChild, markup));
- sh.autoBoxAdjust = false;
- }
- return sh;
- },
-
- push : function(sh){
- p.push(sh);
- }
- };
-}();/**
- * @class Ext.BoxComponent
- * @extends Ext.Component
- * <p>Base class for any {@link Ext.Component Component} that is to be sized as a box, using width and height.</p>
- * <p>BoxComponent provides automatic box model adjustments for sizing and positioning and will work correctly
- * within the Component rendering model.</p>
- * <p>A BoxComponent may be created as a custom Component which encapsulates any HTML element, either a pre-existing
- * element, or one that is created to your specifications at render time. Usually, to participate in layouts,
- * a Component will need to be a <b>Box</b>Component in order to have its width and height managed.</p>
- * <p>To use a pre-existing element as a BoxComponent, configure it so that you preset the <b>el</b> property to the
- * element to reference:<pre><code>
-var pageHeader = new Ext.BoxComponent({
- el: 'my-header-div'
-});</code></pre>
- * This may then be {@link Ext.Container#add added} to a {@link Ext.Container Container} as a child item.</p>
- * <p>To create a BoxComponent based around a HTML element to be created at render time, use the
- * {@link Ext.Component#autoEl autoEl} config option which takes the form of a
- * {@link Ext.DomHelper DomHelper} specification:<pre><code>
-var myImage = new Ext.BoxComponent({
- autoEl: {
- tag: 'img',
- src: '/images/my-image.jpg'
- }
-});</code></pre></p>
- * @constructor
- * @param {Ext.Element/String/Object} config The configuration options.
- * @xtype box
- */
-Ext.BoxComponent = Ext.extend(Ext.Component, {
-
- // Configs below are used for all Components when rendered by BorderLayout.
- /**
- * @cfg {String} region <p><b>Note</b>: this config is only used when this BoxComponent is rendered
- * by a Container which has been configured to use the <b>{@link Ext.layout.BorderLayout BorderLayout}</b>
- * layout manager (e.g. specifying <tt>layout:'border'</tt>).</p><br>
- * <p>See {@link Ext.layout.BorderLayout} also.</p>
- */
- // margins config is used when a BoxComponent is rendered by BorderLayout or BoxLayout.
- /**
- * @cfg {Object} margins <p><b>Note</b>: this config is only used when this BoxComponent is rendered
- * by a Container which has been configured to use the <b>{@link Ext.layout.BorderLayout BorderLayout}</b>
- * or one of the two <b>{@link Ext.layout.BoxLayout BoxLayout} subclasses.</b></p>
- * <p>An object containing margins to apply to this BoxComponent in the
- * format:</p><pre><code>
-{
- top: (top margin),
- right: (right margin),
- bottom: (bottom margin),
- left: (left margin)
-}</code></pre>
- * <p>May also be a string containing space-separated, numeric margin values. The order of the
- * sides associated with each value matches the way CSS processes margin values:</p>
- * <p><div class="mdetail-params"><ul>
- * <li>If there is only one value, it applies to all sides.</li>
- * <li>If there are two values, the top and bottom borders are set to the first value and the
- * right and left are set to the second.</li>
- * <li>If there are three values, the top is set to the first value, the left and right are set
- * to the second, and the bottom is set to the third.</li>
- * <li>If there are four values, they apply to the top, right, bottom, and left, respectively.</li>
- * </ul></div></p>
- * <p>Defaults to:</p><pre><code>
- * {top:0, right:0, bottom:0, left:0}
- * </code></pre>
- */
- /**
- * @cfg {Number} x
- * The local x (left) coordinate for this component if contained within a positioning container.
- */
- /**
- * @cfg {Number} y
- * The local y (top) coordinate for this component if contained within a positioning container.
- */
- /**
- * @cfg {Number} pageX
- * The page level x coordinate for this component if contained within a positioning container.
- */
- /**
- * @cfg {Number} pageY
- * The page level y coordinate for this component if contained within a positioning container.
- */
- /**
- * @cfg {Number} height
- * The height of this component in pixels (defaults to auto).
- * <b>Note</b> to express this dimension as a percentage or offset see {@link Ext.Component#anchor}.
- */
- /**
- * @cfg {Number} width
- * The width of this component in pixels (defaults to auto).
- * <b>Note</b> to express this dimension as a percentage or offset see {@link Ext.Component#anchor}.
- */
- /**
- * @cfg {Boolean} autoHeight
- * <p>True to use height:'auto', false to use fixed height (or allow it to be managed by its parent
- * Container's {@link Ext.Container#layout layout manager}. Defaults to false.</p>
- * <p><b>Note</b>: Although many components inherit this config option, not all will
- * function as expected with a height of 'auto'. Setting autoHeight:true means that the
- * browser will manage height based on the element's contents, and that Ext will not manage it at all.</p>
- * <p>If the <i>browser</i> is managing the height, be aware that resizes performed by the browser in response
- * to changes within the structure of the Component cannot be detected. Therefore changes to the height might
- * result in elements needing to be synchronized with the new height. Example:</p><pre><code>
-var w = new Ext.Window({
- title: 'Window',
- width: 600,
- autoHeight: true,
- items: {
- title: 'Collapse Me',
- height: 400,
- collapsible: true,
- border: false,
- listeners: {
- beforecollapse: function() {
- w.el.shadow.hide();
- },
- beforeexpand: function() {
- w.el.shadow.hide();
- },
- collapse: function() {
- w.syncShadow();
- },
- expand: function() {
- w.syncShadow();
- }
- }
- }
-}).show();
-</code></pre>
- */
- /**
- * @cfg {Boolean} autoWidth
- * <p>True to use width:'auto', false to use fixed width (or allow it to be managed by its parent
- * Container's {@link Ext.Container#layout layout manager}. Defaults to false.</p>
- * <p><b>Note</b>: Although many components inherit this config option, not all will
- * function as expected with a width of 'auto'. Setting autoWidth:true means that the
- * browser will manage width based on the element's contents, and that Ext will not manage it at all.</p>
- * <p>If the <i>browser</i> is managing the width, be aware that resizes performed by the browser in response
- * to changes within the structure of the Component cannot be detected. Therefore changes to the width might
- * result in elements needing to be synchronized with the new width. For example, where the target element is:</p><pre><code>
-<div id='grid-container' style='margin-left:25%;width:50%'></div>
-</code></pre>
- * A Panel rendered into that target element must listen for browser window resize in order to relay its
- * child items when the browser changes its width:<pre><code>
-var myPanel = new Ext.Panel({
- renderTo: 'grid-container',
- monitorResize: true, // relay on browser resize
- title: 'Panel',
- height: 400,
- autoWidth: true,
- layout: 'hbox',
- layoutConfig: {
- align: 'stretch'
- },
- defaults: {
- flex: 1
- },
- items: [{
- title: 'Box 1',
- }, {
- title: 'Box 2'
- }, {
- title: 'Box 3'
- }],
-});
-</code></pre>
- */
-
- /* // private internal config
- * {Boolean} deferHeight
- * True to defer height calculations to an external component, false to allow this component to set its own
- * height (defaults to false).
- */
-
- // private
- initComponent : function(){
- Ext.BoxComponent.superclass.initComponent.call(this);
- this.addEvents(
- /**
- * @event resize
- * Fires after the component is resized.
- * @param {Ext.Component} this
- * @param {Number} adjWidth The box-adjusted width that was set
- * @param {Number} adjHeight The box-adjusted height that was set
- * @param {Number} rawWidth The width that was originally specified
- * @param {Number} rawHeight The height that was originally specified
- */
- 'resize',
- /**
- * @event move
- * Fires after the component is moved.
- * @param {Ext.Component} this
- * @param {Number} x The new x position
- * @param {Number} y The new y position
- */
- 'move'
- );
- },
-
- // private, set in afterRender to signify that the component has been rendered
- boxReady : false,
- // private, used to defer height settings to subclasses
- deferHeight: false,
-
- /**
- * Sets the width and height of this BoxComponent. This method fires the {@link #resize} event. This method can accept
- * either width and height as separate arguments, or you can pass a size object like <code>{width:10, height:20}</code>.
- * @param {Mixed} width The new width to set. This may be one of:<div class="mdetail-params"><ul>
- * <li>A Number specifying the new width in the {@link #getEl Element}'s {@link Ext.Element#defaultUnit}s (by default, pixels).</li>
- * <li>A String used to set the CSS width style.</li>
- * <li>A size object in the format <code>{width: widthValue, height: heightValue}</code>.</li>
- * <li><code>undefined</code> to leave the width unchanged.</li>
- * </ul></div>
- * @param {Mixed} height The new height to set (not required if a size object is passed as the first arg).
- * This may be one of:<div class="mdetail-params"><ul>
- * <li>A Number specifying the new height in the {@link #getEl Element}'s {@link Ext.Element#defaultUnit}s (by default, pixels).</li>
- * <li>A String used to set the CSS height style. Animation may <b>not</b> be used.</li>
- * <li><code>undefined</code> to leave the height unchanged.</li>
- * </ul></div>
- * @return {Ext.BoxComponent} this
- */
- setSize : function(w, h){
- // support for standard size objects
- if(typeof w == 'object'){
- h = w.height;
- w = w.width;
- }
- // not rendered
- if(!this.boxReady){
- this.width = w;
- this.height = h;
- return this;
- }
-
- // prevent recalcs when not needed
- if(this.cacheSizes !== false && this.lastSize && this.lastSize.width == w && this.lastSize.height == h){
- return this;
- }
- this.lastSize = {width: w, height: h};
- var adj = this.adjustSize(w, h);
- var aw = adj.width, ah = adj.height;
- if(aw !== undefined || ah !== undefined){ // this code is nasty but performs better with floaters
- var rz = this.getResizeEl();
- if(!this.deferHeight && aw !== undefined && ah !== undefined){
- rz.setSize(aw, ah);
- }else if(!this.deferHeight && ah !== undefined){
- rz.setHeight(ah);
- }else if(aw !== undefined){
- rz.setWidth(aw);
- }
- this.onResize(aw, ah, w, h);
- this.fireEvent('resize', this, aw, ah, w, h);
- }
- return this;
- },
-
- /**
- * Sets the width of the component. This method fires the {@link #resize} event.
- * @param {Number} width The new width to setThis may be one of:<div class="mdetail-params"><ul>
- * <li>A Number specifying the new width in the {@link #getEl Element}'s {@link Ext.Element#defaultUnit}s (by default, pixels).</li>
- * <li>A String used to set the CSS width style.</li>
- * </ul></div>
- * @return {Ext.BoxComponent} this
- */
- setWidth : function(width){
- return this.setSize(width);
- },
-
- /**
- * Sets the height of the component. This method fires the {@link #resize} event.
- * @param {Number} height The new height to set. This may be one of:<div class="mdetail-params"><ul>
- * <li>A Number specifying the new height in the {@link #getEl Element}'s {@link Ext.Element#defaultUnit}s (by default, pixels).</li>
- * <li>A String used to set the CSS height style.</li>
- * <li><i>undefined</i> to leave the height unchanged.</li>
- * </ul></div>
- * @return {Ext.BoxComponent} this
- */
- setHeight : function(height){
- return this.setSize(undefined, height);
- },
-
- /**
- * Gets the current size of the component's underlying element.
- * @return {Object} An object containing the element's size {width: (element width), height: (element height)}
- */
- getSize : function(){
- return this.getResizeEl().getSize();
- },
-
- /**
- * Gets the current width of the component's underlying element.
- * @return {Number}
- */
- getWidth : function(){
- return this.getResizeEl().getWidth();
- },
-
- /**
- * Gets the current height of the component's underlying element.
- * @return {Number}
- */
- getHeight : function(){
- return this.getResizeEl().getHeight();
- },
-
- /**
- * Gets the current size of the component's underlying element, including space taken by its margins.
- * @return {Object} An object containing the element's size {width: (element width + left/right margins), height: (element height + top/bottom margins)}
- */
- getOuterSize : function(){
- var el = this.getResizeEl();
- return {width: el.getWidth() + el.getMargins('lr'),
- height: el.getHeight() + el.getMargins('tb')};
- },
-
- /**
- * Gets the current XY position of the component's underlying element.
- * @param {Boolean} local (optional) If true the element's left and top are returned instead of page XY (defaults to false)
- * @return {Array} The XY position of the element (e.g., [100, 200])
- */
- getPosition : function(local){
- var el = this.getPositionEl();
- if(local === true){
- return [el.getLeft(true), el.getTop(true)];
- }
- return this.xy || el.getXY();
- },
-
- /**
- * Gets the current box measurements of the component's underlying element.
- * @param {Boolean} local (optional) If true the element's left and top are returned instead of page XY (defaults to false)
- * @return {Object} box An object in the format {x, y, width, height}
- */
- getBox : function(local){
- var pos = this.getPosition(local);
- var s = this.getSize();
- s.x = pos[0];
- s.y = pos[1];
- return s;
- },
-
- /**
- * Sets the current box measurements of the component's underlying element.
- * @param {Object} box An object in the format {x, y, width, height}
- * @return {Ext.BoxComponent} this
- */
- updateBox : function(box){
- this.setSize(box.width, box.height);
- this.setPagePosition(box.x, box.y);
- return this;
- },
-
- /**
- * <p>Returns the outermost Element of this Component which defines the Components overall size.</p>
- * <p><i>Usually</i> this will return the same Element as <code>{@link #getEl}</code>,
- * but in some cases, a Component may have some more wrapping Elements around its main
- * active Element.</p>
- * <p>An example is a ComboBox. It is encased in a <i>wrapping</i> Element which
- * contains both the <code><input></code> Element (which is what would be returned
- * by its <code>{@link #getEl}</code> method, <i>and</i> the trigger button Element.
- * This Element is returned as the <code>resizeEl</code>.
- */
- getResizeEl : function(){
- return this.resizeEl || this.el;
- },
-
- // protected
- getPositionEl : function(){
- return this.positionEl || this.el;
- },
-
- /**
- * Sets the left and top of the component. To set the page XY position instead, use {@link #setPagePosition}.
- * This method fires the {@link #move} event.
- * @param {Number} left The new left
- * @param {Number} top The new top
- * @return {Ext.BoxComponent} this
- */
- setPosition : function(x, y){
- if(x && typeof x[1] == 'number'){
- y = x[1];
- x = x[0];
- }
- this.x = x;
- this.y = y;
- if(!this.boxReady){
- return this;
- }
- var adj = this.adjustPosition(x, y);
- var ax = adj.x, ay = adj.y;
-
- var el = this.getPositionEl();
- if(ax !== undefined || ay !== undefined){
- if(ax !== undefined && ay !== undefined){
- el.setLeftTop(ax, ay);
- }else if(ax !== undefined){
- el.setLeft(ax);
- }else if(ay !== undefined){
- el.setTop(ay);
- }
- this.onPosition(ax, ay);
- this.fireEvent('move', this, ax, ay);
- }
- return this;
- },
-
- /**
- * Sets the page XY position of the component. To set the left and top instead, use {@link #setPosition}.
- * This method fires the {@link #move} event.
- * @param {Number} x The new x position
- * @param {Number} y The new y position
- * @return {Ext.BoxComponent} this
- */
- setPagePosition : function(x, y){
- if(x && typeof x[1] == 'number'){
- y = x[1];
- x = x[0];
- }
- this.pageX = x;
- this.pageY = y;
- if(!this.boxReady){
- return;
- }
- if(x === undefined || y === undefined){ // cannot translate undefined points
- return;
- }
- var p = this.getPositionEl().translatePoints(x, y);
- this.setPosition(p.left, p.top);
- return this;
- },
-
- // private
- onRender : function(ct, position){
- Ext.BoxComponent.superclass.onRender.call(this, ct, position);
- if(this.resizeEl){
- this.resizeEl = Ext.get(this.resizeEl);
- }
- if(this.positionEl){
- this.positionEl = Ext.get(this.positionEl);
- }
- },
-
- // private
- afterRender : function(){
- Ext.BoxComponent.superclass.afterRender.call(this);
- this.boxReady = true;
- this.setSize(this.width, this.height);
- if(this.x || this.y){
- this.setPosition(this.x, this.y);
- }else if(this.pageX || this.pageY){
- this.setPagePosition(this.pageX, this.pageY);
- }
- },
-
- /**
- * Force the component's size to recalculate based on the underlying element's current height and width.
- * @return {Ext.BoxComponent} this
- */
- syncSize : function(){
- delete this.lastSize;
- this.setSize(this.autoWidth ? undefined : this.getResizeEl().getWidth(), this.autoHeight ? undefined : this.getResizeEl().getHeight());
- return this;
- },
-
- /* // protected
- * Called after the component is resized, this method is empty by default but can be implemented by any
- * subclass that needs to perform custom logic after a resize occurs.
- * @param {Number} adjWidth The box-adjusted width that was set
- * @param {Number} adjHeight The box-adjusted height that was set
- * @param {Number} rawWidth The width that was originally specified
- * @param {Number} rawHeight The height that was originally specified
- */
- onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
-
- },
-
- /* // protected
- * Called after the component is moved, this method is empty by default but can be implemented by any
- * subclass that needs to perform custom logic after a move occurs.
- * @param {Number} x The new x position
- * @param {Number} y The new y position
- */
- onPosition : function(x, y){
-
- },
-
- // private
- adjustSize : function(w, h){
- if(this.autoWidth){
- w = 'auto';
- }
- if(this.autoHeight){
- h = 'auto';
- }
- return {width : w, height: h};
- },
-
- // private
- adjustPosition : function(x, y){
- return {x : x, y: y};
- }
-});
-Ext.reg('box', Ext.BoxComponent);
-
-
-/**
- * @class Ext.Spacer
- * @extends Ext.BoxComponent
- * <p>Used to provide a sizable space in a layout.</p>
- * @constructor
- * @param {Object} config
- */
-Ext.Spacer = Ext.extend(Ext.BoxComponent, {
- autoEl:'div'
-});
-Ext.reg('spacer', Ext.Spacer);/**\r
- * @class Ext.SplitBar\r
- * @extends Ext.util.Observable\r
- * Creates draggable splitter bar functionality from two elements (element to be dragged and element to be resized).\r
- * <br><br>\r
- * Usage:\r
- * <pre><code>\r
-var split = new Ext.SplitBar("elementToDrag", "elementToSize",\r
- Ext.SplitBar.HORIZONTAL, Ext.SplitBar.LEFT);\r
-split.setAdapter(new Ext.SplitBar.AbsoluteLayoutAdapter("container"));\r
-split.minSize = 100;\r
-split.maxSize = 600;\r
-split.animate = true;\r
-split.on('moved', splitterMoved);\r
-</code></pre>\r
- * @constructor\r
- * Create a new SplitBar\r
- * @param {Mixed} dragElement The element to be dragged and act as the SplitBar.\r
- * @param {Mixed} resizingElement The element to be resized based on where the SplitBar element is dragged\r
- * @param {Number} orientation (optional) Either Ext.SplitBar.HORIZONTAL or Ext.SplitBar.VERTICAL. (Defaults to HORIZONTAL)\r
- * @param {Number} placement (optional) Either Ext.SplitBar.LEFT or Ext.SplitBar.RIGHT for horizontal or \r
- Ext.SplitBar.TOP or Ext.SplitBar.BOTTOM for vertical. (By default, this is determined automatically by the initial\r
- position of the SplitBar).\r
- */\r
-Ext.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){\r
- \r
- /** @private */\r
- this.el = Ext.get(dragElement, true);\r
- this.el.dom.unselectable = "on";\r
- /** @private */\r
- this.resizingEl = Ext.get(resizingElement, true);\r
-\r
- /**\r
- * @private\r
- * The orientation of the split. Either Ext.SplitBar.HORIZONTAL or Ext.SplitBar.VERTICAL. (Defaults to HORIZONTAL)\r
- * Note: If this is changed after creating the SplitBar, the placement property must be manually updated\r
- * @type Number\r
- */\r
- this.orientation = orientation || Ext.SplitBar.HORIZONTAL;\r
- \r
- /**\r
- * The increment, in pixels by which to move this SplitBar. When <i>undefined</i>, the SplitBar moves smoothly.\r
- * @type Number\r
- * @property tickSize\r
- */\r
- /**\r
- * The minimum size of the resizing element. (Defaults to 0)\r
- * @type Number\r
- */\r
- this.minSize = 0;\r
- \r
- /**\r
- * The maximum size of the resizing element. (Defaults to 2000)\r
- * @type Number\r
- */\r
- this.maxSize = 2000;\r
- \r
- /**\r
- * Whether to animate the transition to the new size\r
- * @type Boolean\r
- */\r
- this.animate = false;\r
- \r
- /**\r
- * Whether to create a transparent shim that overlays the page when dragging, enables dragging across iframes.\r
- * @type Boolean\r
- */\r
- this.useShim = false;\r
- \r
- /** @private */\r
- this.shim = null;\r
- \r
- if(!existingProxy){\r
- /** @private */\r
- this.proxy = Ext.SplitBar.createProxy(this.orientation);\r
- }else{\r
- this.proxy = Ext.get(existingProxy).dom;\r
- }\r
- /** @private */\r
- this.dd = new Ext.dd.DDProxy(this.el.dom.id, "XSplitBars", {dragElId : this.proxy.id});\r
- \r
- /** @private */\r
- this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this);\r
- \r
- /** @private */\r
- this.dd.endDrag = this.onEndProxyDrag.createDelegate(this);\r
- \r
- /** @private */\r
- this.dragSpecs = {};\r
- \r
- /**\r
- * @private The adapter to use to positon and resize elements\r
- */\r
- this.adapter = new Ext.SplitBar.BasicLayoutAdapter();\r
- this.adapter.init(this);\r
- \r
- if(this.orientation == Ext.SplitBar.HORIZONTAL){\r
- /** @private */\r
- this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? Ext.SplitBar.LEFT : Ext.SplitBar.RIGHT);\r
- this.el.addClass("x-splitbar-h");\r
- }else{\r
- /** @private */\r
- this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? Ext.SplitBar.TOP : Ext.SplitBar.BOTTOM);\r
- this.el.addClass("x-splitbar-v");\r
- }\r
- \r
- this.addEvents(\r
- /**\r
- * @event resize\r
- * Fires when the splitter is moved (alias for {@link #moved})\r
- * @param {Ext.SplitBar} this\r
- * @param {Number} newSize the new width or height\r
- */\r
- "resize",\r
- /**\r
- * @event moved\r
- * Fires when the splitter is moved\r
- * @param {Ext.SplitBar} this\r
- * @param {Number} newSize the new width or height\r
- */\r
- "moved",\r
- /**\r
- * @event beforeresize\r
- * Fires before the splitter is dragged\r
- * @param {Ext.SplitBar} this\r
- */\r
- "beforeresize",\r
-\r
- "beforeapply"\r
- );\r
-\r
- Ext.SplitBar.superclass.constructor.call(this);\r
-};\r
-\r
-Ext.extend(Ext.SplitBar, Ext.util.Observable, {\r
- onStartProxyDrag : function(x, y){\r
- this.fireEvent("beforeresize", this);\r
- this.overlay = Ext.DomHelper.append(document.body, {cls: "x-drag-overlay", html: " "}, true);\r
- this.overlay.unselectable();\r
- this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));\r
- this.overlay.show();\r
- Ext.get(this.proxy).setDisplayed("block");\r
- var size = this.adapter.getElementSize(this);\r
- this.activeMinSize = this.getMinimumSize();\r
- this.activeMaxSize = this.getMaximumSize();\r
- var c1 = size - this.activeMinSize;\r
- var c2 = Math.max(this.activeMaxSize - size, 0);\r
- if(this.orientation == Ext.SplitBar.HORIZONTAL){\r
- this.dd.resetConstraints();\r
- this.dd.setXConstraint(\r
- this.placement == Ext.SplitBar.LEFT ? c1 : c2, \r
- this.placement == Ext.SplitBar.LEFT ? c2 : c1,\r
- this.tickSize\r
- );\r
- this.dd.setYConstraint(0, 0);\r
- }else{\r
- this.dd.resetConstraints();\r
- this.dd.setXConstraint(0, 0);\r
- this.dd.setYConstraint(\r
- this.placement == Ext.SplitBar.TOP ? c1 : c2, \r
- this.placement == Ext.SplitBar.TOP ? c2 : c1,\r
- this.tickSize\r
- );\r
- }\r
- this.dragSpecs.startSize = size;\r
- this.dragSpecs.startPoint = [x, y];\r
- Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd, x, y);\r
- },\r
- \r
- /** \r
- * @private Called after the drag operation by the DDProxy\r
- */\r
- onEndProxyDrag : function(e){\r
- Ext.get(this.proxy).setDisplayed(false);\r
- var endPoint = Ext.lib.Event.getXY(e);\r
- if(this.overlay){\r
- Ext.destroy(this.overlay);\r
- delete this.overlay;\r
- }\r
- var newSize;\r
- if(this.orientation == Ext.SplitBar.HORIZONTAL){\r
- newSize = this.dragSpecs.startSize + \r
- (this.placement == Ext.SplitBar.LEFT ?\r
- endPoint[0] - this.dragSpecs.startPoint[0] :\r
- this.dragSpecs.startPoint[0] - endPoint[0]\r
- );\r
- }else{\r
- newSize = this.dragSpecs.startSize + \r
- (this.placement == Ext.SplitBar.TOP ?\r
- endPoint[1] - this.dragSpecs.startPoint[1] :\r
- this.dragSpecs.startPoint[1] - endPoint[1]\r
- );\r
- }\r
- newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize);\r
- if(newSize != this.dragSpecs.startSize){\r
- if(this.fireEvent('beforeapply', this, newSize) !== false){\r
- this.adapter.setElementSize(this, newSize);\r
- this.fireEvent("moved", this, newSize);\r
- this.fireEvent("resize", this, newSize);\r
- }\r
- }\r
- },\r
- \r
- /**\r
- * Get the adapter this SplitBar uses\r
- * @return The adapter object\r
- */\r
- getAdapter : function(){\r
- return this.adapter;\r
- },\r
- \r
- /**\r
- * Set the adapter this SplitBar uses\r
- * @param {Object} adapter A SplitBar adapter object\r
- */\r
- setAdapter : function(adapter){\r
- this.adapter = adapter;\r
- this.adapter.init(this);\r
- },\r
- \r
- /**\r
- * Gets the minimum size for the resizing element\r
- * @return {Number} The minimum size\r
- */\r
- getMinimumSize : function(){\r
- return this.minSize;\r
- },\r
- \r
- /**\r
- * Sets the minimum size for the resizing element\r
- * @param {Number} minSize The minimum size\r
- */\r
- setMinimumSize : function(minSize){\r
- this.minSize = minSize;\r
- },\r
- \r
- /**\r
- * Gets the maximum size for the resizing element\r
- * @return {Number} The maximum size\r
- */\r
- getMaximumSize : function(){\r
- return this.maxSize;\r
- },\r
- \r
- /**\r
- * Sets the maximum size for the resizing element\r
- * @param {Number} maxSize The maximum size\r
- */\r
- setMaximumSize : function(maxSize){\r
- this.maxSize = maxSize;\r
- },\r
- \r
- /**\r
- * Sets the initialize size for the resizing element\r
- * @param {Number} size The initial size\r
- */\r
- setCurrentSize : function(size){\r
- var oldAnimate = this.animate;\r
- this.animate = false;\r
- this.adapter.setElementSize(this, size);\r
- this.animate = oldAnimate;\r
- },\r
- \r
- /**\r
- * Destroy this splitbar. \r
- * @param {Boolean} removeEl True to remove the element\r
- */\r
- destroy : function(removeEl){\r
- Ext.destroy(this.shim, Ext.get(this.proxy));\r
- this.dd.unreg();\r
- if(removeEl){\r
- this.el.remove();\r
- }\r
- this.purgeListeners();\r
- }\r
-});\r
-\r
-/**\r
- * @private static Create our own proxy element element. So it will be the same same size on all browsers, we won't use borders. Instead we use a background color.\r
- */\r
-Ext.SplitBar.createProxy = function(dir){\r
- var proxy = new Ext.Element(document.createElement("div"));\r
- proxy.unselectable();\r
- var cls = 'x-splitbar-proxy';\r
- proxy.addClass(cls + ' ' + (dir == Ext.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v'));\r
- document.body.appendChild(proxy.dom);\r
- return proxy.dom;\r
-};\r
-\r
-/** \r
- * @class Ext.SplitBar.BasicLayoutAdapter\r
- * Default Adapter. It assumes the splitter and resizing element are not positioned\r
- * elements and only gets/sets the width of the element. Generally used for table based layouts.\r
- */\r
-Ext.SplitBar.BasicLayoutAdapter = function(){\r
-};\r
-\r
-Ext.SplitBar.BasicLayoutAdapter.prototype = {\r
- // do nothing for now\r
- init : function(s){\r
- \r
- },\r
- /**\r
- * Called before drag operations to get the current size of the resizing element. \r
- * @param {Ext.SplitBar} s The SplitBar using this adapter\r
- */\r
- getElementSize : function(s){\r
- if(s.orientation == Ext.SplitBar.HORIZONTAL){\r
- return s.resizingEl.getWidth();\r
- }else{\r
- return s.resizingEl.getHeight();\r
- }\r
- },\r
- \r
- /**\r
- * Called after drag operations to set the size of the resizing element.\r
- * @param {Ext.SplitBar} s The SplitBar using this adapter\r
- * @param {Number} newSize The new size to set\r
- * @param {Function} onComplete A function to be invoked when resizing is complete\r
- */\r
- setElementSize : function(s, newSize, onComplete){\r
- if(s.orientation == Ext.SplitBar.HORIZONTAL){\r
- if(!s.animate){\r
- s.resizingEl.setWidth(newSize);\r
- if(onComplete){\r
- onComplete(s, newSize);\r
- }\r
- }else{\r
- s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut');\r
- }\r
- }else{\r
- \r
- if(!s.animate){\r
- s.resizingEl.setHeight(newSize);\r
- if(onComplete){\r
- onComplete(s, newSize);\r
- }\r
- }else{\r
- s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut');\r
- }\r
- }\r
- }\r
-};\r
-\r
-/** \r
- *@class Ext.SplitBar.AbsoluteLayoutAdapter\r
- * @extends Ext.SplitBar.BasicLayoutAdapter\r
- * Adapter that moves the splitter element to align with the resized sizing element. \r
- * Used with an absolute positioned SplitBar.\r
- * @param {Mixed} container The container that wraps around the absolute positioned content. If it's\r
- * document.body, make sure you assign an id to the body element.\r
- */\r
-Ext.SplitBar.AbsoluteLayoutAdapter = function(container){\r
- this.basic = new Ext.SplitBar.BasicLayoutAdapter();\r
- this.container = Ext.get(container);\r
-};\r
-\r
-Ext.SplitBar.AbsoluteLayoutAdapter.prototype = {\r
- init : function(s){\r
- this.basic.init(s);\r
- },\r
- \r
- getElementSize : function(s){\r
- return this.basic.getElementSize(s);\r
- },\r
- \r
- setElementSize : function(s, newSize, onComplete){\r
- this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s]));\r
- },\r
- \r
- moveSplitter : function(s){\r
- var yes = Ext.SplitBar;\r
- switch(s.placement){\r
- case yes.LEFT:\r
- s.el.setX(s.resizingEl.getRight());\r
- break;\r
- case yes.RIGHT:\r
- s.el.setStyle("right", (this.container.getWidth() - s.resizingEl.getLeft()) + "px");\r
- break;\r
- case yes.TOP:\r
- s.el.setY(s.resizingEl.getBottom());\r
- break;\r
- case yes.BOTTOM:\r
- s.el.setY(s.resizingEl.getTop() - s.el.getHeight());\r
- break;\r
- }\r
- }\r
-};\r
-\r
-/**\r
- * Orientation constant - Create a vertical SplitBar\r
- * @static\r
- * @type Number\r
- */\r
-Ext.SplitBar.VERTICAL = 1;\r
-\r
-/**\r
- * Orientation constant - Create a horizontal SplitBar\r
- * @static\r
- * @type Number\r
- */\r
-Ext.SplitBar.HORIZONTAL = 2;\r
-\r
-/**\r
- * Placement constant - The resizing element is to the left of the splitter element\r
- * @static\r
- * @type Number\r
- */\r
-Ext.SplitBar.LEFT = 1;\r
-\r
-/**\r
- * Placement constant - The resizing element is to the right of the splitter element\r
- * @static\r
- * @type Number\r
- */\r
-Ext.SplitBar.RIGHT = 2;\r
-\r
-/**\r
- * Placement constant - The resizing element is positioned above the splitter element\r
- * @static\r
- * @type Number\r
- */\r
-Ext.SplitBar.TOP = 3;\r
-\r
-/**\r
- * Placement constant - The resizing element is positioned under splitter element\r
- * @static\r
- * @type Number\r
- */\r
-Ext.SplitBar.BOTTOM = 4;\r
-/**
- * @class Ext.Container
- * @extends Ext.BoxComponent
- * <p>Base class for any {@link Ext.BoxComponent} that may contain other Components. Containers handle the
- * basic behavior of containing items, namely adding, inserting and removing items.</p>
- *
- * <p>The most commonly used Container classes are {@link Ext.Panel}, {@link Ext.Window} and {@link Ext.TabPanel}.
- * If you do not need the capabilities offered by the aforementioned classes you can create a lightweight
- * Container to be encapsulated by an HTML element to your specifications by using the
- * <tt><b>{@link Ext.Component#autoEl autoEl}</b></tt> config option. This is a useful technique when creating
- * embedded {@link Ext.layout.ColumnLayout column} layouts inside {@link Ext.form.FormPanel FormPanels}
- * for example.</p>
- *
- * <p>The code below illustrates both how to explicitly create a Container, and how to implicitly
- * create one using the <b><tt>'container'</tt></b> xtype:<pre><code>
-// explicitly create a Container
-var embeddedColumns = new Ext.Container({
- autoEl: 'div', // This is the default
- layout: 'column',
- defaults: {
- // implicitly create Container by specifying xtype
- xtype: 'container',
- autoEl: 'div', // This is the default.
- layout: 'form',
- columnWidth: 0.5,
- style: {
- padding: '10px'
- }
- },
-// The two items below will be Ext.Containers, each encapsulated by a <DIV> element.
- items: [{
- items: {
- xtype: 'datefield',
- name: 'startDate',
- fieldLabel: 'Start date'
- }
- }, {
- items: {
- xtype: 'datefield',
- name: 'endDate',
- fieldLabel: 'End date'
- }
- }]
-});</code></pre></p>
- *
- * <p><u><b>Layout</b></u></p>
- * <p>Container classes delegate the rendering of child Components to a layout
- * manager class which must be configured into the Container using the
- * <code><b>{@link #layout}</b></code> configuration property.</p>
- * <p>When either specifying child <code>{@link #items}</code> of a Container,
- * or dynamically {@link #add adding} Components to a Container, remember to
- * consider how you wish the Container to arrange those child elements, and
- * whether those child elements need to be sized using one of Ext's built-in
- * <b><code>{@link #layout}</code></b> schemes. By default, Containers use the
- * {@link Ext.layout.ContainerLayout ContainerLayout} scheme which only
- * renders child components, appending them one after the other inside the
- * Container, and <b>does not apply any sizing</b> at all.</p>
- * <p>A common mistake is when a developer neglects to specify a
- * <b><code>{@link #layout}</code></b> (e.g. widgets like GridPanels or
- * TreePanels are added to Containers for which no <tt><b>{@link #layout}</b></tt>
- * has been specified). If a Container is left to use the default
- * {@link Ext.layout.ContainerLayout ContainerLayout} scheme, none of its
- * child components will be resized, or changed in any way when the Container
- * is resized.</p>
- * <p>Certain layout managers allow dynamic addition of child components.
- * Those that do include {@link Ext.layout.CardLayout},
- * {@link Ext.layout.AnchorLayout}, {@link Ext.layout.FormLayout}, and
- * {@link Ext.layout.TableLayout}. For example:<pre><code>
-// Create the GridPanel.
-var myNewGrid = new Ext.grid.GridPanel({
- store: myStore,
- columns: myColumnModel,
- title: 'Results', // the title becomes the title of the tab
-});
-
-myTabPanel.add(myNewGrid); // {@link Ext.TabPanel} implicitly uses {@link Ext.layout.CardLayout CardLayout}
-myTabPanel.{@link Ext.TabPanel#setActiveTab setActiveTab}(myNewGrid);
- * </code></pre></p>
- * <p>The example above adds a newly created GridPanel to a TabPanel. Note that
- * a TabPanel uses {@link Ext.layout.CardLayout} as its layout manager which
- * means all its child items are sized to {@link Ext.layout.FitLayout fit}
- * exactly into its client area.
- * <p><b><u>Overnesting is a common problem</u></b>.
- * An example of overnesting occurs when a GridPanel is added to a TabPanel
- * by wrapping the GridPanel <i>inside</i> a wrapping Panel (that has no
- * <tt><b>{@link #layout}</b></tt> specified) and then add that wrapping Panel
- * to the TabPanel. The point to realize is that a GridPanel <b>is</b> a
- * Component which can be added directly to a Container. If the wrapping Panel
- * has no <tt><b>{@link #layout}</b></tt> configuration, then the overnested
- * GridPanel will not be sized as expected.<p>
-</code></pre>
- *
- * <p><u><b>Adding via remote configuration</b></u></p>
- *
- * <p>A server side script can be used to add Components which are generated dynamically on the server.
- * An example of adding a GridPanel to a TabPanel where the GridPanel is generated by the server
- * based on certain parameters:
- * </p><pre><code>
-// execute an Ajax request to invoke server side script:
-Ext.Ajax.request({
- url: 'gen-invoice-grid.php',
- // send additional parameters to instruct server script
- params: {
- startDate: Ext.getCmp('start-date').getValue(),
- endDate: Ext.getCmp('end-date').getValue()
- },
- // process the response object to add it to the TabPanel:
- success: function(xhr) {
- var newComponent = eval(xhr.responseText); // see discussion below
- myTabPanel.add(newComponent); // add the component to the TabPanel
- myTabPanel.setActiveTab(newComponent);
- },
- failure: function() {
- Ext.Msg.alert("Grid create failed", "Server communication failure");
- }
-});
-</code></pre>
- * <p>The server script needs to return an executable Javascript statement which, when processed
- * using <tt>eval()</tt>, will return either a config object with an {@link Ext.Component#xtype xtype},
- * or an instantiated Component. The server might return this for example:</p><pre><code>
-(function() {
- function formatDate(value){
- return value ? value.dateFormat('M d, Y') : '';
- };
-
- var store = new Ext.data.Store({
- url: 'get-invoice-data.php',
- baseParams: {
- startDate: '01/01/2008',
- endDate: '01/31/2008'
- },
- reader: new Ext.data.JsonReader({
- record: 'transaction',
- idProperty: 'id',
- totalRecords: 'total'
- }, [
- 'customer',
- 'invNo',
- {name: 'date', type: 'date', dateFormat: 'm/d/Y'},
- {name: 'value', type: 'float'}
- ])
- });
-
- var grid = new Ext.grid.GridPanel({
- title: 'Invoice Report',
- bbar: new Ext.PagingToolbar(store),
- store: store,
- columns: [
- {header: "Customer", width: 250, dataIndex: 'customer', sortable: true},
- {header: "Invoice Number", width: 120, dataIndex: 'invNo', sortable: true},
- {header: "Invoice Date", width: 100, dataIndex: 'date', renderer: formatDate, sortable: true},
- {header: "Value", width: 120, dataIndex: 'value', renderer: 'usMoney', sortable: true}
- ],
- });
- store.load();
- return grid; // return instantiated component
-})();
-</code></pre>
- * <p>When the above code fragment is passed through the <tt>eval</tt> function in the success handler
- * of the Ajax request, the code is executed by the Javascript processor, and the anonymous function
- * runs, and returns the instantiated grid component.</p>
- * <p>Note: since the code above is <i>generated</i> by a server script, the <tt>baseParams</tt> for
- * the Store, the metadata to allow generation of the Record layout, and the ColumnModel
- * can all be generated into the code since these are all known on the server.</p>
- *
- * @xtype container
- */
-Ext.Container = Ext.extend(Ext.BoxComponent, {
- /**
- * @cfg {Boolean} monitorResize
- * True to automatically monitor window resize events to handle anything that is sensitive to the current size
- * of the viewport. This value is typically managed by the chosen <code>{@link #layout}</code> and should not need
- * to be set manually.
- */
- /**
- * @cfg {String/Object} layout
- * When creating complex UIs, it is important to remember that sizing and
- * positioning of child items is the responsibility of the Container's
- * layout manager. If you expect child items to be sized in response to
- * user interactions, <b>you must specify a layout manager</b> which
- * creates and manages the type of layout you have in mind. For example:<pre><code>
-new Ext.Window({
- width:300, height: 300,
- layout: 'fit', // explicitly set layout manager: override the default (layout:'auto')
- items: [{
- title: 'Panel inside a Window'
- }]
-}).show();
- * </code></pre>
- * <p>Omitting the {@link #layout} config means that the
- * {@link Ext.layout.ContainerLayout default layout manager} will be used which does
- * nothing but render child components sequentially into the Container (no sizing or
- * positioning will be performed in this situation).</p>
- * <p>The layout manager class for this container may be specified as either as an
- * Object or as a String:</p>
- * <div><ul class="mdetail-params">
- *
- * <li><u>Specify as an Object</u></li>
- * <div><ul class="mdetail-params">
- * <li>Example usage:</li>
-<pre><code>
-layout: {
- type: 'vbox',
- padding: '5',
- align: 'left'
-}
-</code></pre>
- *
- * <li><tt><b>type</b></tt></li>
- * <br/><p>The layout type to be used for this container. If not specified,
- * a default {@link Ext.layout.ContainerLayout} will be created and used.</p>
- * <br/><p>Valid layout <tt>type</tt> values are:</p>
- * <div class="sub-desc"><ul class="mdetail-params">
- * <li><tt><b>{@link Ext.layout.AbsoluteLayout absolute}</b></tt></li>
- * <li><tt><b>{@link Ext.layout.AccordionLayout accordion}</b></tt></li>
- * <li><tt><b>{@link Ext.layout.AnchorLayout anchor}</b></tt></li>
- * <li><tt><b>{@link Ext.layout.ContainerLayout auto}</b></tt> <b>Default</b></li>
- * <li><tt><b>{@link Ext.layout.BorderLayout border}</b></tt></li>
- * <li><tt><b>{@link Ext.layout.CardLayout card}</b></tt></li>
- * <li><tt><b>{@link Ext.layout.ColumnLayout column}</b></tt></li>
- * <li><tt><b>{@link Ext.layout.FitLayout fit}</b></tt></li>
- * <li><tt><b>{@link Ext.layout.FormLayout form}</b></tt></li>
- * <li><tt><b>{@link Ext.layout.HBoxLayout hbox}</b></tt></li>
- * <li><tt><b>{@link Ext.layout.MenuLayout menu}</b></tt></li>
- * <li><tt><b>{@link Ext.layout.TableLayout table}</b></tt></li>
- * <li><tt><b>{@link Ext.layout.ToolbarLayout toolbar}</b></tt></li>
- * <li><tt><b>{@link Ext.layout.VBoxLayout vbox}</b></tt></li>
- * </ul></div>
- *
- * <li>Layout specific configuration properties</li>
- * <br/><p>Additional layout specific configuration properties may also be
- * specified. For complete details regarding the valid config options for
- * each layout type, see the layout class corresponding to the <tt>type</tt>
- * specified.</p>
- *
- * </ul></div>
- *
- * <li><u>Specify as a String</u></li>
- * <div><ul class="mdetail-params">
- * <li>Example usage:</li>
-<pre><code>
-layout: 'vbox',
-layoutConfig: {
- padding: '5',
- align: 'left'
-}
-</code></pre>
- * <li><tt><b>layout</b></tt></li>
- * <br/><p>The layout <tt>type</tt> to be used for this container (see list
- * of valid layout type values above).</p><br/>
- * <li><tt><b>{@link #layoutConfig}</b></tt></li>
- * <br/><p>Additional layout specific configuration properties. For complete
- * details regarding the valid config options for each layout type, see the
- * layout class corresponding to the <tt>layout</tt> specified.</p>
- * </ul></div></ul></div>
- */
- /**
- * @cfg {Object} layoutConfig
- * This is a config object containing properties specific to the chosen
- * <b><code>{@link #layout}</code></b> if <b><code>{@link #layout}</code></b>
- * has been specified as a <i>string</i>.</p>
- */
- /**
- * @cfg {Boolean/Number} bufferResize
- * When set to true (100 milliseconds) or a number of milliseconds, the layout assigned for this container will buffer
- * the frequency it calculates and does a re-layout of components. This is useful for heavy containers or containers
- * with a large quantity of sub-components for which frequent layout calls would be expensive.
- */
- bufferResize: 100,
-
- /**
- * @cfg {String/Number} activeItem
- * A string component id or the numeric index of the component that should be initially activated within the
- * container's layout on render. For example, activeItem: 'item-1' or activeItem: 0 (index 0 = the first
- * item in the container's collection). activeItem only applies to layout styles that can display
- * items one at a time (like {@link Ext.layout.AccordionLayout}, {@link Ext.layout.CardLayout} and
- * {@link Ext.layout.FitLayout}). Related to {@link Ext.layout.ContainerLayout#activeItem}.
- */
- /**
- * @cfg {Object/Array} items
- * <pre><b>** IMPORTANT</b>: be sure to specify a <b><code>{@link #layout}</code> ! **</b></pre>
- * <p>A single item, or an array of child Components to be added to this container,
- * for example:</p>
- * <pre><code>
-// specifying a single item
-items: {...},
-layout: 'fit', // specify a layout!
-
-// specifying multiple items
-items: [{...}, {...}],
-layout: 'anchor', // specify a layout!
- * </code></pre>
- * <p>Each item may be:</p>
- * <div><ul class="mdetail-params">
- * <li>any type of object based on {@link Ext.Component}</li>
- * <li>a fully instanciated object or</li>
- * <li>an object literal that:</li>
- * <div><ul class="mdetail-params">
- * <li>has a specified <code>{@link Ext.Component#xtype xtype}</code></li>
- * <li>the {@link Ext.Component#xtype} specified is associated with the Component
- * desired and should be chosen from one of the available xtypes as listed
- * in {@link Ext.Component}.</li>
- * <li>If an <code>{@link Ext.Component#xtype xtype}</code> is not explicitly
- * specified, the {@link #defaultType} for that Container is used.</li>
- * <li>will be "lazily instanciated", avoiding the overhead of constructing a fully
- * instanciated Component object</li>
- * </ul></div></ul></div>
- * <p><b>Notes</b>:</p>
- * <div><ul class="mdetail-params">
- * <li>Ext uses lazy rendering. Child Components will only be rendered
- * should it become necessary. Items are automatically laid out when they are first
- * shown (no sizing is done while hidden), or in response to a {@link #doLayout} call.</li>
- * <li>Do not specify <code>{@link Ext.Panel#contentEl contentEl}</code>/
- * <code>{@link Ext.Panel#html html}</code> with <code>items</code>.</li>
- * </ul></div>
- */
- /**
- * @cfg {Object} defaults
- * <p>A config object that will be applied to all components added to this container either via the {@link #items}
- * config or via the {@link #add} or {@link #insert} methods. The <tt>defaults</tt> config can contain any
- * number of name/value property pairs to be added to each item, and should be valid for the types of items
- * being added to the container. For example, to automatically apply padding to the body of each of a set of
- * contained {@link Ext.Panel} items, you could pass: <tt>defaults: {bodyStyle:'padding:15px'}</tt>.</p><br/>
- * <p><b>Note</b>: <tt>defaults</tt> will not be applied to config objects if the option is already specified.
- * For example:</p><pre><code>
-defaults: { // defaults are applied to items, not the container
- autoScroll:true
-},
-items: [
- {
- xtype: 'panel', // defaults <b>do not</b> have precedence over
- id: 'panel1', // options in config objects, so the defaults
- autoScroll: false // will not be applied here, panel1 will be autoScroll:false
- },
- new Ext.Panel({ // defaults <b>do</b> have precedence over options
- id: 'panel2', // options in components, so the defaults
- autoScroll: false // will be applied here, panel2 will be autoScroll:true.
- })
-]
- * </code></pre>
- */
-
-
- /** @cfg {Boolean} autoDestroy
- * If true the container will automatically destroy any contained component that is removed from it, else
- * destruction must be handled manually (defaults to true).
- */
- autoDestroy : true,
-
- /** @cfg {Boolean} forceLayout
- * If true the container will force a layout initially even if hidden or collapsed. This option
- * is useful for forcing forms to render in collapsed or hidden containers. (defaults to false).
- */
- forceLayout: false,
-
- /** @cfg {Boolean} hideBorders
- * True to hide the borders of each contained component, false to defer to the component's existing
- * border settings (defaults to false).
- */
- /** @cfg {String} defaultType
- * <p>The default {@link Ext.Component xtype} of child Components to create in this Container when
- * a child item is specified as a raw configuration object, rather than as an instantiated Component.</p>
- * <p>Defaults to <tt>'panel'</tt>, except {@link Ext.menu.Menu} which defaults to <tt>'menuitem'</tt>,
- * and {@link Ext.Toolbar} and {@link Ext.ButtonGroup} which default to <tt>'button'</tt>.</p>
- */
- defaultType : 'panel',
-
- // private
- initComponent : function(){
- Ext.Container.superclass.initComponent.call(this);
-
- this.addEvents(
- /**
- * @event afterlayout
- * Fires when the components in this container are arranged by the associated layout manager.
- * @param {Ext.Container} this
- * @param {ContainerLayout} layout The ContainerLayout implementation for this container
- */
- 'afterlayout',
- /**
- * @event beforeadd
- * Fires before any {@link Ext.Component} is added or inserted into the container.
- * A handler can return false to cancel the add.
- * @param {Ext.Container} this
- * @param {Ext.Component} component The component being added
- * @param {Number} index The index at which the component will be added to the container's items collection
- */
- 'beforeadd',
- /**
- * @event beforeremove
- * Fires before any {@link Ext.Component} is removed from the container. A handler can return
- * false to cancel the remove.
- * @param {Ext.Container} this
- * @param {Ext.Component} component The component being removed
- */
- 'beforeremove',
- /**
- * @event add
- * @bubbles
- * Fires after any {@link Ext.Component} is added or inserted into the container.
- * @param {Ext.Container} this
- * @param {Ext.Component} component The component that was added
- * @param {Number} index The index at which the component was added to the container's items collection
- */
- 'add',
- /**
- * @event remove
- * @bubbles
- * Fires after any {@link Ext.Component} is removed from the container.
- * @param {Ext.Container} this
- * @param {Ext.Component} component The component that was removed
- */
- 'remove'
- );
-
- this.enableBubble('add', 'remove');
-
- /**
- * The collection of components in this container as a {@link Ext.util.MixedCollection}
- * @type MixedCollection
- * @property items
- */
- var items = this.items;
- if(items){
- delete this.items;
- if(Ext.isArray(items) && items.length > 0){
- this.add.apply(this, items);
- }else{
- this.add(items);
- }
- }
- },
-
- // private
- initItems : function(){
- if(!this.items){
- this.items = new Ext.util.MixedCollection(false, this.getComponentId);
- this.getLayout(); // initialize the layout
- }
- },
-
- // private
- setLayout : function(layout){
- if(this.layout && this.layout != layout){
- this.layout.setContainer(null);
- }
- this.initItems();
- this.layout = layout;
- layout.setContainer(this);
- },
-
- // private
- render : function(){
- Ext.Container.superclass.render.apply(this, arguments);
- if(this.layout){
- if(Ext.isObject(this.layout) && !this.layout.layout){
- this.layoutConfig = this.layout;
- this.layout = this.layoutConfig.type;
- }
- if(typeof this.layout == 'string'){
- this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);
- }
- this.setLayout(this.layout);
-
- if(this.activeItem !== undefined){
- var item = this.activeItem;
- delete this.activeItem;
- this.layout.setActiveItem(item);
- }
- }
- if(!this.ownerCt){
- // force a layout if no ownerCt is set
- this.doLayout(false, true);
- }
- if(this.monitorResize === true){
- Ext.EventManager.onWindowResize(this.doLayout, this, [false]);
- }
- },
-
- /**
- * <p>Returns the Element to be used to contain the child Components of this Container.</p>
- * <p>An implementation is provided which returns the Container's {@link #getEl Element}, but
- * if there is a more complex structure to a Container, this may be overridden to return
- * the element into which the {@link #layout layout} renders child Components.</p>
- * @return {Ext.Element} The Element to render child Components into.
- */
- getLayoutTarget : function(){
- return this.el;
- },
-
- // private - used as the key lookup function for the items collection
- getComponentId : function(comp){
- return comp.getItemId();
- },
-
- /**
- * <p>Adds {@link Ext.Component Component}(s) to this Container.</p>
- * <br><p><b>Description</b></u> :
- * <div><ul class="mdetail-params">
- * <li>Fires the {@link #beforeadd} event before adding</li>
- * <li>The Container's {@link #defaults default config values} will be applied
- * accordingly (see <code>{@link #defaults}</code> for details).</li>
- * <li>Fires the {@link #add} event after the component has been added.</li>
- * </ul></div>
- * <br><p><b>Notes</b></u> :
- * <div><ul class="mdetail-params">
- * <li>If the Container is <i>already rendered</i> when <tt>add</tt>
- * is called, you may need to call {@link #doLayout} to refresh the view which causes
- * any unrendered child Components to be rendered. This is required so that you can
- * <tt>add</tt> multiple child components if needed while only refreshing the layout
- * once. For example:<pre><code>
-var tb = new {@link Ext.Toolbar}();
-tb.render(document.body); // toolbar is rendered
-tb.add({text:'Button 1'}); // add multiple items ({@link #defaultType} for {@link Ext.Toolbar Toolbar} is 'button')
-tb.add({text:'Button 2'});
-tb.{@link #doLayout}(); // refresh the layout
- * </code></pre></li>
- * <li><i>Warning:</i> Containers directly managed by the BorderLayout layout manager
- * may not be removed or added. See the Notes for {@link Ext.layout.BorderLayout BorderLayout}
- * for more details.</li>
- * </ul></div>
- * @param {Object/Array} component
- * <p>Either a single component or an Array of components to add. See
- * <code>{@link #items}</code> for additional information.</p>
- * @param {Object} (Optional) component_2
- * @param {Object} (Optional) component_n
- * @return {Ext.Component} component The Component (or config object) that was added.
- */
- add : function(comp){
- this.initItems();
- var args = arguments.length > 1;
- if(args || Ext.isArray(comp)){
- Ext.each(args ? arguments : comp, function(c){
- this.add(c);
- }, this);
- return;
- }
- var c = this.lookupComponent(this.applyDefaults(comp));
- var pos = this.items.length;
- if(this.fireEvent('beforeadd', this, c, pos) !== false && this.onBeforeAdd(c) !== false){
- this.items.add(c);
- c.ownerCt = this;
- this.fireEvent('add', this, c, pos);
- }
- return c;
- },
-
- /**
- * Inserts a Component into this Container at a specified index. Fires the
- * {@link #beforeadd} event before inserting, then fires the {@link #add} event after the
- * Component has been inserted.
- * @param {Number} index The index at which the Component will be inserted
- * into the Container's items collection
- * @param {Ext.Component} component The child Component to insert.<br><br>
- * Ext uses lazy rendering, and will only render the inserted Component should
- * it become necessary.<br><br>
- * A Component config object may be passed in order to avoid the overhead of
- * constructing a real Component object if lazy rendering might mean that the
- * inserted Component will not be rendered immediately. To take advantage of
- * this 'lazy instantiation', set the {@link Ext.Component#xtype} config
- * property to the registered type of the Component wanted.<br><br>
- * For a list of all available xtypes, see {@link Ext.Component}.
- * @return {Ext.Component} component The Component (or config object) that was
- * inserted with the Container's default config values applied.
- */
- insert : function(index, comp){
- this.initItems();
- var a = arguments, len = a.length;
- if(len > 2){
- for(var i = len-1; i >= 1; --i) {
- this.insert(index, a[i]);
- }
- return;
- }
- var c = this.lookupComponent(this.applyDefaults(comp));
-
- if(c.ownerCt == this && this.items.indexOf(c) < index){
- --index;
- }
-
- if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){
- this.items.insert(index, c);
- c.ownerCt = this;
- this.fireEvent('add', this, c, index);
- }
- return c;
- },
-
- // private
- applyDefaults : function(c){
- if(this.defaults){
- if(typeof c == 'string'){
- c = Ext.ComponentMgr.get(c);
- Ext.apply(c, this.defaults);
- }else if(!c.events){
- Ext.applyIf(c, this.defaults);
- }else{
- Ext.apply(c, this.defaults);
- }
- }
- return c;
- },
-
- // private
- onBeforeAdd : function(item){
- if(item.ownerCt){
- item.ownerCt.remove(item, false);
- }
- if(this.hideBorders === true){
- item.border = (item.border === true);
- }
- },
-
- /**
- * Removes a component from this container. Fires the {@link #beforeremove} event before removing, then fires
- * the {@link #remove} event after the component has been removed.
- * @param {Component/String} component The component reference or id to remove.
- * @param {Boolean} autoDestroy (optional) True to automatically invoke the removed Component's {@link Ext.Component#destroy} function.
- * Defaults to the value of this Container's {@link #autoDestroy} config.
- * @return {Ext.Component} component The Component that was removed.
- */
- remove : function(comp, autoDestroy){
- this.initItems();
- var c = this.getComponent(comp);
- if(c && this.fireEvent('beforeremove', this, c) !== false){
- this.items.remove(c);
- delete c.ownerCt;
- if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){
- c.destroy();
- }
- if(this.layout && this.layout.activeItem == c){
- delete this.layout.activeItem;
- }
- this.fireEvent('remove', this, c);
- }
- return c;
- },
-
- /**
- * Removes all components from this container.
- * @param {Boolean} autoDestroy (optional) True to automatically invoke the removed Component's {@link Ext.Component#destroy} function.
- * Defaults to the value of this Container's {@link #autoDestroy} config.
- * @return {Array} Array of the destroyed components
- */
- removeAll: function(autoDestroy){
- this.initItems();
- var item, rem = [], items = [];
- this.items.each(function(i){
- rem.push(i);
- });
- for (var i = 0, len = rem.length; i < len; ++i){
- item = rem[i];
- this.remove(item, autoDestroy);
- if(item.ownerCt !== this){
- items.push(item);
- }
- }
- return items;
- },
-
- /**
- * Examines this container's <code>{@link #items}</code> <b>property</b>
- * and gets a direct child component of this container.
- * @param {String/Number} comp This parameter may be any of the following:
- * <div><ul class="mdetail-params">
- * <li>a <b><tt>String</tt></b> : representing the <code>{@link Ext.Component#itemId itemId}</code>
- * or <code>{@link Ext.Component#id id}</code> of the child component </li>
- * <li>a <b><tt>Number</tt></b> : representing the position of the child component
- * within the <code>{@link #items}</code> <b>property</b></li>
- * </ul></div>
- * <p>For additional information see {@link Ext.util.MixedCollection#get}.
- * @return Ext.Component The component (if found).
- */
- getComponent : function(comp){
- if(Ext.isObject(comp)){
- return comp;
- }
- return this.items.get(comp);
- },
-
- // private
- lookupComponent : function(comp){
- if(typeof comp == 'string'){
- return Ext.ComponentMgr.get(comp);
- }else if(!comp.events){
- return this.createComponent(comp);
- }
- return comp;
- },
-
- // private
- createComponent : function(config){
- return Ext.create(config, this.defaultType);
- },
-
- /**
- * Force this container's layout to be recalculated. A call to this function is required after adding a new component
- * to an already rendered container, or possibly after changing sizing/position properties of child components.
- * @param {Boolean} shallow (optional) True to only calc the layout of this component, and let child components auto
- * calc layouts as required (defaults to false, which calls doLayout recursively for each subcontainer)
- * @param {Boolean} force (optional) True to force a layout to occur, even if the item is hidden.
- * @return {Ext.Container} this
- */
- doLayout: function(shallow, force){
- var rendered = this.rendered,
- forceLayout = this.forceLayout;
-
- if(!this.isVisible() || this.collapsed){
- this.deferLayout = this.deferLayout || !shallow;
- if(!(force || forceLayout)){
- return;
- }
- shallow = shallow && !this.deferLayout;
- } else {
- delete this.deferLayout;
- }
- if(rendered && this.layout){
- this.layout.layout();
- }
- if(shallow !== true && this.items){
- var cs = this.items.items;
- for(var i = 0, len = cs.length; i < len; i++){
- var c = cs[i];
- if(c.doLayout){
- c.forceLayout = forceLayout;
- c.doLayout();
- }
- }
- }
- if(rendered){
- this.onLayout(shallow, force);
- }
- delete this.forceLayout;
- },
-
- //private
- onLayout : Ext.emptyFn,
-
- onShow : function(){
- Ext.Container.superclass.onShow.call(this);
- if(this.deferLayout !== undefined){
- this.doLayout(true);
- }
- },
-
- /**
- * Returns the layout currently in use by the container. If the container does not currently have a layout
- * set, a default {@link Ext.layout.ContainerLayout} will be created and set as the container's layout.
- * @return {ContainerLayout} layout The container's layout
- */
- getLayout : function(){
- if(!this.layout){
- var layout = new Ext.layout.ContainerLayout(this.layoutConfig);
- this.setLayout(layout);
- }
- return this.layout;
- },
-
- // private
- beforeDestroy : function(){
- if(this.items){
- Ext.destroy.apply(Ext, this.items.items);
- }
- if(this.monitorResize){
- Ext.EventManager.removeResizeListener(this.doLayout, this);
- }
- Ext.destroy(this.layout);
- Ext.Container.superclass.beforeDestroy.call(this);
- },
-
- /**
- * Bubbles up the component/container heirarchy, calling the specified function with each component. The scope (<i>this</i>) of
- * function call will be the scope provided or the current component. The arguments to the function
- * will be the args provided or the current component. If the function returns false at any point,
- * the bubble is stopped.
- * @param {Function} fn The function to call
- * @param {Object} scope (optional) The scope of the function (defaults to current node)
- * @param {Array} args (optional) The args to call the function with (default to passing the current component)
- * @return {Ext.Container} this
- */
- bubble : function(fn, scope, args){
- var p = this;
- while(p){
- if(fn.apply(scope || p, args || [p]) === false){
- break;
- }
- p = p.ownerCt;
- }
- return this;
- },
-
- /**
- * Cascades down the component/container heirarchy from this component (called first), calling the specified function with
- * each component. The scope (<i>this</i>) of
- * function call will be the scope provided or the current component. The arguments to the function
- * will be the args provided or the current component. If the function returns false at any point,
- * the cascade is stopped on that branch.
- * @param {Function} fn The function to call
- * @param {Object} scope (optional) The scope of the function (defaults to current component)
- * @param {Array} args (optional) The args to call the function with (defaults to passing the current component)
- * @return {Ext.Container} this
- */
- cascade : function(fn, scope, args){
- if(fn.apply(scope || this, args || [this]) !== false){
- if(this.items){
- var cs = this.items.items;
- for(var i = 0, len = cs.length; i < len; i++){
- if(cs[i].cascade){
- cs[i].cascade(fn, scope, args);
- }else{
- fn.apply(scope || cs[i], args || [cs[i]]);
- }
- }
- }
- }
- return this;
- },
-
- /**
- * Find a component under this container at any level by id
- * @param {String} id
- * @return Ext.Component
- */
- findById : function(id){
- var m, ct = this;
- this.cascade(function(c){
- if(ct != c && c.id === id){
- m = c;
- return false;
- }
- });
- return m || null;
- },
-
- /**
- * Find a component under this container at any level by xtype or class
- * @param {String/Class} xtype The xtype string for a component, or the class of the component directly
- * @param {Boolean} shallow (optional) False to check whether this Component is descended from the xtype (this is
- * the default), or true to check whether this Component is directly of the specified xtype.
- * @return {Array} Array of Ext.Components
- */
- findByType : function(xtype, shallow){
- return this.findBy(function(c){
- return c.isXType(xtype, shallow);
- });
- },
-
- /**
- * Find a component under this container at any level by property
- * @param {String} prop
- * @param {String} value
- * @return {Array} Array of Ext.Components
- */
- find : function(prop, value){
- return this.findBy(function(c){
- return c[prop] === value;
- });
- },
-
- /**
- * Find a component under this container at any level by a custom function. If the passed function returns
- * true, the component will be included in the results. The passed function is called with the arguments (component, this container).
- * @param {Function} fn The function to call
- * @param {Object} scope (optional)
- * @return {Array} Array of Ext.Components
- */
- findBy : function(fn, scope){
- var m = [], ct = this;
- this.cascade(function(c){
- if(ct != c && fn.call(scope || c, c, ct) === true){
- m.push(c);
- }
- });
- return m;
- },
-
- /**
- * Get a component contained by this container (alias for items.get(key))
- * @param {String/Number} key The index or id of the component
- * @return {Ext.Component} Ext.Component
- */
- get : function(key){
- return this.items.get(key);
- }
-});
-
-Ext.Container.LAYOUTS = {};
-Ext.reg('container', Ext.Container);
-/**
- * @class Ext.layout.ContainerLayout
- * <p>The ContainerLayout class is the default layout manager delegated by {@link Ext.Container} to
- * render any child Components when no <tt>{@link Ext.Container#layout layout}</tt> is configured into
- * a {@link Ext.Container Container}. ContainerLayout provides the basic foundation for all other layout
- * classes in Ext. It simply renders all child Components into the Container, performing no sizing or
- * positioning services. To utilize a layout that provides sizing and positioning of child Components,
- * specify an appropriate <tt>{@link Ext.Container#layout layout}</tt>.</p>
- * <p>This class is intended to be extended or created via the <tt><b>{@link Ext.Container#layout layout}</b></tt>
- * configuration property. See <tt><b>{@link Ext.Container#layout}</b></tt> for additional details.</p>
- */
-Ext.layout.ContainerLayout = function(config){
- Ext.apply(this, config);
-};
-
-Ext.layout.ContainerLayout.prototype = {
- /**
- * @cfg {String} extraCls
- * <p>An optional extra CSS class that will be added to the container. This can be useful for adding
- * customized styles to the container or any of its children using standard CSS rules. See
- * {@link Ext.Component}.{@link Ext.Component#ctCls ctCls} also.</p>
- * <p><b>Note</b>: <tt>extraCls</tt> defaults to <tt>''</tt> except for the following classes
- * which assign a value by default:
- * <div class="mdetail-params"><ul>
- * <li>{@link Ext.layout.AbsoluteLayout Absolute Layout} : <tt>'x-abs-layout-item'</tt></li>
- * <li>{@link Ext.layout.Box Box Layout} : <tt>'x-box-item'</tt></li>
- * <li>{@link Ext.layout.ColumnLayout Column Layout} : <tt>'x-column'</tt></li>
- * </ul></div>
- * To configure the above Classes with an extra CSS class append to the default. For example,
- * for ColumnLayout:<pre><code>
- * extraCls: 'x-column custom-class'
- * </code></pre>
- * </p>
- */
- /**
- * @cfg {Boolean} renderHidden
- * True to hide each contained item on render (defaults to false).
- */
-
- /**
- * A reference to the {@link Ext.Component} that is active. For example, <pre><code>
- * if(myPanel.layout.activeItem.id == 'item-1') { ... }
- * </code></pre>
- * <tt>activeItem</tt> only applies to layout styles that can display items one at a time
- * (like {@link Ext.layout.AccordionLayout}, {@link Ext.layout.CardLayout}
- * and {@link Ext.layout.FitLayout}). Read-only. Related to {@link Ext.Container#activeItem}.
- * @type {Ext.Component}
- * @property activeItem
- */
-
- // private
- monitorResize:false,
- // private
- activeItem : null,
-
- // private
- layout : function(){
- var target = this.container.getLayoutTarget();
- this.onLayout(this.container, target);
- this.container.fireEvent('afterlayout', this.container, this);
- },
-
- // private
- onLayout : function(ct, target){
- this.renderAll(ct, target);
- },
-
- // private
- isValidParent : function(c, target){
- return target && c.getDomPositionEl().dom.parentNode == (target.dom || target);
- },
-
- // private
- renderAll : function(ct, target){
- var items = ct.items.items;
- for(var i = 0, len = items.length; i < len; i++) {
- var c = items[i];
- if(c && (!c.rendered || !this.isValidParent(c, target))){
- this.renderItem(c, i, target);
- }
- }
- },
-
- // private
- renderItem : function(c, position, target){
- if(c && !c.rendered){
- c.render(target, position);
- this.configureItem(c, position);
- }else if(c && !this.isValidParent(c, target)){
- if(typeof position == 'number'){
- position = target.dom.childNodes[position];
- }
- target.dom.insertBefore(c.getDomPositionEl().dom, position || null);
- c.container = target;
- this.configureItem(c, position);
- }
- },
-
- // private
- configureItem: function(c, position){
- if(this.extraCls){
- var t = c.getPositionEl ? c.getPositionEl() : c;
- t.addClass(this.extraCls);
- }
- if (this.renderHidden && c != this.activeItem) {
- c.hide();
- }
- if(c.doLayout){
- c.doLayout(false, this.forceLayout);
- }
- },
-
- // private
- onResize: function(){
- if(this.container.collapsed){
- return;
- }
- var b = this.container.bufferResize;
- if(b){
- if(!this.resizeTask){
- this.resizeTask = new Ext.util.DelayedTask(this.runLayout, this);
- this.resizeBuffer = typeof b == 'number' ? b : 100;
- }
- this.resizeTask.delay(this.resizeBuffer);
- }else{
- this.runLayout();
- }
- },
-
- // private
- runLayout: function(){
- this.layout();
- this.container.onLayout();
- },
-
- // private
- setContainer : function(ct){
- if(this.monitorResize && ct != this.container){
- if(this.container){
- this.container.un('resize', this.onResize, this);
- this.container.un('bodyresize', this.onResize, this);
- }
- if(ct){
- ct.on({
- scope: this,
- resize: this.onResize,
- bodyresize: this.onResize
- });
- }
- }
- this.container = ct;
- },
-
- // private
- parseMargins : function(v){
- if(typeof v == 'number'){
- v = v.toString();
- }
- var ms = v.split(' ');
- var len = ms.length;
- if(len == 1){
- ms[1] = ms[0];
- ms[2] = ms[0];
- ms[3] = ms[0];
- }
- if(len == 2){
- ms[2] = ms[0];
- ms[3] = ms[1];
- }
- if(len == 3){
- ms[3] = ms[1];
- }
- return {
- top:parseInt(ms[0], 10) || 0,
- right:parseInt(ms[1], 10) || 0,
- bottom:parseInt(ms[2], 10) || 0,
- left:parseInt(ms[3], 10) || 0
- };
- },
-
- /**
- * The {@link Template Ext.Template} used by Field rendering layout classes (such as
- * {@link Ext.layout.FormLayout}) to create the DOM structure of a fully wrapped,
- * labeled and styled form Field. A default Template is supplied, but this may be
- * overriden to create custom field structures. The template processes values returned from
- * {@link Ext.layout.FormLayout#getTemplateArgs}.
- * @property fieldTpl
- * @type Ext.Template
- */
- fieldTpl: (function() {
- var t = new Ext.Template(
- '<div class="x-form-item {itemCls}" tabIndex="-1">',
- '<label for="{id}" style="{labelStyle}" class="x-form-item-label">{label}{labelSeparator}</label>',
- '<div class="x-form-element" id="x-form-el-{id}" style="{elementStyle}">',
- '</div><div class="{clearCls}"></div>',
- '</div>'
- );
- t.disableFormats = true;
- return t.compile();
- })(),
-
- /*
- * Destroys this layout. This is a template method that is empty by default, but should be implemented
- * by subclasses that require explicit destruction to purge event handlers or remove DOM nodes.
- * @protected
- */
- destroy : Ext.emptyFn
-};
-Ext.Container.LAYOUTS['auto'] = Ext.layout.ContainerLayout;/**\r
- * @class Ext.layout.FitLayout\r
- * @extends Ext.layout.ContainerLayout\r
- * <p>This is a base class for layouts that contain <b>a single item</b> that automatically expands to fill the layout's\r
- * container. This class is intended to be extended or created via the <tt>layout:'fit'</tt> {@link Ext.Container#layout}\r
- * config, and should generally not need to be created directly via the new keyword.</p>\r
- * <p>FitLayout does not have any direct config options (other than inherited ones). To fit a panel to a container\r
- * using FitLayout, simply set layout:'fit' on the container and add a single panel to it. If the container has\r
- * multiple panels, only the first one will be displayed. Example usage:</p>\r
- * <pre><code>\r
-var p = new Ext.Panel({\r
- title: 'Fit Layout',\r
- layout:'fit',\r
- items: {\r
- title: 'Inner Panel',\r
- html: '<p>This is the inner panel content</p>',\r
- border: false\r
- }\r
-});\r
-</code></pre>\r
- */\r
-Ext.layout.FitLayout = Ext.extend(Ext.layout.ContainerLayout, {\r
- // private\r
- monitorResize:true,\r
-\r
- // private\r
- onLayout : function(ct, target){\r
- Ext.layout.FitLayout.superclass.onLayout.call(this, ct, target);\r
- if(!this.container.collapsed){\r
- var sz = (Ext.isIE6 && Ext.isStrict && target.dom == document.body) ? target.getViewSize() : target.getStyleSize();\r
- this.setItemSize(this.activeItem || ct.items.itemAt(0), sz);\r
- }\r
- },\r
-\r
- // private\r
- setItemSize : function(item, size){\r
- if(item && size.height > 0){ // display none?\r
- item.setSize(size);\r
- }\r
- }\r
-});\r
-Ext.Container.LAYOUTS['fit'] = Ext.layout.FitLayout;/**\r
- * @class Ext.layout.CardLayout\r
- * @extends Ext.layout.FitLayout\r
- * <p>This layout manages multiple child Components, each fitted to the Container, where only a single child Component can be\r
- * visible at any given time. This layout style is most commonly used for wizards, tab implementations, etc.\r
- * This class is intended to be extended or created via the layout:'card' {@link Ext.Container#layout} config,\r
- * and should generally not need to be created directly via the new keyword.</p>\r
- * <p>The CardLayout's focal method is {@link #setActiveItem}. Since only one panel is displayed at a time,\r
- * the only way to move from one Component to the next is by calling setActiveItem, passing the id or index of\r
- * the next panel to display. The layout itself does not provide a user interface for handling this navigation,\r
- * so that functionality must be provided by the developer.</p>\r
- * <p>In the following example, a simplistic wizard setup is demonstrated. A button bar is added\r
- * to the footer of the containing panel to provide navigation buttons. The buttons will be handled by a\r
- * common navigation routine -- for this example, the implementation of that routine has been ommitted since\r
- * it can be any type of custom logic. Note that other uses of a CardLayout (like a tab control) would require a\r
- * completely different implementation. For serious implementations, a better approach would be to extend\r
- * CardLayout to provide the custom functionality needed. Example usage:</p>\r
- * <pre><code>\r
-var navHandler = function(direction){\r
- // This routine could contain business logic required to manage the navigation steps.\r
- // It would call setActiveItem as needed, manage navigation button state, handle any\r
- // branching logic that might be required, handle alternate actions like cancellation\r
- // or finalization, etc. A complete wizard implementation could get pretty\r
- // sophisticated depending on the complexity required, and should probably be\r
- // done as a subclass of CardLayout in a real-world implementation.\r
-};\r
-\r
-var card = new Ext.Panel({\r
- title: 'Example Wizard',\r
- layout:'card',\r
- activeItem: 0, // make sure the active item is set on the container config!\r
- bodyStyle: 'padding:15px',\r
- defaults: {\r
- // applied to each contained panel\r
- border:false\r
- },\r
- // just an example of one possible navigation scheme, using buttons\r
- bbar: [\r
- {\r
- id: 'move-prev',\r
- text: 'Back',\r
- handler: navHandler.createDelegate(this, [-1]),\r
- disabled: true\r
- },\r
- '->', // greedy spacer so that the buttons are aligned to each side\r
- {\r
- id: 'move-next',\r
- text: 'Next',\r
- handler: navHandler.createDelegate(this, [1])\r
- }\r
- ],\r
- // the panels (or "cards") within the layout\r
- items: [{\r
- id: 'card-0',\r
- html: '<h1>Welcome to the Wizard!</h1><p>Step 1 of 3</p>'\r
- },{\r
- id: 'card-1',\r
- html: '<p>Step 2 of 3</p>'\r
- },{\r
- id: 'card-2',\r
- html: '<h1>Congratulations!</h1><p>Step 3 of 3 - Complete</p>'\r
- }]\r
-});\r
-</code></pre>\r
- */\r
-Ext.layout.CardLayout = Ext.extend(Ext.layout.FitLayout, {\r
- /**\r
- * @cfg {Boolean} deferredRender\r
- * True to render each contained item at the time it becomes active, false to render all contained items\r
- * as soon as the layout is rendered (defaults to false). If there is a significant amount of content or\r
- * a lot of heavy controls being rendered into panels that are not displayed by default, setting this to\r
- * true might improve performance.\r
- */\r
- deferredRender : false,\r
- \r
- /**\r
- * @cfg {Boolean} layoutOnCardChange\r
- * True to force a layout of the active item when the active card is changed. Defaults to false.\r
- */\r
- layoutOnCardChange : false,\r
-\r
- /**\r
- * @cfg {Boolean} renderHidden @hide\r
- */\r
- // private\r
- renderHidden : true,\r
- \r
- constructor: function(config){\r
- Ext.layout.CardLayout.superclass.constructor.call(this, config);\r
- this.forceLayout = (this.deferredRender === false);\r
- },\r
-\r
- /**\r
- * Sets the active (visible) item in the layout.\r
- * @param {String/Number} item The string component id or numeric index of the item to activate\r
- */\r
- setActiveItem : function(item){\r
- item = this.container.getComponent(item);\r
- if(this.activeItem != item){\r
- if(this.activeItem){\r
- this.activeItem.hide();\r
- }\r
- this.activeItem = item;\r
- item.show();\r
- this.container.doLayout();\r
- if(this.layoutOnCardChange && item.doLayout){\r
- item.doLayout();\r
- }\r
- }\r
- },\r
-\r
- // private\r
- renderAll : function(ct, target){\r
- if(this.deferredRender){\r
- this.renderItem(this.activeItem, undefined, target);\r
- }else{\r
- Ext.layout.CardLayout.superclass.renderAll.call(this, ct, target);\r
- }\r
- }\r
-});\r
-Ext.Container.LAYOUTS['card'] = Ext.layout.CardLayout;/**\r
- * @class Ext.layout.AnchorLayout\r
- * @extends Ext.layout.ContainerLayout\r
- * <p>This is a layout that enables anchoring of contained elements relative to the container's dimensions.\r
- * If the container is resized, all anchored items are automatically rerendered according to their\r
- * <b><tt>{@link #anchor}</tt></b> rules.</p>\r
- * <p>This class is intended to be extended or created via the layout:'anchor' {@link Ext.Container#layout}\r
- * config, and should generally not need to be created directly via the new keyword.</p>\r
- * <p>AnchorLayout does not have any direct config options (other than inherited ones). By default,\r
- * AnchorLayout will calculate anchor measurements based on the size of the container itself. However, the\r
- * container using the AnchorLayout can supply an anchoring-specific config property of <b>anchorSize</b>.\r
- * If anchorSize is specifed, the layout will use it as a virtual container for the purposes of calculating\r
- * anchor measurements based on it instead, allowing the container to be sized independently of the anchoring\r
- * logic if necessary. For example:</p>\r
- * <pre><code>\r
-var viewport = new Ext.Viewport({\r
- layout:'anchor',\r
- anchorSize: {width:800, height:600},\r
- items:[{\r
- title:'Item 1',\r
- html:'Content 1',\r
- width:800,\r
- anchor:'right 20%'\r
- },{\r
- title:'Item 2',\r
- html:'Content 2',\r
- width:300,\r
- anchor:'50% 30%'\r
- },{\r
- title:'Item 3',\r
- html:'Content 3',\r
- width:600,\r
- anchor:'-100 50%'\r
- }]\r
-});\r
- * </code></pre>\r
- */\r
-Ext.layout.AnchorLayout = Ext.extend(Ext.layout.ContainerLayout, {\r
- /**\r
- * @cfg {String} anchor\r
- * <p>This configuation option is to be applied to <b>child <tt>items</tt></b> of a container managed by\r
- * this layout (ie. configured with <tt>layout:'anchor'</tt>).</p><br/>\r
- * \r
- * <p>This value is what tells the layout how an item should be anchored to the container. <tt>items</tt>\r
- * added to an AnchorLayout accept an anchoring-specific config property of <b>anchor</b> which is a string\r
- * containing two values: the horizontal anchor value and the vertical anchor value (for example, '100% 50%').\r
- * The following types of anchor values are supported:<div class="mdetail-params"><ul>\r
- * \r
- * <li><b>Percentage</b> : Any value between 1 and 100, expressed as a percentage.<div class="sub-desc">\r
- * The first anchor is the percentage width that the item should take up within the container, and the\r
- * second is the percentage height. For example:<pre><code>\r
-// two values specified\r
-anchor: '100% 50%' // render item complete width of the container and\r
- // 1/2 height of the container\r
-// one value specified\r
-anchor: '100%' // the width value; the height will default to auto\r
- * </code></pre></div></li>\r
- * \r
- * <li><b>Offsets</b> : Any positive or negative integer value.<div class="sub-desc">\r
- * This is a raw adjustment where the first anchor is the offset from the right edge of the container,\r
- * and the second is the offset from the bottom edge. For example:<pre><code>\r
-// two values specified\r
-anchor: '-50 -100' // render item the complete width of the container\r
- // minus 50 pixels and\r
- // the complete height minus 100 pixels.\r
-// one value specified\r
-anchor: '-50' // anchor value is assumed to be the right offset value\r
- // bottom offset will default to 0\r
- * </code></pre></div></li>\r
- * \r
- * <li><b>Sides</b> : Valid values are <tt>'right'</tt> (or <tt>'r'</tt>) and <tt>'bottom'</tt>\r
- * (or <tt>'b'</tt>).<div class="sub-desc">\r
- * Either the container must have a fixed size or an anchorSize config value defined at render time in\r
- * order for these to have any effect.</div></li>\r
- *\r
- * <li><b>Mixed</b> : <div class="sub-desc">\r
- * Anchor values can also be mixed as needed. For example, to render the width offset from the container\r
- * right edge by 50 pixels and 75% of the container's height use:\r
- * <pre><code>\r
-anchor: '-50 75%' \r
- * </code></pre></div></li>\r
- * \r
- * \r
- * </ul></div>\r
- */\r
- \r
- // private\r
- monitorResize:true,\r
-\r
- // private\r
- getAnchorViewSize : function(ct, target){\r
- return target.dom == document.body ?\r
- target.getViewSize() : target.getStyleSize();\r
- },\r
-\r
- // private\r
- onLayout : function(ct, target){\r
- Ext.layout.AnchorLayout.superclass.onLayout.call(this, ct, target);\r
-\r
- var size = this.getAnchorViewSize(ct, target);\r
-\r
- var w = size.width, h = size.height;\r
-\r
- if(w < 20 && h < 20){\r
- return;\r
- }\r
-\r
- // find the container anchoring size\r
- var aw, ah;\r
- if(ct.anchorSize){\r
- if(typeof ct.anchorSize == 'number'){\r
- aw = ct.anchorSize;\r
- }else{\r
- aw = ct.anchorSize.width;\r
- ah = ct.anchorSize.height;\r
- }\r
- }else{\r
- aw = ct.initialConfig.width;\r
- ah = ct.initialConfig.height;\r
- }\r
-\r
- var cs = ct.items.items, len = cs.length, i, c, a, cw, ch;\r
- for(i = 0; i < len; i++){\r
- c = cs[i];\r
- if(c.anchor){\r
- a = c.anchorSpec;\r
- if(!a){ // cache all anchor values\r
- var vs = c.anchor.split(' ');\r
- c.anchorSpec = a = {\r
- right: this.parseAnchor(vs[0], c.initialConfig.width, aw),\r
- bottom: this.parseAnchor(vs[1], c.initialConfig.height, ah)\r
- };\r
- }\r
- cw = a.right ? this.adjustWidthAnchor(a.right(w), c) : undefined;\r
- ch = a.bottom ? this.adjustHeightAnchor(a.bottom(h), c) : undefined;\r
-\r
- if(cw || ch){\r
- c.setSize(cw || undefined, ch || undefined);\r
- }\r
- }\r
- }\r
- },\r
-\r
- // private\r
- parseAnchor : function(a, start, cstart){\r
- if(a && a != 'none'){\r
- var last;\r
- if(/^(r|right|b|bottom)$/i.test(a)){ // standard anchor\r
- var diff = cstart - start;\r
- return function(v){\r
- if(v !== last){\r
- last = v;\r
- return v - diff;\r
- }\r
- }\r
- }else if(a.indexOf('%') != -1){\r
- var ratio = parseFloat(a.replace('%', ''))*.01; // percentage\r
- return function(v){\r
- if(v !== last){\r
- last = v;\r
- return Math.floor(v*ratio);\r
- }\r
- }\r
- }else{\r
- a = parseInt(a, 10);\r
- if(!isNaN(a)){ // simple offset adjustment\r
- return function(v){\r
- if(v !== last){\r
- last = v;\r
- return v + a;\r
- }\r
- }\r
- }\r
- }\r
- }\r
- return false;\r
- },\r
-\r
- // private\r
- adjustWidthAnchor : function(value, comp){\r
- return value;\r
- },\r
-\r
- // private\r
- adjustHeightAnchor : function(value, comp){\r
- return value;\r
- }\r
- \r
- /**\r
- * @property activeItem\r
- * @hide\r
- */\r
-});\r
-Ext.Container.LAYOUTS['anchor'] = Ext.layout.AnchorLayout;/**\r
- * @class Ext.layout.ColumnLayout\r
- * @extends Ext.layout.ContainerLayout\r
- * <p>This is the layout style of choice for creating structural layouts in a multi-column format where the width of\r
- * each column can be specified as a percentage or fixed width, but the height is allowed to vary based on the content.\r
- * This class is intended to be extended or created via the layout:'column' {@link Ext.Container#layout} config,\r
- * and should generally not need to be created directly via the new keyword.</p>\r
- * <p>ColumnLayout does not have any direct config options (other than inherited ones), but it does support a\r
- * specific config property of <b><tt>columnWidth</tt></b> that can be included in the config of any panel added to it. The\r
- * layout will use the columnWidth (if present) or width of each panel during layout to determine how to size each panel.\r
- * If width or columnWidth is not specified for a given panel, its width will default to the panel's width (or auto).</p>\r
- * <p>The width property is always evaluated as pixels, and must be a number greater than or equal to 1.\r
- * The columnWidth property is always evaluated as a percentage, and must be a decimal value greater than 0 and\r
- * less than 1 (e.g., .25).</p>\r
- * <p>The basic rules for specifying column widths are pretty simple. The logic makes two passes through the\r
- * set of contained panels. During the first layout pass, all panels that either have a fixed width or none\r
- * specified (auto) are skipped, but their widths are subtracted from the overall container width. During the second\r
- * pass, all panels with columnWidths are assigned pixel widths in proportion to their percentages based on\r
- * the total <b>remaining</b> container width. In other words, percentage width panels are designed to fill the space\r
- * left over by all the fixed-width and/or auto-width panels. Because of this, while you can specify any number of columns\r
- * with different percentages, the columnWidths must always add up to 1 (or 100%) when added together, otherwise your\r
- * layout may not render as expected. Example usage:</p>\r
- * <pre><code>\r
-// All columns are percentages -- they must add up to 1\r
-var p = new Ext.Panel({\r
- title: 'Column Layout - Percentage Only',\r
- layout:'column',\r
- items: [{\r
- title: 'Column 1',\r
- columnWidth: .25 \r
- },{\r
- title: 'Column 2',\r
- columnWidth: .6\r
- },{\r
- title: 'Column 3',\r
- columnWidth: .15\r
- }]\r
-});\r
-\r
-// Mix of width and columnWidth -- all columnWidth values must add up\r
-// to 1. The first column will take up exactly 120px, and the last two\r
-// columns will fill the remaining container width.\r
-var p = new Ext.Panel({\r
- title: 'Column Layout - Mixed',\r
- layout:'column',\r
- items: [{\r
- title: 'Column 1',\r
- width: 120\r
- },{\r
- title: 'Column 2',\r
- columnWidth: .8\r
- },{\r
- title: 'Column 3',\r
- columnWidth: .2\r
- }]\r
-});\r
-</code></pre>\r
- */\r
-Ext.layout.ColumnLayout = Ext.extend(Ext.layout.ContainerLayout, {\r
- // private\r
- monitorResize:true,\r
- \r
- extraCls: 'x-column',\r
-\r
- scrollOffset : 0,\r
-\r
- // private\r
- isValidParent : function(c, target){\r
- return (c.getPositionEl ? c.getPositionEl() : c.getEl()).dom.parentNode == this.innerCt.dom;\r
- },\r
-\r
- // private\r
- onLayout : function(ct, target){\r
- var cs = ct.items.items, len = cs.length, c, i;\r
-\r
- if(!this.innerCt){\r
- target.addClass('x-column-layout-ct');\r
-\r
- // the innerCt prevents wrapping and shuffling while\r
- // the container is resizing\r
- this.innerCt = target.createChild({cls:'x-column-inner'});\r
- this.innerCt.createChild({cls:'x-clear'});\r
- }\r
- this.renderAll(ct, this.innerCt);\r
-\r
- var size = Ext.isIE && target.dom != Ext.getBody().dom ? target.getStyleSize() : target.getViewSize();\r
-\r
- if(size.width < 1 && size.height < 1){ // display none?\r
- return;\r
- }\r
-\r
- var w = size.width - target.getPadding('lr') - this.scrollOffset,\r
- h = size.height - target.getPadding('tb'),\r
- pw = w;\r
-\r
- this.innerCt.setWidth(w);\r
- \r
- // some columns can be percentages while others are fixed\r
- // so we need to make 2 passes\r
-\r
- for(i = 0; i < len; i++){\r
- c = cs[i];\r
- if(!c.columnWidth){\r
- pw -= (c.getSize().width + c.getEl().getMargins('lr'));\r
- }\r
- }\r
-\r
- pw = pw < 0 ? 0 : pw;\r
-\r
- for(i = 0; i < len; i++){\r
- c = cs[i];\r
- if(c.columnWidth){\r
- c.setSize(Math.floor(c.columnWidth*pw) - c.getEl().getMargins('lr'));\r
- }\r
- }\r
- }\r
- \r
- /**\r
- * @property activeItem\r
- * @hide\r
- */\r
-});\r
-\r
-Ext.Container.LAYOUTS['column'] = Ext.layout.ColumnLayout;/**
- * @class Ext.layout.BorderLayout
- * @extends Ext.layout.ContainerLayout
- * <p>This is a multi-pane, application-oriented UI layout style that supports multiple
- * nested panels, automatic {@link Ext.layout.BorderLayout.Region#split split} bars between
- * {@link Ext.layout.BorderLayout.Region#BorderLayout.Region regions} and built-in
- * {@link Ext.layout.BorderLayout.Region#collapsible expanding and collapsing} of regions.</p>
- * <p>This class is intended to be extended or created via the <tt>layout:'border'</tt>
- * {@link Ext.Container#layout} config, and should generally not need to be created directly
- * via the new keyword.</p>
- * <p>BorderLayout does not have any direct config options (other than inherited ones).
- * All configuration options available for customizing the BorderLayout are at the
- * {@link Ext.layout.BorderLayout.Region} and {@link Ext.layout.BorderLayout.SplitRegion}
- * levels.</p>
- * <p>Example usage:</p>
- * <pre><code>
-var myBorderPanel = new Ext.Panel({
- {@link Ext.Component#renderTo renderTo}: document.body,
- {@link Ext.BoxComponent#width width}: 700,
- {@link Ext.BoxComponent#height height}: 500,
- {@link Ext.Panel#title title}: 'Border Layout',
- {@link Ext.Container#layout layout}: 'border',
- {@link Ext.Container#items items}: [{
- {@link Ext.Panel#title title}: 'South Region is resizable',
- {@link Ext.layout.BorderLayout.Region#BorderLayout.Region region}: 'south', // position for region
- {@link Ext.BoxComponent#height height}: 100,
- {@link Ext.layout.BorderLayout.Region#split split}: true, // enable resizing
- {@link Ext.SplitBar#minSize minSize}: 75, // defaults to {@link Ext.layout.BorderLayout.Region#minHeight 50}
- {@link Ext.SplitBar#maxSize maxSize}: 150,
- {@link Ext.layout.BorderLayout.Region#margins margins}: '0 5 5 5'
- },{
- // xtype: 'panel' implied by default
- {@link Ext.Panel#title title}: 'West Region is collapsible',
- {@link Ext.layout.BorderLayout.Region#BorderLayout.Region region}:'west',
- {@link Ext.layout.BorderLayout.Region#margins margins}: '5 0 0 5',
- {@link Ext.BoxComponent#width width}: 200,
- {@link Ext.layout.BorderLayout.Region#collapsible collapsible}: true, // make collapsible
- {@link Ext.layout.BorderLayout.Region#cmargins cmargins}: '5 5 0 5', // adjust top margin when collapsed
- {@link Ext.Component#id id}: 'west-region-container',
- {@link Ext.Container#layout layout}: 'fit',
- {@link Ext.Panel#unstyled unstyled}: true
- },{
- {@link Ext.Panel#title title}: 'Center Region',
- {@link Ext.layout.BorderLayout.Region#BorderLayout.Region region}: 'center', // center region is required, no width/height specified
- {@link Ext.Component#xtype xtype}: 'container',
- {@link Ext.Container#layout layout}: 'fit',
- {@link Ext.layout.BorderLayout.Region#margins margins}: '5 5 0 0'
- }]
-});