3 Ext.DomHelper = function(){
4 var tempTableEl = null,
5 emptyTags = /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i,
6 tableRe = /^table|tbody|tr|td$/i,
7 confRe = /tag|children|cn|html$/i,
8 tableElRe = /td|tr|tbody/i,
9 cssRe = /([a-z0-9-]+)\s*:\s*([^;\s]+(?:\s*[^;\s]+)*);?/gi,
13 afterbegin = 'afterbegin',
14 afterend = 'afterend',
15 beforebegin = 'beforebegin',
16 beforeend = 'beforeend',
25 function doInsert(el, o, returnElement, pos, sibling, append){
26 var newNode = pub.insertHtml(pos, Ext.getDom(el), createHtml(o));
27 return returnElement ? Ext.get(newNode, true) : newNode;
31 function createHtml(o){
38 if(typeof o == "string"){
40 } else if (Ext.isArray(o)) {
41 for (var i=0; i < o.length; i++) {
43 b += createHtml(o[i]);
47 b += '<' + (o.tag = o.tag || 'div');
50 if(!confRe.test(attr)){
51 if (typeof val == "object") {
52 b += ' ' + attr + '="';
54 b += key + ':' + val[key] + ';';
58 b += ' ' + ({cls : 'class', htmlFor : 'for'}[attr] || attr) + '="' + val + '"';
63 if (emptyTags.test(o.tag)) {
67 if ((cn = o.children || o.cn)) {
72 b += '</' + o.tag + '>';
78 function ieTable(depth, s, h, e){
79 tempTableEl.innerHTML = [s, h, e].join('');
87 if(ns = el.nextSibling){
88 var df = document.createDocumentFragment();
100 function insertIntoTable(tag, where, el, html) {
104 tempTableEl = tempTableEl || document.createElement('div');
106 if(tag == 'td' && (where == afterbegin || where == beforeend) ||
107 !tableElRe.test(tag) && (where == beforebegin || where == afterend)) {
110 before = where == beforebegin ? el :
111 where == afterend ? el.nextSibling :
112 where == afterbegin ? el.firstChild : null;
114 if (where == beforebegin || where == afterend) {
118 if (tag == 'td' || (tag == 'tr' && (where == beforeend || where == afterbegin))) {
119 node = ieTable(4, trs, html, tre);
120 } else if ((tag == 'tbody' && (where == beforeend || where == afterbegin)) ||
121 (tag == 'tr' && (where == beforebegin || where == afterend))) {
122 node = ieTable(3, tbs, html, tbe);
124 node = ieTable(2, ts, html, te);
126 el.insertBefore(node, before);
133 markup : function(o){
134 return createHtml(o);
138 applyStyles : function(el, styles){
143 if (typeof styles == "function") {
144 styles = styles.call();
146 if (typeof styles == "string") {
147 while ((matches = cssRe.exec(styles))) {
148 el.setStyle(matches[1], matches[2]);
150 } else if (typeof styles == "object") {
157 insertHtml : function(where, el, html){
166 where = where.toLowerCase();
168 hash[beforebegin] = ['BeforeBegin', 'previousSibling'];
169 hash[afterend] = ['AfterEnd', 'nextSibling'];
171 if (el.insertAdjacentHTML) {
172 if(tableRe.test(el.tagName) && (rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html))){
176 hash[afterbegin] = ['AfterBegin', 'firstChild'];
177 hash[beforeend] = ['BeforeEnd', 'lastChild'];
178 if ((hashVal = hash[where])) {
179 el.insertAdjacentHTML(hashVal[0], html);
180 return el[hashVal[1]];
183 range = el.ownerDocument.createRange();
184 setStart = 'setStart' + (endRe.test(where) ? 'After' : 'Before');
187 frag = range.createContextualFragment(html);
188 el.parentNode.insertBefore(frag, where == beforebegin ? el : el.nextSibling);
189 return el[(where == beforebegin ? 'previous' : 'next') + 'Sibling'];
191 rangeEl = (where == afterbegin ? 'first' : 'last') + 'Child';
193 range[setStart](el[rangeEl]);
194 frag = range.createContextualFragment(html);
195 if(where == afterbegin){
196 el.insertBefore(frag, el.firstChild);
198 el.appendChild(frag);
206 throw 'Illegal insertion point -> "' + where + '"';
210 insertBefore : function(el, o, returnElement){
211 return doInsert(el, o, returnElement, beforebegin);
215 insertAfter : function(el, o, returnElement){
216 return doInsert(el, o, returnElement, afterend, 'nextSibling');
220 insertFirst : function(el, o, returnElement){
221 return doInsert(el, o, returnElement, afterbegin, 'firstChild');
225 append : function(el, o, returnElement){
226 return doInsert(el, o, returnElement, beforeend, '', true);
230 overwrite : function(el, o, returnElement){
232 el.innerHTML = createHtml(o);
233 return returnElement ? Ext.get(el.firstChild) : el.firstChild;
236 createHtml : createHtml
241 Ext.apply(Ext.DomHelper,
244 afterbegin = 'afterbegin',
245 afterend = 'afterend',
246 beforebegin = 'beforebegin',
247 beforeend = 'beforeend',
248 confRe = /tag|children|cn|html$/i;
251 function doInsert(el, o, returnElement, pos, sibling, append){
255 newNode = createDom(o, null);
257 el.appendChild(newNode);
259 (sibling == 'firstChild' ? el : el.parentNode).insertBefore(newNode, el[sibling] || el);
262 newNode = Ext.DomHelper.insertHtml(pos, el, Ext.DomHelper.createHtml(o));
264 return returnElement ? Ext.get(newNode, true) : newNode;
269 function createDom(o, parentNode){
277 if (Ext.isArray(o)) {
278 el = doc.createDocumentFragment();
279 for (var i = 0, l = o.length; i < l; i++) {
282 } else if (typeof o == 'string') {
283 el = doc.createTextNode(o);
285 el = doc.createElement( o.tag || 'div' );
286 useSet = !!el.setAttribute;
287 for (var attr in o) {
288 if(!confRe.test(attr)){
294 el.setAttribute(attr, val);
301 Ext.DomHelper.applyStyles(el, o.style);
303 if ((cn = o.children || o.cn)) {
306 el.innerHTML = o.html;
310 parentNode.appendChild(el);
317 createTemplate : function(o){
318 var html = Ext.DomHelper.createHtml(o);
319 return new Ext.Template(html);
326 insertBefore : function(el, o, returnElement){
327 return doInsert(el, o, returnElement, beforebegin);
331 insertAfter : function(el, o, returnElement){
332 return doInsert(el, o, returnElement, afterend, 'nextSibling');
336 insertFirst : function(el, o, returnElement){
337 return doInsert(el, o, returnElement, afterbegin, 'firstChild');
341 append: function(el, o, returnElement){
342 return doInsert(el, o, returnElement, beforeend, '', true);
351 Ext.Template = function(html){
357 if (Ext.isArray(html)) {
358 html = html.join("");
359 } else if (a.length > 1) {
360 for(var i = 0, len = a.length; i < len; i++){
362 if(typeof v == 'object'){
378 Ext.Template.prototype = {
380 re : /\{([\w-]+)\}/g,
384 applyTemplate : function(values){
388 me.compiled(values) :
389 me.html.replace(me.re, function(m, name){
390 return values[name] !== undefined ? values[name] : "";
395 set : function(html, compile){
399 return compile ? me.compile() : me;
403 compile : function(){
405 sep = Ext.isGecko ? "+" : ",";
407 function fn(m, name){
408 name = "values['" + name + "']";
409 return "'"+ sep + '(' + name + " == undefined ? '' : " + name + ')' + sep + "'";
412 eval("this.compiled = function(values){ return " + (Ext.isGecko ? "'" : "['") +
413 me.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) +
414 (Ext.isGecko ? "';};" : "'].join('');};"));
419 insertFirst: function(el, values, returnElement){
420 return this.doInsert('afterBegin', el, values, returnElement);
424 insertBefore: function(el, values, returnElement){
425 return this.doInsert('beforeBegin', el, values, returnElement);
429 insertAfter : function(el, values, returnElement){
430 return this.doInsert('afterEnd', el, values, returnElement);
434 append : function(el, values, returnElement){
435 return this.doInsert('beforeEnd', el, values, returnElement);
438 doInsert : function(where, el, values, returnEl){
440 var newNode = Ext.DomHelper.insertHtml(where, el, this.applyTemplate(values));
441 return returnEl ? Ext.get(newNode, true) : newNode;
445 overwrite : function(el, values, returnElement){
447 el.innerHTML = this.applyTemplate(values);
448 return returnElement ? Ext.get(el.firstChild, true) : el.firstChild;
452 Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;
455 Ext.Template.from = function(el, config){
457 return new Ext.Template(el.value || el.innerHTML, config || '');
460 Ext.apply(Ext.Template.prototype, {
462 disableFormats : false,
466 re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
467 argsRe : /^\s*['"](.*)["']\s*$/,
469 compileBRe : /(\r\n|\n)/g,
473 * Returns an HTML fragment of this template with the specified values applied.
474 * @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'})
475 * @return {String} The HTML fragment
478 applyTemplate : function(values){
480 useF = me.disableFormats !== true,
481 fm = Ext.util.Format,
485 return me.compiled(values);
487 function fn(m, name, format, args){
488 if (format && useF) {
489 if (format.substr(0, 5) == "this.") {
490 return tpl.call(format.substr(5), values[name], values);
493 // quoted values are required for strings in compiled templates,
494 // but for non compiled we need to strip them
495 // quoted reversed for jsmin
497 args = args.split(',');
498 for(var i = 0, len = args.length; i < len; i++){
499 args[i] = args[i].replace(re, "$1");
501 args = [values[name]].concat(args);
503 args = [values[name]];
505 return fm[format].apply(fm, args);
508 return values[name] !== undefined ? values[name] : "";
511 return me.html.replace(me.re, fn);
515 * Compiles the template into an internal function, eliminating the RegEx overhead.
516 * @return {Ext.Template} this
519 compile : function(){
521 fm = Ext.util.Format,
522 useF = me.disableFormats !== true,
523 sep = Ext.isGecko ? "+" : ",",
526 function fn(m, name, format, args){
528 args = args ? ',' + args : "";
529 if(format.substr(0, 5) != "this."){
530 format = "fm." + format + '(';
532 format = 'this.call("'+ format.substr(5) + '", ';
536 args= ''; format = "(values['" + name + "'] == undefined ? '' : ";
538 return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'";
541 // branched to use + in gecko and [].join() in others
543 body = "this.compiled = function(values){ return '" +
544 me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn) +
547 body = ["this.compiled = function(values){ return ['"];
548 body.push(me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn));
549 body.push("'].join('');};");
550 body = body.join('');
556 // private function used to call members
557 call : function(fnName, value, allValues){
558 return this[fnName](value, allValues);
561 Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;
563 * This is code is also distributed under MIT license for use
564 * with jQuery and prototype JavaScript libraries.
567 * @class Ext.DomQuery
568 Provides high performance selector/xpath processing by compiling queries into reusable functions. New pseudo classes and matchers can be plugged. It works on HTML and XML documents (if a content node is passed in).
570 DomQuery supports most of the <a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215/#selectors">CSS3 selectors spec</a>, along with some custom selectors and basic XPath.</p>
573 All selectors, attribute filters and pseudos below can be combined infinitely in any order. For example "div.foo:nth-child(odd)[@foo=bar].bar:first" would be a perfectly valid selector. Node filters are processed in the order in which they appear, which allows you to optimize your queries for your document structure.
575 <h4>Element Selectors:</h4>
577 <li> <b>*</b> any element</li>
578 <li> <b>E</b> an element with the tag E</li>
579 <li> <b>E F</b> All descendent elements of E that have the tag F</li>
580 <li> <b>E > F</b> or <b>E/F</b> all direct children elements of E that have the tag F</li>
581 <li> <b>E + F</b> all elements with the tag F that are immediately preceded by an element with the tag E</li>
582 <li> <b>E ~ F</b> all elements with the tag F that are preceded by a sibling element with the tag E</li>
584 <h4>Attribute Selectors:</h4>
585 <p>The use of @ and quotes are optional. For example, div[@foo='bar'] is also a valid attribute selector.</p>
587 <li> <b>E[foo]</b> has an attribute "foo"</li>
588 <li> <b>E[foo=bar]</b> has an attribute "foo" that equals "bar"</li>
589 <li> <b>E[foo^=bar]</b> has an attribute "foo" that starts with "bar"</li>
590 <li> <b>E[foo$=bar]</b> has an attribute "foo" that ends with "bar"</li>
591 <li> <b>E[foo*=bar]</b> has an attribute "foo" that contains the substring "bar"</li>
592 <li> <b>E[foo%=2]</b> has an attribute "foo" that is evenly divisible by 2</li>
593 <li> <b>E[foo!=bar]</b> has an attribute "foo" that does not equal "bar"</li>
595 <h4>Pseudo Classes:</h4>
597 <li> <b>E:first-child</b> E is the first child of its parent</li>
598 <li> <b>E:last-child</b> E is the last child of its parent</li>
599 <li> <b>E:nth-child(<i>n</i>)</b> E is the <i>n</i>th child of its parent (1 based as per the spec)</li>
600 <li> <b>E:nth-child(odd)</b> E is an odd child of its parent</li>
601 <li> <b>E:nth-child(even)</b> E is an even child of its parent</li>
602 <li> <b>E:only-child</b> E is the only child of its parent</li>
603 <li> <b>E:checked</b> E is an element that is has a checked attribute that is true (e.g. a radio or checkbox) </li>
604 <li> <b>E:first</b> the first E in the resultset</li>
605 <li> <b>E:last</b> the last E in the resultset</li>
606 <li> <b>E:nth(<i>n</i>)</b> the <i>n</i>th E in the resultset (1 based)</li>
607 <li> <b>E:odd</b> shortcut for :nth-child(odd)</li>
608 <li> <b>E:even</b> shortcut for :nth-child(even)</li>
609 <li> <b>E:contains(foo)</b> E's innerHTML contains the substring "foo"</li>
610 <li> <b>E:nodeValue(foo)</b> E contains a textNode with a nodeValue that equals "foo"</li>
611 <li> <b>E:not(S)</b> an E element that does not match simple selector S</li>
612 <li> <b>E:has(S)</b> an E element that has a descendent that matches simple selector S</li>
613 <li> <b>E:next(S)</b> an E element whose next sibling matches simple selector S</li>
614 <li> <b>E:prev(S)</b> an E element whose previous sibling matches simple selector S</li>
615 <li> <b>E:any(S1|S2|S2)</b> an E element which matches any of the simple selectors S1, S2 or S3
617 <h4>CSS Value Selectors:</h4>
619 <li> <b>E{display=none}</b> css value "display" that equals "none"</li>
620 <li> <b>E{display^=none}</b> css value "display" that starts with "none"</li>
621 <li> <b>E{display$=none}</b> css value "display" that ends with "none"</li>
622 <li> <b>E{display*=none}</b> css value "display" that contains the substring "none"</li>
623 <li> <b>E{display%=2}</b> css value "display" that is evenly divisible by 2</li>
624 <li> <b>E{display!=none}</b> css value "display" that does not equal "none"</li>
628 Ext.DomQuery = function(){
633 trimRe = /^\s+|\s+$/g,
634 tplRe = /\{(\d+)\}/g,
635 modeRe = /^(\s?[\/>+~]\s?|\s|$)/,
636 tagTokenRe = /^(#)?([\w-\*]+)/,
637 nthRe = /(\d*)n\+?(\d*)/,
642 isIE = window.ActiveXObject ? true : false,
647 eval("var batch = 30803;");
651 function child(parent, index){
653 n = parent.firstChild;
667 while((n = n.nextSibling) && n.nodeType != 1);
673 while((n = n.previousSibling) && n.nodeType != 1);
679 function children(parent){
680 var n = parent.firstChild,
684 nextNode = n.nextSibling;
686 if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){
687 parent.removeChild(n);
690 n.nodeIndex = ++nodeIndex;
700 function byClassName(nodeSet, cls){
704 var result = [], ri = -1;
705 for(var i = 0, ci; ci = nodeSet[i]; i++){
706 if((' '+ci.className+' ').indexOf(cls) != -1){
713 function attrValue(n, attr){
715 if(!n.tagName && typeof n.length != "undefined"){
725 if(attr == "class" || attr == "className"){
728 return n.getAttribute(attr) || n[attr];
736 function getNodes(ns, mode, tagName){
737 var result = [], ri = -1, cs;
741 tagName = tagName || "*";
743 if(typeof ns.getElementsByTagName != "undefined"){
750 for(var i = 0, ni; ni = ns[i]; i++){
751 cs = ni.getElementsByTagName(tagName);
752 for(var j = 0, ci; ci = cs[j]; j++){
758 } else if(mode == "/" || mode == ">"){
759 var utag = tagName.toUpperCase();
760 for(var i = 0, ni, cn; ni = ns[i]; i++){
762 for(var j = 0, cj; cj = cn[j]; j++){
763 if(cj.nodeName == utag || cj.nodeName == tagName || tagName == '*'){
770 }else if(mode == "+"){
771 var utag = tagName.toUpperCase();
772 for(var i = 0, n; n = ns[i]; i++){
773 while((n = n.nextSibling) && n.nodeType != 1);
774 if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){
780 }else if(mode == "~"){
781 var utag = tagName.toUpperCase();
782 for(var i = 0, n; n = ns[i]; i++){
783 while((n = n.nextSibling)){
784 if (n.nodeName == utag || n.nodeName == tagName || tagName == '*'){
793 function concat(a, b){
797 for(var i = 0, l = b.length; i < l; i++){
803 function byTag(cs, tagName){
804 if(cs.tagName || cs == document){
810 var result = [], ri = -1;
811 tagName = tagName.toLowerCase();
812 for(var i = 0, ci; ci = cs[i]; i++){
813 if(ci.nodeType == 1 && ci.tagName.toLowerCase() == tagName){
820 function byId(cs, id){
821 if(cs.tagName || cs == document){
827 var result = [], ri = -1;
828 for(var i = 0, ci; ci = cs[i]; i++){
829 if(ci && ci.id == id){
839 function byAttribute(cs, attr, value, op, custom){
842 useGetStyle = custom == "{",
843 fn = Ext.DomQuery.operators[op],
848 for(var i = 0, ci; ci = cs[i]; i++){
850 if(ci.nodeType != 1){
855 xml = Ext.DomQuery.isXml(ci);
862 a = Ext.DomQuery.getStyle(ci, attr);
863 } else if (attr == "class" || attr == "className"){
865 } else if (attr == "for"){
867 } else if (attr == "href"){
870 a = ci.getAttribute("href", 2);
872 a = ci.getAttribute(attr);
875 a = ci.getAttribute(attr);
877 if((fn && fn(a, value)) || (!fn && a)){
884 function byPseudo(cs, name, value){
885 return Ext.DomQuery.pseudos[name](cs, value);
888 function nodupIEXml(cs){
891 cs[0].setAttribute("_nodup", d);
893 for(var i = 1, len = cs.length; i < len; i++){
895 if(!c.getAttribute("_nodup") != d){
896 c.setAttribute("_nodup", d);
900 for(var i = 0, len = cs.length; i < len; i++){
901 cs[i].removeAttribute("_nodup");
910 var len = cs.length, c, i, r = cs, cj, ri = -1;
911 if(!len || typeof cs.nodeType != "undefined" || len == 1){
914 if(isIE && typeof cs[0].selectSingleNode != "undefined"){
915 return nodupIEXml(cs);
919 for(i = 1; c = cs[i]; i++){
924 for(var j = 0; j < i; j++){
927 for(j = i+1; cj = cs[j]; j++){
939 function quickDiffIEXml(c1, c2){
942 for(var i = 0, len = c1.length; i < len; i++){
943 c1[i].setAttribute("_qdiff", d);
945 for(var i = 0, len = c2.length; i < len; i++){
946 if(c2[i].getAttribute("_qdiff") != d){
950 for(var i = 0, len = c1.length; i < len; i++){
951 c1[i].removeAttribute("_qdiff");
956 function quickDiff(c1, c2){
957 var len1 = c1.length,
963 if(isIE && typeof c1[0].selectSingleNode != "undefined"){
964 return quickDiffIEXml(c1, c2);
966 for(var i = 0; i < len1; i++){
969 for(var i = 0, len = c2.length; i < len; i++){
970 if(c2[i]._qdiff != d){
977 function quickId(ns, mode, root, id){
979 var d = root.ownerDocument || root;
980 return d.getElementById(id);
982 ns = getNodes(ns, mode, "*");
987 getStyle : function(el, name){
988 return Ext.fly(el).getStyle(name);
991 compile : function(path, type){
992 type = type || "select";
995 var fn = ["var f = function(root){\n var mode; ++batch; var n = root || document;\n"],
998 matchers = Ext.DomQuery.matchers,
999 matchersLn = matchers.length,
1002 lmode = path.match(modeRe);
1004 if(lmode && lmode[1]){
1005 fn[fn.length] = 'mode="'+lmode[1].replace(trimRe, "")+'";';
1006 path = path.replace(lmode[1], "");
1010 while(path.substr(0, 1)=="/"){
1011 path = path.substr(1);
1014 while(path && lastPath != path){
1016 var tokenMatch = path.match(tagTokenRe);
1017 if(type == "select"){
1020 if(tokenMatch[1] == "#"){
1021 fn[fn.length] = 'n = quickId(n, mode, root, "'+tokenMatch[2]+'");';
1023 fn[fn.length] = 'n = getNodes(n, mode, "'+tokenMatch[2]+'");';
1025 path = path.replace(tokenMatch[0], "");
1026 }else if(path.substr(0, 1) != '@'){
1027 fn[fn.length] = 'n = getNodes(n, mode, "*");';
1032 if(tokenMatch[1] == "#"){
1033 fn[fn.length] = 'n = byId(n, "'+tokenMatch[2]+'");';
1035 fn[fn.length] = 'n = byTag(n, "'+tokenMatch[2]+'");';
1037 path = path.replace(tokenMatch[0], "");
1040 while(!(modeMatch = path.match(modeRe))){
1041 var matched = false;
1042 for(var j = 0; j < matchersLn; j++){
1043 var t = matchers[j];
1044 var m = path.match(t.re);
1046 fn[fn.length] = t.select.replace(tplRe, function(x, i){
1049 path = path.replace(m[0], "");
1056 throw 'Error parsing selector, parsing failed at "' + path + '"';
1060 fn[fn.length] = 'mode="'+modeMatch[1].replace(trimRe, "")+'";';
1061 path = path.replace(modeMatch[1], "");
1065 fn[fn.length] = "return nodup(n);\n}";
1073 jsSelect: function(path, root, type){
1075 root = root || document;
1077 if(typeof root == "string"){
1078 root = document.getElementById(root);
1080 var paths = path.split(","),
1084 for(var i = 0, len = paths.length; i < len; i++){
1085 var subPath = paths[i].replace(trimRe, "");
1087 if(!cache[subPath]){
1088 cache[subPath] = Ext.DomQuery.compile(subPath);
1089 if(!cache[subPath]){
1090 throw subPath + " is not a valid selector";
1093 var result = cache[subPath](root);
1094 if(result && result != document){
1095 results = results.concat(result);
1101 if(paths.length > 1){
1102 return nodup(results);
1106 isXml: function(el) {
1107 var docEl = (el ? el.ownerDocument || el : 0).documentElement;
1108 return docEl ? docEl.nodeName !== "HTML" : false;
1110 select : document.querySelectorAll ? function(path, root, type) {
1111 root = root || document;
1112 if (!Ext.DomQuery.isXml(root)) {
1114 var cs = root.querySelectorAll(path);
1115 return Ext.toArray(cs);
1119 return Ext.DomQuery.jsSelect.call(this, path, root, type);
1120 } : function(path, root, type) {
1121 return Ext.DomQuery.jsSelect.call(this, path, root, type);
1125 selectNode : function(path, root){
1126 return Ext.DomQuery.select(path, root)[0];
1130 selectValue : function(path, root, defaultValue){
1131 path = path.replace(trimRe, "");
1132 if(!valueCache[path]){
1133 valueCache[path] = Ext.DomQuery.compile(path, "select");
1135 var n = valueCache[path](root), v;
1136 n = n[0] ? n[0] : n;
1142 if (typeof n.normalize == 'function') n.normalize();
1144 v = (n && n.firstChild ? n.firstChild.nodeValue : null);
1145 return ((v === null||v === undefined||v==='') ? defaultValue : v);
1149 selectNumber : function(path, root, defaultValue){
1150 var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0);
1151 return parseFloat(v);
1155 is : function(el, ss){
1156 if(typeof el == "string"){
1157 el = document.getElementById(el);
1159 var isArray = Ext.isArray(el),
1160 result = Ext.DomQuery.filter(isArray ? el : [el], ss);
1161 return isArray ? (result.length == el.length) : (result.length > 0);
1165 filter : function(els, ss, nonMatches){
1166 ss = ss.replace(trimRe, "");
1167 if(!simpleCache[ss]){
1168 simpleCache[ss] = Ext.DomQuery.compile(ss, "simple");
1170 var result = simpleCache[ss](els);
1171 return nonMatches ? quickDiff(result, els) : result;
1177 select: 'n = byClassName(n, " {1} ");'
1179 re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,
1180 select: 'n = byPseudo(n, "{1}", "{2}");'
1182 re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,
1183 select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'
1186 select: 'n = byId(n, "{1}");'
1189 select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
1195 "=" : function(a, v){
1198 "!=" : function(a, v){
1201 "^=" : function(a, v){
1202 return a && a.substr(0, v.length) == v;
1204 "$=" : function(a, v){
1205 return a && a.substr(a.length-v.length) == v;
1207 "*=" : function(a, v){
1208 return a && a.indexOf(v) !== -1;
1210 "%=" : function(a, v){
1211 return (a % v) == 0;
1213 "|=" : function(a, v){
1214 return a && (a == v || a.substr(0, v.length+1) == v+'-');
1216 "~=" : function(a, v){
1217 return a && (' '+a+' ').indexOf(' '+v+' ') != -1;
1223 "first-child" : function(c){
1224 var r = [], ri = -1, n;
1225 for(var i = 0, ci; ci = n = c[i]; i++){
1226 while((n = n.previousSibling) && n.nodeType != 1);
1234 "last-child" : function(c){
1235 var r = [], ri = -1, n;
1236 for(var i = 0, ci; ci = n = c[i]; i++){
1237 while((n = n.nextSibling) && n.nodeType != 1);
1245 "nth-child" : function(c, a) {
1246 var r = [], ri = -1,
1247 m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a),
1248 f = (m[1] || 1) - 0, l = m[2] - 0;
1249 for(var i = 0, n; n = c[i]; i++){
1250 var pn = n.parentNode;
1251 if (batch != pn._batch) {
1253 for(var cn = pn.firstChild; cn; cn = cn.nextSibling){
1254 if(cn.nodeType == 1){
1261 if (l == 0 || n.nodeIndex == l){
1264 } else if ((n.nodeIndex + l) % f == 0){
1272 "only-child" : function(c){
1273 var r = [], ri = -1;;
1274 for(var i = 0, ci; ci = c[i]; i++){
1275 if(!prev(ci) && !next(ci)){
1282 "empty" : function(c){
1283 var r = [], ri = -1;
1284 for(var i = 0, ci; ci = c[i]; i++){
1285 var cns = ci.childNodes, j = 0, cn, empty = true;
1288 if(cn.nodeType == 1 || cn.nodeType == 3){
1300 "contains" : function(c, v){
1301 var r = [], ri = -1;
1302 for(var i = 0, ci; ci = c[i]; i++){
1303 if((ci.textContent||ci.innerText||'').indexOf(v) != -1){
1310 "nodeValue" : function(c, v){
1311 var r = [], ri = -1;
1312 for(var i = 0, ci; ci = c[i]; i++){
1313 if(ci.firstChild && ci.firstChild.nodeValue == v){
1320 "checked" : function(c){
1321 var r = [], ri = -1;
1322 for(var i = 0, ci; ci = c[i]; i++){
1323 if(ci.checked == true){
1330 "not" : function(c, ss){
1331 return Ext.DomQuery.filter(c, ss, true);
1334 "any" : function(c, selectors){
1335 var ss = selectors.split('|'),
1337 for(var i = 0, ci; ci = c[i]; i++){
1338 for(var j = 0; s = ss[j]; j++){
1339 if(Ext.DomQuery.is(ci, s)){
1348 "odd" : function(c){
1349 return this["nth-child"](c, "odd");
1352 "even" : function(c){
1353 return this["nth-child"](c, "even");
1356 "nth" : function(c, a){
1357 return c[a-1] || [];
1360 "first" : function(c){
1364 "last" : function(c){
1365 return c[c.length-1] || [];
1368 "has" : function(c, ss){
1369 var s = Ext.DomQuery.select,
1371 for(var i = 0, ci; ci = c[i]; i++){
1372 if(s(ss, ci).length > 0){
1379 "next" : function(c, ss){
1380 var is = Ext.DomQuery.is,
1382 for(var i = 0, ci; ci = c[i]; i++){
1391 "prev" : function(c, ss){
1392 var is = Ext.DomQuery.is,
1394 for(var i = 0, ci; ci = c[i]; i++){
1407 Ext.query = Ext.DomQuery.select;
1409 Ext.util.DelayedTask = function(fn, scope, args){
1415 fn.apply(scope, args || []);
1419 me.delay = function(delay, newFn, newScope, newArgs){
1422 scope = newScope || scope;
1423 args = newArgs || args;
1424 id = setInterval(call, delay);
1428 me.cancel = function(){
1436 var EXTUTIL = Ext.util,
1441 EXTUTIL.Observable = function(){
1443 var me = this, e = me.events;
1445 me.on(me.listeners);
1446 delete me.listeners;
1448 me.events = e || {};
1451 EXTUTIL.Observable.prototype = {
1453 filterOptRe : /^(?:scope|delay|buffer|single)$/,
1456 fireEvent : function(){
1457 var a = Array.prototype.slice.call(arguments, 0),
1458 ename = a[0].toLowerCase(),
1461 ce = me.events[ename],
1465 if (me.eventsSuspended === TRUE) {
1466 if (q = me.eventQueue) {
1470 else if(typeof ce == 'object') {
1472 if(ce.fire.apply(ce, a.slice(1)) === FALSE) {
1475 c = me.getBubbleTarget && me.getBubbleTarget();
1476 if(c && c.enableBubble) {
1477 cc = c.events[ename];
1478 if(!cc || typeof cc != 'object' || !cc.bubble) {
1479 c.enableBubble(ename);
1481 return c.fireEvent.apply(c, a);
1486 ret = ce.fire.apply(ce, a);
1493 addListener : function(eventName, fn, scope, o){
1499 if (typeof eventName == 'object') {
1503 if (!me.filterOptRe.test(e)) {
1504 me.addListener(e, oe.fn || oe, oe.scope || o.scope, oe.fn ? oe : o);
1508 eventName = eventName.toLowerCase();
1509 ce = me.events[eventName] || TRUE;
1510 if (typeof ce == 'boolean') {
1511 me.events[eventName] = ce = new EXTUTIL.Event(me, eventName);
1513 ce.addListener(fn, scope, typeof o == 'object' ? o : {});
1518 removeListener : function(eventName, fn, scope){
1519 var ce = this.events[eventName.toLowerCase()];
1520 if (typeof ce == 'object') {
1521 ce.removeListener(fn, scope);
1526 purgeListeners : function(){
1527 var events = this.events,
1532 if(typeof evt == 'object'){
1533 evt.clearListeners();
1539 addEvents : function(o){
1541 me.events = me.events || {};
1542 if (typeof o == 'string') {
1546 me.events[a[i]] = me.events[a[i]] || TRUE;
1549 Ext.applyIf(me.events, o);
1554 hasListener : function(eventName){
1555 var e = this.events[eventName.toLowerCase()];
1556 return typeof e == 'object' && e.listeners.length > 0;
1560 suspendEvents : function(queueSuspended){
1561 this.eventsSuspended = TRUE;
1562 if(queueSuspended && !this.eventQueue){
1563 this.eventQueue = [];
1568 resumeEvents : function(){
1570 queued = me.eventQueue || [];
1571 me.eventsSuspended = FALSE;
1572 delete me.eventQueue;
1573 EACH(queued, function(e) {
1574 me.fireEvent.apply(me, e);
1579 var OBSERVABLE = EXTUTIL.Observable.prototype;
1581 OBSERVABLE.on = OBSERVABLE.addListener;
1583 OBSERVABLE.un = OBSERVABLE.removeListener;
1586 EXTUTIL.Observable.releaseCapture = function(o){
1587 o.fireEvent = OBSERVABLE.fireEvent;
1590 function createTargeted(h, o, scope){
1592 if(o.target == arguments[0]){
1593 h.apply(scope, Array.prototype.slice.call(arguments, 0));
1598 function createBuffered(h, o, l, scope){
1599 l.task = new EXTUTIL.DelayedTask();
1601 l.task.delay(o.buffer, h, scope, Array.prototype.slice.call(arguments, 0));
1605 function createSingle(h, e, fn, scope){
1607 e.removeListener(fn, scope);
1608 return h.apply(scope, arguments);
1612 function createDelayed(h, o, l, scope){
1614 var task = new EXTUTIL.DelayedTask();
1619 task.delay(o.delay || 10, h, scope, Array.prototype.slice.call(arguments, 0));
1623 EXTUTIL.Event = function(obj, name){
1626 this.listeners = [];
1629 EXTUTIL.Event.prototype = {
1630 addListener : function(fn, scope, options){
1633 scope = scope || me.obj;
1634 if(!me.isListening(fn, scope)){
1635 l = me.createListener(fn, scope, options);
1637 me.listeners = me.listeners.slice(0);
1639 me.listeners.push(l);
1643 createListener: function(fn, scope, o){
1645 scope = scope || this.obj;
1652 h = createTargeted(h, o, scope);
1655 h = createDelayed(h, o, l, scope);
1658 h = createSingle(h, this, fn, scope);
1661 h = createBuffered(h, o, l, scope);
1667 findListener : function(fn, scope){
1668 var list = this.listeners,
1672 scope = scope || this.obj;
1676 if(l.fn == fn && l.scope == scope){
1684 isListening : function(fn, scope){
1685 return this.findListener(fn, scope) != -1;
1688 removeListener : function(fn, scope){
1694 if((index = me.findListener(fn, scope)) != -1){
1696 me.listeners = me.listeners.slice(0);
1698 l = me.listeners[index];
1703 k = l.tasks && l.tasks.length;
1706 l.tasks[k].cancel();
1710 me.listeners.splice(index, 1);
1717 clearListeners : function(){
1722 me.removeListener(l[i].fn, l[i].scope);
1728 listeners = me.listeners,
1729 len = listeners.length,
1735 var args = Array.prototype.slice.call(arguments, 0);
1736 for (; i < len; i++) {
1738 if(l && l.fireFn.apply(l.scope || me.obj || window, args) === FALSE) {
1739 return (me.firing = FALSE);
1750 Ext.apply(Ext.util.Observable.prototype, function(){
1754 function getMethodEvent(method){
1755 var e = (this.methodEvents = this.methodEvents ||
1756 {})[method], returnValue, v, cancel, obj = this;
1759 this.methodEvents[method] = e = {};
1760 e.originalFn = this[method];
1761 e.methodName = method;
1765 var makeCall = function(fn, scope, args){
1766 if((v = fn.apply(scope || obj, args)) !== undefined){
1767 if (typeof v == 'object') {
1768 if(v.returnValue !== undefined){
1769 returnValue = v.returnValue;
1773 cancel = !!v.cancel;
1785 this[method] = function(){
1786 var args = Array.prototype.slice.call(arguments, 0),
1788 returnValue = v = undefined;
1791 for(var i = 0, len = e.before.length; i < len; i++){
1793 makeCall(b.fn, b.scope, args);
1799 if((v = e.originalFn.apply(obj, args)) !== undefined){
1803 for(var i = 0, len = e.after.length; i < len; i++){
1805 makeCall(b.fn, b.scope, args);
1820 beforeMethod : function(method, fn, scope){
1821 getMethodEvent.call(this, method).before.push({
1828 afterMethod : function(method, fn, scope){
1829 getMethodEvent.call(this, method).after.push({
1835 removeMethodListener: function(method, fn, scope){
1836 var e = this.getMethodEvent(method);
1837 for(var i = 0, len = e.before.length; i < len; i++){
1838 if(e.before[i].fn == fn && e.before[i].scope == scope){
1839 e.before.splice(i, 1);
1843 for(var i = 0, len = e.after.length; i < len; i++){
1844 if(e.after[i].fn == fn && e.after[i].scope == scope){
1845 e.after.splice(i, 1);
1852 relayEvents : function(o, events){
1854 function createHandler(ename){
1856 return me.fireEvent.apply(me, [ename].concat(Array.prototype.slice.call(arguments, 0)));
1859 for(var i = 0, len = events.length; i < len; i++){
1860 var ename = events[i];
1861 me.events[ename] = me.events[ename] || true;
1862 o.on(ename, createHandler(ename), me);
1867 enableBubble : function(events){
1869 if(!Ext.isEmpty(events)){
1870 events = Ext.isArray(events) ? events : Array.prototype.slice.call(arguments, 0);
1871 for(var i = 0, len = events.length; i < len; i++){
1872 var ename = events[i];
1873 ename = ename.toLowerCase();
1874 var ce = me.events[ename] || true;
1875 if (typeof ce == 'boolean') {
1876 ce = new Ext.util.Event(me, ename);
1877 me.events[ename] = ce;
1888 Ext.util.Observable.capture = function(o, fn, scope){
1889 o.fireEvent = o.fireEvent.createInterceptor(fn, scope);
1894 Ext.util.Observable.observeClass = function(c, listeners){
1897 Ext.apply(c, new Ext.util.Observable());
1898 Ext.util.Observable.capture(c.prototype, c.fireEvent, c);
1900 if(typeof listeners == 'object'){
1908 Ext.EventManager = function(){
1911 docReadyState = false,
1912 DETECT_NATIVE = Ext.isGecko || Ext.isWebKit || Ext.isSafari,
1917 DOMCONTENTLOADED = "DOMContentLoaded",
1918 COMPLETE = 'complete',
1919 propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,
1921 specialElCache = [];
1926 len = specialElCache.length,
1931 if(el.getElementById || el.navigator){
1933 for(; i < len; ++i){
1934 o = specialElCache[i];
1943 specialElCache.push({
1952 if(!Ext.elCache[id]){
1953 Ext.Element.addToCache(new Ext.Element(el), id);
1955 Ext.elCache[id].skipGC = true;
1963 function addListener(el, ename, fn, task, wrap, scope){
1964 el = Ext.getDom(el);
1966 es = Ext.elCache[id].events,
1969 wfn = E.on(el, ename, wrap);
1970 es[ename] = es[ename] || [];
1973 es[ename].push([fn, wrap, scope, wfn, task]);
1979 if(el.addEventListener && ename == "mousewheel"){
1980 var args = ["DOMMouseScroll", wrap, false];
1981 el.addEventListener.apply(el, args);
1982 Ext.EventManager.addListener(WINDOW, 'unload', function(){
1983 el.removeEventListener.apply(el, args);
1988 if(el == DOC && ename == "mousedown"){
1989 Ext.EventManager.stoppedMouseDownEvent.addListener(wrap);
1993 function doScrollChk(){
2000 DOC.documentElement.doScroll('left');
2009 function checkReadyState(e){
2011 if(Ext.isIE && doScrollChk()){
2014 if(DOC.readyState == COMPLETE){
2018 docReadyState || (docReadyProcId = setTimeout(arguments.callee, 2));
2023 function checkStyleSheets(e){
2024 styles || (styles = Ext.query('style, link[rel=stylesheet]'));
2025 if(styles.length == DOC.styleSheets.length){
2029 docReadyState || (docReadyProcId = setTimeout(arguments.callee, 2));
2033 function OperaDOMContentLoaded(e){
2034 DOC.removeEventListener(DOMCONTENTLOADED, arguments.callee, false);
2038 function fireDocReady(e){
2040 docReadyState = true;
2043 clearTimeout(docReadyProcId);
2046 DOC.removeEventListener(DOMCONTENTLOADED, fireDocReady, false);
2048 if(Ext.isIE && checkReadyState.bindIE){
2049 DOC.detachEvent('onreadystatechange', checkReadyState);
2051 E.un(WINDOW, "load", arguments.callee);
2053 if(docReadyEvent && !Ext.isReady){
2055 docReadyEvent.fire();
2056 docReadyEvent.listeners = [];
2061 function initDocReady(){
2062 docReadyEvent || (docReadyEvent = new Ext.util.Event());
2063 if (DETECT_NATIVE) {
2064 DOC.addEventListener(DOMCONTENTLOADED, fireDocReady, false);
2070 if(!checkReadyState()){
2071 checkReadyState.bindIE = true;
2072 DOC.attachEvent('onreadystatechange', checkReadyState);
2075 }else if(Ext.isOpera ){
2079 (DOC.readyState == COMPLETE && checkStyleSheets()) ||
2080 DOC.addEventListener(DOMCONTENTLOADED, OperaDOMContentLoaded, false);
2082 }else if (Ext.isWebKit){
2087 E.on(WINDOW, "load", fireDocReady);
2090 function createTargeted(h, o){
2092 var args = Ext.toArray(arguments);
2093 if(o.target == Ext.EventObject.setEvent(args[0]).target){
2094 h.apply(this, args);
2099 function createBuffered(h, o, task){
2102 task.delay(o.buffer, h, null, [new Ext.EventObjectImpl(e)]);
2106 function createSingle(h, el, ename, fn, scope){
2108 Ext.EventManager.removeListener(el, ename, fn, scope);
2113 function createDelayed(h, o, fn){
2115 var task = new Ext.util.DelayedTask(h);
2119 fn.tasks.push(task);
2120 task.delay(o.delay || 10, h, null, [new Ext.EventObjectImpl(e)]);
2124 function listen(element, ename, opt, fn, scope){
2125 var o = (!opt || typeof opt == "boolean") ? {} : opt,
2126 el = Ext.getDom(element), task;
2129 scope = scope || o.scope;
2132 throw "Error listening for \"" + ename + '\". Element "' + element + '" doesn\'t exist.';
2139 e = Ext.EventObject.setEvent(e);
2142 if(!(t = e.getTarget(o.delegate, el))){
2151 if (o.preventDefault) {
2154 if (o.stopPropagation) {
2155 e.stopPropagation();
2161 fn.call(scope || el, e, t, o);
2164 h = createTargeted(h, o);
2167 h = createDelayed(h, o, fn);
2170 h = createSingle(h, el, ename, fn, scope);
2173 task = new Ext.util.DelayedTask(h);
2174 h = createBuffered(h, o, task);
2177 addListener(el, ename, fn, task, h, scope);
2183 addListener : function(element, eventName, fn, scope, options){
2184 if(typeof eventName == 'object'){
2185 var o = eventName, e, val;
2188 if(!propRe.test(e)){
2189 if(Ext.isFunction(val)){
2191 listen(element, e, o, val, o.scope);
2194 listen(element, e, val);
2199 listen(element, eventName, options, fn, scope);
2204 removeListener : function(el, eventName, fn, scope){
2205 el = Ext.getDom(el);
2207 f = el && (Ext.elCache[id].events)[eventName] || [],
2208 wrap, i, l, k, len, fnc;
2210 for (i = 0, len = f.length; i < len; i++) {
2213 if (Ext.isArray(fnc = f[i]) && fnc[0] == fn && (!scope || fnc[2] == scope)) {
2217 k = fn.tasks && fn.tasks.length;
2220 fn.tasks[k].cancel();
2225 E.un(el, eventName, E.extAdapter ? fnc[3] : wrap);
2228 if(wrap && el.addEventListener && eventName == "mousewheel"){
2229 el.removeEventListener("DOMMouseScroll", wrap, false);
2233 if(wrap && el == DOC && eventName == "mousedown"){
2234 Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
2238 if (f.length === 0) {
2239 delete Ext.elCache[id].events[eventName];
2241 for (k in Ext.elCache[id].events) {
2244 Ext.elCache[id].events = {};
2251 removeAll : function(el){
2252 el = Ext.getDom(el);
2254 ec = Ext.elCache[id] || {},
2255 es = ec.events || {},
2256 f, i, len, ename, fn, k, wrap;
2259 if(es.hasOwnProperty(ename)){
2262 for (i = 0, len = f.length; i < len; i++) {
2267 if(fn[0].tasks && (k = fn[0].tasks.length)) {
2269 fn[0].tasks[k].cancel();
2274 E.un(el, ename, E.extAdapter ? fn[3] : wrap);
2277 if(el.addEventListener && wrap && ename == "mousewheel"){
2278 el.removeEventListener("DOMMouseScroll", wrap, false);
2282 if(wrap && el == DOC && ename == "mousedown"){
2283 Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
2288 if (Ext.elCache[id]) {
2289 Ext.elCache[id].events = {};
2293 getListeners : function(el, eventName) {
2294 el = Ext.getDom(el);
2296 ec = Ext.elCache[id] || {},
2297 es = ec.events || {},
2299 if (es && es[eventName]) {
2300 return es[eventName];
2306 purgeElement : function(el, recurse, eventName) {
2307 el = Ext.getDom(el);
2309 ec = Ext.elCache[id] || {},
2310 es = ec.events || {},
2313 if (es && es.hasOwnProperty(eventName)) {
2315 for (i = 0, len = f.length; i < len; i++) {
2316 Ext.EventManager.removeListener(el, eventName, f[i][0]);
2320 Ext.EventManager.removeAll(el);
2322 if (recurse && el && el.childNodes) {
2323 for (i = 0, len = el.childNodes.length; i < len; i++) {
2324 Ext.EventManager.purgeElement(el.childNodes[i], recurse, eventName);
2329 _unload : function() {
2331 for (el in Ext.elCache) {
2332 Ext.EventManager.removeAll(el);
2335 delete Ext.Element._flyweights;
2341 ajax = Ext.lib.Ajax;
2342 (typeof ajax.conn == 'object') ? conn = ajax.conn : conn = {};
2346 ajax.abort({conn: c, tId: tid});
2351 onDocumentReady : function(fn, scope, options){
2353 docReadyEvent || (docReadyEvent = new Ext.util.Event());
2354 docReadyEvent.addListener(fn, scope, options);
2355 docReadyEvent.fire();
2356 docReadyEvent.listeners = [];
2361 options = options || {};
2362 options.delay = options.delay || 1;
2363 docReadyEvent.addListener(fn, scope, options);
2368 fireDocReady : fireDocReady
2371 pub.on = pub.addListener;
2373 pub.un = pub.removeListener;
2375 pub.stoppedMouseDownEvent = new Ext.util.Event();
2379 Ext.onReady = Ext.EventManager.onDocumentReady;
2385 var initExtCss = function(){
2387 var bd = document.body || document.getElementsByTagName('body')[0];
2388 if(!bd){ return false; }
2390 Ext.isIE ? "ext-ie " + (Ext.isIE6 ? 'ext-ie6' : (Ext.isIE7 ? 'ext-ie7' : 'ext-ie8'))
2391 : Ext.isGecko ? "ext-gecko " + (Ext.isGecko2 ? 'ext-gecko2' : 'ext-gecko3')
2392 : Ext.isOpera ? "ext-opera"
2393 : Ext.isWebKit ? "ext-webkit" : ""];
2396 cls.push("ext-safari " + (Ext.isSafari2 ? 'ext-safari2' : (Ext.isSafari3 ? 'ext-safari3' : 'ext-safari4')));
2397 }else if(Ext.isChrome){
2398 cls.push("ext-chrome");
2402 cls.push("ext-mac");
2405 cls.push("ext-linux");
2408 if(Ext.isStrict || Ext.isBorderBox){
2409 var p = bd.parentNode;
2411 p.className += Ext.isStrict ? ' ext-strict' : ' ext-border-box';
2414 bd.className += cls.join(' ');
2419 Ext.onReady(initExtCss);
2425 Ext.EventObject = function(){
2426 var E = Ext.lib.Event,
2427 clickRe = /(dbl)?click/,
2442 btnMap = Ext.isIE ? {1:0,4:1,2:2} :
2443 (Ext.isWebKit ? {1:0,2:1,3:2} : {0:0,1:1,2:2});
2445 Ext.EventObjectImpl = function(e){
2447 this.setEvent(e.browserEvent || e);
2451 Ext.EventObjectImpl.prototype = {
2453 setEvent : function(e){
2455 if(e == me || (e && e.browserEvent)){
2458 me.browserEvent = e;
2461 me.button = e.button ? btnMap[e.button] : (e.which ? e.which - 1 : -1);
2462 if(clickRe.test(e.type) && me.button == -1){
2466 me.shiftKey = e.shiftKey;
2468 me.ctrlKey = e.ctrlKey || e.metaKey || false;
2469 me.altKey = e.altKey;
2471 me.keyCode = e.keyCode;
2472 me.charCode = e.charCode;
2474 me.target = E.getTarget(e);
2479 me.shiftKey = false;
2491 stopEvent : function(){
2493 if(me.browserEvent){
2494 if(me.browserEvent.type == 'mousedown'){
2495 Ext.EventManager.stoppedMouseDownEvent.fire(me);
2497 E.stopEvent(me.browserEvent);
2502 preventDefault : function(){
2503 if(this.browserEvent){
2504 E.preventDefault(this.browserEvent);
2509 stopPropagation : function(){
2511 if(me.browserEvent){
2512 if(me.browserEvent.type == 'mousedown'){
2513 Ext.EventManager.stoppedMouseDownEvent.fire(me);
2515 E.stopPropagation(me.browserEvent);
2520 getCharCode : function(){
2521 return this.charCode || this.keyCode;
2525 getKey : function(){
2526 return this.normalizeKey(this.keyCode || this.charCode)
2530 normalizeKey: function(k){
2531 return Ext.isSafari ? (safariKeys[k] || k) : k;
2535 getPageX : function(){
2540 getPageY : function(){
2550 getTarget : function(selector, maxDepth, returnEl){
2551 return selector ? Ext.fly(this.target).findParent(selector, maxDepth, returnEl) : (returnEl ? Ext.get(this.target) : this.target);
2555 getRelatedTarget : function(){
2556 return this.browserEvent ? E.getRelatedTarget(this.browserEvent) : null;
2560 getWheelDelta : function(){
2561 var e = this.browserEvent;
2564 delta = e.wheelDelta/120;
2566 delta = -e.detail/3;
2572 within : function(el, related, allowEl){
2574 var t = this[related ? "getRelatedTarget" : "getTarget"]();
2575 return t && ((allowEl ? (t == Ext.getDom(el)) : false) || Ext.fly(el).contains(t));
2581 return new Ext.EventObjectImpl();
2584 Ext.apply(Ext.EventManager, function(){
2590 propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,
2596 useKeydown = Ext.isWebKit ?
2597 Ext.num(navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1]) >= 525 :
2598 !((Ext.isGecko && !Ext.isWindows) || Ext.isOpera);
2602 doResizeEvent: function(){
2603 var h = D.getViewHeight(),
2604 w = D.getViewWidth();
2607 if(curHeight != h || curWidth != w){
2608 resizeEvent.fire(curWidth = w, curHeight = h);
2613 onWindowResize : function(fn, scope, options){
2615 resizeEvent = new Ext.util.Event();
2616 resizeTask = new Ext.util.DelayedTask(this.doResizeEvent);
2617 Ext.EventManager.on(window, "resize", this.fireWindowResize, this);
2619 resizeEvent.addListener(fn, scope, options);
2623 fireWindowResize : function(){
2625 resizeTask.delay(100);
2630 onTextResize : function(fn, scope, options){
2632 textEvent = new Ext.util.Event();
2633 var textEl = new Ext.Element(document.createElement('div'));
2634 textEl.dom.className = 'x-text-resize';
2635 textEl.dom.innerHTML = 'X';
2636 textEl.appendTo(document.body);
2637 textSize = textEl.dom.offsetHeight;
2638 setInterval(function(){
2639 if(textEl.dom.offsetHeight != textSize){
2640 textEvent.fire(textSize, textSize = textEl.dom.offsetHeight);
2642 }, this.textResizeInterval);
2644 textEvent.addListener(fn, scope, options);
2648 removeResizeListener : function(fn, scope){
2650 resizeEvent.removeListener(fn, scope);
2655 fireResize : function(){
2657 resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
2662 textResizeInterval : 50,
2669 useKeydown: useKeydown
2673 Ext.EventManager.on = Ext.EventManager.addListener;
2676 Ext.apply(Ext.EventObjectImpl.prototype, {
2856 isNavKeyPress : function(){
2858 k = this.normalizeKey(me.keyCode);
2859 return (k >= 33 && k <= 40) ||
2865 isSpecialKey : function(){
2866 var k = this.normalizeKey(this.keyCode);
2867 return (this.type == 'keypress' && this.ctrlKey) ||
2868 this.isNavKeyPress() ||
2869 (k == this.BACKSPACE) ||
2870 (k >= 16 && k <= 20) ||
2871 (k >= 44 && k <= 46);
2874 getPoint : function(){
2875 return new Ext.lib.Point(this.xy[0], this.xy[1]);
2879 hasModifier : function(){
2880 return ((this.ctrlKey || this.altKey) || this.shiftKey);
2886 Ext.Element = function(element, forceNew){
2887 var dom = typeof element == "string" ?
2888 DOC.getElementById(element) : element,
2891 if(!dom) return null;
2895 if(!forceNew && id && Ext.elCache[id]){
2896 return Ext.elCache[id].el;
2903 this.id = id || Ext.id(dom);
2906 var DH = Ext.DomHelper,
2912 set : function(o, useSet){
2916 useSet = (useSet !== false) && !!el.setAttribute;
2919 if (o.hasOwnProperty(attr)) {
2921 if (attr == 'style') {
2922 DH.applyStyles(el, val);
2923 } else if (attr == 'cls') {
2925 } else if (useSet) {
2926 el.setAttribute(attr, val);
2987 is : function(simpleSelector){
2988 return Ext.DomQuery.is(this.dom, simpleSelector);
2992 focus : function(defer, dom) {
2994 dom = dom || me.dom;
2997 me.focus.defer(defer, null, [null, dom]);
3014 getValue : function(asNumber){
3015 var val = this.dom.value;
3016 return asNumber ? parseInt(val, 10) : val;
3020 addListener : function(eventName, fn, scope, options){
3021 Ext.EventManager.on(this.dom, eventName, fn, scope || this, options);
3026 removeListener : function(eventName, fn, scope){
3027 Ext.EventManager.removeListener(this.dom, eventName, fn, scope || this);
3032 removeAllListeners : function(){
3033 Ext.EventManager.removeAll(this.dom);
3038 purgeAllListeners : function() {
3039 Ext.EventManager.purgeElement(this, true);
3043 addUnits : function(size){
3044 if(size === "" || size == "auto" || size === undefined){
3046 } else if(!isNaN(size) || !unitPattern.test(size)){
3047 size = size + (this.defaultUnit || 'px');
3053 load : function(url, params, cb){
3054 Ext.Ajax.request(Ext.apply({
3056 url: url.url || url,
3059 indicatorText: url.indicatorText || ''
3060 }, Ext.isObject(url) ? url : {}));
3065 isBorderBox : function(){
3066 return noBoxAdjust[(this.dom.tagName || "").toLowerCase()] || Ext.isBorderBox;
3070 remove : function(){
3076 Ext.removeNode(dom);
3081 hover : function(overFn, outFn, scope, options){
3083 me.on('mouseenter', overFn, scope || me.dom, options);
3084 me.on('mouseleave', outFn, scope || me.dom, options);
3089 contains : function(el){
3090 return !el ? false : Ext.lib.Dom.isAncestor(this.dom, el.dom ? el.dom : el);
3094 getAttributeNS : function(ns, name){
3095 return this.getAttribute(name, ns);
3099 getAttribute : Ext.isIE ? function(name, ns){
3101 type = typeof d[ns + ":" + name];
3103 if(['undefined', 'unknown'].indexOf(type) == -1){
3104 return d[ns + ":" + name];
3107 } : function(name, ns){
3109 return d.getAttributeNS(ns, name) || d.getAttribute(ns + ":" + name) || d.getAttribute(name) || d[name];
3113 update : function(html) {
3115 this.dom.innerHTML = html;
3121 var ep = El.prototype;
3123 El.addMethods = function(o){
3128 ep.on = ep.addListener;
3131 ep.un = ep.removeListener;
3134 ep.autoBoxAdjust = true;
3137 var unitPattern = /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i,
3143 El.get = function(el){
3147 if(!el){ return null; }
3148 if (typeof el == "string") {
3149 if (!(elm = DOC.getElementById(el))) {
3152 if (EC[el] && EC[el].el) {
3156 ex = El.addToCache(new El(elm));
3159 } else if (el.tagName) {
3163 if (EC[id] && EC[id].el) {
3167 ex = El.addToCache(new El(el));
3170 } else if (el instanceof El) {
3176 if (Ext.isIE && (el.id == undefined || el.id == '')) {
3179 el.dom = DOC.getElementById(el.id) || el.dom;
3183 } else if(el.isComposite) {
3185 } else if(Ext.isArray(el)) {
3186 return El.select(el);
3187 } else if(el == DOC) {
3190 var f = function(){};
3191 f.prototype = El.prototype;
3200 El.addToCache = function(el, id){
3211 El.data = function(el, key, value){
3216 var c = EC[el.id].data;
3217 if(arguments.length == 2){
3220 return (c[key] = value);
3227 function garbageCollect(){
3228 if(!Ext.enableGarbageCollector){
3229 clearInterval(El.collectorThreadId);
3260 if(!d || !d.parentNode || (!d.offsetParent && !DOC.getElementById(eid))){
3261 if(Ext.enableListenerCollection){
3262 Ext.EventManager.removeAll(d);
3273 EC = Ext.elCache = t;
3277 El.collectorThreadId = setInterval(garbageCollect, 30000);
3279 var flyFn = function(){};
3280 flyFn.prototype = El.prototype;
3283 El.Flyweight = function(dom){
3287 El.Flyweight.prototype = new flyFn();
3288 El.Flyweight.prototype.isFlyweight = true;
3289 El._flyweights = {};
3292 El.fly = function(el, named){
3294 named = named || '_global';
3296 if (el = Ext.getDom(el)) {
3297 (El._flyweights[named] = El._flyweights[named] || new El.Flyweight()).dom = el;
3298 ret = El._flyweights[named];
3310 var noBoxAdjust = Ext.isStrict ? {
3313 input:1, select:1, textarea:1
3315 if(Ext.isIE || Ext.isGecko){
3316 noBoxAdjust['button'] = 1;
3321 Ext.Element.addMethods({
3323 swallowEvent : function(eventName, preventDefault){
3326 e.stopPropagation();
3331 if(Ext.isArray(eventName)){
3332 Ext.each(eventName, function(e) {
3337 me.on(eventName, fn);
3342 relayEvent : function(eventName, observable){
3343 this.on(eventName, function(e){
3344 observable.fireEvent(eventName, e);
3349 clean : function(forceReclean){
3355 if(Ext.Element.data(dom, 'isCleaned') && forceReclean !== true){
3360 var nx = n.nextSibling;
3361 if(n.nodeType == 3 && !/\S/.test(n.nodeValue)){
3368 Ext.Element.data(dom, 'isCleaned', true);
3374 var um = this.getUpdater();
3375 um.update.apply(um, arguments);
3380 getUpdater : function(){
3381 return this.updateManager || (this.updateManager = new Ext.Updater(this));
3385 update : function(html, loadScripts, callback){
3391 if(loadScripts !== true){
3392 this.dom.innerHTML = html;
3393 if(typeof callback == 'function'){
3402 html += '<span id="' + id + '"></span>';
3404 Ext.lib.Event.onAvailable(id, function(){
3406 hd = DOC.getElementsByTagName("head")[0],
3407 re = /(?:<script([^>]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig,
3408 srcRe = /\ssrc=([\'\"])(.*?)\1/i,
3409 typeRe = /\stype=([\'\"])(.*?)\1/i,
3417 while((match = re.exec(html))){
3419 srcMatch = attrs ? attrs.match(srcRe) : false;
3420 if(srcMatch && srcMatch[2]){
3421 s = DOC.createElement("script");
3422 s.src = srcMatch[2];
3423 typeMatch = attrs.match(typeRe);
3424 if(typeMatch && typeMatch[2]){
3425 s.type = typeMatch[2];
3428 }else if(match[2] && match[2].length > 0){
3429 if(window.execScript) {
3430 window.execScript(match[2]);
3432 window.eval(match[2]);
3436 el = DOC.getElementById(id);
3437 if(el){Ext.removeNode(el);}
3438 if(typeof callback == 'function'){
3442 dom.innerHTML = html.replace(/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig, "");
3447 removeAllListeners : function(){
3448 this.removeAnchor();
3449 Ext.EventManager.removeAll(this.dom);
3454 createProxy : function(config, renderTo, matchBox){
3455 config = (typeof config == 'object') ? config : {tag : "div", cls: config};
3458 proxy = renderTo ? Ext.DomHelper.append(renderTo, config, true) :
3459 Ext.DomHelper.insertBefore(me.dom, config, true);
3461 if(matchBox && me.setBox && me.getBox){
3462 proxy.setBox(me.getBox());
3468 Ext.Element.prototype.getUpdateManager = Ext.Element.prototype.getUpdater;
3470 Ext.Element.addMethods({
3472 getAnchorXY : function(anchor, local, s){
3475 anchor = (anchor || "tl").toLowerCase();
3479 vp = me.dom == document.body || me.dom == document,
3480 w = s.width || vp ? Ext.lib.Dom.getViewWidth() : me.getWidth(),
3481 h = s.height || vp ? Ext.lib.Dom.getViewHeight() : me.getHeight(),
3485 scroll = me.getScroll(),
3486 extraX = vp ? scroll.left : !local ? o[0] : 0,
3487 extraY = vp ? scroll.top : !local ? o[1] : 0,
3489 c : [r(w * 0.5), r(h * 0.5)],
3490 t : [r(w * 0.5), 0],
3491 l : [0, r(h * 0.5)],
3492 r : [w, r(h * 0.5)],
3493 b : [r(w * 0.5), h],
3501 return [xy[0] + extraX, xy[1] + extraY];
3505 anchorTo : function(el, alignment, offsets, animate, monitorScroll, callback){
3508 scroll = !Ext.isEmpty(monitorScroll),
3509 action = function(){
3510 Ext.fly(dom).alignTo(el, alignment, offsets, animate);
3511 Ext.callback(callback, Ext.fly(dom));
3513 anchor = this.getAnchor();
3516 this.removeAnchor();
3522 Ext.EventManager.onWindowResize(action, null);
3525 Ext.EventManager.on(window, 'scroll', action, null,
3526 {buffer: !isNaN(monitorScroll) ? monitorScroll : 50});
3533 removeAnchor : function(){
3535 anchor = this.getAnchor();
3537 if(anchor && anchor.fn){
3538 Ext.EventManager.removeResizeListener(anchor.fn);
3540 Ext.EventManager.un(window, 'scroll', anchor.fn);
3548 getAnchor : function(){
3549 var data = Ext.Element.data,
3554 var anchor = data(dom, '_anchor');
3557 anchor = data(dom, '_anchor', {});
3563 getAlignToXY : function(el, p, o){
3567 throw "Element.alignToXY with an element that doesn't exist";
3571 p = (!p || p == "?" ? "tl-bl?" : (!/-/.test(p) && p !== "" ? "tl-" + p : p || "tl-bl")).toLowerCase();
3583 dw = Ext.lib.Dom.getViewWidth() -10,
3584 dh = Ext.lib.Dom.getViewHeight()-10,
3592 docElement = doc.documentElement,
3594 scrollX = (docElement.scrollLeft || docBody.scrollLeft || 0)+5,
3595 scrollY = (docElement.scrollTop || docBody.scrollTop || 0)+5,
3599 m = p.match(/^([a-z]+)-([a-z]+)(\?)?$/);
3602 throw "Element.alignTo with an invalid alignment " + p;
3611 a1 = me.getAnchorXY(p1, true);
3612 a2 = el.getAnchorXY(p2, false);
3614 x = a2[0] - a1[0] + o[0];
3615 y = a2[1] - a1[1] + o[1];
3625 p1x = p1.charAt(p1.length-1);
3627 p2x = p2.charAt(p2.length-1);
3628 swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t"));
3629 swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r"));
3632 if (x + w > dw + scrollX) {
3633 x = swapX ? r.left-w : dw+scrollX-w;
3636 x = swapX ? r.right : scrollX;
3638 if (y + h > dh + scrollY) {
3639 y = swapY ? r.top-h : dh+scrollY-h;
3642 y = swapY ? r.bottom : scrollY;
3649 alignTo : function(element, position, offsets, animate){
3651 return me.setXY(me.getAlignToXY(element, position, offsets),
3652 me.preanim && !!animate ? me.preanim(arguments, 3) : false);
3656 adjustForConstraints : function(xy, parent, offsets){
3657 return this.getConstrainToXY(parent || document, false, offsets, xy) || xy;
3661 getConstrainToXY : function(el, local, offsets, proposedXY){
3662 var os = {top:0, left:0, bottom:0, right: 0};
3664 return function(el, local, offsets, proposedXY){
3666 offsets = offsets ? Ext.applyIf(offsets, os) : os;
3668 var vw, vh, vx = 0, vy = 0;
3669 if(el.dom == document.body || el.dom == document){
3670 vw =Ext.lib.Dom.getViewWidth();
3671 vh = Ext.lib.Dom.getViewHeight();
3673 vw = el.dom.clientWidth;
3674 vh = el.dom.clientHeight;
3676 var vxy = el.getXY();
3682 var s = el.getScroll();
3684 vx += offsets.left + s.left;
3685 vy += offsets.top + s.top;
3687 vw -= offsets.right;
3688 vh -= offsets.bottom;
3692 xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]),
3693 x = xy[0], y = xy[1],
3694 offset = this.getConstrainOffset(),
3695 w = this.dom.offsetWidth + offset,
3696 h = this.dom.offsetHeight + offset;
3719 return moved ? [x, y] : false;
3779 getConstrainOffset : function(){
3784 getCenterXY : function(){
3785 return this.getAlignToXY(document, 'c-c');
3789 center : function(centerIn){
3790 return this.alignTo(centerIn || document, 'c-c');
3794 Ext.Element.addMethods(function(){
3795 var PARENTNODE = 'parentNode',
3796 NEXTSIBLING = 'nextSibling',
3797 PREVIOUSSIBLING = 'previousSibling',
3803 findParent : function(simpleSelector, maxDepth, returnEl){
3808 if(Ext.isGecko && Object.prototype.toString.call(p) == '[object XULElement]') {
3811 maxDepth = maxDepth || 50;
3812 if (isNaN(maxDepth)) {
3813 stopEl = Ext.getDom(maxDepth);
3814 maxDepth = Number.MAX_VALUE;
3816 while(p && p.nodeType == 1 && depth < maxDepth && p != b && p != stopEl){
3817 if(DQ.is(p, simpleSelector)){
3818 return returnEl ? GET(p) : p;
3827 findParentNode : function(simpleSelector, maxDepth, returnEl){
3828 var p = Ext.fly(this.dom.parentNode, '_internal');
3829 return p ? p.findParent(simpleSelector, maxDepth, returnEl) : null;
3833 up : function(simpleSelector, maxDepth){
3834 return this.findParentNode(simpleSelector, maxDepth, true);
3838 select : function(selector){
3839 return Ext.Element.select(selector, this.dom);
3843 query : function(selector){
3844 return DQ.select(selector, this.dom);
3848 child : function(selector, returnDom){
3849 var n = DQ.selectNode(selector, this.dom);
3850 return returnDom ? n : GET(n);
3854 down : function(selector, returnDom){
3855 var n = DQ.selectNode(" > " + selector, this.dom);
3856 return returnDom ? n : GET(n);
3860 parent : function(selector, returnDom){
3861 return this.matchNode(PARENTNODE, PARENTNODE, selector, returnDom);
3865 next : function(selector, returnDom){
3866 return this.matchNode(NEXTSIBLING, NEXTSIBLING, selector, returnDom);
3870 prev : function(selector, returnDom){
3871 return this.matchNode(PREVIOUSSIBLING, PREVIOUSSIBLING, selector, returnDom);
3876 first : function(selector, returnDom){
3877 return this.matchNode(NEXTSIBLING, 'firstChild', selector, returnDom);
3881 last : function(selector, returnDom){
3882 return this.matchNode(PREVIOUSSIBLING, 'lastChild', selector, returnDom);
3885 matchNode : function(dir, start, selector, returnDom){
3886 var n = this.dom[start];
3888 if(n.nodeType == 1 && (!selector || DQ.is(n, selector))){
3889 return !returnDom ? GET(n) : n;
3897 Ext.Element.addMethods({
3899 select : function(selector, unique){
3900 return Ext.Element.select(selector, unique, this.dom);
3903 Ext.Element.addMethods(
3905 var GETDOM = Ext.getDom,
3911 appendChild: function(el){
3912 return GET(el).appendTo(this);
3916 appendTo: function(el){
3917 GETDOM(el).appendChild(this.dom);
3922 insertBefore: function(el){
3923 (el = GETDOM(el)).parentNode.insertBefore(this.dom, el);
3928 insertAfter: function(el){
3929 (el = GETDOM(el)).parentNode.insertBefore(this.dom, el.nextSibling);
3934 insertFirst: function(el, returnDom){
3936 if(el.nodeType || el.dom || typeof el == 'string'){
3938 this.dom.insertBefore(el, this.dom.firstChild);
3939 return !returnDom ? GET(el) : el;
3941 return this.createChild(el, this.dom.firstChild, returnDom);
3946 replace: function(el){
3948 this.insertBefore(el);
3954 replaceWith: function(el){
3957 if(el.nodeType || el.dom || typeof el == 'string'){
3959 me.dom.parentNode.insertBefore(el, me.dom);
3961 el = DH.insertBefore(me.dom, el);
3964 delete Ext.elCache[me.id];
3965 Ext.removeNode(me.dom);
3966 me.id = Ext.id(me.dom = el);
3967 Ext.Element.addToCache(me.isFlyweight ? new Ext.Element(me.dom) : me);
3972 createChild: function(config, insertBefore, returnDom){
3973 config = config || {tag:'div'};
3974 return insertBefore ?
3975 DH.insertBefore(insertBefore, config, returnDom !== true) :
3976 DH[!this.dom.firstChild ? 'overwrite' : 'append'](this.dom, config, returnDom !== true);
3980 wrap: function(config, returnDom){
3981 var newEl = DH.insertBefore(this.dom, config || {tag: "div"}, !returnDom);
3982 newEl.dom ? newEl.dom.appendChild(this.dom) : newEl.appendChild(this.dom);
3987 insertHtml : function(where, html, returnEl){
3988 var el = DH.insertHtml(where, this.dom, html);
3989 return returnEl ? Ext.get(el) : el;
3993 Ext.apply(Ext.Element.prototype, function() {
3994 var GETDOM = Ext.getDom,
4000 insertSibling: function(el, where, returnDom){
4003 isAfter = (where || 'before').toLowerCase() == 'after',
4006 if(Ext.isArray(el)){
4008 Ext.each(el, function(e) {
4009 rt = Ext.fly(insertEl, '_internal').insertSibling(e, where, returnDom);
4019 if(el.nodeType || el.dom){
4020 rt = me.dom.parentNode.insertBefore(GETDOM(el), isAfter ? me.dom.nextSibling : me.dom);
4025 if (isAfter && !me.dom.nextSibling) {
4026 rt = DH.append(me.dom.parentNode, el, !returnDom);
4028 rt = DH[isAfter ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom);
4035 Ext.Element.addMethods(function(){
4038 camelRe = /(-[a-z])/gi,
4039 view = document.defaultView,
4040 propFloat = Ext.isIE ? 'styleFloat' : 'cssFloat',
4041 opacityRe = /alpha\(opacity=(.*)\)/i,
4042 trimRe = /^\s+|\s+$/g,
4045 PADDING = "padding",
4055 ISCLIPPED = 'isClipped',
4056 OVERFLOW = 'overflow',
4057 OVERFLOWX = 'overflow-x',
4058 OVERFLOWY = 'overflow-y',
4059 ORIGINALCLIP = 'originalClip',
4061 borders = {l: BORDER + LEFT + WIDTH, r: BORDER + RIGHT + WIDTH, t: BORDER + TOP + WIDTH, b: BORDER + BOTTOM + WIDTH},
4062 paddings = {l: PADDING + LEFT, r: PADDING + RIGHT, t: PADDING + TOP, b: PADDING + BOTTOM},
4063 margins = {l: MARGIN + LEFT, r: MARGIN + RIGHT, t: MARGIN + TOP, b: MARGIN + BOTTOM},
4064 data = Ext.Element.data;
4068 function camelFn(m, a) {
4069 return a.charAt(1).toUpperCase();
4072 function chkCache(prop) {
4073 return propCache[prop] || (propCache[prop] = prop == 'float' ? propFloat : prop.replace(camelRe, camelFn));
4078 adjustWidth : function(width) {
4080 var isNum = (typeof width == "number");
4081 if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
4082 width -= (me.getBorderWidth("lr") + me.getPadding("lr"));
4084 return (isNum && width < 0) ? 0 : width;
4088 adjustHeight : function(height) {
4090 var isNum = (typeof height == "number");
4091 if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
4092 height -= (me.getBorderWidth("tb") + me.getPadding("tb"));
4094 return (isNum && height < 0) ? 0 : height;
4099 addClass : function(className){
4106 if (!Ext.isArray(className)) {
4107 if (typeof className == 'string' && !this.hasClass(className)) {
4108 me.dom.className += " " + className;
4112 for (i = 0, len = className.length; i < len; i++) {
4114 if (typeof v == 'string' && (' ' + me.dom.className + ' ').indexOf(' ' + v + ' ') == -1) {
4119 me.dom.className += " " + cls.join(" ");
4126 removeClass : function(className){
4133 if (!Ext.isArray(className)){
4134 className = [className];
4136 if (me.dom && me.dom.className) {
4137 elClasses = me.dom.className.replace(trimRe, '').split(spacesRe);
4138 for (i = 0, len = className.length; i < len; i++) {
4140 if (typeof cls == 'string') {
4141 cls = cls.replace(trimRe, '');
4142 idx = elClasses.indexOf(cls);
4144 elClasses.splice(idx, 1);
4148 me.dom.className = elClasses.join(" ");
4154 radioClass : function(className){
4155 var cn = this.dom.parentNode.childNodes,
4159 className = Ext.isArray(className) ? className : [className];
4160 for (i = 0, len = cn.length; i < len; i++) {
4162 if (v && v.nodeType == 1) {
4163 Ext.fly(v, '_internal').removeClass(className);
4166 return this.addClass(className);
4170 toggleClass : function(className){
4171 return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);
4175 hasClass : function(className){
4176 return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1;
4180 replaceClass : function(oldClassName, newClassName){
4181 return this.removeClass(oldClassName).addClass(newClassName);
4184 isStyle : function(style, val) {
4185 return this.getStyle(style) == val;
4189 getStyle : function(){
4190 return view && view.getComputedStyle ?
4203 prop = chkCache(prop);
4205 if(wk && (/marginRight/.test(prop))) {
4206 display = this.getStyle('display');
4207 el.style.display = 'inline-block';
4209 out = (v = el.style[prop]) ? v :
4210 (cs = view.getComputedStyle(el, "")) ? cs[prop] : null;
4214 if(out == 'rgba(0, 0, 0, 0)'){
4215 out = 'transparent';
4217 el.style.display = display;
4227 if(el == document) return null;
4228 if (prop == 'opacity') {
4229 if (el.style.filter.match) {
4230 if(m = el.style.filter.match(opacityRe)){
4231 var fv = parseFloat(m[1]);
4233 return fv ? fv / 100 : 0;
4239 prop = chkCache(prop);
4240 return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);
4245 getColor : function(attr, defaultValue, prefix){
4246 var v = this.getStyle(attr),
4247 color = (typeof prefix != 'undefined') ? prefix : '#',
4250 if(!v || (/transparent|inherit/.test(v))) {
4251 return defaultValue;
4254 Ext.each(v.slice(4, v.length -1).split(','), function(s){
4255 h = parseInt(s, 10);
4256 color += (h < 16 ? '0' : '') + h.toString(16);
4259 v = v.replace('#', '');
4260 color += v.length == 3 ? v.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : v;
4262 return(color.length > 5 ? color.toLowerCase() : defaultValue);
4266 setStyle : function(prop, value){
4269 if (typeof prop != 'object') {
4274 for (style in prop) {
4275 value = prop[style];
4276 style == 'opacity' ?
4277 this.setOpacity(value) :
4278 this.dom.style[chkCache(style)] = value;
4284 setOpacity : function(opacity, animate){
4288 if(!animate || !me.anim){
4290 var opac = opacity < 1 ? 'alpha(opacity=' + opacity * 100 + ')' : '',
4291 val = s.filter.replace(opacityRe, '').replace(trimRe, '');
4294 s.filter = val + (val.length > 0 ? ' ' : '') + opac;
4296 s.opacity = opacity;
4299 me.anim({opacity: {to: opacity}}, me.preanim(arguments, 1), null, .35, 'easeIn');
4305 clearOpacity : function(){
4306 var style = this.dom.style;
4308 if(!Ext.isEmpty(style.filter)){
4309 style.filter = style.filter.replace(opacityRe, '').replace(trimRe, '');
4312 style.opacity = style['-moz-opacity'] = style['-khtml-opacity'] = '';
4318 getHeight : function(contentHeight){
4321 hidden = Ext.isIE && me.isStyle('display', 'none'),
4322 h = MATH.max(dom.offsetHeight, hidden ? 0 : dom.clientHeight) || 0;
4324 h = !contentHeight ? h : h - me.getBorderWidth("tb") - me.getPadding("tb");
4325 return h < 0 ? 0 : h;
4329 getWidth : function(contentWidth){
4332 hidden = Ext.isIE && me.isStyle('display', 'none'),
4333 w = MATH.max(dom.offsetWidth, hidden ? 0 : dom.clientWidth) || 0;
4334 w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");
4335 return w < 0 ? 0 : w;
4339 setWidth : function(width, animate){
4341 width = me.adjustWidth(width);
4342 !animate || !me.anim ?
4343 me.dom.style.width = me.addUnits(width) :
4344 me.anim({width : {to : width}}, me.preanim(arguments, 1));
4349 setHeight : function(height, animate){
4351 height = me.adjustHeight(height);
4352 !animate || !me.anim ?
4353 me.dom.style.height = me.addUnits(height) :
4354 me.anim({height : {to : height}}, me.preanim(arguments, 1));
4359 getBorderWidth : function(side){
4360 return this.addStyles(side, borders);
4364 getPadding : function(side){
4365 return this.addStyles(side, paddings);
4373 if(!data(dom, ISCLIPPED)){
4374 data(dom, ISCLIPPED, true);
4375 data(dom, ORIGINALCLIP, {
4376 o: me.getStyle(OVERFLOW),
4377 x: me.getStyle(OVERFLOWX),
4378 y: me.getStyle(OVERFLOWY)
4380 me.setStyle(OVERFLOW, HIDDEN);
4381 me.setStyle(OVERFLOWX, HIDDEN);
4382 me.setStyle(OVERFLOWY, HIDDEN);
4388 unclip : function(){
4392 if(data(dom, ISCLIPPED)){
4393 data(dom, ISCLIPPED, false);
4394 var o = data(dom, ORIGINALCLIP);
4396 me.setStyle(OVERFLOW, o.o);
4399 me.setStyle(OVERFLOWX, o.x);
4402 me.setStyle(OVERFLOWY, o.y);
4409 addStyles : function(sides, styles){
4411 sidesArr = sides.match(wordsRe),
4415 len = sidesArr.length;
4416 for (i = 0; i < len; i++) {
4418 size = side && parseInt(this.getStyle(styles[side]), 10);
4420 ttlSize += MATH.abs(size);
4433 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>';
4435 Ext.Element.addMethods(function(){
4436 var INTERNAL = "_internal",
4437 pxMatch = /(\d+\.?\d+)px/;
4440 applyStyles : function(style){
4441 Ext.DomHelper.applyStyles(this.dom, style);
4446 getStyles : function(){
4448 Ext.each(arguments, function(v) {
4449 ret[v] = this.getStyle(v);
4456 setOverflow : function(v){
4458 if(v=='auto' && Ext.isMac && Ext.isGecko2){
4459 dom.style.overflow = 'hidden';
4460 (function(){dom.style.overflow = 'auto';}).defer(1);
4462 dom.style.overflow = v;
4467 boxWrap : function(cls){
4468 cls = cls || 'x-box';
4469 var el = Ext.get(this.insertHtml("beforeBegin", "<div class='" + cls + "'>" + String.format(Ext.Element.boxMarkup, cls) + "</div>"));
4470 Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom);
4475 setSize : function(width, height, animate){
4477 if(typeof width == 'object'){
4478 height = width.height;
4479 width = width.width;
4481 width = me.adjustWidth(width);
4482 height = me.adjustHeight(height);
4483 if(!animate || !me.anim){
4484 me.dom.style.width = me.addUnits(width);
4485 me.dom.style.height = me.addUnits(height);
4487 me.anim({width: {to: width}, height: {to: height}}, me.preanim(arguments, 2));
4493 getComputedHeight : function(){
4495 h = Math.max(me.dom.offsetHeight, me.dom.clientHeight);
4497 h = parseFloat(me.getStyle('height')) || 0;
4498 if(!me.isBorderBox()){
4499 h += me.getFrameWidth('tb');
4506 getComputedWidth : function(){
4507 var w = Math.max(this.dom.offsetWidth, this.dom.clientWidth);
4509 w = parseFloat(this.getStyle('width')) || 0;
4510 if(!this.isBorderBox()){
4511 w += this.getFrameWidth('lr');
4518 getFrameWidth : function(sides, onlyContentBox){
4519 return onlyContentBox && this.isBorderBox() ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides));
4523 addClassOnOver : function(className){
4526 Ext.fly(this, INTERNAL).addClass(className);
4529 Ext.fly(this, INTERNAL).removeClass(className);
4536 addClassOnFocus : function(className){
4537 this.on("focus", function(){
4538 Ext.fly(this, INTERNAL).addClass(className);
4540 this.on("blur", function(){
4541 Ext.fly(this, INTERNAL).removeClass(className);
4547 addClassOnClick : function(className){
4549 this.on("mousedown", function(){
4550 Ext.fly(dom, INTERNAL).addClass(className);
4551 var d = Ext.getDoc(),
4553 Ext.fly(dom, INTERNAL).removeClass(className);
4554 d.removeListener("mouseup", fn);
4556 d.on("mouseup", fn);
4563 getViewSize : function(){
4566 isDoc = (d == doc || d == doc.body);
4570 var extdom = Ext.lib.Dom;
4572 width : extdom.getViewWidth(),
4573 height : extdom.getViewHeight()
4579 width : d.clientWidth,
4580 height : d.clientHeight
4587 getStyleSize : function(){
4592 isDoc = (d == doc || d == doc.body),
4597 var extdom = Ext.lib.Dom;
4599 width : extdom.getViewWidth(),
4600 height : extdom.getViewHeight()
4604 if(s.width && s.width != 'auto'){
4605 w = parseFloat(s.width);
4606 if(me.isBorderBox()){
4607 w -= me.getFrameWidth('lr');
4611 if(s.height && s.height != 'auto'){
4612 h = parseFloat(s.height);
4613 if(me.isBorderBox()){
4614 h -= me.getFrameWidth('tb');
4618 return {width: w || me.getWidth(true), height: h || me.getHeight(true)};
4622 getSize : function(contentSize){
4623 return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)};
4627 repaint : function(){
4629 this.addClass("x-repaint");
4630 setTimeout(function(){
4631 Ext.fly(dom).removeClass("x-repaint");
4637 unselectable : function(){
4638 this.dom.unselectable = "on";
4639 return this.swallowEvent("selectstart", true).
4640 applyStyles("-moz-user-select:none;-khtml-user-select:none;").
4641 addClass("x-unselectable");
4645 getMargins : function(side){
4648 hash = {t:"top", l:"left", r:"right", b: "bottom"},
4652 for (key in me.margins){
4653 o[hash[key]] = parseFloat(me.getStyle(me.margins[key])) || 0;
4657 return me.addStyles.call(me, side, me.margins);
4664 var D = Ext.lib.Dom,
4669 POSITION = "position",
4671 RELATIVE = "relative",
4675 Ext.Element.addMethods({
4678 return D.getX(this.dom);
4683 return D.getY(this.dom);
4688 return D.getXY(this.dom);
4692 getOffsetsTo : function(el){
4693 var o = this.getXY(),
4694 e = Ext.fly(el, '_internal').getXY();
4695 return [o[0]-e[0],o[1]-e[1]];
4699 setX : function(x, animate){
4700 return this.setXY([x, this.getY()], this.animTest(arguments, animate, 1));
4704 setY : function(y, animate){
4705 return this.setXY([this.getX(), y], this.animTest(arguments, animate, 1));
4709 setLeft : function(left){
4710 this.setStyle(LEFT, this.addUnits(left));
4715 setTop : function(top){
4716 this.setStyle(TOP, this.addUnits(top));
4721 setRight : function(right){
4722 this.setStyle(RIGHT, this.addUnits(right));
4727 setBottom : function(bottom){
4728 this.setStyle(BOTTOM, this.addUnits(bottom));
4733 setXY : function(pos, animate){
4735 if(!animate || !me.anim){
4736 D.setXY(me.dom, pos);
4738 me.anim({points: {to: pos}}, me.preanim(arguments, 1), 'motion');
4744 setLocation : function(x, y, animate){
4745 return this.setXY([x, y], this.animTest(arguments, animate, 2));
4749 moveTo : function(x, y, animate){
4750 return this.setXY([x, y], this.animTest(arguments, animate, 2));
4754 getLeft : function(local){
4755 return !local ? this.getX() : parseInt(this.getStyle(LEFT), 10) || 0;
4759 getRight : function(local){
4761 return !local ? me.getX() + me.getWidth() : (me.getLeft(true) + me.getWidth()) || 0;
4765 getTop : function(local) {
4766 return !local ? this.getY() : parseInt(this.getStyle(TOP), 10) || 0;
4770 getBottom : function(local){
4772 return !local ? me.getY() + me.getHeight() : (me.getTop(true) + me.getHeight()) || 0;
4776 position : function(pos, zIndex, x, y){
4779 if(!pos && me.isStyle(POSITION, STATIC)){
4780 me.setStyle(POSITION, RELATIVE);
4782 me.setStyle(POSITION, pos);
4785 me.setStyle(ZINDEX, zIndex);
4787 if(x || y) me.setXY([x || false, y || false]);
4791 clearPositioning : function(value){
4792 value = value || '';
4805 getPositioning : function(){
4806 var l = this.getStyle(LEFT);
4807 var t = this.getStyle(TOP);
4809 "position" : this.getStyle(POSITION),
4811 "right" : l ? "" : this.getStyle(RIGHT),
4813 "bottom" : t ? "" : this.getStyle(BOTTOM),
4814 "z-index" : this.getStyle(ZINDEX)
4819 setPositioning : function(pc){
4821 style = me.dom.style;
4825 if(pc.right == AUTO){
4828 if(pc.bottom == AUTO){
4836 translatePoints : function(x, y){
4837 y = isNaN(x[1]) ? y : x[1];
4838 x = isNaN(x[0]) ? x : x[0];
4840 relative = me.isStyle(POSITION, RELATIVE),
4842 l = parseInt(me.getStyle(LEFT), 10),
4843 t = parseInt(me.getStyle(TOP), 10);
4845 l = !isNaN(l) ? l : (relative ? 0 : me.dom.offsetLeft);
4846 t = !isNaN(t) ? t : (relative ? 0 : me.dom.offsetTop);
4848 return {left: (x - o[0] + l), top: (y - o[1] + t)};
4851 animTest : function(args, animate, i) {
4852 return !!animate && this.preanim ? this.preanim(args, i) : false;
4856 Ext.Element.addMethods({
4858 setBox : function(box, adjust, animate){
4862 if((adjust && !me.autoBoxAdjust) && !me.isBorderBox()){
4863 w -= (me.getBorderWidth("lr") + me.getPadding("lr"));
4864 h -= (me.getBorderWidth("tb") + me.getPadding("tb"));
4866 me.setBounds(box.x, box.y, w, h, me.animTest.call(me, arguments, animate, 2));
4871 getBox : function(contentBox, local) {
4876 getBorderWidth = me.getBorderWidth,
4877 getPadding = me.getPadding,
4885 left = parseInt(me.getStyle("left"), 10) || 0;
4886 top = parseInt(me.getStyle("top"), 10) || 0;
4889 var el = me.dom, w = el.offsetWidth, h = el.offsetHeight, bx;
4891 bx = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: w, height: h};
4893 l = getBorderWidth.call(me, "l") + getPadding.call(me, "l");
4894 r = getBorderWidth.call(me, "r") + getPadding.call(me, "r");
4895 t = getBorderWidth.call(me, "t") + getPadding.call(me, "t");
4896 b = getBorderWidth.call(me, "b") + getPadding.call(me, "b");
4897 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)};
4899 bx.right = bx.x + bx.width;
4900 bx.bottom = bx.y + bx.height;
4905 move : function(direction, distance, animate){
4910 left = [x - distance, y],
4911 right = [x + distance, y],
4912 top = [x, y - distance],
4913 bottom = [x, y + distance],
4927 direction = direction.toLowerCase();
4928 me.moveTo(hash[direction][0], hash[direction][1], me.animTest.call(me, arguments, animate, 2));
4932 setLeftTop : function(left, top){
4934 style = me.dom.style;
4935 style.left = me.addUnits(left);
4936 style.top = me.addUnits(top);
4941 getRegion : function(){
4942 return Ext.lib.Dom.getRegion(this.dom);
4946 setBounds : function(x, y, width, height, animate){
4948 if (!animate || !me.anim) {
4949 me.setSize(width, height);
4950 me.setLocation(x, y);
4952 me.anim({points: {to: [x, y]},
4953 width: {to: me.adjustWidth(width)},
4954 height: {to: me.adjustHeight(height)}},
4955 me.preanim(arguments, 4),
4962 setRegion : function(region, animate) {
4963 return this.setBounds(region.left, region.top, region.right-region.left, region.bottom-region.top, this.animTest.call(this, arguments, animate, 1));
4966 Ext.Element.addMethods({
4968 isScrollable : function(){
4970 return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth;
4974 scrollTo : function(side, value){
4975 this.dom["scroll" + (/top/i.test(side) ? "Top" : "Left")] = value;
4980 getScroll : function(){
4984 docElement = doc.documentElement,
4989 if(d == doc || d == body){
4990 if(Ext.isIE && Ext.isStrict){
4991 l = docElement.scrollLeft;
4992 t = docElement.scrollTop;
4994 l = window.pageXOffset;
4995 t = window.pageYOffset;
4997 ret = {left: l || (body ? body.scrollLeft : 0), top: t || (body ? body.scrollTop : 0)};
4999 ret = {left: d.scrollLeft, top: d.scrollTop};
5004 Ext.Element.addMethods({
5006 scrollTo : function(side, value, animate) {
5008 var top = /top/i.test(side),
5012 if (!animate || !me.anim) {
5014 prop = 'scroll' + (top ? 'Top' : 'Left');
5019 prop = 'scroll' + (top ? 'Left' : 'Top');
5020 me.anim({scroll: {to: top ? [dom[prop], value] : [value, dom[prop]]}}, me.preanim(arguments, 2), 'scroll');
5026 scrollIntoView : function(container, hscroll) {
5027 var c = Ext.getDom(container) || Ext.getBody().dom,
5029 o = this.getOffsetsTo(c),
5030 l = o[0] + c.scrollLeft,
5031 t = o[1] + c.scrollTop,
5032 b = t + el.offsetHeight,
5033 r = l + el.offsetWidth,
5034 ch = c.clientHeight,
5035 ct = parseInt(c.scrollTop, 10),
5036 cl = parseInt(c.scrollLeft, 10),
5038 cr = cl + c.clientWidth;
5040 if (el.offsetHeight > ch || t < ct) {
5047 c.scrollTop = c.scrollTop;
5049 if (hscroll !== false) {
5050 if (el.offsetWidth > c.clientWidth || l < cl) {
5054 c.scrollLeft = r - c.clientWidth;
5056 c.scrollLeft = c.scrollLeft;
5062 scrollChildIntoView : function(child, hscroll) {
5063 Ext.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll);
5067 scroll : function(direction, distance, animate) {
5068 if (!this.isScrollable()) {
5072 l = el.scrollLeft, t = el.scrollTop,
5073 w = el.scrollWidth, h = el.scrollHeight,
5074 cw = el.clientWidth, ch = el.clientHeight,
5075 scrolled = false, v,
5077 l: Math.min(l + distance, w-cw),
5078 r: v = Math.max(l - distance, 0),
5079 t: Math.max(t - distance, 0),
5080 b: Math.min(t + distance, h-ch)
5085 direction = direction.substr(0, 1);
5086 if ((v = hash[direction]) > -1) {
5088 this.scrollTo(direction == 'l' || direction == 'r' ? 'left' : 'top', v, this.preanim(arguments, 2));
5094 Ext.Element.VISIBILITY = 1;
5096 Ext.Element.DISPLAY = 2;
5098 Ext.Element.addMethods(function(){
5099 var VISIBILITY = "visibility",
5100 DISPLAY = "display",
5102 OFFSETS = "offsets",
5104 ORIGINALDISPLAY = 'originalDisplay',
5105 VISMODE = 'visibilityMode',
5106 ELDISPLAY = Ext.Element.DISPLAY,
5107 data = Ext.Element.data,
5108 getDisplay = function(dom){
5109 var d = data(dom, ORIGINALDISPLAY);
5110 if(d === undefined){
5111 data(dom, ORIGINALDISPLAY, d = '');
5115 getVisMode = function(dom){
5116 var m = data(dom, VISMODE);
5117 if(m === undefined){
5118 data(dom, VISMODE, m = 1);
5125 originalDisplay : "",
5129 setVisibilityMode : function(visMode){
5130 data(this.dom, VISMODE, visMode);
5135 animate : function(args, duration, onComplete, easing, animType){
5136 this.anim(args, {duration: duration, callback: onComplete, easing: easing}, animType);
5141 anim : function(args, opt, animType, defaultDur, defaultEase, cb){
5142 animType = animType || 'run';
5145 anim = Ext.lib.Anim[animType](
5148 (opt.duration || defaultDur) || .35,
5149 (opt.easing || defaultEase) || 'easeOut',
5152 if(opt.callback) opt.callback.call(opt.scope || me, me, opt);
5161 preanim : function(a, i){
5162 return !a[i] ? false : (typeof a[i] == 'object' ? a[i]: {duration: a[i+1], callback: a[i+2], easing: a[i+3]});
5166 isVisible : function() {
5167 return !this.isStyle(VISIBILITY, HIDDEN) && !this.isStyle(DISPLAY, NONE);
5171 setVisible : function(visible, animate){
5172 var me = this, isDisplay, isVisible, isOffsets,
5176 if (typeof animate == 'string'){
5177 isDisplay = animate == DISPLAY;
5178 isVisible = animate == VISIBILITY;
5179 isOffsets = animate == OFFSETS;
5182 isDisplay = getVisMode(this.dom) == ELDISPLAY;
5183 isVisible = !isDisplay;
5186 if (!animate || !me.anim) {
5188 me.setDisplayed(visible);
5189 } else if (isOffsets){
5191 me.hideModeStyles = {
5192 position: me.getStyle('position'),
5193 top: me.getStyle('top'),
5194 left: me.getStyle('left')
5197 me.applyStyles({position: 'absolute', top: '-10000px', left: '-10000px'});
5199 me.applyStyles(me.hideModeStyles || {position: '', top: '', left: ''});
5203 dom.style.visibility = visible ? "visible" : HIDDEN;
5209 me.setVisible(true);
5211 me.anim({opacity: { to: (visible?1:0) }},
5212 me.preanim(arguments, 1),
5218 dom.style[isDisplay ? DISPLAY : VISIBILITY] = (isDisplay) ? NONE : HIDDEN;
5219 Ext.fly(dom).setOpacity(1);
5227 toggle : function(animate){
5229 me.setVisible(!me.isVisible(), me.preanim(arguments, 0));
5234 setDisplayed : function(value) {
5235 if(typeof value == "boolean"){
5236 value = value ? getDisplay(this.dom) : NONE;
5238 this.setStyle(DISPLAY, value);
5243 fixDisplay : function(){
5245 if(me.isStyle(DISPLAY, NONE)){
5246 me.setStyle(VISIBILITY, HIDDEN);
5247 me.setStyle(DISPLAY, getDisplay(this.dom));
5248 if(me.isStyle(DISPLAY, NONE)){
5249 me.setStyle(DISPLAY, "block");
5255 hide : function(animate){
5257 if (typeof animate == 'string'){
5258 this.setVisible(false, animate);
5261 this.setVisible(false, this.preanim(arguments, 0));
5266 show : function(animate){
5268 if (typeof animate == 'string'){
5269 this.setVisible(true, animate);
5272 this.setVisible(true, this.preanim(arguments, 0));
5278 Ext.Element.addMethods(
5280 var VISIBILITY = "visibility",
5281 DISPLAY = "display",
5284 XMASKED = "x-masked",
5285 XMASKEDRELATIVE = "x-masked-relative",
5286 data = Ext.Element.data;
5290 isVisible : function(deep) {
5291 var vis = !this.isStyle(VISIBILITY,HIDDEN) && !this.isStyle(DISPLAY,NONE),
5292 p = this.dom.parentNode;
5293 if(deep !== true || !vis){
5296 while(p && !/^body/i.test(p.tagName)){
5297 if(!Ext.fly(p, '_isVisible').isVisible()){
5306 isDisplayed : function() {
5307 return !this.isStyle(DISPLAY, NONE);
5311 enableDisplayMode : function(display){
5312 this.setVisibilityMode(Ext.Element.DISPLAY);
5313 if(!Ext.isEmpty(display)){
5314 data(this.dom, 'originalDisplay', display);
5320 mask : function(msg, msgCls){
5324 EXTELMASKMSG = "ext-el-mask-msg",
5328 if(!/^body/i.test(dom.tagName) && me.getStyle('position') == 'static'){
5329 me.addClass(XMASKEDRELATIVE);
5331 if((el = data(dom, 'maskMsg'))){
5334 if((el = data(dom, 'mask'))){
5338 mask = dh.append(dom, {cls : "ext-el-mask"}, true);
5339 data(dom, 'mask', mask);
5341 me.addClass(XMASKED);
5342 mask.setDisplayed(true);
5343 if(typeof msg == 'string'){
5344 var mm = dh.append(dom, {cls : EXTELMASKMSG, cn:{tag:'div'}}, true);
5345 data(dom, 'maskMsg', mm);
5346 mm.dom.className = msgCls ? EXTELMASKMSG + " " + msgCls : EXTELMASKMSG;
5347 mm.dom.firstChild.innerHTML = msg;
5348 mm.setDisplayed(true);
5351 if(Ext.isIE && !(Ext.isIE7 && Ext.isStrict) && me.getStyle('height') == 'auto'){
5352 mask.setSize(undefined, me.getHeight());
5358 unmask : function(){
5361 mask = data(dom, 'mask'),
5362 maskMsg = data(dom, 'maskMsg');
5366 data(dom, 'maskMsg', undefined);
5369 data(dom, 'mask', undefined);
5372 me.removeClass([XMASKED, XMASKEDRELATIVE]);
5377 isMasked : function(){
5378 var m = data(this.dom, 'mask');
5379 return m && m.isVisible();
5383 createShim : function(){
5384 var el = document.createElement('iframe'),
5386 el.frameBorder = '0';
5387 el.className = 'ext-shim';
5388 el.src = Ext.SSL_SECURE_URL;
5389 shim = Ext.get(this.dom.parentNode.insertBefore(el, this.dom));
5390 shim.autoBoxAdjust = false;
5395 Ext.Element.addMethods({
5397 addKeyListener : function(key, fn, scope){
5399 if(typeof key != 'object' || Ext.isArray(key)){
5415 return new Ext.KeyMap(this, config);
5419 addKeyMap : function(config){
5420 return new Ext.KeyMap(this, config);
5426 UNDEFINED = undefined,
5440 ABSOLUTE = "absolute",
5441 VISIBLE = "visible",
5443 POSITION = "position",
5444 EASEOUT = "easeOut",
5446 flyEl = new Ext.Element.Flyweight(),
5448 getObject = function(o){
5451 fly = function(dom){
5453 flyEl.id = Ext.id(dom);
5457 getQueue = function(id){
5463 setQueue = function(id, value){
5468 Ext.enableFx = TRUE;
5475 switchStatements : function(key, fn, argHash){
5476 return fn.apply(this, argHash[key]);
5480 slideIn : function(anchor, o){
5496 anchor = anchor || "t";
5498 me.queueFx(o, function(){
5499 xy = fly(dom).getXY();
5501 fly(dom).fixDisplay();
5504 r = fly(dom).getFxRestore();
5505 b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight};
5506 b.right = b.x + b.width;
5507 b.bottom = b.y + b.height;
5510 fly(dom).setWidth(b.width).setHeight(b.height);
5513 wrap = fly(dom).fxWrap(r.pos, o, HIDDEN);
5515 st.visibility = VISIBLE;
5516 st.position = ABSOLUTE;
5520 fly(dom).fxUnwrap(wrap, r.pos, o);
5522 st.height = r.height;
5523 fly(dom).afterFx(o);
5527 pt = {to: [b.x, b.y]};
5529 bh = {to: b.height};
5531 function argCalc(wrap, style, ww, wh, sXY, sXYval, s1, s2, w, h, p){
5533 fly(wrap).setWidth(ww).setHeight(wh);
5535 fly(wrap)[sXY](sXYval);
5537 style[s1] = style[s2] = "0";
5550 args = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, {
5551 t : [wrap, st, b.width, 0, NULL, NULL, LEFT, BOTTOM, NULL, bh, NULL],
5552 l : [wrap, st, 0, b.height, NULL, NULL, RIGHT, TOP, bw, NULL, NULL],
5553 r : [wrap, st, b.width, b.height, SETX, b.right, LEFT, TOP, NULL, NULL, pt],
5554 b : [wrap, st, b.width, b.height, SETY, b.bottom, LEFT, TOP, NULL, bh, pt],
5555 tl : [wrap, st, 0, 0, NULL, NULL, RIGHT, BOTTOM, bw, bh, pt],
5556 bl : [wrap, st, 0, 0, SETY, b.y + b.height, RIGHT, TOP, bw, bh, pt],
5557 br : [wrap, st, 0, 0, SETXY, [b.right, b.bottom], LEFT, TOP, bw, bh, pt],
5558 tr : [wrap, st, 0, 0, SETX, b.x + b.width, LEFT, BOTTOM, bw, bh, pt]
5561 st.visibility = VISIBLE;
5564 arguments.callee.anim = fly(wrap).fxanim(args,
5575 slideOut : function(anchor, o){
5587 anchor = anchor || "t";
5589 me.queueFx(o, function(){
5592 r = fly(dom).getFxRestore();
5593 b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight};
5594 b.right = b.x + b.width;
5595 b.bottom = b.y + b.height;
5598 fly(dom).setWidth(b.width).setHeight(b.height);
5601 wrap = fly(dom).fxWrap(r.pos, o, VISIBLE);
5603 st.visibility = VISIBLE;
5604 st.position = ABSOLUTE;
5605 fly(wrap).setWidth(b.width).setHeight(b.height);
5608 o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();
5609 fly(dom).fxUnwrap(wrap, r.pos, o);
5611 st.height = r.height;
5612 fly(dom).afterFx(o);
5615 function argCalc(style, s1, s2, p1, v1, p2, v2, p3, v3){
5618 style[s1] = style[s2] = "0";
5630 a = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, {
5631 t : [st, LEFT, BOTTOM, HEIGHT, zero],
5632 l : [st, RIGHT, TOP, WIDTH, zero],
5633 r : [st, LEFT, TOP, WIDTH, zero, POINTS, {to : [b.right, b.y]}],
5634 b : [st, LEFT, TOP, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}],
5635 tl : [st, RIGHT, BOTTOM, WIDTH, zero, HEIGHT, zero],
5636 bl : [st, RIGHT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}],
5637 br : [st, LEFT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x + b.width, b.bottom]}],
5638 tr : [st, LEFT, BOTTOM, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.right, b.y]}]
5641 arguments.callee.anim = fly(wrap).fxanim(a,
5661 me.queueFx(o, function(){
5662 width = fly(dom).getWidth();
5663 height = fly(dom).getHeight();
5664 fly(dom).clearOpacity();
5668 r = fly(dom).getFxRestore();
5671 o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();
5672 fly(dom).clearOpacity();
5673 fly(dom).setPositioning(r.pos);
5675 st.height = r.height;
5677 fly(dom).afterFx(o);
5680 arguments.callee.anim = fly(dom).fxanim({
5681 width : {to : fly(dom).adjustWidth(width * 2)},
5682 height : {to : fly(dom).adjustHeight(height * 2)},
5683 points : {by : [-width * .5, -height * .5]},
5685 fontSize: {to : 200, unit: "%"}
5697 switchOff : function(o){
5704 me.queueFx(o, function(){
5705 fly(dom).clearOpacity();
5709 r = fly(dom).getFxRestore();
5712 o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();
5713 fly(dom).clearOpacity();
5714 fly(dom).setPositioning(r.pos);
5716 st.height = r.height;
5717 fly(dom).afterFx(o);
5720 fly(dom).fxanim({opacity : {to : 0.3}},
5726 fly(dom).clearOpacity();
5730 points : {by : [0, fly(dom).getHeight() * .5]}
5744 highlight : function(color, o){
5748 attr = o.attr || "backgroundColor",
5752 me.queueFx(o, function(){
5753 fly(dom).clearOpacity();
5757 dom.style[attr] = restore;
5758 fly(dom).afterFx(o);
5760 restore = dom.style[attr];
5761 a[attr] = {from: color || "ffff9c", to: o.endColor || fly(dom).getColor(attr) || "ffffff"};
5762 arguments.callee.anim = fly(dom).fxanim(a,
5773 frame : function(color, count, o){
5780 me.queueFx(o, function(){
5781 color = color || '#C3DAF9';
5782 if(color.length == 6){
5783 color = '#' + color;
5788 var xy = fly(dom).getXY(),
5789 b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight},
5791 proxy = fly(document.body || document.documentElement).createChild({
5793 position : ABSOLUTE,
5795 border : '0px solid ' + color
5798 return proxy.queueFx({}, animFn);
5802 arguments.callee.anim = {
5811 var scale = Ext.isBorderBox ? 2 : 1;
5812 active = proxy.anim({
5813 top : {from : b.y, to : b.y - 20},
5814 left : {from : b.x, to : b.x - 20},
5815 borderWidth : {from : 0, to : 10},
5816 opacity : {from : 1, to : 0},
5817 height : {from : b.height, to : b.height + 20 * scale},
5818 width : {from : b.width, to : b.width + 20 * scale}
5820 duration: o.duration || 1,
5821 callback: function() {
5823 --count > 0 ? queue() : fly(dom).afterFx(o);
5826 arguments.callee.anim = {
5839 pause : function(seconds){
5843 this.queueFx({}, function(){
5844 t = setTimeout(function(){
5845 fly(dom).afterFx({});
5847 arguments.callee.anim = {
5851 fly(dom).afterFx({});
5859 fadeIn : function(o){
5863 to = o.endOpacity || 1;
5865 me.queueFx(o, function(){
5866 fly(dom).setOpacity(0);
5867 fly(dom).fixDisplay();
5868 dom.style.visibility = VISIBLE;
5869 arguments.callee.anim = fly(dom).fxanim({opacity:{to:to}},
5870 o, NULL, .5, EASEOUT, function(){
5872 fly(dom).clearOpacity();
5874 fly(dom).afterFx(o);
5881 fadeOut : function(o){
5886 to = o.endOpacity || 0;
5888 me.queueFx(o, function(){
5889 arguments.callee.anim = fly(dom).fxanim({
5890 opacity : {to : to}},
5897 Ext.Element.data(dom, 'visibilityMode') == Ext.Element.DISPLAY || o.useDisplay ?
5898 style.display = "none" :
5899 style.visibility = HIDDEN;
5901 fly(dom).clearOpacity();
5903 fly(dom).afterFx(o);
5910 scale : function(w, h, o){
5911 this.shift(Ext.apply({}, o, {
5919 shift : function(o){
5924 this.queueFx(o, function(){
5925 for (var prop in o) {
5926 if (o[prop] != UNDEFINED) {
5927 a[prop] = {to : o[prop]};
5931 a.width ? a.width.to = fly(dom).adjustWidth(o.width) : a;
5932 a.height ? a.height.to = fly(dom).adjustWidth(o.height) : a;
5934 if (a.x || a.y || a.xy) {
5936 {to : [ a.x ? a.x.to : fly(dom).getX(),
5937 a.y ? a.y.to : fly(dom).getY()]};
5940 arguments.callee.anim = fly(dom).fxanim(a,
5946 fly(dom).afterFx(o);
5953 ghost : function(anchor, o){
5958 a = {opacity: {to: 0}, points: {}},
5964 anchor = anchor || "b";
5966 me.queueFx(o, function(){
5968 r = fly(dom).getFxRestore();
5969 w = fly(dom).getWidth();
5970 h = fly(dom).getHeight();
5973 o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();
5974 fly(dom).clearOpacity();
5975 fly(dom).setPositioning(r.pos);
5977 st.height = r.height;
5978 fly(dom).afterFx(o);
5981 pt.by = fly(dom).switchStatements(anchor.toLowerCase(), function(v1,v2){ return [v1, v2];}, {
5992 arguments.callee.anim = fly(dom).fxanim(a,
6002 syncFx : function(){
6004 me.fxDefaults = Ext.apply(me.fxDefaults || {}, {
6013 sequenceFx : function(){
6015 me.fxDefaults = Ext.apply(me.fxDefaults || {}, {
6024 nextFx : function(){
6025 var ef = getQueue(this.dom.id)[0];
6032 hasActiveFx : function(){
6033 return getQueue(this.dom.id)[0];
6037 stopFx : function(finish){
6040 if(me.hasActiveFx()){
6041 var cur = getQueue(id)[0];
6042 if(cur && cur.anim){
6043 if(cur.anim.isAnimated){
6044 setQueue(id, [cur]);
6045 cur.anim.stop(finish !== undefined ? finish : TRUE);
6055 beforeFx : function(o){
6056 if(this.hasActiveFx() && !o.concurrent){
6067 hasFxBlock : function(){
6068 var q = getQueue(this.dom.id);
6069 return q && q[0] && q[0].block;
6073 queueFx : function(o, fn){
6074 var me = fly(this.dom);
6075 if(!me.hasFxBlock()){
6076 Ext.applyIf(o, me.fxDefaults);
6078 var run = me.beforeFx(o);
6080 getQueue(me.dom.id).push(fn);
6092 fxWrap : function(pos, o, vis){
6096 if(!o.wrap || !(wrap = Ext.getDom(o.wrap))){
6098 wrapXY = fly(dom).getXY();
6100 var div = document.createElement("div");
6101 div.style.visibility = vis;
6102 wrap = dom.parentNode.insertBefore(div, dom);
6103 fly(wrap).setPositioning(pos);
6104 if(fly(wrap).isStyle(POSITION, "static")){
6105 fly(wrap).position("relative");
6107 fly(dom).clearPositioning('auto');
6109 wrap.appendChild(dom);
6111 fly(wrap).setXY(wrapXY);
6118 fxUnwrap : function(wrap, pos, o){
6120 fly(dom).clearPositioning();
6121 fly(dom).setPositioning(pos);
6123 var pn = fly(wrap).dom.parentNode;
6124 pn.insertBefore(dom, wrap);
6130 getFxRestore : function(){
6131 var st = this.dom.style;
6132 return {pos: this.getPositioning(), width: st.width, height : st.height};
6136 afterFx : function(o){
6140 fly(dom).setStyle(o.afterStyle);
6143 fly(dom).addClass(o.afterCls);
6145 if(o.remove == TRUE){
6149 o.callback.call(o.scope, fly(dom));
6152 getQueue(id).shift();
6158 fxanim : function(args, opt, animType, defaultDur, defaultEase, cb){
6159 animType = animType || 'run';
6161 var anim = Ext.lib.Anim[animType](
6164 (opt.duration || defaultDur) || .35,
6165 (opt.easing || defaultEase) || EASEOUT,
6175 Ext.Fx.resize = Ext.Fx.scale;
6179 Ext.Element.addMethods(Ext.Fx);
6182 Ext.CompositeElementLite = function(els, root){
6185 this.add(els, root);
6186 this.el = new Ext.Element.Flyweight();
6189 Ext.CompositeElementLite.prototype = {
6193 getElement : function(el){
6202 transformElement : function(el){
6203 return Ext.getDom(el);
6207 getCount : function(){
6208 return this.elements.length;
6211 add : function(els, root){
6213 elements = me.elements;
6217 if(typeof els == "string"){
6218 els = Ext.Element.selectorFunction(els, root);
6219 }else if(els.isComposite){
6221 }else if(!Ext.isIterable(els)){
6225 for(var i = 0, len = els.length; i < len; ++i){
6226 elements.push(me.transformElement(els[i]));
6231 invoke : function(fn, args){
6238 for(i = 0; i < len; i++) {
6241 Ext.Element.prototype[fn].apply(me.getElement(e), args);
6247 item : function(index){
6249 el = me.elements[index],
6253 out = me.getElement(el);
6259 addListener : function(eventName, handler, scope, opt){
6260 var els = this.elements,
6264 for(i = 0; i<len; i++) {
6267 Ext.EventManager.on(e, eventName, handler, scope || e, opt);
6273 each : function(fn, scope){
6279 for(i = 0; i<len; i++) {
6282 e = this.getElement(e);
6283 if(fn.call(scope || e, e, me, i) === false){
6292 fill : function(els){
6300 filter : function(selector){
6303 fn = Ext.isFunction(selector) ? selector
6305 return el.is(selector);
6308 me.each(function(el, self, i) {
6309 if (fn(el, i) !== false) {
6310 els[els.length] = me.transformElement(el);
6319 indexOf : function(el){
6320 return this.elements.indexOf(this.transformElement(el));
6324 replaceElement : function(el, replacement, domReplace){
6325 var index = !isNaN(el) ? el : this.indexOf(el),
6328 replacement = Ext.getDom(replacement);
6330 d = this.elements[index];
6331 d.parentNode.insertBefore(replacement, d);
6334 this.elements.splice(index, 1, replacement);
6345 Ext.CompositeElementLite.prototype.on = Ext.CompositeElementLite.prototype.addListener;
6349 ElProto = Ext.Element.prototype,
6350 CelProto = Ext.CompositeElementLite.prototype;
6352 for(fnName in ElProto){
6353 if(Ext.isFunction(ElProto[fnName])){
6355 CelProto[fnName] = CelProto[fnName] || function(){
6356 return this.invoke(fnName, arguments);
6358 }).call(CelProto, fnName);
6365 Ext.Element.selectorFunction = Ext.DomQuery.select;
6369 Ext.Element.select = function(selector, root){
6371 if(typeof selector == "string"){
6372 els = Ext.Element.selectorFunction(selector, root);
6373 }else if(selector.length !== undefined){
6376 throw "Invalid selector";
6378 return new Ext.CompositeElementLite(els);
6381 Ext.select = Ext.Element.select;
6383 Ext.apply(Ext.CompositeElementLite.prototype, {
6384 addElements : function(els, root){
6388 if(typeof els == "string"){
6389 els = Ext.Element.selectorFunction(els, root);
6391 var yels = this.elements;
6392 Ext.each(els, function(e) {
6393 yels.push(Ext.get(e));
6400 return this.item(0);
6405 return this.item(this.getCount()-1);
6409 contains : function(el){
6410 return this.indexOf(el) != -1;
6414 removeElement : function(keys, removeDom){
6416 els = this.elements,
6418 Ext.each(keys, function(val){
6419 if ((el = (els[val] || els[val = me.indexOf(val)]))) {
6434 Ext.CompositeElement = Ext.extend(Ext.CompositeElementLite, {
6436 constructor : function(els, root){
6438 this.add(els, root);
6442 getElement : function(el){
6448 transformElement : function(el){
6460 Ext.Element.select = function(selector, unique, root){
6462 if(typeof selector == "string"){
6463 els = Ext.Element.selectorFunction(selector, root);
6464 }else if(selector.length !== undefined){
6467 throw "Invalid selector";
6470 return (unique === true) ? new Ext.CompositeElement(els) : new Ext.CompositeElementLite(els);
6474 Ext.select = Ext.Element.select;(function(){
6475 var BEFOREREQUEST = "beforerequest",
6476 REQUESTCOMPLETE = "requestcomplete",
6477 REQUESTEXCEPTION = "requestexception",
6478 UNDEFINED = undefined,
6485 Ext.data.Connection = function(config){
6486 Ext.apply(this, config);
6495 Ext.data.Connection.superclass.constructor.call(this);
6498 Ext.extend(Ext.data.Connection, Ext.util.Observable, {
6509 disableCaching: true,
6512 disableCachingParam: '_dc',
6515 request : function(o){
6517 if(me.fireEvent(BEFOREREQUEST, me, o)){
6519 if(!Ext.isEmpty(o.indicatorText)){
6520 me.indicatorText = '<div class="loading-indicator">'+o.indicatorText+"</div>";
6522 if(me.indicatorText) {
6523 Ext.getDom(o.el).innerHTML = me.indicatorText;
6525 o.success = (Ext.isFunction(o.success) ? o.success : function(){}).createInterceptor(function(response) {
6526 Ext.getDom(o.el).innerHTML = response.responseText;
6531 url = o.url || me.url,
6533 cb = {success: me.handleResponse,
6534 failure: me.handleFailure,
6536 argument: {options: o},
6537 timeout : o.timeout || me.timeout
6543 if (Ext.isFunction(p)) {
6544 p = p.call(o.scope||WINDOW, o);
6547 p = Ext.urlEncode(me.extraParams, Ext.isObject(p) ? Ext.urlEncode(p) : p);
6549 if (Ext.isFunction(url)) {
6550 url = url.call(o.scope || WINDOW, o);
6553 if((form = Ext.getDom(o.form))){
6554 url = url || form.action;
6555 if(o.isUpload || /multipart\/form-data/i.test(form.getAttribute("enctype"))) {
6556 return me.doFormUpload.call(me, o, p, url);
6558 serForm = Ext.lib.Ajax.serializeForm(form);
6559 p = p ? (p + '&' + serForm) : serForm;
6562 method = o.method || me.method || ((p || o.xmlData || o.jsonData) ? POST : GET);
6564 if(method === GET && (me.disableCaching && o.disableCaching !== false) || o.disableCaching === true){
6565 var dcp = o.disableCachingParam || me.disableCachingParam;
6566 url = Ext.urlAppend(url, dcp + '=' + (new Date().getTime()));
6569 o.headers = Ext.apply(o.headers || {}, me.defaultHeaders || {});
6571 if(o.autoAbort === true || me.autoAbort) {
6575 if((method == GET || o.xmlData || o.jsonData) && p){
6576 url = Ext.urlAppend(url, p);
6579 return (me.transId = Ext.lib.Ajax.request(method, url, cb, p, o));
6581 return o.callback ? o.callback.apply(o.scope, [o,UNDEFINED,UNDEFINED]) : null;
6586 isLoading : function(transId){
6587 return transId ? Ext.lib.Ajax.isCallInProgress(transId) : !! this.transId;
6591 abort : function(transId){
6592 if(transId || this.isLoading()){
6593 Ext.lib.Ajax.abort(transId || this.transId);
6598 handleResponse : function(response){
6599 this.transId = false;
6600 var options = response.argument.options;
6601 response.argument = options ? options.argument : null;
6602 this.fireEvent(REQUESTCOMPLETE, this, response, options);
6603 if(options.success){
6604 options.success.call(options.scope, response, options);
6606 if(options.callback){
6607 options.callback.call(options.scope, options, true, response);
6612 handleFailure : function(response, e){
6613 this.transId = false;
6614 var options = response.argument.options;
6615 response.argument = options ? options.argument : null;
6616 this.fireEvent(REQUESTEXCEPTION, this, response, options, e);
6617 if(options.failure){
6618 options.failure.call(options.scope, response, options);
6620 if(options.callback){
6621 options.callback.call(options.scope, options, false, response);
6626 doFormUpload : function(o, ps, url){
6629 frame = doc.createElement('iframe'),
6630 form = Ext.getDom(o.form),
6633 encoding = 'multipart/form-data',
6635 target: form.target,
6636 method: form.method,
6637 encoding: form.encoding,
6638 enctype: form.enctype,
6643 Ext.fly(frame).set({
6647 src: Ext.SSL_SECURE_URL
6650 doc.body.appendChild(frame);
6654 document.frames[id].name = id;
6663 action: url || buf.action
6667 Ext.iterate(Ext.urlDecode(ps, false), function(k, v){
6668 hd = doc.createElement('input');
6674 form.appendChild(hd);
6681 r = {responseText : '',
6683 argument : o.argument},
6688 doc = frame.contentWindow.document || frame.contentDocument || WINDOW.frames[id].document;
6691 if(/textarea/i.test((firstChild = doc.body.firstChild || {}).tagName)){
6692 r.responseText = firstChild.value;
6694 r.responseText = doc.body.innerHTML;
6698 r.responseXML = doc.XMLDocument || doc;
6703 Ext.EventManager.removeListener(frame, LOAD, cb, me);
6705 me.fireEvent(REQUESTCOMPLETE, me, r, o);
6707 function runCallback(fn, scope, args){
6708 if(Ext.isFunction(fn)){
6709 fn.apply(scope, args);
6713 runCallback(o.success, o.scope, [r, o]);
6714 runCallback(o.callback, o.scope, [o, true, r]);
6716 if(!me.debugUploads){
6717 setTimeout(function(){Ext.removeNode(frame);}, 100);
6721 Ext.EventManager.on(frame, LOAD, cb, this);
6724 Ext.fly(form).set(buf);
6725 Ext.each(hiddens, function(h) {
6733 Ext.Ajax = new Ext.data.Connection({
6754 serializeForm : function(form){
6755 return Ext.lib.Ajax.serializeForm(form);
6759 Ext.UpdateManager = Ext.Updater = Ext.extend(Ext.util.Observable,
6761 var BEFOREUPDATE = "beforeupdate",
6763 FAILURE = "failure";
6766 function processSuccess(response){
6768 me.transaction = null;
6769 if (response.argument.form && response.argument.reset) {
6771 response.argument.form.reset();
6774 if (me.loadScripts) {
6775 me.renderer.render(me.el, response, me,
6776 updateComplete.createDelegate(me, [response]));
6778 me.renderer.render(me.el, response, me);
6779 updateComplete.call(me, response);
6784 function updateComplete(response, type, success){
6785 this.fireEvent(type || UPDATE, this.el, response);
6786 if(Ext.isFunction(response.argument.callback)){
6787 response.argument.callback.call(response.argument.scope, this.el, Ext.isEmpty(success) ? true : false, response, response.argument.options);
6792 function processFailure(response){
6793 updateComplete.call(this, response, FAILURE, !!(this.transaction = null));
6797 constructor: function(el, forceNew){
6800 if(!forceNew && el.updateManager){
6801 return el.updateManager;
6806 me.defaultUrl = null;
6817 Ext.apply(me, Ext.Updater.defaults);
6826 me.transaction = null;
6828 me.refreshDelegate = me.refresh.createDelegate(me);
6830 me.updateDelegate = me.update.createDelegate(me);
6832 me.formUpdateDelegate = (me.formUpdate || function(){}).createDelegate(me);
6835 me.renderer = me.renderer || me.getDefaultRenderer();
6837 Ext.Updater.superclass.constructor.call(me);
6841 setRenderer : function(renderer){
6842 this.renderer = renderer;
6846 getRenderer : function(){
6847 return this.renderer;
6851 getDefaultRenderer: function() {
6852 return new Ext.Updater.BasicRenderer();
6856 setDefaultUrl : function(defaultUrl){
6857 this.defaultUrl = defaultUrl;
6866 update : function(url, params, callback, discardUrl){
6871 if(me.fireEvent(BEFOREUPDATE, me.el, url, params) !== false){
6872 if(Ext.isObject(url)){
6875 params = params || cfg.params;
6876 callback = callback || cfg.callback;
6877 discardUrl = discardUrl || cfg.discardUrl;
6878 callerScope = cfg.scope;
6879 if(!Ext.isEmpty(cfg.nocache)){me.disableCaching = cfg.nocache;};
6880 if(!Ext.isEmpty(cfg.text)){me.indicatorText = '<div class="loading-indicator">'+cfg.text+"</div>";};
6881 if(!Ext.isEmpty(cfg.scripts)){me.loadScripts = cfg.scripts;};
6882 if(!Ext.isEmpty(cfg.timeout)){me.timeout = cfg.timeout;};
6887 me.defaultUrl = url;
6889 if(Ext.isFunction(url)){
6893 var o = Ext.apply({}, {
6895 params: (Ext.isFunction(params) && callerScope) ? params.createDelegate(callerScope) : params,
6896 success: processSuccess,
6897 failure: processFailure,
6899 callback: undefined,
6900 timeout: (me.timeout*1000),
6901 disableCaching: me.disableCaching,
6906 "callback": callback,
6907 "scope": callerScope || window,
6912 me.transaction = Ext.Ajax.request(o);
6917 formUpdate : function(form, url, reset, callback){
6919 if(me.fireEvent(BEFOREUPDATE, me.el, form, url) !== false){
6920 if(Ext.isFunction(url)){
6923 form = Ext.getDom(form);
6924 me.transaction = Ext.Ajax.request({
6927 success: processSuccess,
6928 failure: processFailure,
6930 timeout: (me.timeout*1000),
6934 "callback": callback,
6938 me.showLoading.defer(1, me);
6943 startAutoRefresh : function(interval, url, params, callback, refreshNow){
6946 me.update(url || me.defaultUrl, params, callback, true);
6948 if(me.autoRefreshProcId){
6949 clearInterval(me.autoRefreshProcId);
6951 me.autoRefreshProcId = setInterval(me.update.createDelegate(me, [url || me.defaultUrl, params, callback, true]), interval * 1000);
6955 stopAutoRefresh : function(){
6956 if(this.autoRefreshProcId){
6957 clearInterval(this.autoRefreshProcId);
6958 delete this.autoRefreshProcId;
6963 isAutoRefreshing : function(){
6964 return !!this.autoRefreshProcId;
6968 showLoading : function(){
6969 if(this.showLoadIndicator){
6970 this.el.dom.innerHTML = this.indicatorText;
6976 if(this.transaction){
6977 Ext.Ajax.abort(this.transaction);
6982 isUpdating : function(){
6983 return this.transaction ? Ext.Ajax.isLoading(this.transaction) : false;
6987 refresh : function(callback){
6988 if(this.defaultUrl){
6989 this.update(this.defaultUrl, null, callback, true);
6996 Ext.Updater.defaults = {
7000 disableCaching : false,
7002 showLoadIndicator : true,
7004 indicatorText : '<div class="loading-indicator">Loading...</div>',
7006 loadScripts : false,
7008 sslBlankUrl : Ext.SSL_SECURE_URL
7013 Ext.Updater.updateElement = function(el, url, params, options){
7014 var um = Ext.get(el).getUpdater();
7015 Ext.apply(um, options);
7016 um.update(url, params, options ? options.callback : null);
7020 Ext.Updater.BasicRenderer = function(){};
7022 Ext.Updater.BasicRenderer.prototype = {
7024 render : function(el, response, updateManager, callback){
7025 el.update(response.responseText, updateManager.loadScripts, callback);
7034 Date.useStrict = false;
7040 function xf(format) {
7041 var args = Array.prototype.slice.call(arguments, 1);
7042 return format.replace(/\{(\d+)\}/g, function(m, i) {
7049 Date.formatCodeToRegex = function(character, currentGroup) {
7051 var p = Date.parseCodes[character];
7054 p = typeof p == 'function'? p() : p;
7055 Date.parseCodes[character] = p;
7058 return p ? Ext.applyIf({
7059 c: p.c ? xf(p.c, currentGroup || "{0}") : p.c
7063 s:Ext.escapeRe(character)
7068 var $f = Date.formatCodeToRegex;
7073 "M$": function(input, strict) {
7076 var re = new RegExp('\\/Date\\(([-+])?(\\d+)(?:[+-]\\d{4})?\\)\\/');
7077 var r = (input || '').match(re);
7078 return r? new Date(((r[1] || '') + r[2]) * 1) : null;
7087 return '\\/Date(' + this.getTime() + ')\\/';
7161 getShortMonthName : function(month) {
7162 return Date.monthNames[month].substring(0, 3);
7166 getShortDayName : function(day) {
7167 return Date.dayNames[day].substring(0, 3);
7171 getMonthNumber : function(name) {
7173 return Date.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()];
7178 d: "String.leftPad(this.getDate(), 2, '0')",
7179 D: "Date.getShortDayName(this.getDay())",
7180 j: "this.getDate()",
7181 l: "Date.dayNames[this.getDay()]",
7182 N: "(this.getDay() ? this.getDay() : 7)",
7183 S: "this.getSuffix()",
7185 z: "this.getDayOfYear()",
7186 W: "String.leftPad(this.getWeekOfYear(), 2, '0')",
7187 F: "Date.monthNames[this.getMonth()]",
7188 m: "String.leftPad(this.getMonth() + 1, 2, '0')",
7189 M: "Date.getShortMonthName(this.getMonth())",
7190 n: "(this.getMonth() + 1)",
7191 t: "this.getDaysInMonth()",
7192 L: "(this.isLeapYear() ? 1 : 0)",
7193 o: "(this.getFullYear() + (this.getWeekOfYear() == 1 && this.getMonth() > 0 ? +1 : (this.getWeekOfYear() >= 52 && this.getMonth() < 11 ? -1 : 0)))",
7194 Y: "this.getFullYear()",
7195 y: "('' + this.getFullYear()).substring(2, 4)",
7196 a: "(this.getHours() < 12 ? 'am' : 'pm')",
7197 A: "(this.getHours() < 12 ? 'AM' : 'PM')",
7198 g: "((this.getHours() % 12) ? this.getHours() % 12 : 12)",
7199 G: "this.getHours()",
7200 h: "String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0')",
7201 H: "String.leftPad(this.getHours(), 2, '0')",
7202 i: "String.leftPad(this.getMinutes(), 2, '0')",
7203 s: "String.leftPad(this.getSeconds(), 2, '0')",
7204 u: "String.leftPad(this.getMilliseconds(), 3, '0')",
7205 O: "this.getGMTOffset()",
7206 P: "this.getGMTOffset(true)",
7207 T: "this.getTimezone()",
7208 Z: "(this.getTimezoneOffset() * -60)",
7211 for (var c = "Y-m-dTH:i:sP", code = [], i = 0, l = c.length; i < l; ++i) {
7212 var e = c.charAt(i);
7213 code.push(e == "T" ? "'T'" : Date.getFormatCode(e));
7215 return code.join(" + ");
7219 U: "Math.round(this.getTime() / 1000)"
7223 isValid : function(y, m, d, h, i, s, ms) {
7230 var dt = new Date(y, m - 1, d, h, i, s, ms);
7232 return y == dt.getFullYear() &&
7233 m == dt.getMonth() + 1 &&
7234 d == dt.getDate() &&
7235 h == dt.getHours() &&
7236 i == dt.getMinutes() &&
7237 s == dt.getSeconds() &&
7238 ms == dt.getMilliseconds();
7242 parseDate : function(input, format, strict) {
7243 var p = Date.parseFunctions;
7244 if (p[format] == null) {
7245 Date.createParser(format);
7247 return p[format](input, Ext.isDefined(strict) ? strict : Date.useStrict);
7251 getFormatCode : function(character) {
7252 var f = Date.formatCodes[character];
7255 f = typeof f == 'function'? f() : f;
7256 Date.formatCodes[character] = f;
7260 return f || ("'" + String.escape(character) + "'");
7264 createFormat : function(format) {
7269 for (var i = 0; i < format.length; ++i) {
7270 ch = format.charAt(i);
7271 if (!special && ch == "\\") {
7273 } else if (special) {
7275 code.push("'" + String.escape(ch) + "'");
7277 code.push(Date.getFormatCode(ch))
7280 Date.formatFunctions[format] = new Function("return " + code.join('+'));
7284 createParser : function() {
7286 "var dt, y, m, d, h, i, s, ms, o, z, zz, u, v,",
7287 "def = Date.defaults,",
7288 "results = String(input).match(Date.parseRegexes[{0}]);",
7294 "v = new Date(u * 1000);",
7299 "dt = (new Date()).clearTime();",
7302 "y = Ext.num(y, Ext.num(def.y, dt.getFullYear()));",
7303 "m = Ext.num(m, Ext.num(def.m - 1, dt.getMonth()));",
7304 "d = Ext.num(d, Ext.num(def.d, dt.getDate()));",
7307 "h = Ext.num(h, Ext.num(def.h, dt.getHours()));",
7308 "i = Ext.num(i, Ext.num(def.i, dt.getMinutes()));",
7309 "s = Ext.num(s, Ext.num(def.s, dt.getSeconds()));",
7310 "ms = Ext.num(ms, Ext.num(def.ms, dt.getMilliseconds()));",
7312 "if(z >= 0 && y >= 0){",
7317 "v = new Date(y, 0, 1, h, i, s, ms);",
7320 "v = !strict? v : (strict === true && (z <= 364 || (v.isLeapYear() && z <= 365))? v.add(Date.DAY, z) : null);",
7321 "}else if(strict === true && !Date.isValid(y, m + 1, d, h, i, s, ms)){",
7325 "v = new Date(y, m, d, h, i, s, ms);",
7334 "v = v.add(Date.SECOND, -v.getTimezoneOffset() * 60 - zz);",
7337 "v = v.add(Date.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));",
7344 return function(format) {
7345 var regexNum = Date.parseRegexes.length,
7352 for (var i = 0; i < format.length; ++i) {
7353 ch = format.charAt(i);
7354 if (!special && ch == "\\") {
7356 } else if (special) {
7358 regex.push(String.escape(ch));
7360 var obj = $f(ch, currentGroup);
7361 currentGroup += obj.g;
7363 if (obj.g && obj.c) {
7369 Date.parseRegexes[regexNum] = new RegExp("^" + regex.join('') + "$");
7370 Date.parseFunctions[format] = new Function("input", "strict", xf(code, regexNum, calc.join('')));
7379 c:"d = parseInt(results[{0}], 10);\n",
7384 c:"d = parseInt(results[{0}], 10);\n",
7388 for (var a = [], i = 0; i < 7; a.push(Date.getShortDayName(i)), ++i);
7392 s:"(?:" + a.join("|") +")"
7399 s:"(?:" + Date.dayNames.join("|") + ")"
7419 c:"z = parseInt(results[{0}], 10);\n",
7430 c:"m = parseInt(Date.getMonthNumber(results[{0}]), 10);\n",
7431 s:"(" + Date.monthNames.join("|") + ")"
7435 for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i);
7436 return Ext.applyIf({
7437 s:"(" + a.join("|") + ")"
7442 c:"m = parseInt(results[{0}], 10) - 1;\n",
7447 c:"m = parseInt(results[{0}], 10) - 1;\n",
7465 c:"y = parseInt(results[{0}], 10);\n",
7470 c:"var ty = parseInt(results[{0}], 10);\n"
7471 + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n",
7476 c:"if (results[{0}] == 'am') {\n"
7477 + "if (!h || h == 12) { h = 0; }\n"
7478 + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",
7483 c:"if (results[{0}] == 'AM') {\n"
7484 + "if (!h || h == 12) { h = 0; }\n"
7485 + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",
7493 c:"h = parseInt(results[{0}], 10);\n",
7501 c:"h = parseInt(results[{0}], 10);\n",
7506 c:"i = parseInt(results[{0}], 10);\n",
7511 c:"s = parseInt(results[{0}], 10);\n",
7516 c:"ms = results[{0}]; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n",
7522 "o = results[{0}];",
7523 "var sn = o.substring(0,1),",
7524 "hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60),",
7525 "mn = o.substring(3,5) % 60;",
7526 "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"
7533 "o = results[{0}];",
7534 "var sn = o.substring(0,1),",
7535 "hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60),",
7536 "mn = o.substring(4,6) % 60;",
7537 "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"
7539 s: "([+\-]\\d{2}:\\d{2})"
7548 c:"zz = results[{0}] * 1;\n"
7549 + "zz = (-43200 <= zz && zz <= 50400)? zz : null;\n",
7550 s:"([+\-]?\\d{1,5})"
7561 {c:"ms = results[7] || '0'; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n"},
7564 "if(results[8] == 'Z'){",
7566 "}else if (results[8].indexOf(':') > -1){",
7575 for (var i = 0, l = arr.length; i < l; ++i) {
7576 calc.push(arr[i].c);
7584 "(?:", "-", arr[1].s,
7585 "(?:", "-", arr[2].s,
7588 arr[3].s, ":", arr[4].s,
7589 "(?::", arr[5].s, ")?",
7590 "(?:(?:\\.|,)(\\d+))?",
7591 "(Z|(?:[-+]\\d{2}(?::)?\\d{2}))?",
7600 c:"u = parseInt(results[{0}], 10);\n",
7608 Ext.apply(Date.prototype, {
7610 dateFormat : function(format) {
7611 if (Date.formatFunctions[format] == null) {
7612 Date.createFormat(format);
7614 return Date.formatFunctions[format].call(this);
7618 getTimezone : function() {
7631 return this.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, "");
7635 getGMTOffset : function(colon) {
7636 return (this.getTimezoneOffset() > 0 ? "-" : "+")
7637 + String.leftPad(Math.floor(Math.abs(this.getTimezoneOffset()) / 60), 2, "0")
7638 + (colon ? ":" : "")
7639 + String.leftPad(Math.abs(this.getTimezoneOffset() % 60), 2, "0");
7643 getDayOfYear: function() {
7646 m = this.getMonth(),
7649 for (i = 0, d.setDate(1), d.setMonth(0); i < m; d.setMonth(++i)) {
7650 num += d.getDaysInMonth();
7652 return num + this.getDate() - 1;
7656 getWeekOfYear : function() {
7662 var DC3 = Date.UTC(this.getFullYear(), this.getMonth(), this.getDate() + 3) / ms1d,
7663 AWN = Math.floor(DC3 / 7),
7664 Wyr = new Date(AWN * ms7d).getUTCFullYear();
7666 return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
7671 isLeapYear : function() {
7672 var year = this.getFullYear();
7673 return !!((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
7677 getFirstDayOfMonth : function() {
7678 var day = (this.getDay() - (this.getDate() - 1)) % 7;
7679 return (day < 0) ? (day + 7) : day;
7683 getLastDayOfMonth : function() {
7684 return this.getLastDateOfMonth().getDay();
7689 getFirstDateOfMonth : function() {
7690 return new Date(this.getFullYear(), this.getMonth(), 1);
7694 getLastDateOfMonth : function() {
7695 return new Date(this.getFullYear(), this.getMonth(), this.getDaysInMonth());
7699 getDaysInMonth: function() {
7700 var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
7703 var m = this.getMonth();
7705 return m == 1 && this.isLeapYear() ? 29 : daysInMonth[m];
7710 getSuffix : function() {
7711 switch (this.getDate()) {
7728 clone : function() {
7729 return new Date(this.getTime());
7733 isDST : function() {
7736 return new Date(this.getFullYear(), 0, 1).getTimezoneOffset() != this.getTimezoneOffset();
7740 clearTime : function(clone) {
7742 return this.clone().clearTime();
7746 var d = this.getDate();
7752 this.setMilliseconds(0);
7754 if (this.getDate() != d) {
7759 for (var hr = 1, c = this.add(Date.HOUR, hr); c.getDate() != d; hr++, c = this.add(Date.HOUR, hr));
7762 this.setHours(c.getHours());
7769 add : function(interval, value) {
7770 var d = this.clone();
7771 if (!interval || value === 0) return d;
7773 switch(interval.toLowerCase()) {
7775 d.setMilliseconds(this.getMilliseconds() + value);
7778 d.setSeconds(this.getSeconds() + value);
7781 d.setMinutes(this.getMinutes() + value);
7784 d.setHours(this.getHours() + value);
7787 d.setDate(this.getDate() + value);
7790 var day = this.getDate();
7792 day = Math.min(day, this.getFirstDateOfMonth().add('mo', value).getLastDateOfMonth().getDate());
7795 d.setMonth(this.getMonth() + value);
7798 d.setFullYear(this.getFullYear() + value);
7805 between : function(start, end) {
7806 var t = this.getTime();
7807 return start.getTime() <= t && t <= end.getTime();
7813 Date.prototype.format = Date.prototype.dateFormat;
7817 if (Ext.isSafari && (navigator.userAgent.match(/WebKit\/(\d+)/)[1] || NaN) < 420) {
7818 Ext.apply(Date.prototype, {
7819 _xMonth : Date.prototype.setMonth,
7820 _xDate : Date.prototype.setDate,
7824 setMonth : function(num) {
7826 var n = Math.ceil(-num),
7827 back_year = Math.ceil(n / 12),
7828 month = (n % 12) ? 12 - n % 12 : 0;
7830 this.setFullYear(this.getFullYear() - back_year);
7832 return this._xMonth(month);
7834 return this._xMonth(num);
7841 setDate : function(d) {
7844 return this.setTime(this.getTime() - (this.getDate() - d) * 864e5);
7853 Ext.util.MixedCollection = function(allowFunctions, keyFn){
7869 this.allowFunctions = allowFunctions === true;
7871 this.getKey = keyFn;
7873 Ext.util.MixedCollection.superclass.constructor.call(this);
7876 Ext.extend(Ext.util.MixedCollection, Ext.util.Observable, {
7879 allowFunctions : false,
7882 add : function(key, o){
7883 if(arguments.length == 1){
7885 key = this.getKey(o);
7887 if(typeof key != 'undefined' && key !== null){
7888 var old = this.map[key];
7889 if(typeof old != 'undefined'){
7890 return this.replace(key, o);
7896 this.keys.push(key);
7897 this.fireEvent('add', this.length-1, o, key);
7902 getKey : function(o){
7907 replace : function(key, o){
7908 if(arguments.length == 1){
7910 key = this.getKey(o);
7912 var old = this.map[key];
7913 if(typeof key == 'undefined' || key === null || typeof old == 'undefined'){
7914 return this.add(key, o);
7916 var index = this.indexOfKey(key);
7917 this.items[index] = o;
7919 this.fireEvent('replace', key, old, o);
7924 addAll : function(objs){
7925 if(arguments.length > 1 || Ext.isArray(objs)){
7926 var args = arguments.length > 1 ? arguments : objs;
7927 for(var i = 0, len = args.length; i < len; i++){
7931 for(var key in objs){
7932 if(this.allowFunctions || typeof objs[key] != 'function'){
7933 this.add(key, objs[key]);
7940 each : function(fn, scope){
7941 var items = [].concat(this.items);
7942 for(var i = 0, len = items.length; i < len; i++){
7943 if(fn.call(scope || items[i], items[i], i, len) === false){
7950 eachKey : function(fn, scope){
7951 for(var i = 0, len = this.keys.length; i < len; i++){
7952 fn.call(scope || window, this.keys[i], this.items[i], i, len);
7957 find : function(fn, scope){
7958 for(var i = 0, len = this.items.length; i < len; i++){
7959 if(fn.call(scope || window, this.items[i], this.keys[i])){
7960 return this.items[i];
7967 insert : function(index, key, o){
7968 if(arguments.length == 2){
7970 key = this.getKey(o);
7972 if(this.containsKey(key)){
7973 this.suspendEvents();
7974 this.removeKey(key);
7975 this.resumeEvents();
7977 if(index >= this.length){
7978 return this.add(key, o);
7981 this.items.splice(index, 0, o);
7982 if(typeof key != 'undefined' && key !== null){
7985 this.keys.splice(index, 0, key);
7986 this.fireEvent('add', index, o, key);
7991 remove : function(o){
7992 return this.removeAt(this.indexOf(o));
7996 removeAt : function(index){
7997 if(index < this.length && index >= 0){
7999 var o = this.items[index];
8000 this.items.splice(index, 1);
8001 var key = this.keys[index];
8002 if(typeof key != 'undefined'){
8003 delete this.map[key];
8005 this.keys.splice(index, 1);
8006 this.fireEvent('remove', o, key);
8013 removeKey : function(key){
8014 return this.removeAt(this.indexOfKey(key));
8018 getCount : function(){
8023 indexOf : function(o){
8024 return this.items.indexOf(o);
8028 indexOfKey : function(key){
8029 return this.keys.indexOf(key);
8033 item : function(key){
8034 var mk = this.map[key],
8035 item = mk !== undefined ? mk : (typeof key == 'number') ? this.items[key] : undefined;
8036 return typeof item != 'function' || this.allowFunctions ? item : null;
8040 itemAt : function(index){
8041 return this.items[index];
8045 key : function(key){
8046 return this.map[key];
8050 contains : function(o){
8051 return this.indexOf(o) != -1;
8055 containsKey : function(key){
8056 return typeof this.map[key] != 'undefined';
8065 this.fireEvent('clear');
8070 return this.items[0];
8075 return this.items[this.length-1];
8079 _sort : function(property, dir, fn){
8081 dsc = String(dir).toUpperCase() == 'DESC' ? -1 : 1,
8089 fn = fn || function(a, b) {
8094 for(i = 0, len = items.length; i < len; i++){
8103 c.sort(function(a, b){
8104 var v = fn(a[property], b[property]) * dsc;
8106 v = (a.index < b.index ? -1 : 1);
8112 for(i = 0, len = c.length; i < len; i++){
8113 items[i] = c[i].value;
8117 this.fireEvent('sort', this);
8121 sort : function(dir, fn){
8122 this._sort('value', dir, fn);
8126 reorder: function(mapping) {
8127 this.suspendEvents();
8129 var items = this.items,
8131 length = items.length,
8137 for (oldIndex in mapping) {
8138 order[mapping[oldIndex]] = items[oldIndex];
8141 for (index = 0; index < length; index++) {
8142 if (mapping[index] == undefined) {
8143 remaining.push(items[index]);
8147 for (index = 0; index < length; index++) {
8148 if (order[index] == undefined) {
8149 order[index] = remaining.shift();
8156 this.resumeEvents();
8157 this.fireEvent('sort', this);
8161 keySort : function(dir, fn){
8162 this._sort('key', dir, fn || function(a, b){
8163 var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase();
8164 return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
8169 getRange : function(start, end){
8170 var items = this.items;
8171 if(items.length < 1){
8175 end = Math.min(typeof end == 'undefined' ? this.length-1 : end, this.length-1);
8178 for(i = start; i <= end; i++) {
8179 r[r.length] = items[i];
8182 for(i = start; i >= end; i--) {
8183 r[r.length] = items[i];
8190 filter : function(property, value, anyMatch, caseSensitive){
8191 if(Ext.isEmpty(value, false)){
8192 return this.clone();
8194 value = this.createValueMatcher(value, anyMatch, caseSensitive);
8195 return this.filterBy(function(o){
8196 return o && value.test(o[property]);
8201 filterBy : function(fn, scope){
8202 var r = new Ext.util.MixedCollection();
8203 r.getKey = this.getKey;
8204 var k = this.keys, it = this.items;
8205 for(var i = 0, len = it.length; i < len; i++){
8206 if(fn.call(scope||this, it[i], k[i])){
8214 findIndex : function(property, value, start, anyMatch, caseSensitive){
8215 if(Ext.isEmpty(value, false)){
8218 value = this.createValueMatcher(value, anyMatch, caseSensitive);
8219 return this.findIndexBy(function(o){
8220 return o && value.test(o[property]);
8225 findIndexBy : function(fn, scope, start){
8226 var k = this.keys, it = this.items;
8227 for(var i = (start||0), len = it.length; i < len; i++){
8228 if(fn.call(scope||this, it[i], k[i])){
8236 createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) {
8238 var er = Ext.escapeRe;
8239 value = String(value);
8241 if (anyMatch === true) {
8244 value = '^' + er(value);
8245 if (exactMatch === true) {
8249 value = new RegExp(value, caseSensitive ? '' : 'i');
8256 var r = new Ext.util.MixedCollection();
8257 var k = this.keys, it = this.items;
8258 for(var i = 0, len = it.length; i < len; i++){
8261 r.getKey = this.getKey;
8266 Ext.util.MixedCollection.prototype.get = Ext.util.MixedCollection.prototype.item;
8268 Ext.util.JSON = new (function(){
8269 var useHasOwn = !!{}.hasOwnProperty,
8270 isNative = function() {
8271 var useNative = null;
8274 if (useNative === null) {
8275 useNative = Ext.USE_NATIVE_JSON && window.JSON && JSON.toString() == '[object JSON]';
8282 return n < 10 ? "0" + n : n;
8284 doDecode = function(json){
8285 return eval("(" + json + ')');
8287 doEncode = function(o){
8288 if(!Ext.isDefined(o) || o === null){
8290 }else if(Ext.isArray(o)){
8291 return encodeArray(o);
8292 }else if(Ext.isDate(o)){
8293 return Ext.util.JSON.encodeDate(o);
8294 }else if(Ext.isString(o)){
8295 return encodeString(o);
8296 }else if(typeof o == "number"){
8298 return isFinite(o) ? String(o) : "null";
8299 }else if(Ext.isBoolean(o)){
8302 var a = ["{"], b, i, v;
8305 if(!o.getElementsByTagName){
8306 if(!useHasOwn || o.hasOwnProperty(i)) {
8317 a.push(doEncode(i), ":",
8318 v === null ? "null" : doEncode(v));
8337 encodeString = function(s){
8338 if (/["\\\x00-\x1f]/.test(s)) {
8339 return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) {
8346 Math.floor(c / 16).toString(16) +
8347 (c % 16).toString(16);
8350 return '"' + s + '"';
8352 encodeArray = function(o){
8353 var a = ["["], b, i, l = o.length, v;
8354 for (i = 0; i < l; i += 1) {
8365 a.push(v === null ? "null" : Ext.util.JSON.encode(v));
8374 this.encodeDate = function(o){
8375 return '"' + o.getFullYear() + "-" +
8376 pad(o.getMonth() + 1) + "-" +
8377 pad(o.getDate()) + "T" +
8378 pad(o.getHours()) + ":" +
8379 pad(o.getMinutes()) + ":" +
8380 pad(o.getSeconds()) + '"';
8384 this.encode = function() {
8386 return function(o) {
8389 ec = isNative() ? JSON.stringify : doEncode;
8397 this.decode = function() {
8399 return function(json) {
8402 dc = isNative() ? JSON.parse : doDecode;
8410 Ext.encode = Ext.util.JSON.encode;
8412 Ext.decode = Ext.util.JSON.decode;
8414 Ext.util.Format = function(){
8415 var trimRe = /^\s+|\s+$/g,
8416 stripTagsRE = /<\/?[^>]+>/gi,
8417 stripScriptsRe = /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,
8422 ellipsis : function(value, len, word){
8423 if(value && value.length > len){
8425 var vs = value.substr(0, len - 2),
8426 index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?'));
8427 if(index == -1 || index < (len - 15)){
8428 return value.substr(0, len - 3) + "...";
8430 return vs.substr(0, index) + "...";
8433 return value.substr(0, len - 3) + "...";
8440 undef : function(value){
8441 return value !== undefined ? value : "";
8445 defaultValue : function(value, defaultValue){
8446 return value !== undefined && value !== '' ? value : defaultValue;
8450 htmlEncode : function(value){
8451 return !value ? value : String(value).replace(/&/g, "&").replace(/>/g, ">").replace(/</g, "<").replace(/"/g, """);
8455 htmlDecode : function(value){
8456 return !value ? value : String(value).replace(/>/g, ">").replace(/</g, "<").replace(/"/g, '"').replace(/&/g, "&");
8460 trim : function(value){
8461 return String(value).replace(trimRe, "");
8465 substr : function(value, start, length){
8466 return String(value).substr(start, length);
8470 lowercase : function(value){
8471 return String(value).toLowerCase();
8475 uppercase : function(value){
8476 return String(value).toUpperCase();
8480 capitalize : function(value){
8481 return !value ? value : value.charAt(0).toUpperCase() + value.substr(1).toLowerCase();
8485 call : function(value, fn){
8486 if(arguments.length > 2){
8487 var args = Array.prototype.slice.call(arguments, 2);
8488 args.unshift(value);
8489 return eval(fn).apply(window, args);
8491 return eval(fn).call(window, value);
8496 usMoney : function(v){
8497 v = (Math.round((v-0)*100))/100;
8498 v = (v == Math.floor(v)) ? v + ".00" : ((v*10 == Math.floor(v*10)) ? v + "0" : v);
8500 var ps = v.split('.'),
8502 sub = ps[1] ? '.'+ ps[1] : '.00',
8504 while (r.test(whole)) {
8505 whole = whole.replace(r, '$1' + ',' + '$2');
8508 if(v.charAt(0) == '-'){
8509 return '-$' + v.substr(1);
8515 date : function(v, format){
8520 v = new Date(Date.parse(v));
8522 return v.dateFormat(format || "m/d/Y");
8526 dateRenderer : function(format){
8528 return Ext.util.Format.date(v, format);
8533 stripTags : function(v){
8534 return !v ? v : String(v).replace(stripTagsRE, "");
8538 stripScripts : function(v){
8539 return !v ? v : String(v).replace(stripScriptsRe, "");
8543 fileSize : function(size){
8545 return size + " bytes";
8546 } else if(size < 1048576) {
8547 return (Math.round(((size*10) / 1024))/10) + " KB";
8549 return (Math.round(((size*10) / 1048576))/10) + " MB";
8556 return function(v, a){
8558 fns[a] = new Function('v', 'return v ' + a + ';');
8565 round : function(value, precision) {
8566 var result = Number(value);
8567 if (typeof precision == 'number') {
8568 precision = Math.pow(10, precision);
8569 result = Math.round(value * precision) / precision;
8575 number: function(v, format) {
8579 v = Ext.num(v, NaN);
8589 if(format.substr(format.length - 2) == '/i'){
8590 format = format.substr(0, format.length - 2);
8596 var hasComma = format.indexOf(comma) != -1,
8597 psplit = (i18n ? format.replace(/[^\d\,]/g, '') : format.replace(/[^\d\.]/g, '')).split(dec);
8599 if(1 < psplit.length){
8600 v = v.toFixed(psplit[1].length);
8601 }else if(2 < psplit.length){
8602 throw ('NumberFormatException: invalid format, formats should have no more than 1 period: ' + format);
8607 var fnum = v.toString();
8609 psplit = fnum.split('.');
8612 var cnum = psplit[0], parr = [], j = cnum.length, m = Math.floor(j / 3), n = cnum.length % 3 || 3;
8614 for (var i = 0; i < j; i += n) {
8618 parr[parr.length] = cnum.substr(i, n);
8621 fnum = parr.join(comma);
8623 fnum += dec + psplit[1];
8627 fnum = psplit[0] + dec + psplit[1];
8631 return (neg ? '-' : '') + format.replace(/[\d,?\.?]+/, fnum);
8635 numberRenderer : function(format){
8637 return Ext.util.Format.number(v, format);
8642 plural : function(v, s, p){
8643 return v +' ' + (v == 1 ? s : (p ? p : s+'s'));
8647 nl2br : function(v){
8648 return Ext.isEmpty(v) ? '' : v.replace(nl2brRe, '<br/>');
8653 Ext.XTemplate = function(){
8654 Ext.XTemplate.superclass.constructor.apply(this, arguments);
8658 re = /<tpl\b[^>]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/,
8659 nameRe = /^<tpl\b[^>]*?for="(.*?)"/,
8660 ifRe = /^<tpl\b[^>]*?if="(.*?)"/,
8661 execRe = /^<tpl\b[^>]*?exec="(.*?)"/,
8670 WITHVALUES = 'with(values){ ';
8672 s = ['<tpl>', s, '</tpl>'].join('');
8674 while((m = s.match(re))){
8675 var m2 = m[0].match(nameRe),
8676 m3 = m[0].match(ifRe),
8677 m4 = m[0].match(execRe),
8681 name = m2 && m2[1] ? m2[1] : '';
8684 exp = m3 && m3[1] ? m3[1] : null;
8686 fn = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + RETURN +(Ext.util.Format.htmlDecode(exp))+'; }');
8690 exp = m4 && m4[1] ? m4[1] : null;
8692 exec = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES +(Ext.util.Format.htmlDecode(exp))+'; }');
8697 case '.': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + VALUES + '; }'); break;
8698 case '..': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + PARENT + '; }'); break;
8699 default: name = new Function(VALUES, PARENT, WITHVALUES + RETURN + name + '; }');
8709 s = s.replace(m[0], '{xtpl'+ id + '}');
8712 for(var i = tpls.length-1; i >= 0; --i){
8713 me.compileTpl(tpls[i]);
8715 me.master = tpls[tpls.length-1];
8718 Ext.extend(Ext.XTemplate, Ext.Template, {
8720 re : /\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\\]\s?[\d\.\+\-\*\\\(\)]+)?\}/g,
8722 codeRe : /\{\[((?:\\\]|.|\n)*?)\]\}/g,
8725 applySubTemplate : function(id, values, parent, xindex, xcount){
8731 if ((t.test && !t.test.call(me, values, parent, xindex, xcount)) ||
8732 (t.exec && t.exec.call(me, values, parent, xindex, xcount))) {
8735 vs = t.target ? t.target.call(me, values, parent) : values;
8737 parent = t.target ? values : parent;
8738 if(t.target && Ext.isArray(vs)){
8739 for(var i = 0, len = vs.length; i < len; i++){
8740 buf[buf.length] = t.compiled.call(me, vs[i], parent, i+1, len);
8742 return buf.join('');
8744 return t.compiled.call(me, vs, parent, xindex, xcount);
8748 compileTpl : function(tpl){
8749 var fm = Ext.util.Format,
8750 useF = this.disableFormats !== true,
8751 sep = Ext.isGecko ? "+" : ",",
8754 function fn(m, name, format, args, math){
8755 if(name.substr(0, 4) == 'xtpl'){
8756 return "'"+ sep +'this.applySubTemplate('+name.substr(4)+', values, parent, xindex, xcount)'+sep+"'";
8761 }else if(name === '#'){
8763 }else if(name.indexOf('.') != -1){
8766 v = "values['" + name + "']";
8769 v = '(' + v + math + ')';
8771 if (format && useF) {
8772 args = args ? ',' + args : "";
8773 if(format.substr(0, 5) != "this."){
8774 format = "fm." + format + '(';
8776 format = 'this.call("'+ format.substr(5) + '", ';
8780 args= ''; format = "("+v+" === undefined ? '' : ";
8782 return "'"+ sep + format + v + args + ")"+sep+"'";
8785 function codeFn(m, code){
8787 return "'" + sep + '(' + code.replace(/\\'/g, "'") + ')' + sep + "'";
8792 body = "tpl.compiled = function(values, parent, xindex, xcount){ return '" +
8793 tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn) +
8796 body = ["tpl.compiled = function(values, parent, xindex, xcount){ return ['"];
8797 body.push(tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn));
8798 body.push("'].join('');};");
8799 body = body.join('');
8806 applyTemplate : function(values){
8807 return this.master.compiled.call(this, values, {}, 1, 1);
8811 compile : function(){return this;}
8819 Ext.XTemplate.prototype.apply = Ext.XTemplate.prototype.applyTemplate;
8822 Ext.XTemplate.from = function(el){
8823 el = Ext.getDom(el);
8824 return new Ext.XTemplate(el.value || el.innerHTML);
8827 Ext.util.CSS = function(){
8831 var camelRe = /(-[a-z])/gi;
8832 var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };
8836 createStyleSheet : function(cssText, id){
8838 var head = doc.getElementsByTagName("head")[0];
8839 var rules = doc.createElement("style");
8840 rules.setAttribute("type", "text/css");
8842 rules.setAttribute("id", id);
8845 head.appendChild(rules);
8846 ss = rules.styleSheet;
8847 ss.cssText = cssText;
8850 rules.appendChild(doc.createTextNode(cssText));
8852 rules.cssText = cssText;
8854 head.appendChild(rules);
8855 ss = rules.styleSheet ? rules.styleSheet : (rules.sheet || doc.styleSheets[doc.styleSheets.length-1]);
8857 this.cacheStyleSheet(ss);
8862 removeStyleSheet : function(id){
8863 var existing = doc.getElementById(id);
8865 existing.parentNode.removeChild(existing);
8870 swapStyleSheet : function(id, url){
8871 this.removeStyleSheet(id);
8872 var ss = doc.createElement("link");
8873 ss.setAttribute("rel", "stylesheet");
8874 ss.setAttribute("type", "text/css");
8875 ss.setAttribute("id", id);
8876 ss.setAttribute("href", url);
8877 doc.getElementsByTagName("head")[0].appendChild(ss);
8881 refreshCache : function(){
8882 return this.getRules(true);
8886 cacheStyleSheet : function(ss){
8891 var ssRules = ss.cssRules || ss.rules;
8892 for(var j = ssRules.length-1; j >= 0; --j){
8893 rules[ssRules[j].selectorText.toLowerCase()] = ssRules[j];
8899 getRules : function(refreshCache){
8900 if(rules === null || refreshCache){
8902 var ds = doc.styleSheets;
8903 for(var i =0, len = ds.length; i < len; i++){
8905 this.cacheStyleSheet(ds[i]);
8913 getRule : function(selector, refreshCache){
8914 var rs = this.getRules(refreshCache);
8915 if(!Ext.isArray(selector)){
8916 return rs[selector.toLowerCase()];
8918 for(var i = 0; i < selector.length; i++){
8919 if(rs[selector[i]]){
8920 return rs[selector[i].toLowerCase()];
8928 updateRule : function(selector, property, value){
8929 if(!Ext.isArray(selector)){
8930 var rule = this.getRule(selector);
8932 rule.style[property.replace(camelRe, camelFn)] = value;
8936 for(var i = 0; i < selector.length; i++){
8937 if(this.updateRule(selector[i], property, value)){
8946 Ext.util.ClickRepeater = Ext.extend(Ext.util.Observable, {
8948 constructor : function(el, config){
8949 this.el = Ext.get(el);
8950 this.el.unselectable();
8952 Ext.apply(this, config);
8964 this.disabled = true;
8970 this.on("click", this.handler, this.scope || this);
8973 Ext.util.ClickRepeater.superclass.constructor.call(this);
8978 preventDefault : true,
8979 stopDefault : false,
8985 this.el.on('mousedown', this.handleMouseDown, this);
8987 this.el.on('dblclick', this.handleDblClick, this);
8989 if(this.preventDefault || this.stopDefault){
8990 this.el.on('click', this.eventOptions, this);
8993 this.disabled = false;
8997 disable: function( force){
8998 if(force || !this.disabled){
8999 clearTimeout(this.timer);
9000 if(this.pressClass){
9001 this.el.removeClass(this.pressClass);
9003 Ext.getDoc().un('mouseup', this.handleMouseUp, this);
9004 this.el.removeAllListeners();
9006 this.disabled = true;
9010 setDisabled: function(disabled){
9011 this[disabled ? 'disable' : 'enable']();
9014 eventOptions: function(e){
9015 if(this.preventDefault){
9018 if(this.stopDefault){
9024 destroy : function() {
9026 Ext.destroy(this.el);
9027 this.purgeListeners();
9030 handleDblClick : function(e){
9031 clearTimeout(this.timer);
9034 this.fireEvent("mousedown", this, e);
9035 this.fireEvent("click", this, e);
9039 handleMouseDown : function(e){
9040 clearTimeout(this.timer);
9042 if(this.pressClass){
9043 this.el.addClass(this.pressClass);
9045 this.mousedownTime = new Date();
9047 Ext.getDoc().on("mouseup", this.handleMouseUp, this);
9048 this.el.on("mouseout", this.handleMouseOut, this);
9050 this.fireEvent("mousedown", this, e);
9051 this.fireEvent("click", this, e);
9054 if (this.accelerate) {
9057 this.timer = this.click.defer(this.delay || this.interval, this, [e]);
9061 click : function(e){
9062 this.fireEvent("click", this, e);
9063 this.timer = this.click.defer(this.accelerate ?
9064 this.easeOutExpo(this.mousedownTime.getElapsed(),
9068 this.interval, this, [e]);
9071 easeOutExpo : function (t, b, c, d) {
9072 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
9076 handleMouseOut : function(){
9077 clearTimeout(this.timer);
9078 if(this.pressClass){
9079 this.el.removeClass(this.pressClass);
9081 this.el.on("mouseover", this.handleMouseReturn, this);
9085 handleMouseReturn : function(){
9086 this.el.un("mouseover", this.handleMouseReturn, this);
9087 if(this.pressClass){
9088 this.el.addClass(this.pressClass);
9094 handleMouseUp : function(e){
9095 clearTimeout(this.timer);
9096 this.el.un("mouseover", this.handleMouseReturn, this);
9097 this.el.un("mouseout", this.handleMouseOut, this);
9098 Ext.getDoc().un("mouseup", this.handleMouseUp, this);
9099 this.el.removeClass(this.pressClass);
9100 this.fireEvent("mouseup", this, e);
9103 Ext.KeyNav = function(el, config){
9104 this.el = Ext.get(el);
9105 Ext.apply(this, config);
9107 this.disabled = true;
9112 Ext.KeyNav.prototype = {
9116 defaultEventAction: "stopEvent",
9118 forceKeyDown : false,
9121 relay : function(e){
9123 var h = this.keyToHandler[k];
9125 if(this.doRelay(e, this[h], h) !== true){
9126 e[this.defaultEventAction]();
9132 doRelay : function(e, h, hname){
9133 return h.call(this.scope || this, e);
9166 stopKeyUp: function(e) {
9169 if (k >= 37 && k <= 40) {
9177 destroy: function(){
9182 enable: function() {
9183 if (this.disabled) {
9184 if (Ext.isSafari2) {
9186 this.el.on('keyup', this.stopKeyUp, this);
9189 this.el.on(this.isKeydown()? 'keydown' : 'keypress', this.relay, this);
9190 this.disabled = false;
9195 disable: function() {
9196 if (!this.disabled) {
9197 if (Ext.isSafari2) {
9199 this.el.un('keyup', this.stopKeyUp, this);
9202 this.el.un(this.isKeydown()? 'keydown' : 'keypress', this.relay, this);
9203 this.disabled = true;
9208 setDisabled : function(disabled){
9209 this[disabled ? "disable" : "enable"]();
9213 isKeydown: function(){
9214 return this.forceKeyDown || Ext.EventManager.useKeydown;
9218 Ext.KeyMap = function(el, config, eventName){
9219 this.el = Ext.get(el);
9220 this.eventName = eventName || "keydown";
9223 this.addBinding(config);
9228 Ext.KeyMap.prototype = {
9233 addBinding : function(config){
9234 if(Ext.isArray(config)){
9235 Ext.each(config, function(c){
9240 var keyCode = config.key,
9241 fn = config.fn || config.handler,
9242 scope = config.scope;
9244 if (config.stopEvent) {
9245 this.stopEvent = config.stopEvent;
9248 if(typeof keyCode == "string"){
9250 var keyString = keyCode.toUpperCase();
9251 for(var j = 0, len = keyString.length; j < len; j++){
9252 ks.push(keyString.charCodeAt(j));
9256 var keyArray = Ext.isArray(keyCode);
9258 var handler = function(e){
9259 if(this.checkModifiers(config, e)){
9262 for(var i = 0, len = keyCode.length; i < len; i++){
9263 if(keyCode[i] == k){
9267 fn.call(scope || window, k, e);
9276 fn.call(scope || window, k, e);
9281 this.bindings.push(handler);
9285 checkModifiers: function(config, e){
9286 var val, key, keys = ['shift', 'ctrl', 'alt'];
9287 for (var i = 0, len = keys.length; i < len; ++i){
9290 if(!(val === undefined || (val === e[key + 'Key']))){
9298 on : function(key, fn, scope){
9299 var keyCode, shift, ctrl, alt;
9300 if(typeof key == "object" && !Ext.isArray(key)){
9319 handleKeyDown : function(e){
9321 var b = this.bindings;
9322 for(var i = 0, len = b.length; i < len; i++){
9329 isEnabled : function(){
9330 return this.enabled;
9336 this.el.on(this.eventName, this.handleKeyDown, this);
9337 this.enabled = true;
9342 disable: function(){
9344 this.el.removeListener(this.eventName, this.handleKeyDown, this);
9345 this.enabled = false;
9350 setDisabled : function(disabled){
9351 this[disabled ? "disable" : "enable"]();
9354 Ext.util.TextMetrics = function(){
9358 measure : function(el, text, fixedWidth){
9360 shared = Ext.util.TextMetrics.Instance(el, fixedWidth);
9363 shared.setFixedWidth(fixedWidth || 'auto');
9364 return shared.getSize(text);
9368 createInstance : function(el, fixedWidth){
9369 return Ext.util.TextMetrics.Instance(el, fixedWidth);
9374 Ext.util.TextMetrics.Instance = function(bindTo, fixedWidth){
9375 var ml = new Ext.Element(document.createElement('div'));
9376 document.body.appendChild(ml.dom);
9377 ml.position('absolute');
9378 ml.setLeftTop(-1000, -1000);
9382 ml.setWidth(fixedWidth);
9387 getSize : function(text){
9389 var s = ml.getSize();
9395 bind : function(el){
9397 Ext.fly(el).getStyles('font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing')
9402 setFixedWidth : function(width){
9407 getWidth : function(text){
9408 ml.dom.style.width = 'auto';
9409 return this.getSize(text).width;
9413 getHeight : function(text){
9414 return this.getSize(text).height;
9418 instance.bind(bindTo);
9423 Ext.Element.addMethods({
9425 getTextWidth : function(text, min, max){
9426 return (Ext.util.TextMetrics.measure(this.dom, Ext.value(text, this.dom.innerHTML, true)).width).constrain(min || 0, max || 1000000);
9430 Ext.util.Cookies = {
9432 set : function(name, value){
9433 var argv = arguments;
9434 var argc = arguments.length;
9435 var expires = (argc > 2) ? argv[2] : null;
9436 var path = (argc > 3) ? argv[3] : '/';
9437 var domain = (argc > 4) ? argv[4] : null;
9438 var secure = (argc > 5) ? argv[5] : false;
9439 document.cookie = name + "=" + escape(value) + ((expires === null) ? "" : ("; expires=" + expires.toGMTString())) + ((path === null) ? "" : ("; path=" + path)) + ((domain === null) ? "" : ("; domain=" + domain)) + ((secure === true) ? "; secure" : "");
9443 get : function(name){
9444 var arg = name + "=";
9445 var alen = arg.length;
9446 var clen = document.cookie.length;
9451 if(document.cookie.substring(i, j) == arg){
9452 return Ext.util.Cookies.getCookieVal(j);
9454 i = document.cookie.indexOf(" ", i) + 1;
9463 clear : function(name){
9464 if(Ext.util.Cookies.get(name)){
9465 document.cookie = name + "=" + "; expires=Thu, 01-Jan-70 00:00:01 GMT";
9469 getCookieVal : function(offset){
9470 var endstr = document.cookie.indexOf(";", offset);
9472 endstr = document.cookie.length;
9474 return unescape(document.cookie.substring(offset, endstr));
9477 Ext.handleError = function(e) {
9482 Ext.Error = function(message) {
9484 this.message = (this.lang[message]) ? this.lang[message] : message;
9487 Ext.Error.prototype = new Error();
9488 Ext.apply(Ext.Error.prototype, {
9494 getName : function() {
9498 getMessage : function() {
9499 return this.message;
9502 toJson : function() {
9503 return Ext.encode(this);
9507 Ext.ComponentMgr = function(){
9508 var all = new Ext.util.MixedCollection();
9514 register : function(c){
9519 unregister : function(c){
9529 onAvailable : function(id, fn, scope){
9530 all.on("add", function(index, o){
9532 fn.call(scope || o, o);
9533 all.un("add", fn, scope);
9548 isRegistered : function(xtype){
9549 return types[xtype] !== undefined;
9553 isPluginRegistered : function(ptype){
9554 return ptypes[ptype] !== undefined;
9558 registerType : function(xtype, cls){
9564 create : function(config, defaultType){
9565 return config.render ? config : new types[config.xtype || defaultType](config);
9569 registerPlugin : function(ptype, cls){
9570 ptypes[ptype] = cls;
9575 createPlugin : function(config, defaultType){
9576 var PluginCls = ptypes[config.ptype || defaultType];
9577 if (PluginCls.init) {
9580 return new PluginCls(config);
9587 Ext.reg = Ext.ComponentMgr.registerType;
9589 Ext.preg = Ext.ComponentMgr.registerPlugin;
9591 Ext.create = Ext.ComponentMgr.create;
9592 Ext.Component = function(config){
9593 config = config || {};
9594 if(config.initialConfig){
9595 if(config.isAction){
9596 this.baseAction = config;
9598 config = config.initialConfig;
9599 }else if(config.tagName || config.dom || Ext.isString(config)){
9600 config = {applyTo: config, id: config.id || config};
9604 this.initialConfig = config;
9606 Ext.apply(this, config);
9635 'beforestaterestore',
9644 Ext.ComponentMgr.register(this);
9645 Ext.Component.superclass.constructor.call(this);
9647 if(this.baseAction){
9648 this.baseAction.addComponent(this);
9651 this.initComponent();
9654 if(Ext.isArray(this.plugins)){
9655 for(var i = 0, len = this.plugins.length; i < len; i++){
9656 this.plugins[i] = this.initPlugin(this.plugins[i]);
9659 this.plugins = this.initPlugin(this.plugins);
9663 if(this.stateful !== false){
9668 this.applyToMarkup(this.applyTo);
9669 delete this.applyTo;
9670 }else if(this.renderTo){
9671 this.render(this.renderTo);
9672 delete this.renderTo;
9677 Ext.Component.AUTO_ID = 1000;
9679 Ext.extend(Ext.Component, Ext.util.Observable, {
9710 disabledClass : 'x-item-disabled',
9712 allowDomMove : true,
9716 hideMode : 'display',
9732 tplWriteMode : 'overwrite',
9741 ctype : 'Ext.Component',
9747 getActionEl : function(){
9748 return this[this.actionMode];
9751 initPlugin : function(p){
9752 if(p.ptype && !Ext.isFunction(p.init)){
9753 p = Ext.ComponentMgr.createPlugin(p);
9754 }else if(Ext.isString(p)){
9755 p = Ext.ComponentMgr.createPlugin({
9764 initComponent : function(){
9767 this.on(this.listeners);
9768 delete this.listeners;
9770 this.enableBubble(this.bubbleEvents);
9774 render : function(container, position){
9775 if(!this.rendered && this.fireEvent('beforerender', this) !== false){
9776 if(!container && this.el){
9777 this.el = Ext.get(this.el);
9778 container = this.el.dom.parentNode;
9779 this.allowDomMove = false;
9781 this.container = Ext.get(container);
9783 this.container.addClass(this.ctCls);
9785 this.rendered = true;
9786 if(position !== undefined){
9787 if(Ext.isNumber(position)){
9788 position = this.container.dom.childNodes[position];
9790 position = Ext.getDom(position);
9793 this.onRender(this.container, position || null);
9795 this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]);
9798 this.el.addClass(this.cls);
9802 this.el.applyStyles(this.style);
9806 this.el.addClassOnOver(this.overCls);
9808 this.fireEvent('render', this);
9813 var contentTarget = this.getContentTarget();
9815 contentTarget.update(Ext.DomHelper.markup(this.html));
9818 if (this.contentEl){
9819 var ce = Ext.getDom(this.contentEl);
9820 Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']);
9821 contentTarget.appendChild(ce);
9824 if (!this.tpl.compile) {
9825 this.tpl = new Ext.XTemplate(this.tpl);
9828 this.tpl[this.tplWriteMode](contentTarget, this.data);
9832 this.afterRender(this.container);
9844 if(this.stateful !== false){
9845 this.initStateEvents();
9847 this.fireEvent('afterrender', this);
9854 update: function(htmlOrData, loadScripts, cb) {
9855 var contentTarget = this.getContentTarget();
9856 if (this.tpl && typeof htmlOrData !== "string") {
9857 this.tpl[this.tplWriteMode](contentTarget, htmlOrData || {});
9859 var html = Ext.isObject(htmlOrData) ? Ext.DomHelper.markup(htmlOrData) : htmlOrData;
9860 contentTarget.update(html, loadScripts, cb);
9866 onAdded : function(container, pos) {
9867 this.ownerCt = container;
9869 this.fireEvent('added', this, container, pos);
9873 onRemoved : function() {
9875 this.fireEvent('removed', this, this.ownerCt);
9876 delete this.ownerCt;
9880 initRef : function() {
9882 if(this.ref && !this.refOwner){
9883 var levels = this.ref.split('/'),
9884 last = levels.length,
9888 while(t && i < last){
9893 t[this.refName = levels[--i]] = this;
9900 removeRef : function() {
9901 if (this.refOwner && this.refName) {
9902 delete this.refOwner[this.refName];
9903 delete this.refOwner;
9908 initState : function(){
9909 if(Ext.state.Manager){
9910 var id = this.getStateId();
9912 var state = Ext.state.Manager.get(id);
9914 if(this.fireEvent('beforestaterestore', this, state) !== false){
9915 this.applyState(Ext.apply({}, state));
9916 this.fireEvent('staterestore', this, state);
9924 getStateId : function(){
9925 return this.stateId || ((/^(ext-comp-|ext-gen)/).test(String(this.id)) ? null : this.id);
9929 initStateEvents : function(){
9930 if(this.stateEvents){
9931 for(var i = 0, e; e = this.stateEvents[i]; i++){
9932 this.on(e, this.saveState, this, {delay:100});
9938 applyState : function(state){
9940 Ext.apply(this, state);
9945 getState : function(){
9950 saveState : function(){
9951 if(Ext.state.Manager && this.stateful !== false){
9952 var id = this.getStateId();
9954 var state = this.getState();
9955 if(this.fireEvent('beforestatesave', this, state) !== false){
9956 Ext.state.Manager.set(id, state);
9957 this.fireEvent('statesave', this, state);
9964 applyToMarkup : function(el){
9965 this.allowDomMove = false;
9966 this.el = Ext.get(el);
9967 this.render(this.el.dom.parentNode);
9971 addClass : function(cls){
9973 this.el.addClass(cls);
9975 this.cls = this.cls ? this.cls + ' ' + cls : cls;
9981 removeClass : function(cls){
9983 this.el.removeClass(cls);
9985 this.cls = this.cls.split(' ').remove(cls).join(' ');
9992 onRender : function(ct, position){
9993 if(!this.el && this.autoEl){
9994 if(Ext.isString(this.autoEl)){
9995 this.el = document.createElement(this.autoEl);
9997 var div = document.createElement('div');
9998 Ext.DomHelper.overwrite(div, this.autoEl);
9999 this.el = div.firstChild;
10002 this.el.id = this.getId();
10006 this.el = Ext.get(this.el);
10007 if(this.allowDomMove !== false){
10008 ct.dom.insertBefore(this.el.dom, position);
10010 Ext.removeNode(div);
10018 getAutoCreate : function(){
10019 var cfg = Ext.isObject(this.autoCreate) ?
10020 this.autoCreate : Ext.apply({}, this.defaultAutoCreate);
10021 if(this.id && !cfg.id){
10028 afterRender : Ext.emptyFn,
10031 destroy : function(){
10032 if(!this.isDestroyed){
10033 if(this.fireEvent('beforedestroy', this) !== false){
10034 this.destroying = true;
10035 this.beforeDestroy();
10036 if(this.ownerCt && this.ownerCt.remove){
10037 this.ownerCt.remove(this, false);
10041 if(this.actionMode == 'container' || this.removeMode == 'container'){
10042 this.container.remove();
10046 if(this.focusTask && this.focusTask.cancel){
10047 this.focusTask.cancel();
10050 Ext.ComponentMgr.unregister(this);
10051 this.fireEvent('destroy', this);
10052 this.purgeListeners();
10053 this.destroying = false;
10054 this.isDestroyed = true;
10059 deleteMembers : function(){
10060 var args = arguments;
10061 for(var i = 0, len = args.length; i < len; ++i){
10062 delete this[args[i]];
10067 beforeDestroy : Ext.emptyFn,
10070 onDestroy : Ext.emptyFn,
10073 getEl : function(){
10078 getContentTarget : function(){
10083 getId : function(){
10084 return this.id || (this.id = 'ext-comp-' + (++Ext.Component.AUTO_ID));
10088 getItemId : function(){
10089 return this.itemId || this.getId();
10093 focus : function(selectText, delay){
10095 this.focusTask = new Ext.util.DelayedTask(this.focus, this, [selectText, false]);
10096 this.focusTask.delay(Ext.isNumber(delay) ? delay : 10);
10099 if(this.rendered && !this.isDestroyed){
10101 if(selectText === true){
10102 this.el.dom.select();
10117 disable : function( silent){
10121 this.disabled = true;
10122 if(silent !== true){
10123 this.fireEvent('disable', this);
10129 onDisable : function(){
10130 this.getActionEl().addClass(this.disabledClass);
10131 this.el.dom.disabled = true;
10135 enable : function(){
10139 this.disabled = false;
10140 this.fireEvent('enable', this);
10145 onEnable : function(){
10146 this.getActionEl().removeClass(this.disabledClass);
10147 this.el.dom.disabled = false;
10151 setDisabled : function(disabled){
10152 return this[disabled ? 'disable' : 'enable']();
10157 if(this.fireEvent('beforeshow', this) !== false){
10158 this.hidden = false;
10159 if(this.autoRender){
10160 this.render(Ext.isBoolean(this.autoRender) ? Ext.getBody() : this.autoRender);
10165 this.fireEvent('show', this);
10171 onShow : function(){
10172 this.getVisibilityEl().removeClass('x-hide-' + this.hideMode);
10177 if(this.fireEvent('beforehide', this) !== false){
10179 this.fireEvent('hide', this);
10185 doHide: function(){
10186 this.hidden = true;
10193 onHide : function(){
10194 this.getVisibilityEl().addClass('x-hide-' + this.hideMode);
10198 getVisibilityEl : function(){
10199 return this.hideParent ? this.container : this.getActionEl();
10203 setVisible : function(visible){
10204 return this[visible ? 'show' : 'hide']();
10208 isVisible : function(){
10209 return this.rendered && this.getVisibilityEl().isVisible();
10213 cloneConfig : function(overrides){
10214 overrides = overrides || {};
10215 var id = overrides.id || Ext.id();
10216 var cfg = Ext.applyIf(overrides, this.initialConfig);
10218 return new this.constructor(cfg);
10222 getXType : function(){
10223 return this.constructor.xtype;
10227 isXType : function(xtype, shallow){
10229 if (Ext.isFunction(xtype)){
10230 xtype = xtype.xtype;
10231 }else if (Ext.isObject(xtype)){
10232 xtype = xtype.constructor.xtype;
10235 return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 : this.constructor.xtype == xtype;
10239 getXTypes : function(){
10240 var tc = this.constructor;
10242 var c = [], sc = this;
10243 while(sc && sc.constructor.xtype){
10244 c.unshift(sc.constructor.xtype);
10245 sc = sc.constructor.superclass;
10248 tc.xtypes = c.join('/');
10254 findParentBy : function(fn) {
10255 for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt);
10260 findParentByType : function(xtype) {
10261 return Ext.isFunction(xtype) ?
10262 this.findParentBy(function(p){
10263 return p.constructor === xtype;
10265 this.findParentBy(function(p){
10266 return p.constructor.xtype === xtype;
10271 getPositionEl : function(){
10272 return this.positionEl || this.el;
10276 purgeListeners : function(){
10277 Ext.Component.superclass.purgeListeners.call(this);
10279 this.on('beforedestroy', this.clearMons, this, {single: true});
10284 clearMons : function(){
10285 Ext.each(this.mons, function(m){
10286 m.item.un(m.ename, m.fn, m.scope);
10292 createMons: function(){
10295 this.on('beforedestroy', this.clearMons, this, {single: true});
10300 mon : function(item, ename, fn, scope, opt){
10302 if(Ext.isObject(ename)){
10303 var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
10307 if(propRe.test(e)){
10310 if(Ext.isFunction(o[e])){
10313 item: item, ename: e, fn: o[e], scope: o.scope
10315 item.on(e, o[e], o.scope, o);
10319 item: item, ename: e, fn: o[e], scope: o.scope
10328 item: item, ename: ename, fn: fn, scope: scope
10330 item.on(ename, fn, scope, opt);
10334 mun : function(item, ename, fn, scope){
10337 for(var i = 0, len = this.mons.length; i < len; ++i){
10338 mon = this.mons[i];
10339 if(item === mon.item && ename == mon.ename && fn === mon.fn && scope === mon.scope){
10340 this.mons.splice(i, 1);
10341 item.un(ename, fn, scope);
10350 nextSibling : function(){
10352 var index = this.ownerCt.items.indexOf(this);
10353 if(index != -1 && index+1 < this.ownerCt.items.getCount()){
10354 return this.ownerCt.items.itemAt(index+1);
10361 previousSibling : function(){
10363 var index = this.ownerCt.items.indexOf(this);
10365 return this.ownerCt.items.itemAt(index-1);
10372 getBubbleTarget : function(){
10373 return this.ownerCt;
10377 Ext.reg('component', Ext.Component);
10378 Ext.Action = Ext.extend(Object, {
10387 constructor : function(config){
10388 this.initialConfig = config;
10389 this.itemId = config.itemId = (config.itemId || config.id || Ext.id());
10397 setText : function(text){
10398 this.initialConfig.text = text;
10399 this.callEach('setText', [text]);
10403 getText : function(){
10404 return this.initialConfig.text;
10408 setIconClass : function(cls){
10409 this.initialConfig.iconCls = cls;
10410 this.callEach('setIconClass', [cls]);
10414 getIconClass : function(){
10415 return this.initialConfig.iconCls;
10419 setDisabled : function(v){
10420 this.initialConfig.disabled = v;
10421 this.callEach('setDisabled', [v]);
10425 enable : function(){
10426 this.setDisabled(false);
10430 disable : function(){
10431 this.setDisabled(true);
10435 isDisabled : function(){
10436 return this.initialConfig.disabled;
10440 setHidden : function(v){
10441 this.initialConfig.hidden = v;
10442 this.callEach('setVisible', [!v]);
10447 this.setHidden(false);
10452 this.setHidden(true);
10456 isHidden : function(){
10457 return this.initialConfig.hidden;
10461 setHandler : function(fn, scope){
10462 this.initialConfig.handler = fn;
10463 this.initialConfig.scope = scope;
10464 this.callEach('setHandler', [fn, scope]);
10468 each : function(fn, scope){
10469 Ext.each(this.items, fn, scope);
10473 callEach : function(fnName, args){
10474 var cs = this.items;
10475 for(var i = 0, len = cs.length; i < len; i++){
10476 cs[i][fnName].apply(cs[i], args);
10481 addComponent : function(comp){
10482 this.items.push(comp);
10483 comp.on('destroy', this.removeComponent, this);
10487 removeComponent : function(comp){
10488 this.items.remove(comp);
10492 execute : function(){
10493 this.initialConfig.handler.apply(this.initialConfig.scope || window, arguments);
10498 Ext.Layer = function(config, existingEl){
10499 config = config || {};
10500 var dh = Ext.DomHelper;
10501 var cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body;
10503 this.dom = Ext.getDom(existingEl);
10506 var o = config.dh || {tag: 'div', cls: 'x-layer'};
10507 this.dom = dh.append(pel, o);
10510 this.addClass(config.cls);
10512 this.constrain = config.constrain !== false;
10513 this.setVisibilityMode(Ext.Element.VISIBILITY);
10515 this.id = this.dom.id = config.id;
10517 this.id = Ext.id(this.dom);
10519 this.zindex = config.zindex || this.getZIndex();
10520 this.position('absolute', this.zindex);
10522 this.shadowOffset = config.shadowOffset || 4;
10523 this.shadow = new Ext.Shadow({
10524 offset : this.shadowOffset,
10525 mode : config.shadow
10528 this.shadowOffset = 0;
10530 this.useShim = config.shim !== false && Ext.useShims;
10531 this.useDisplay = config.useDisplay;
10535 var supr = Ext.Element.prototype;
10540 Ext.extend(Ext.Layer, Ext.Element, {
10542 getZIndex : function(){
10543 return this.zindex || parseInt((this.getShim() || this).getStyle('z-index'), 10) || 11000;
10546 getShim : function(){
10553 var shim = shims.shift();
10555 shim = this.createShim();
10556 shim.enableDisplayMode('block');
10557 shim.dom.style.display = 'none';
10558 shim.dom.style.visibility = 'visible';
10560 var pn = this.dom.parentNode;
10561 if(shim.dom.parentNode != pn){
10562 pn.insertBefore(shim.dom, this.dom);
10564 shim.setStyle('z-index', this.getZIndex()-2);
10569 hideShim : function(){
10571 this.shim.setDisplayed(false);
10572 shims.push(this.shim);
10577 disableShadow : function(){
10579 this.shadowDisabled = true;
10580 this.shadow.hide();
10581 this.lastShadowOffset = this.shadowOffset;
10582 this.shadowOffset = 0;
10586 enableShadow : function(show){
10588 this.shadowDisabled = false;
10589 this.shadowOffset = this.lastShadowOffset;
10590 delete this.lastShadowOffset;
10600 sync : function(doShow){
10601 var shadow = this.shadow;
10602 if(!this.updating && this.isVisible() && (shadow || this.useShim)){
10603 var shim = this.getShim(),
10604 w = this.getWidth(),
10605 h = this.getHeight(),
10606 l = this.getLeft(true),
10607 t = this.getTop(true);
10609 if(shadow && !this.shadowDisabled){
10610 if(doShow && !shadow.isVisible()){
10613 shadow.realign(l, t, w, h);
10620 var shadowAdj = shadow.el.getXY(), shimStyle = shim.dom.style,
10621 shadowSize = shadow.el.getSize();
10622 shimStyle.left = (shadowAdj[0])+'px';
10623 shimStyle.top = (shadowAdj[1])+'px';
10624 shimStyle.width = (shadowSize.width)+'px';
10625 shimStyle.height = (shadowSize.height)+'px';
10631 shim.setSize(w, h);
10632 shim.setLeftTop(l, t);
10638 destroy : function(){
10641 this.shadow.hide();
10643 this.removeAllListeners();
10644 Ext.removeNode(this.dom);
10648 remove : function(){
10653 beginUpdate : function(){
10654 this.updating = true;
10658 endUpdate : function(){
10659 this.updating = false;
10664 hideUnders : function(negOffset){
10666 this.shadow.hide();
10672 constrainXY : function(){
10673 if(this.constrain){
10674 var vw = Ext.lib.Dom.getViewWidth(),
10675 vh = Ext.lib.Dom.getViewHeight();
10676 var s = Ext.getDoc().getScroll();
10678 var xy = this.getXY();
10679 var x = xy[0], y = xy[1];
10680 var so = this.shadowOffset;
10681 var w = this.dom.offsetWidth+so, h = this.dom.offsetHeight+so;
10685 if((x + w) > vw+s.left){
10689 if((y + h) > vh+s.top){
10704 var ay = this.avoidY;
10705 if(y <= ay && (y+h) >= ay){
10711 supr.setXY.call(this, xy);
10718 getConstrainOffset : function(){
10719 return this.shadowOffset;
10722 isVisible : function(){
10723 return this.visible;
10727 showAction : function(){
10728 this.visible = true;
10729 if(this.useDisplay === true){
10730 this.setDisplayed('');
10731 }else if(this.lastXY){
10732 supr.setXY.call(this, this.lastXY);
10733 }else if(this.lastLT){
10734 supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]);
10739 hideAction : function(){
10740 this.visible = false;
10741 if(this.useDisplay === true){
10742 this.setDisplayed(false);
10744 this.setLeftTop(-10000,-10000);
10749 setVisible : function(v, a, d, c, e){
10754 var cb = function(){
10759 }.createDelegate(this);
10760 supr.setVisible.call(this, true, true, d, cb, e);
10763 this.hideUnders(true);
10772 }.createDelegate(this);
10774 supr.setVisible.call(this, v, a, d, cb, e);
10784 storeXY : function(xy){
10785 delete this.lastLT;
10789 storeLeftTop : function(left, top){
10790 delete this.lastXY;
10791 this.lastLT = [left, top];
10795 beforeFx : function(){
10796 this.beforeAction();
10797 return Ext.Layer.superclass.beforeFx.apply(this, arguments);
10801 afterFx : function(){
10802 Ext.Layer.superclass.afterFx.apply(this, arguments);
10803 this.sync(this.isVisible());
10807 beforeAction : function(){
10808 if(!this.updating && this.shadow){
10809 this.shadow.hide();
10814 setLeft : function(left){
10815 this.storeLeftTop(left, this.getTop(true));
10816 supr.setLeft.apply(this, arguments);
10821 setTop : function(top){
10822 this.storeLeftTop(this.getLeft(true), top);
10823 supr.setTop.apply(this, arguments);
10828 setLeftTop : function(left, top){
10829 this.storeLeftTop(left, top);
10830 supr.setLeftTop.apply(this, arguments);
10835 setXY : function(xy, a, d, c, e){
10837 this.beforeAction();
10839 var cb = this.createCB(c);
10840 supr.setXY.call(this, xy, a, d, cb, e);
10848 createCB : function(c){
10860 setX : function(x, a, d, c, e){
10861 this.setXY([x, this.getY()], a, d, c, e);
10866 setY : function(y, a, d, c, e){
10867 this.setXY([this.getX(), y], a, d, c, e);
10872 setSize : function(w, h, a, d, c, e){
10873 this.beforeAction();
10874 var cb = this.createCB(c);
10875 supr.setSize.call(this, w, h, a, d, cb, e);
10883 setWidth : function(w, a, d, c, e){
10884 this.beforeAction();
10885 var cb = this.createCB(c);
10886 supr.setWidth.call(this, w, a, d, cb, e);
10894 setHeight : function(h, a, d, c, e){
10895 this.beforeAction();
10896 var cb = this.createCB(c);
10897 supr.setHeight.call(this, h, a, d, cb, e);
10905 setBounds : function(x, y, w, h, a, d, c, e){
10906 this.beforeAction();
10907 var cb = this.createCB(c);
10909 this.storeXY([x, y]);
10910 supr.setXY.call(this, [x, y]);
10911 supr.setSize.call(this, w, h, a, d, cb, e);
10914 supr.setBounds.call(this, x, y, w, h, a, d, cb, e);
10920 setZIndex : function(zindex){
10921 this.zindex = zindex;
10922 this.setStyle('z-index', zindex + 2);
10924 this.shadow.setZIndex(zindex + 1);
10927 this.shim.setStyle('z-index', zindex);
10934 Ext.Shadow = function(config){
10935 Ext.apply(this, config);
10936 if(typeof this.mode != "string"){
10937 this.mode = this.defaultMode;
10939 var o = this.offset, a = {h: 0};
10940 var rad = Math.floor(this.offset/2);
10941 switch(this.mode.toLowerCase()){
10947 a.l -= this.offset + rad;
10948 a.t -= this.offset + rad;
10959 a.l -= (this.offset - rad);
10960 a.t -= this.offset + rad;
10962 a.w -= (this.offset - rad)*2;
10973 a.l -= (this.offset - rad);
10974 a.t -= (this.offset - rad);
10976 a.w -= (this.offset + rad + 1);
10977 a.h -= (this.offset + rad);
10986 Ext.Shadow.prototype = {
10992 defaultMode: "drop",
10995 show : function(target){
10996 target = Ext.get(target);
10998 this.el = Ext.Shadow.Pool.pull();
10999 if(this.el.dom.nextSibling != target.dom){
11000 this.el.insertBefore(target);
11003 this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10)-1);
11005 this.el.dom.style.filter="progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius="+(this.offset)+")";
11008 target.getLeft(true),
11009 target.getTop(true),
11013 this.el.dom.style.display = "block";
11017 isVisible : function(){
11018 return this.el ? true : false;
11022 realign : function(l, t, w, h){
11026 var a = this.adjusts, d = this.el.dom, s = d.style;
11028 s.left = (l+a.l)+"px";
11029 s.top = (t+a.t)+"px";
11030 var sw = (w+a.w), sh = (h+a.h), sws = sw +"px", shs = sh + "px";
11031 if(s.width != sws || s.height != shs){
11035 var cn = d.childNodes;
11036 var sww = Math.max(0, (sw-12))+"px";
11037 cn[0].childNodes[1].style.width = sww;
11038 cn[1].childNodes[1].style.width = sww;
11039 cn[2].childNodes[1].style.width = sww;
11040 cn[1].style.height = Math.max(0, (sh-12))+"px";
11048 this.el.dom.style.display = "none";
11049 Ext.Shadow.Pool.push(this.el);
11055 setZIndex : function(z){
11058 this.el.setStyle("z-index", z);
11064 Ext.Shadow.Pool = function(){
11066 var markup = Ext.isIE ?
11067 '<div class="x-ie-shadow"></div>' :
11068 '<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>';
11071 var sh = p.shift();
11073 sh = Ext.get(Ext.DomHelper.insertHtml("beforeBegin", document.body.firstChild, markup));
11074 sh.autoBoxAdjust = false;
11079 push : function(sh){
11084 Ext.BoxComponent = Ext.extend(Ext.Component, {
11113 initComponent : function(){
11114 Ext.BoxComponent.superclass.initComponent.call(this);
11126 deferHeight: false,
11129 setSize : function(w, h){
11132 if(typeof w == 'object'){
11136 if (Ext.isDefined(w) && Ext.isDefined(this.boxMinWidth) && (w < this.boxMinWidth)) {
11137 w = this.boxMinWidth;
11139 if (Ext.isDefined(h) && Ext.isDefined(this.boxMinHeight) && (h < this.boxMinHeight)) {
11140 h = this.boxMinHeight;
11142 if (Ext.isDefined(w) && Ext.isDefined(this.boxMaxWidth) && (w > this.boxMaxWidth)) {
11143 w = this.boxMaxWidth;
11145 if (Ext.isDefined(h) && Ext.isDefined(this.boxMaxHeight) && (h > this.boxMaxHeight)) {
11146 h = this.boxMaxHeight;
11149 if(!this.boxReady){
11156 if(this.cacheSizes !== false && this.lastSize && this.lastSize.width == w && this.lastSize.height == h){
11159 this.lastSize = {width: w, height: h};
11160 var adj = this.adjustSize(w, h),
11164 if(aw !== undefined || ah !== undefined){
11165 rz = this.getResizeEl();
11166 if(!this.deferHeight && aw !== undefined && ah !== undefined){
11167 rz.setSize(aw, ah);
11168 }else if(!this.deferHeight && ah !== undefined){
11170 }else if(aw !== undefined){
11173 this.onResize(aw, ah, w, h);
11174 this.fireEvent('resize', this, aw, ah, w, h);
11180 setWidth : function(width){
11181 return this.setSize(width);
11185 setHeight : function(height){
11186 return this.setSize(undefined, height);
11190 getSize : function(){
11191 return this.getResizeEl().getSize();
11195 getWidth : function(){
11196 return this.getResizeEl().getWidth();
11200 getHeight : function(){
11201 return this.getResizeEl().getHeight();
11205 getOuterSize : function(){
11206 var el = this.getResizeEl();
11207 return {width: el.getWidth() + el.getMargins('lr'),
11208 height: el.getHeight() + el.getMargins('tb')};
11212 getPosition : function(local){
11213 var el = this.getPositionEl();
11214 if(local === true){
11215 return [el.getLeft(true), el.getTop(true)];
11217 return this.xy || el.getXY();
11221 getBox : function(local){
11222 var pos = this.getPosition(local);
11223 var s = this.getSize();
11230 updateBox : function(box){
11231 this.setSize(box.width, box.height);
11232 this.setPagePosition(box.x, box.y);
11237 getResizeEl : function(){
11238 return this.resizeEl || this.el;
11242 setAutoScroll : function(scroll){
11244 this.getContentTarget().setOverflow(scroll ? 'auto' : '');
11246 this.autoScroll = scroll;
11251 setPosition : function(x, y){
11252 if(x && typeof x[1] == 'number'){
11258 if(!this.boxReady){
11261 var adj = this.adjustPosition(x, y);
11262 var ax = adj.x, ay = adj.y;
11264 var el = this.getPositionEl();
11265 if(ax !== undefined || ay !== undefined){
11266 if(ax !== undefined && ay !== undefined){
11267 el.setLeftTop(ax, ay);
11268 }else if(ax !== undefined){
11270 }else if(ay !== undefined){
11273 this.onPosition(ax, ay);
11274 this.fireEvent('move', this, ax, ay);
11280 setPagePosition : function(x, y){
11281 if(x && typeof x[1] == 'number'){
11287 if(!this.boxReady){
11290 if(x === undefined || y === undefined){
11293 var p = this.getPositionEl().translatePoints(x, y);
11294 this.setPosition(p.left, p.top);
11299 afterRender : function(){
11300 Ext.BoxComponent.superclass.afterRender.call(this);
11302 this.resizeEl = Ext.get(this.resizeEl);
11304 if(this.positionEl){
11305 this.positionEl = Ext.get(this.positionEl);
11307 this.boxReady = true;
11308 Ext.isDefined(this.autoScroll) && this.setAutoScroll(this.autoScroll);
11309 this.setSize(this.width, this.height);
11310 if(this.x || this.y){
11311 this.setPosition(this.x, this.y);
11312 }else if(this.pageX || this.pageY){
11313 this.setPagePosition(this.pageX, this.pageY);
11318 syncSize : function(){
11319 delete this.lastSize;
11320 this.setSize(this.autoWidth ? undefined : this.getResizeEl().getWidth(), this.autoHeight ? undefined : this.getResizeEl().getHeight());
11325 onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
11329 onPosition : function(x, y){
11334 adjustSize : function(w, h){
11335 if(this.autoWidth){
11338 if(this.autoHeight){
11341 return {width : w, height: h};
11345 adjustPosition : function(x, y){
11346 return {x : x, y: y};
11349 Ext.reg('box', Ext.BoxComponent);
11353 Ext.Spacer = Ext.extend(Ext.BoxComponent, {
11356 Ext.reg('spacer', Ext.Spacer);
11357 Ext.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){
11360 this.el = Ext.get(dragElement, true);
11361 this.el.dom.unselectable = "on";
11363 this.resizingEl = Ext.get(resizingElement, true);
11366 this.orientation = orientation || Ext.SplitBar.HORIZONTAL;
11373 this.maxSize = 2000;
11376 this.animate = false;
11379 this.useShim = false;
11384 if(!existingProxy){
11386 this.proxy = Ext.SplitBar.createProxy(this.orientation);
11388 this.proxy = Ext.get(existingProxy).dom;
11391 this.dd = new Ext.dd.DDProxy(this.el.dom.id, "XSplitBars", {dragElId : this.proxy.id});
11394 this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this);
11397 this.dd.endDrag = this.onEndProxyDrag.createDelegate(this);
11400 this.dragSpecs = {};
11403 this.adapter = new Ext.SplitBar.BasicLayoutAdapter();
11404 this.adapter.init(this);
11406 if(this.orientation == Ext.SplitBar.HORIZONTAL){
11408 this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? Ext.SplitBar.LEFT : Ext.SplitBar.RIGHT);
11409 this.el.addClass("x-splitbar-h");
11412 this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? Ext.SplitBar.TOP : Ext.SplitBar.BOTTOM);
11413 this.el.addClass("x-splitbar-v");
11427 Ext.SplitBar.superclass.constructor.call(this);
11430 Ext.extend(Ext.SplitBar, Ext.util.Observable, {
11431 onStartProxyDrag : function(x, y){
11432 this.fireEvent("beforeresize", this);
11433 this.overlay = Ext.DomHelper.append(document.body, {cls: "x-drag-overlay", html: " "}, true);
11434 this.overlay.unselectable();
11435 this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
11436 this.overlay.show();
11437 Ext.get(this.proxy).setDisplayed("block");
11438 var size = this.adapter.getElementSize(this);
11439 this.activeMinSize = this.getMinimumSize();
11440 this.activeMaxSize = this.getMaximumSize();
11441 var c1 = size - this.activeMinSize;
11442 var c2 = Math.max(this.activeMaxSize - size, 0);
11443 if(this.orientation == Ext.SplitBar.HORIZONTAL){
11444 this.dd.resetConstraints();
11445 this.dd.setXConstraint(
11446 this.placement == Ext.SplitBar.LEFT ? c1 : c2,
11447 this.placement == Ext.SplitBar.LEFT ? c2 : c1,
11450 this.dd.setYConstraint(0, 0);
11452 this.dd.resetConstraints();
11453 this.dd.setXConstraint(0, 0);
11454 this.dd.setYConstraint(
11455 this.placement == Ext.SplitBar.TOP ? c1 : c2,
11456 this.placement == Ext.SplitBar.TOP ? c2 : c1,
11460 this.dragSpecs.startSize = size;
11461 this.dragSpecs.startPoint = [x, y];
11462 Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd, x, y);
11466 onEndProxyDrag : function(e){
11467 Ext.get(this.proxy).setDisplayed(false);
11468 var endPoint = Ext.lib.Event.getXY(e);
11470 Ext.destroy(this.overlay);
11471 delete this.overlay;
11474 if(this.orientation == Ext.SplitBar.HORIZONTAL){
11475 newSize = this.dragSpecs.startSize +
11476 (this.placement == Ext.SplitBar.LEFT ?
11477 endPoint[0] - this.dragSpecs.startPoint[0] :
11478 this.dragSpecs.startPoint[0] - endPoint[0]
11481 newSize = this.dragSpecs.startSize +
11482 (this.placement == Ext.SplitBar.TOP ?
11483 endPoint[1] - this.dragSpecs.startPoint[1] :
11484 this.dragSpecs.startPoint[1] - endPoint[1]
11487 newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize);
11488 if(newSize != this.dragSpecs.startSize){
11489 if(this.fireEvent('beforeapply', this, newSize) !== false){
11490 this.adapter.setElementSize(this, newSize);
11491 this.fireEvent("moved", this, newSize);
11492 this.fireEvent("resize", this, newSize);
11498 getAdapter : function(){
11499 return this.adapter;
11503 setAdapter : function(adapter){
11504 this.adapter = adapter;
11505 this.adapter.init(this);
11509 getMinimumSize : function(){
11510 return this.minSize;
11514 setMinimumSize : function(minSize){
11515 this.minSize = minSize;
11519 getMaximumSize : function(){
11520 return this.maxSize;
11524 setMaximumSize : function(maxSize){
11525 this.maxSize = maxSize;
11529 setCurrentSize : function(size){
11530 var oldAnimate = this.animate;
11531 this.animate = false;
11532 this.adapter.setElementSize(this, size);
11533 this.animate = oldAnimate;
11537 destroy : function(removeEl){
11538 Ext.destroy(this.shim, Ext.get(this.proxy));
11543 this.purgeListeners();
11548 Ext.SplitBar.createProxy = function(dir){
11549 var proxy = new Ext.Element(document.createElement("div"));
11550 document.body.appendChild(proxy.dom);
11551 proxy.unselectable();
11552 var cls = 'x-splitbar-proxy';
11553 proxy.addClass(cls + ' ' + (dir == Ext.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v'));
11558 Ext.SplitBar.BasicLayoutAdapter = function(){
11561 Ext.SplitBar.BasicLayoutAdapter.prototype = {
11563 init : function(s){
11567 getElementSize : function(s){
11568 if(s.orientation == Ext.SplitBar.HORIZONTAL){
11569 return s.resizingEl.getWidth();
11571 return s.resizingEl.getHeight();
11576 setElementSize : function(s, newSize, onComplete){
11577 if(s.orientation == Ext.SplitBar.HORIZONTAL){
11579 s.resizingEl.setWidth(newSize);
11581 onComplete(s, newSize);
11584 s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut');
11589 s.resizingEl.setHeight(newSize);
11591 onComplete(s, newSize);
11594 s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut');
11601 Ext.SplitBar.AbsoluteLayoutAdapter = function(container){
11602 this.basic = new Ext.SplitBar.BasicLayoutAdapter();
11603 this.container = Ext.get(container);
11606 Ext.SplitBar.AbsoluteLayoutAdapter.prototype = {
11607 init : function(s){
11608 this.basic.init(s);
11611 getElementSize : function(s){
11612 return this.basic.getElementSize(s);
11615 setElementSize : function(s, newSize, onComplete){
11616 this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s]));
11619 moveSplitter : function(s){
11620 var yes = Ext.SplitBar;
11621 switch(s.placement){
11623 s.el.setX(s.resizingEl.getRight());
11626 s.el.setStyle("right", (this.container.getWidth() - s.resizingEl.getLeft()) + "px");
11629 s.el.setY(s.resizingEl.getBottom());
11632 s.el.setY(s.resizingEl.getTop() - s.el.getHeight());
11639 Ext.SplitBar.VERTICAL = 1;
11642 Ext.SplitBar.HORIZONTAL = 2;
11645 Ext.SplitBar.LEFT = 1;
11648 Ext.SplitBar.RIGHT = 2;
11651 Ext.SplitBar.TOP = 3;
11654 Ext.SplitBar.BOTTOM = 4;
11656 Ext.Container = Ext.extend(Ext.BoxComponent, {
11669 autoDestroy : true,
11672 forceLayout: false,
11676 defaultType : 'panel',
11679 resizeEvent: 'resize',
11682 bubbleEvents: ['add', 'remove'],
11685 initComponent : function(){
11686 Ext.Container.superclass.initComponent.call(this);
11702 var items = this.items;
11710 initItems : function(){
11712 this.items = new Ext.util.MixedCollection(false, this.getComponentId);
11718 setLayout : function(layout){
11719 if(this.layout && this.layout != layout){
11720 this.layout.setContainer(null);
11722 this.layout = layout;
11724 layout.setContainer(this);
11727 afterRender: function(){
11730 Ext.Container.superclass.afterRender.call(this);
11732 this.layout = 'auto';
11734 if(Ext.isObject(this.layout) && !this.layout.layout){
11735 this.layoutConfig = this.layout;
11736 this.layout = this.layoutConfig.type;
11738 if(Ext.isString(this.layout)){
11739 this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);
11741 this.setLayout(this.layout);
11744 if(this.activeItem !== undefined){
11745 var item = this.activeItem;
11746 delete this.activeItem;
11747 this.layout.setActiveItem(item);
11752 this.doLayout(false, true);
11757 if(this.monitorResize === true){
11758 Ext.EventManager.onWindowResize(this.doLayout, this, [false]);
11763 getLayoutTarget : function(){
11768 getComponentId : function(comp){
11769 return comp.getItemId();
11773 add : function(comp){
11775 var args = arguments.length > 1;
11776 if(args || Ext.isArray(comp)){
11778 Ext.each(args ? arguments : comp, function(c){
11779 result.push(this.add(c));
11783 var c = this.lookupComponent(this.applyDefaults(comp));
11784 var index = this.items.length;
11785 if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){
11788 c.onAdded(this, index);
11790 this.fireEvent('add', this, c, index);
11795 onAdd : function(c){
11800 onAdded : function(container, pos) {
11802 this.ownerCt = container;
11805 this.cascade(function(c){
11808 this.fireEvent('added', this, container, pos);
11812 insert : function(index, comp){
11814 var a = arguments, len = a.length;
11817 for(var i = len-1; i >= 1; --i) {
11818 result.push(this.insert(index, a[i]));
11822 var c = this.lookupComponent(this.applyDefaults(comp));
11823 index = Math.min(index, this.items.length);
11824 if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){
11825 if(c.ownerCt == this){
11826 this.items.remove(c);
11828 this.items.insert(index, c);
11829 c.onAdded(this, index);
11831 this.fireEvent('add', this, c, index);
11837 applyDefaults : function(c){
11838 var d = this.defaults;
11840 if(Ext.isFunction(d)){
11841 d = d.call(this, c);
11843 if(Ext.isString(c)){
11844 c = Ext.ComponentMgr.get(c);
11846 }else if(!c.events){
11856 onBeforeAdd : function(item){
11858 item.ownerCt.remove(item, false);
11860 if(this.hideBorders === true){
11861 item.border = (item.border === true);
11866 remove : function(comp, autoDestroy){
11868 var c = this.getComponent(comp);
11869 if(c && this.fireEvent('beforeremove', this, c) !== false){
11870 this.doRemove(c, autoDestroy);
11871 this.fireEvent('remove', this, c);
11876 onRemove: function(c){
11881 doRemove: function(c, autoDestroy){
11882 var l = this.layout,
11883 hasLayout = l && this.rendered;
11888 this.items.remove(c);
11891 if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){
11900 removeAll: function(autoDestroy){
11902 var item, rem = [], items = [];
11903 this.items.each(function(i){
11906 for (var i = 0, len = rem.length; i < len; ++i){
11908 this.remove(item, autoDestroy);
11909 if(item.ownerCt !== this){
11917 getComponent : function(comp){
11918 if(Ext.isObject(comp)){
11919 comp = comp.getItemId();
11921 return this.items.get(comp);
11925 lookupComponent : function(comp){
11926 if(Ext.isString(comp)){
11927 return Ext.ComponentMgr.get(comp);
11928 }else if(!comp.events){
11929 return this.createComponent(comp);
11935 createComponent : function(config, defaultType){
11936 if (config.render) {
11941 var c = Ext.create(Ext.apply({
11943 }, config), defaultType || this.defaultType);
11944 delete c.initialConfig.ownerCt;
11950 canLayout : function() {
11951 var el = this.getVisibilityEl();
11952 return el && el.dom && !el.isStyle("display", "none");
11957 doLayout : function(shallow, force){
11958 var rendered = this.rendered,
11959 forceLayout = force || this.forceLayout;
11961 if(this.collapsed || !this.canLayout()){
11962 this.deferLayout = this.deferLayout || !shallow;
11966 shallow = shallow && !this.deferLayout;
11968 delete this.deferLayout;
11970 if(rendered && this.layout){
11971 this.layout.layout();
11973 if(shallow !== true && this.items){
11974 var cs = this.items.items;
11975 for(var i = 0, len = cs.length; i < len; i++){
11978 c.doLayout(false, forceLayout);
11983 this.onLayout(shallow, forceLayout);
11986 this.hasLayout = true;
11987 delete this.forceLayout;
11990 onLayout : Ext.emptyFn,
11993 shouldBufferLayout: function(){
11995 var hl = this.hasLayout;
11998 return hl ? !this.hasLayoutPending() : false;
12005 hasLayoutPending: function(){
12007 var pending = false;
12008 this.ownerCt.bubble(function(c){
12009 if(c.layoutPending){
12017 onShow : function(){
12019 Ext.Container.superclass.onShow.call(this);
12021 if(Ext.isDefined(this.deferLayout)){
12022 delete this.deferLayout;
12023 this.doLayout(true);
12028 getLayout : function(){
12030 var layout = new Ext.layout.AutoLayout(this.layoutConfig);
12031 this.setLayout(layout);
12033 return this.layout;
12037 beforeDestroy : function(){
12040 while(c = this.items.first()){
12041 this.doRemove(c, true);
12044 if(this.monitorResize){
12045 Ext.EventManager.removeResizeListener(this.doLayout, this);
12047 Ext.destroy(this.layout);
12048 Ext.Container.superclass.beforeDestroy.call(this);
12052 bubble : function(fn, scope, args){
12055 if(fn.apply(scope || p, args || [p]) === false){
12064 cascade : function(fn, scope, args){
12065 if(fn.apply(scope || this, args || [this]) !== false){
12067 var cs = this.items.items;
12068 for(var i = 0, len = cs.length; i < len; i++){
12070 cs[i].cascade(fn, scope, args);
12072 fn.apply(scope || cs[i], args || [cs[i]]);
12081 findById : function(id){
12083 this.cascade(function(c){
12084 if(ct != c && c.id === id){
12093 findByType : function(xtype, shallow){
12094 return this.findBy(function(c){
12095 return c.isXType(xtype, shallow);
12100 find : function(prop, value){
12101 return this.findBy(function(c){
12102 return c[prop] === value;
12107 findBy : function(fn, scope){
12108 var m = [], ct = this;
12109 this.cascade(function(c){
12110 if(ct != c && fn.call(scope || c, c, ct) === true){
12118 get : function(key){
12119 return this.items.get(key);
12123 Ext.Container.LAYOUTS = {};
12124 Ext.reg('container', Ext.Container);
12126 Ext.layout.ContainerLayout = Ext.extend(Object, {
12133 monitorResize:false,
12137 constructor : function(config){
12138 this.id = Ext.id(null, 'ext-layout-');
12139 Ext.apply(this, config);
12145 IEMeasureHack : function(target, viewFlag) {
12146 var tChildren = target.dom.childNodes, tLen = tChildren.length, c, d = [], e, i, ret;
12147 for (i = 0 ; i < tLen ; i++) {
12151 d[i] = e.getStyle('display');
12152 e.setStyle({display: 'none'});
12155 ret = target ? target.getViewSize(viewFlag) : {};
12156 for (i = 0 ; i < tLen ; i++) {
12160 e.setStyle({display: d[i]});
12167 getLayoutTargetSize : Ext.EmptyFn,
12170 layout : function(){
12171 var ct = this.container, target = ct.getLayoutTarget();
12172 if(!(this.hasLayout || Ext.isEmpty(this.targetCls))){
12173 target.addClass(this.targetCls);
12175 this.onLayout(ct, target);
12176 ct.fireEvent('afterlayout', ct, this);
12180 onLayout : function(ct, target){
12181 this.renderAll(ct, target);
12185 isValidParent : function(c, target){
12186 return target && c.getPositionEl().dom.parentNode == (target.dom || target);
12190 renderAll : function(ct, target){
12191 var items = ct.items.items, i, c, len = items.length;
12192 for(i = 0; i < len; i++) {
12194 if(c && (!c.rendered || !this.isValidParent(c, target))){
12195 this.renderItem(c, i, target);
12201 renderItem : function(c, position, target){
12204 c.render(target, position);
12205 this.configureItem(c, position);
12206 } else if (!this.isValidParent(c, target)) {
12207 if (Ext.isNumber(position)) {
12208 position = target.dom.childNodes[position];
12211 target.dom.insertBefore(c.getPositionEl().dom, position || null);
12212 c.container = target;
12213 this.configureItem(c, position);
12220 getRenderedItems: function(ct){
12221 var t = ct.getLayoutTarget(), cti = ct.items.items, len = cti.length, i, c, items = [];
12222 for (i = 0; i < len; i++) {
12223 if((c = cti[i]).rendered && this.isValidParent(c, t)){
12231 configureItem: function(c, position){
12232 if (this.extraCls) {
12233 var t = c.getPositionEl ? c.getPositionEl() : c;
12234 t.addClass(this.extraCls);
12238 if (c.doLayout && this.forceLayout) {
12241 if (this.renderHidden && c != this.activeItem) {
12246 onRemove: function(c){
12247 if(this.activeItem == c){
12248 delete this.activeItem;
12250 if(c.rendered && this.extraCls){
12251 var t = c.getPositionEl ? c.getPositionEl() : c;
12252 t.removeClass(this.extraCls);
12256 afterRemove: function(c){
12257 if(c.removeRestore){
12258 c.removeMode = 'container';
12259 delete c.removeRestore;
12264 onResize: function(){
12265 var ct = this.container,
12270 if(b = ct.bufferResize && ct.shouldBufferLayout()){
12271 if(!this.resizeTask){
12272 this.resizeTask = new Ext.util.DelayedTask(this.runLayout, this);
12273 this.resizeBuffer = Ext.isNumber(b) ? b : 50;
12275 ct.layoutPending = true;
12276 this.resizeTask.delay(this.resizeBuffer);
12282 runLayout: function(){
12283 var ct = this.container;
12286 delete ct.layoutPending;
12290 setContainer : function(ct){
12292 if(this.monitorResize && ct != this.container){
12293 var old = this.container;
12295 old.un(old.resizeEvent, this.onResize, this);
12298 ct.on(ct.resizeEvent, this.onResize, this);
12301 this.container = ct;
12305 parseMargins : function(v){
12306 if (Ext.isNumber(v)) {
12309 var ms = v.split(' '),
12313 ms[1] = ms[2] = ms[3] = ms[0];
12314 } else if(len == 2) {
12317 } else if(len == 3) {
12322 top :parseInt(ms[0], 10) || 0,
12323 right :parseInt(ms[1], 10) || 0,
12324 bottom:parseInt(ms[2], 10) || 0,
12325 left :parseInt(ms[3], 10) || 0
12330 fieldTpl: (function() {
12331 var t = new Ext.Template(
12332 '<div class="x-form-item {itemCls}" tabIndex="-1">',
12333 '<label for="{id}" style="{labelStyle}" class="x-form-item-label">{label}{labelSeparator}</label>',
12334 '<div class="x-form-element" id="x-form-el-{id}" style="{elementStyle}">',
12335 '</div><div class="{clearCls}"></div>',
12338 t.disableFormats = true;
12339 return t.compile();
12343 destroy : function(){
12345 if(this.resizeTask && this.resizeTask.cancel){
12346 this.resizeTask.cancel();
12348 if(!Ext.isEmpty(this.targetCls)){
12349 var target = this.container.getLayoutTarget();
12351 target.removeClass(this.targetCls);
12356 Ext.layout.AutoLayout = Ext.extend(Ext.layout.ContainerLayout, {
12359 monitorResize: true,
12361 onLayout : function(ct, target){
12362 Ext.layout.AutoLayout.superclass.onLayout.call(this, ct, target);
12363 var cs = this.getRenderedItems(ct), len = cs.length, i, c;
12364 for(i = 0; i < len; i++){
12374 Ext.Container.LAYOUTS['auto'] = Ext.layout.AutoLayout;
12376 Ext.layout.FitLayout = Ext.extend(Ext.layout.ContainerLayout, {
12378 monitorResize:true,
12382 getLayoutTargetSize : function() {
12383 var target = this.container.getLayoutTarget();
12388 return target.getStyleSize();
12392 onLayout : function(ct, target){
12393 Ext.layout.FitLayout.superclass.onLayout.call(this, ct, target);
12395 this.setItemSize(this.activeItem || ct.items.itemAt(0), this.getLayoutTargetSize());
12400 setItemSize : function(item, size){
12401 if(item && size.height > 0){
12402 item.setSize(size);
12406 Ext.Container.LAYOUTS['fit'] = Ext.layout.FitLayout;
12407 Ext.layout.CardLayout = Ext.extend(Ext.layout.FitLayout, {
12409 deferredRender : false,
12412 layoutOnCardChange : false,
12416 renderHidden : true,
12421 setActiveItem : function(item){
12422 var ai = this.activeItem,
12423 ct = this.container;
12424 item = ct.getComponent(item);
12427 if(item && ai != item){
12432 if (ai.hidden !== true) {
12435 ai.fireEvent('deactivate', ai);
12438 var layout = item.doLayout && (this.layoutOnCardChange || !item.rendered);
12441 this.activeItem = item;
12445 delete item.deferLayout;
12455 item.fireEvent('activate', item);
12460 renderAll : function(ct, target){
12461 if(this.deferredRender){
12462 this.renderItem(this.activeItem, undefined, target);
12464 Ext.layout.CardLayout.superclass.renderAll.call(this, ct, target);
12468 Ext.Container.LAYOUTS['card'] = Ext.layout.CardLayout;
12470 Ext.layout.AnchorLayout = Ext.extend(Ext.layout.ContainerLayout, {
12474 monitorResize : true,
12479 defaultAnchor : '100%',
12481 parseAnchorRE : /^(r|right|b|bottom)$/i,
12483 getLayoutTargetSize : function() {
12484 var target = this.container.getLayoutTarget();
12489 return target.getStyleSize();
12493 onLayout : function(ct, target){
12494 Ext.layout.AnchorLayout.superclass.onLayout.call(this, ct, target);
12495 var size = this.getLayoutTargetSize();
12497 var w = size.width, h = size.height;
12499 if(w < 20 && h < 20){
12506 if(typeof ct.anchorSize == 'number'){
12507 aw = ct.anchorSize;
12509 aw = ct.anchorSize.width;
12510 ah = ct.anchorSize.height;
12513 aw = ct.initialConfig.width;
12514 ah = ct.initialConfig.height;
12517 var cs = this.getRenderedItems(ct), len = cs.length, i, c, a, cw, ch, el, vs, boxes = [];
12518 for(i = 0; i < len; i++){
12520 el = c.getPositionEl();
12523 if (!c.anchor && c.items && !Ext.isNumber(c.width) && !(Ext.isIE6 && Ext.isStrict)){
12524 c.anchor = this.defaultAnchor;
12530 vs = c.anchor.split(' ');
12531 c.anchorSpec = a = {
12532 right: this.parseAnchor(vs[0], c.initialConfig.width, aw),
12533 bottom: this.parseAnchor(vs[1], c.initialConfig.height, ah)
12536 cw = a.right ? this.adjustWidthAnchor(a.right(w) - el.getMargins('lr'), c) : undefined;
12537 ch = a.bottom ? this.adjustHeightAnchor(a.bottom(h) - el.getMargins('tb'), c) : undefined;
12542 width: cw || undefined,
12543 height: ch || undefined
12548 for (i = 0, len = boxes.length; i < len; i++) {
12550 c.comp.setSize(c.width, c.height);
12555 parseAnchor : function(a, start, cstart){
12556 if(a && a != 'none'){
12559 if(this.parseAnchorRE.test(a)){
12560 var diff = cstart - start;
12561 return function(v){
12568 }else if(a.indexOf('%') != -1){
12569 var ratio = parseFloat(a.replace('%', ''))*.01;
12570 return function(v){
12573 return Math.floor(v*ratio);
12578 a = parseInt(a, 10);
12580 return function(v){
12593 adjustWidthAnchor : function(value, comp){
12598 adjustHeightAnchor : function(value, comp){
12604 Ext.Container.LAYOUTS['anchor'] = Ext.layout.AnchorLayout;
12606 Ext.layout.ColumnLayout = Ext.extend(Ext.layout.ContainerLayout, {
12608 monitorResize:true,
12612 extraCls: 'x-column',
12618 targetCls: 'x-column-layout-ct',
12620 isValidParent : function(c, target){
12621 return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom;
12624 getLayoutTargetSize : function() {
12625 var target = this.container.getLayoutTarget(), ret;
12627 ret = target.getViewSize();
12632 if (Ext.isIE && Ext.isStrict && ret.width == 0){
12633 ret = target.getStyleSize();
12636 ret.width -= target.getPadding('lr');
12637 ret.height -= target.getPadding('tb');
12642 renderAll : function(ct, target) {
12646 this.innerCt = target.createChild({cls:'x-column-inner'});
12647 this.innerCt.createChild({cls:'x-clear'});
12649 Ext.layout.ColumnLayout.superclass.renderAll.call(this, ct, this.innerCt);
12653 onLayout : function(ct, target){
12654 var cs = ct.items.items,
12661 this.renderAll(ct, target);
12663 var size = this.getLayoutTargetSize();
12665 if(size.width < 1 && size.height < 1){
12669 var w = size.width - this.scrollOffset,
12673 this.innerCt.setWidth(w);
12678 for(i = 0; i < len; i++){
12680 m = c.getPositionEl().getMargins('lr');
12682 if(!c.columnWidth){
12683 pw -= (c.getWidth() + m);
12687 pw = pw < 0 ? 0 : pw;
12689 for(i = 0; i < len; i++){
12693 c.setSize(Math.floor(c.columnWidth * pw) - m);
12700 if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) {
12701 var ts = this.getLayoutTargetSize();
12702 if (ts.width != size.width){
12703 this.adjustmentPass = true;
12704 this.onLayout(ct, target);
12708 delete this.adjustmentPass;
12714 Ext.Container.LAYOUTS['column'] = Ext.layout.ColumnLayout;
12716 Ext.layout.BorderLayout = Ext.extend(Ext.layout.ContainerLayout, {
12718 monitorResize:true,
12724 targetCls: 'x-border-layout-ct',
12726 getLayoutTargetSize : function() {
12727 var target = this.container.getLayoutTarget();
12728 return target ? target.getViewSize() : {};
12732 onLayout : function(ct, target){
12733 var collapsed, i, c, pos, items = ct.items.items, len = items.length;
12734 if(!this.rendered){
12736 for(i = 0; i < len; i++) {
12742 c.collapsed = false;
12744 c.render(target, i);
12745 c.getPositionEl().addClass('x-border-panel');
12747 this[pos] = pos != 'center' && c.split ?
12748 new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) :
12749 new Ext.layout.BorderLayout.Region(this, c.initialConfig, pos);
12750 this[pos].render(target, c);
12752 this.rendered = true;
12755 var size = this.getLayoutTargetSize();
12756 if(size.width < 20 || size.height < 20){
12758 this.restoreCollapsed = collapsed;
12761 }else if(this.restoreCollapsed){
12762 collapsed = this.restoreCollapsed;
12763 delete this.restoreCollapsed;
12766 var w = size.width, h = size.height,
12767 centerW = w, centerH = h, centerY = 0, centerX = 0,
12768 n = this.north, s = this.south, west = this.west, e = this.east, c = this.center,
12769 b, m, totalWidth, totalHeight;
12770 if(!c && Ext.layout.BorderLayout.WARN !== false){
12771 throw 'No center region defined in BorderLayout ' + ct.id;
12774 if(n && n.isVisible()){
12776 m = n.getMargins();
12777 b.width = w - (m.left+m.right);
12780 centerY = b.height + b.y + m.bottom;
12781 centerH -= centerY;
12784 if(s && s.isVisible()){
12786 m = s.getMargins();
12787 b.width = w - (m.left+m.right);
12789 totalHeight = (b.height + m.top + m.bottom);
12790 b.y = h - totalHeight + m.top;
12791 centerH -= totalHeight;
12794 if(west && west.isVisible()){
12795 b = west.getSize();
12796 m = west.getMargins();
12797 b.height = centerH - (m.top+m.bottom);
12799 b.y = centerY + m.top;
12800 totalWidth = (b.width + m.left + m.right);
12801 centerX += totalWidth;
12802 centerW -= totalWidth;
12803 west.applyLayout(b);
12805 if(e && e.isVisible()){
12807 m = e.getMargins();
12808 b.height = centerH - (m.top+m.bottom);
12809 totalWidth = (b.width + m.left + m.right);
12810 b.x = w - totalWidth + m.left;
12811 b.y = centerY + m.top;
12812 centerW -= totalWidth;
12816 m = c.getMargins();
12818 x: centerX + m.left,
12819 y: centerY + m.top,
12820 width: centerW - (m.left+m.right),
12821 height: centerH - (m.top+m.bottom)
12823 c.applyLayout(centerBox);
12826 for(i = 0, len = collapsed.length; i < len; i++){
12827 collapsed[i].collapse(false);
12830 if(Ext.isIE && Ext.isStrict){
12834 if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) {
12835 var ts = this.getLayoutTargetSize();
12836 if (ts.width != size.width || ts.height != size.height){
12837 this.adjustmentPass = true;
12838 this.onLayout(ct, target);
12841 delete this.adjustmentPass;
12844 destroy: function() {
12845 var r = ['north', 'south', 'east', 'west'], i, region;
12846 for (i = 0; i < r.length; i++) {
12847 region = this[r[i]];
12849 if(region.destroy){
12851 }else if (region.split){
12852 region.split.destroy(true);
12856 Ext.layout.BorderLayout.superclass.destroy.call(this);
12863 Ext.layout.BorderLayout.Region = function(layout, config, pos){
12864 Ext.apply(this, config);
12865 this.layout = layout;
12866 this.position = pos;
12868 if(typeof this.margins == 'string'){
12869 this.margins = this.layout.parseMargins(this.margins);
12871 this.margins = Ext.applyIf(this.margins || {}, this.defaultMargins);
12872 if(this.collapsible){
12873 if(typeof this.cmargins == 'string'){
12874 this.cmargins = this.layout.parseMargins(this.cmargins);
12876 if(this.collapseMode == 'mini' && !this.cmargins){
12877 this.cmargins = {left:0,top:0,right:0,bottom:0};
12879 this.cmargins = Ext.applyIf(this.cmargins || {},
12880 pos == 'north' || pos == 'south' ? this.defaultNSCMargins : this.defaultEWCMargins);
12885 Ext.layout.BorderLayout.Region.prototype = {
12892 collapsible : false,
12903 defaultMargins : {left:0,top:0,right:0,bottom:0},
12905 defaultNSCMargins : {left:5,top:5,right:5,bottom:5},
12907 defaultEWCMargins : {left:5,top:0,right:5,bottom:0},
12908 floatingZIndex: 100,
12911 isCollapsed : false,
12918 render : function(ct, p){
12920 p.el.enableDisplayMode();
12921 this.targetEl = ct;
12924 var gs = p.getState, ps = this.position;
12925 p.getState = function(){
12926 return Ext.apply(gs.call(p) || {}, this.state);
12927 }.createDelegate(this);
12929 if(ps != 'center'){
12930 p.allowQueuedExpand = false;
12932 beforecollapse: this.beforeCollapse,
12933 collapse: this.onCollapse,
12934 beforeexpand: this.beforeExpand,
12935 expand: this.onExpand,
12940 if(this.collapsible || this.floatable){
12941 p.collapseEl = 'el';
12942 p.slideAnchor = this.getSlideAnchor();
12944 if(p.tools && p.tools.toggle){
12945 p.tools.toggle.addClass('x-tool-collapse-'+ps);
12946 p.tools.toggle.addClassOnOver('x-tool-collapse-'+ps+'-over');
12952 getCollapsedEl : function(){
12953 if(!this.collapsedEl){
12954 if(!this.toolTemplate){
12955 var tt = new Ext.Template(
12956 '<div class="x-tool x-tool-{id}"> </div>'
12958 tt.disableFormats = true;
12960 Ext.layout.BorderLayout.Region.prototype.toolTemplate = tt;
12962 this.collapsedEl = this.targetEl.createChild({
12963 cls: "x-layout-collapsed x-layout-collapsed-"+this.position,
12964 id: this.panel.id + '-xcollapsed'
12966 this.collapsedEl.enableDisplayMode('block');
12968 if(this.collapseMode == 'mini'){
12969 this.collapsedEl.addClass('x-layout-cmini-'+this.position);
12970 this.miniCollapsedEl = this.collapsedEl.createChild({
12971 cls: "x-layout-mini x-layout-mini-"+this.position, html: " "
12973 this.miniCollapsedEl.addClassOnOver('x-layout-mini-over');
12974 this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
12975 this.collapsedEl.on('click', this.onExpandClick, this, {stopEvent:true});
12977 if(this.collapsible !== false && !this.hideCollapseTool) {
12978 var t = this.expandToolEl = this.toolTemplate.append(
12979 this.collapsedEl.dom,
12980 {id:'expand-'+this.position}, true);
12981 t.addClassOnOver('x-tool-expand-'+this.position+'-over');
12982 t.on('click', this.onExpandClick, this, {stopEvent:true});
12984 if(this.floatable !== false || this.titleCollapse){
12985 this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
12986 this.collapsedEl.on("click", this[this.floatable ? 'collapseClick' : 'onExpandClick'], this);
12990 return this.collapsedEl;
12994 onExpandClick : function(e){
12996 this.panel.expand(false);
12998 this.panel.expand();
13003 onCollapseClick : function(e){
13004 this.panel.collapse();
13008 beforeCollapse : function(p, animate){
13009 this.lastAnim = animate;
13011 this.splitEl.hide();
13013 this.getCollapsedEl().show();
13014 var el = this.panel.getEl();
13015 this.originalZIndex = el.getStyle('z-index');
13016 el.setStyle('z-index', 100);
13017 this.isCollapsed = true;
13018 this.layout.layout();
13022 onCollapse : function(animate){
13023 this.panel.el.setStyle('z-index', 1);
13024 if(this.lastAnim === false || this.panel.animCollapse === false){
13025 this.getCollapsedEl().dom.style.visibility = 'visible';
13027 this.getCollapsedEl().slideIn(this.panel.slideAnchor, {duration:.2});
13029 this.state.collapsed = true;
13030 this.panel.saveState();
13034 beforeExpand : function(animate){
13036 this.afterSlideIn();
13038 var c = this.getCollapsedEl();
13040 if(this.position == 'east' || this.position == 'west'){
13041 this.panel.setSize(undefined, c.getHeight());
13043 this.panel.setSize(c.getWidth(), undefined);
13046 c.dom.style.visibility = 'hidden';
13047 this.panel.el.setStyle('z-index', this.floatingZIndex);
13051 onExpand : function(){
13052 this.isCollapsed = false;
13054 this.splitEl.show();
13056 this.layout.layout();
13057 this.panel.el.setStyle('z-index', this.originalZIndex);
13058 this.state.collapsed = false;
13059 this.panel.saveState();
13063 collapseClick : function(e){
13065 e.stopPropagation();
13068 e.stopPropagation();
13074 onHide : function(){
13075 if(this.isCollapsed){
13076 this.getCollapsedEl().hide();
13077 }else if(this.splitEl){
13078 this.splitEl.hide();
13083 onShow : function(){
13084 if(this.isCollapsed){
13085 this.getCollapsedEl().show();
13086 }else if(this.splitEl){
13087 this.splitEl.show();
13092 isVisible : function(){
13093 return !this.panel.hidden;
13097 getMargins : function(){
13098 return this.isCollapsed && this.cmargins ? this.cmargins : this.margins;
13102 getSize : function(){
13103 return this.isCollapsed ? this.getCollapsedEl().getSize() : this.panel.getSize();
13107 setPanel : function(panel){
13108 this.panel = panel;
13112 getMinWidth: function(){
13113 return this.minWidth;
13117 getMinHeight: function(){
13118 return this.minHeight;
13122 applyLayoutCollapsed : function(box){
13123 var ce = this.getCollapsedEl();
13124 ce.setLeftTop(box.x, box.y);
13125 ce.setSize(box.width, box.height);
13129 applyLayout : function(box){
13130 if(this.isCollapsed){
13131 this.applyLayoutCollapsed(box);
13133 this.panel.setPosition(box.x, box.y);
13134 this.panel.setSize(box.width, box.height);
13139 beforeSlide: function(){
13140 this.panel.beforeEffect();
13144 afterSlide : function(){
13145 this.panel.afterEffect();
13149 initAutoHide : function(){
13150 if(this.autoHide !== false){
13151 if(!this.autoHideHd){
13152 this.autoHideSlideTask = new Ext.util.DelayedTask(this.slideIn, this);
13153 this.autoHideHd = {
13154 "mouseout": function(e){
13155 if(!e.within(this.el, true)){
13156 this.autoHideSlideTask.delay(500);
13159 "mouseover" : function(e){
13160 this.autoHideSlideTask.cancel();
13165 this.el.on(this.autoHideHd);
13166 this.collapsedEl.on(this.autoHideHd);
13171 clearAutoHide : function(){
13172 if(this.autoHide !== false){
13173 this.el.un("mouseout", this.autoHideHd.mouseout);
13174 this.el.un("mouseover", this.autoHideHd.mouseover);
13175 this.collapsedEl.un("mouseout", this.autoHideHd.mouseout);
13176 this.collapsedEl.un("mouseover", this.autoHideHd.mouseover);
13181 clearMonitor : function(){
13182 Ext.getDoc().un("click", this.slideInIf, this);
13186 slideOut : function(){
13187 if(this.isSlid || this.el.hasActiveFx()){
13190 this.isSlid = true;
13191 var ts = this.panel.tools, dh, pc;
13192 if(ts && ts.toggle){
13198 pc = this.panel.collapsed;
13199 this.panel.collapsed = false;
13201 if(this.position == 'east' || this.position == 'west'){
13203 dh = this.panel.deferHeight;
13204 this.panel.deferHeight = false;
13206 this.panel.setSize(undefined, this.collapsedEl.getHeight());
13209 this.panel.deferHeight = dh;
13211 this.panel.setSize(this.collapsedEl.getWidth(), undefined);
13215 this.panel.collapsed = pc;
13217 this.restoreLT = [this.el.dom.style.left, this.el.dom.style.top];
13218 this.el.alignTo(this.collapsedEl, this.getCollapseAnchor());
13219 this.el.setStyle("z-index", this.floatingZIndex+2);
13220 this.panel.el.replaceClass('x-panel-collapsed', 'x-panel-floating');
13221 if(this.animFloat !== false){
13222 this.beforeSlide();
13223 this.el.slideIn(this.getSlideAnchor(), {
13224 callback: function(){
13226 this.initAutoHide();
13227 Ext.getDoc().on("click", this.slideInIf, this);
13233 this.initAutoHide();
13234 Ext.getDoc().on("click", this.slideInIf, this);
13239 afterSlideIn : function(){
13240 this.clearAutoHide();
13241 this.isSlid = false;
13242 this.clearMonitor();
13243 this.el.setStyle("z-index", "");
13244 this.panel.el.replaceClass('x-panel-floating', 'x-panel-collapsed');
13245 this.el.dom.style.left = this.restoreLT[0];
13246 this.el.dom.style.top = this.restoreLT[1];
13248 var ts = this.panel.tools;
13249 if(ts && ts.toggle){
13255 slideIn : function(cb){
13256 if(!this.isSlid || this.el.hasActiveFx()){
13260 this.isSlid = false;
13261 if(this.animFloat !== false){
13262 this.beforeSlide();
13263 this.el.slideOut(this.getSlideAnchor(), {
13264 callback: function(){
13267 this.afterSlideIn();
13275 this.afterSlideIn();
13280 slideInIf : function(e){
13281 if(!e.within(this.el)){
13311 getAnchor : function(){
13312 return this.anchors[this.position];
13316 getCollapseAnchor : function(){
13317 return this.canchors[this.position];
13321 getSlideAnchor : function(){
13322 return this.sanchors[this.position];
13326 getAlignAdj : function(){
13327 var cm = this.cmargins;
13328 switch(this.position){
13345 getExpandAdj : function(){
13346 var c = this.collapsedEl, cm = this.cmargins;
13347 switch(this.position){
13349 return [-(cm.right+c.getWidth()+cm.left), 0];
13352 return [cm.right+c.getWidth()+cm.left, 0];
13355 return [0, -(cm.top+cm.bottom+c.getHeight())];
13358 return [0, cm.top+cm.bottom+c.getHeight()];
13363 destroy : function(){
13364 if (this.autoHideSlideTask && this.autoHideSlideTask.cancel){
13365 this.autoHideSlideTask.cancel();
13367 Ext.destroyMembers(this, 'miniCollapsedEl', 'collapsedEl', 'expandToolEl');
13372 Ext.layout.BorderLayout.SplitRegion = function(layout, config, pos){
13373 Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this, layout, config, pos);
13375 this.applyLayout = this.applyFns[pos];
13378 Ext.extend(Ext.layout.BorderLayout.SplitRegion, Ext.layout.BorderLayout.Region, {
13381 splitTip : "Drag to resize.",
13383 collapsibleSplitTip : "Drag to resize. Double click to hide.",
13385 useSplitTips : false,
13390 orientation: Ext.SplitBar.VERTICAL,
13391 placement: Ext.SplitBar.TOP,
13392 maxFn : 'getVMaxSize',
13393 minProp: 'minHeight',
13394 maxProp: 'maxHeight'
13397 orientation: Ext.SplitBar.VERTICAL,
13398 placement: Ext.SplitBar.BOTTOM,
13399 maxFn : 'getVMaxSize',
13400 minProp: 'minHeight',
13401 maxProp: 'maxHeight'
13404 orientation: Ext.SplitBar.HORIZONTAL,
13405 placement: Ext.SplitBar.RIGHT,
13406 maxFn : 'getHMaxSize',
13407 minProp: 'minWidth',
13408 maxProp: 'maxWidth'
13411 orientation: Ext.SplitBar.HORIZONTAL,
13412 placement: Ext.SplitBar.LEFT,
13413 maxFn : 'getHMaxSize',
13414 minProp: 'minWidth',
13415 maxProp: 'maxWidth'
13421 west : function(box){
13422 if(this.isCollapsed){
13423 return this.applyLayoutCollapsed(box);
13425 var sd = this.splitEl.dom, s = sd.style;
13426 this.panel.setPosition(box.x, box.y);
13427 var sw = sd.offsetWidth;
13428 s.left = (box.x+box.width-sw)+'px';
13429 s.top = (box.y)+'px';
13430 s.height = Math.max(0, box.height)+'px';
13431 this.panel.setSize(box.width-sw, box.height);
13433 east : function(box){
13434 if(this.isCollapsed){
13435 return this.applyLayoutCollapsed(box);
13437 var sd = this.splitEl.dom, s = sd.style;
13438 var sw = sd.offsetWidth;
13439 this.panel.setPosition(box.x+sw, box.y);
13440 s.left = (box.x)+'px';
13441 s.top = (box.y)+'px';
13442 s.height = Math.max(0, box.height)+'px';
13443 this.panel.setSize(box.width-sw, box.height);
13445 north : function(box){
13446 if(this.isCollapsed){
13447 return this.applyLayoutCollapsed(box);
13449 var sd = this.splitEl.dom, s = sd.style;
13450 var sh = sd.offsetHeight;
13451 this.panel.setPosition(box.x, box.y);
13452 s.left = (box.x)+'px';
13453 s.top = (box.y+box.height-sh)+'px';
13454 s.width = Math.max(0, box.width)+'px';
13455 this.panel.setSize(box.width, box.height-sh);
13457 south : function(box){
13458 if(this.isCollapsed){
13459 return this.applyLayoutCollapsed(box);
13461 var sd = this.splitEl.dom, s = sd.style;
13462 var sh = sd.offsetHeight;
13463 this.panel.setPosition(box.x, box.y+sh);
13464 s.left = (box.x)+'px';
13465 s.top = (box.y)+'px';
13466 s.width = Math.max(0, box.width)+'px';
13467 this.panel.setSize(box.width, box.height-sh);
13472 render : function(ct, p){
13473 Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p);
13475 var ps = this.position;
13477 this.splitEl = ct.createChild({
13478 cls: "x-layout-split x-layout-split-"+ps, html: " ",
13479 id: this.panel.id + '-xsplit'
13482 if(this.collapseMode == 'mini'){
13483 this.miniSplitEl = this.splitEl.createChild({
13484 cls: "x-layout-mini x-layout-mini-"+ps, html: " "
13486 this.miniSplitEl.addClassOnOver('x-layout-mini-over');
13487 this.miniSplitEl.on('click', this.onCollapseClick, this, {stopEvent:true});
13490 var s = this.splitSettings[ps];
13492 this.split = new Ext.SplitBar(this.splitEl.dom, p.el, s.orientation);
13493 this.split.tickSize = this.tickSize;
13494 this.split.placement = s.placement;
13495 this.split.getMaximumSize = this[s.maxFn].createDelegate(this);
13496 this.split.minSize = this.minSize || this[s.minProp];
13497 this.split.on("beforeapply", this.onSplitMove, this);
13498 this.split.useShim = this.useShim === true;
13499 this.maxSize = this.maxSize || this[s.maxProp];
13502 this.splitEl.hide();
13505 if(this.useSplitTips){
13506 this.splitEl.dom.title = this.collapsible ? this.collapsibleSplitTip : this.splitTip;
13508 if(this.collapsible){
13509 this.splitEl.on("dblclick", this.onCollapseClick, this);
13514 getSize : function(){
13515 if(this.isCollapsed){
13516 return this.collapsedEl.getSize();
13518 var s = this.panel.getSize();
13519 if(this.position == 'north' || this.position == 'south'){
13520 s.height += this.splitEl.dom.offsetHeight;
13522 s.width += this.splitEl.dom.offsetWidth;
13528 getHMaxSize : function(){
13529 var cmax = this.maxSize || 10000;
13530 var center = this.layout.center;
13531 return Math.min(cmax, (this.el.getWidth()+center.el.getWidth())-center.getMinWidth());
13535 getVMaxSize : function(){
13536 var cmax = this.maxSize || 10000;
13537 var center = this.layout.center;
13538 return Math.min(cmax, (this.el.getHeight()+center.el.getHeight())-center.getMinHeight());
13542 onSplitMove : function(split, newSize){
13543 var s = this.panel.getSize();
13544 this.lastSplitSize = newSize;
13545 if(this.position == 'north' || this.position == 'south'){
13546 this.panel.setSize(s.width, newSize);
13547 this.state.height = newSize;
13549 this.panel.setSize(newSize, s.height);
13550 this.state.width = newSize;
13552 this.layout.layout();
13553 this.panel.saveState();
13558 getSplitBar : function(){
13563 destroy : function() {
13564 Ext.destroy(this.miniSplitEl, this.split, this.splitEl);
13565 Ext.layout.BorderLayout.SplitRegion.superclass.destroy.call(this);
13569 Ext.Container.LAYOUTS['border'] = Ext.layout.BorderLayout;
13571 Ext.layout.FormLayout = Ext.extend(Ext.layout.AnchorLayout, {
13574 labelSeparator : ':',
13579 trackLabels: false,
13583 onRemove: function(c){
13584 Ext.layout.FormLayout.superclass.onRemove.call(this, c);
13585 if(this.trackLabels){
13586 c.un('show', this.onFieldShow, this);
13587 c.un('hide', this.onFieldHide, this);
13590 var el = c.getPositionEl(),
13591 ct = c.getItemCt && c.getItemCt();
13592 if (c.rendered && ct) {
13593 if (el && el.dom) {
13594 el.insertAfter(ct);
13597 Ext.destroyMembers(c, 'label', 'itemCt');
13598 if (c.customItemCt) {
13599 Ext.destroyMembers(c, 'getItemCt', 'customItemCt');
13605 setContainer : function(ct){
13606 Ext.layout.FormLayout.superclass.setContainer.call(this, ct);
13608 ct.addClass('x-form-label-'+ct.labelAlign);
13613 labelStyle: 'display:none',
13614 elementStyle: 'padding-left:0;',
13618 this.labelSeparator = Ext.isDefined(ct.labelSeparator) ? ct.labelSeparator : this.labelSeparator;
13619 ct.labelWidth = ct.labelWidth || 100;
13620 if(Ext.isNumber(ct.labelWidth)){
13621 var pad = Ext.isNumber(ct.labelPad) ? ct.labelPad : 5;
13623 labelAdjust: ct.labelWidth + pad,
13624 labelStyle: 'width:' + ct.labelWidth + 'px;',
13625 elementStyle: 'padding-left:' + (ct.labelWidth + pad) + 'px'
13628 if(ct.labelAlign == 'top'){
13630 labelStyle: 'width:auto;',
13632 elementStyle: 'padding-left:0;'
13639 isHide: function(c){
13640 return c.hideLabel || this.container.hideLabels;
13643 onFieldShow: function(c){
13644 c.getItemCt().removeClass('x-hide-' + c.hideMode);
13647 if (c.isComposite) {
13652 onFieldHide: function(c){
13653 c.getItemCt().addClass('x-hide-' + c.hideMode);
13657 getLabelStyle: function(s){
13658 var ls = '', items = [this.labelStyle, s];
13659 for (var i = 0, len = items.length; i < len; ++i){
13662 if (ls.substr(-1, 1) != ';'){
13673 renderItem : function(c, position, target){
13674 if(c && (c.isFormField || c.fieldLabel) && c.inputType != 'hidden'){
13675 var args = this.getTemplateArgs(c);
13676 if(Ext.isNumber(position)){
13677 position = target.dom.childNodes[position] || null;
13680 c.itemCt = this.fieldTpl.insertBefore(position, args, true);
13682 c.itemCt = this.fieldTpl.append(target, args, true);
13688 getItemCt: function(){
13694 c.label = c.getItemCt().child('label.x-form-item-label');
13696 c.render('x-form-el-' + c.id);
13697 }else if(!this.isValidParent(c, target)){
13698 Ext.fly('x-form-el-' + c.id).appendChild(c.getPositionEl());
13700 if(this.trackLabels){
13702 this.onFieldHide(c);
13706 show: this.onFieldShow,
13707 hide: this.onFieldHide
13710 this.configureItem(c);
13712 Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
13717 getTemplateArgs: function(field) {
13718 var noLabelSep = !field.fieldLabel || field.hideLabel;
13722 label : field.fieldLabel,
13723 itemCls : (field.itemCls || this.container.itemCls || '') + (field.hideLabel ? ' x-hide-label' : ''),
13724 clearCls : field.clearCls || 'x-form-clear-left',
13725 labelStyle : this.getLabelStyle(field.labelStyle),
13726 elementStyle : this.elementStyle || '',
13727 labelSeparator: noLabelSep ? '' : (Ext.isDefined(field.labelSeparator) ? field.labelSeparator : this.labelSeparator)
13732 adjustWidthAnchor: function(value, c){
13733 if(c.label && !this.isHide(c) && (this.container.labelAlign != 'top')){
13734 var adjust = Ext.isIE6 || (Ext.isIE && !Ext.isStrict);
13735 return value - this.labelAdjust + (adjust ? -3 : 0);
13740 adjustHeightAnchor : function(value, c){
13741 if(c.label && !this.isHide(c) && (this.container.labelAlign == 'top')){
13742 return value - c.label.getHeight();
13748 isValidParent : function(c, target){
13749 return target && this.container.getEl().contains(c.getPositionEl());
13755 Ext.Container.LAYOUTS['form'] = Ext.layout.FormLayout;
13757 Ext.layout.AccordionLayout = Ext.extend(Ext.layout.FitLayout, {
13763 titleCollapse : true,
13765 hideCollapseTool : false,
13767 collapseFirst : false,
13773 activeOnTop : false,
13777 renderItem : function(c){
13778 if(this.animate === false){
13779 c.animCollapse = false;
13781 c.collapsible = true;
13782 if(this.autoWidth){
13783 c.autoWidth = true;
13785 if(this.titleCollapse){
13786 c.titleCollapse = true;
13788 if(this.hideCollapseTool){
13789 c.hideCollapseTool = true;
13791 if(this.collapseFirst !== undefined){
13792 c.collapseFirst = this.collapseFirst;
13794 if(!this.activeItem && !c.collapsed){
13795 this.setActiveItem(c, true);
13796 }else if(this.activeItem && this.activeItem != c){
13797 c.collapsed = true;
13799 Ext.layout.AccordionLayout.superclass.renderItem.apply(this, arguments);
13800 c.header.addClass('x-accordion-hd');
13801 c.on('beforeexpand', this.beforeExpand, this);
13804 onRemove: function(c){
13805 Ext.layout.AccordionLayout.superclass.onRemove.call(this, c);
13807 c.header.removeClass('x-accordion-hd');
13809 c.un('beforeexpand', this.beforeExpand, this);
13813 beforeExpand : function(p, anim){
13814 var ai = this.activeItem;
13817 delete this.activeItem;
13818 if (!ai.collapsed){
13819 ai.collapse({callback:function(){
13820 p.expand(anim || true);
13825 ai.collapse(this.animate);
13829 if(this.activeOnTop){
13830 p.el.dom.parentNode.insertBefore(p.el.dom, p.el.dom.parentNode.firstChild);
13837 setItemSize : function(item, size){
13838 if(this.fill && item){
13839 var hh = 0, i, ct = this.getRenderedItems(this.container), len = ct.length, p;
13841 for (i = 0; i < len; i++) {
13842 if((p = ct[i]) != item && !p.hidden){
13843 hh += p.header.getHeight();
13850 item.setSize(size);
13855 setActiveItem : function(item){
13856 this.setActive(item, true);
13860 setActive : function(item, expand){
13861 var ai = this.activeItem;
13862 item = this.container.getComponent(item);
13864 if(item.rendered && item.collapsed && expand){
13868 ai.fireEvent('deactivate', ai);
13870 this.activeItem = item;
13871 item.fireEvent('activate', item);
13876 Ext.Container.LAYOUTS.accordion = Ext.layout.AccordionLayout;
13879 Ext.layout.Accordion = Ext.layout.AccordionLayout;
13880 Ext.layout.TableLayout = Ext.extend(Ext.layout.ContainerLayout, {
13884 monitorResize:false,
13888 targetCls: 'x-table-layout-ct',
13894 setContainer : function(ct){
13895 Ext.layout.TableLayout.superclass.setContainer.call(this, ct);
13897 this.currentRow = 0;
13898 this.currentColumn = 0;
13903 onLayout : function(ct, target){
13904 var cs = ct.items.items, len = cs.length, c, i;
13907 target.addClass('x-table-layout-ct');
13909 this.table = target.createChild(
13910 Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
13912 this.renderAll(ct, target);
13916 getRow : function(index){
13917 var row = this.table.tBodies[0].childNodes[index];
13919 row = document.createElement('tr');
13920 this.table.tBodies[0].appendChild(row);
13926 getNextCell : function(c){
13927 var cell = this.getNextNonSpan(this.currentColumn, this.currentRow);
13928 var curCol = this.currentColumn = cell[0], curRow = this.currentRow = cell[1];
13929 for(var rowIndex = curRow; rowIndex < curRow + (c.rowspan || 1); rowIndex++){
13930 if(!this.cells[rowIndex]){
13931 this.cells[rowIndex] = [];
13933 for(var colIndex = curCol; colIndex < curCol + (c.colspan || 1); colIndex++){
13934 this.cells[rowIndex][colIndex] = true;
13937 var td = document.createElement('td');
13941 var cls = 'x-table-layout-cell';
13943 cls += ' ' + c.cellCls;
13945 td.className = cls;
13947 td.colSpan = c.colspan;
13950 td.rowSpan = c.rowspan;
13952 this.getRow(curRow).appendChild(td);
13957 getNextNonSpan: function(colIndex, rowIndex){
13958 var cols = this.columns;
13959 while((cols && colIndex >= cols) || (this.cells[rowIndex] && this.cells[rowIndex][colIndex])) {
13960 if(cols && colIndex >= cols){
13967 return [colIndex, rowIndex];
13971 renderItem : function(c, position, target){
13974 this.table = target.createChild(
13975 Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
13977 if(c && !c.rendered){
13978 c.render(this.getNextCell(c));
13979 this.configureItem(c, position);
13980 }else if(c && !this.isValidParent(c, target)){
13981 var container = this.getNextCell(c);
13982 container.insertBefore(c.getPositionEl().dom, null);
13983 c.container = Ext.get(container);
13984 this.configureItem(c, position);
13989 isValidParent : function(c, target){
13990 return c.getPositionEl().up('table', 5).dom.parentNode === (target.dom || target);
13993 destroy: function(){
13995 Ext.layout.TableLayout.superclass.destroy.call(this);
14001 Ext.Container.LAYOUTS['table'] = Ext.layout.TableLayout;
14002 Ext.layout.AbsoluteLayout = Ext.extend(Ext.layout.AnchorLayout, {
14004 extraCls: 'x-abs-layout-item',
14008 onLayout : function(ct, target){
14010 this.paddingLeft = target.getPadding('l');
14011 this.paddingTop = target.getPadding('t');
14012 Ext.layout.AbsoluteLayout.superclass.onLayout.call(this, ct, target);
14016 adjustWidthAnchor : function(value, comp){
14017 return value ? value - comp.getPosition(true)[0] + this.paddingLeft : value;
14021 adjustHeightAnchor : function(value, comp){
14022 return value ? value - comp.getPosition(true)[1] + this.paddingTop : value;
14026 Ext.Container.LAYOUTS['absolute'] = Ext.layout.AbsoluteLayout;
14028 Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, {
14030 defaultMargins : {left:0,top:0,right:0,bottom:0},
14037 monitorResize : true,
14040 extraCls : 'x-box-item',
14041 targetCls : 'x-box-layout-ct',
14042 innerCls : 'x-box-inner',
14044 constructor : function(config){
14045 Ext.layout.BoxLayout.superclass.constructor.call(this, config);
14047 if (Ext.isString(this.defaultMargins)) {
14048 this.defaultMargins = this.parseMargins(this.defaultMargins);
14053 onLayout: function(container, target) {
14054 Ext.layout.BoxLayout.superclass.onLayout.call(this, container, target);
14056 var items = this.getVisibleItems(container),
14057 tSize = this.getLayoutTargetSize();
14060 this.layoutTargetLastSize = tSize;
14063 this.childBoxCache = this.calculateChildBoxes(items, tSize);
14065 this.updateInnerCtSize(tSize, this.childBoxCache);
14066 this.updateChildBoxes(this.childBoxCache.boxes);
14069 this.handleTargetOverflow(tSize, container, target);
14073 updateChildBoxes: function(boxes) {
14074 for (var i = 0, length = boxes.length; i < length; i++) {
14075 var box = boxes[i],
14076 comp = box.component;
14078 if (box.dirtySize) {
14079 comp.setSize(box.width, box.height);
14082 if (isNaN(box.left) || isNaN(box.top)) {
14085 comp.setPosition(box.left, box.top);
14090 updateInnerCtSize: Ext.emptyFn,
14093 handleTargetOverflow: function(previousTargetSize, container, target) {
14094 var overflow = target.getStyle('overflow');
14096 if (overflow && overflow != 'hidden' &&!this.adjustmentPass) {
14097 var newTargetSize = this.getLayoutTargetSize();
14098 if (newTargetSize.width != previousTargetSize.width || newTargetSize.height != previousTargetSize.height){
14099 this.adjustmentPass = true;
14100 this.onLayout(container, target);
14104 delete this.adjustmentPass;
14108 isValidParent : function(c, target){
14109 return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom;
14113 getVisibleItems: function(ct) {
14114 var ct = ct || this.container,
14115 t = ct.getLayoutTarget(),
14116 cti = ct.items.items,
14121 for (i = 0; i < len; i++) {
14122 if((c = cti[i]).rendered && this.isValidParent(c, t) && c.hidden !== true && c.collapsed !== true){
14131 renderAll : function(ct, target){
14135 this.innerCt = target.createChild({cls:this.innerCls});
14136 this.padding = this.parseMargins(this.padding);
14138 Ext.layout.BoxLayout.superclass.renderAll.call(this, ct, this.innerCt);
14141 getLayoutTargetSize : function(){
14142 var target = this.container.getLayoutTarget(), ret;
14144 ret = target.getViewSize();
14149 if (Ext.isIE && Ext.isStrict && ret.width == 0){
14150 ret = target.getStyleSize();
14153 ret.width -= target.getPadding('lr');
14154 ret.height -= target.getPadding('tb');
14160 renderItem : function(c){
14161 if(Ext.isString(c.margins)){
14162 c.margins = this.parseMargins(c.margins);
14163 }else if(!c.margins){
14164 c.margins = this.defaultMargins;
14166 Ext.layout.BoxLayout.superclass.renderItem.apply(this, arguments);
14171 Ext.layout.VBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
14181 updateInnerCtSize: function(tSize, calcs) {
14182 var innerCtHeight = tSize.height,
14183 innerCtWidth = calcs.meta.maxWidth + this.padding.left + this.padding.right;
14185 if (this.align == 'stretch') {
14186 innerCtWidth = tSize.width;
14187 } else if (this.align == 'center') {
14188 innerCtWidth = Math.max(tSize.width, innerCtWidth);
14193 this.innerCt.setSize(innerCtWidth || undefined, innerCtHeight || undefined);
14197 calculateChildBoxes: function(visibleItems, targetSize) {
14198 var visibleCount = visibleItems.length,
14200 padding = this.padding,
14201 topOffset = padding.top,
14202 leftOffset = padding.left,
14203 paddingVert = topOffset + padding.bottom,
14204 paddingHoriz = leftOffset + padding.right,
14206 width = targetSize.width - this.scrollOffset,
14207 height = targetSize.height,
14208 availWidth = Math.max(0, width - paddingHoriz),
14210 isStart = this.pack == 'start',
14211 isCenter = this.pack == 'center',
14212 isEnd = this.pack == 'end',
14222 child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedHeight, horizMargins, stretchWidth;
14225 for (i = 0; i < visibleCount; i++) {
14226 child = visibleItems[i];
14227 childHeight = child.height;
14228 childWidth = child.width;
14229 canLayout = !child.hasLayout && Ext.isFunction(child.doLayout);
14233 if (!Ext.isNumber(childHeight)) {
14236 if (child.flex && !childHeight) {
14237 totalFlex += child.flex;
14243 if (!childHeight && canLayout) {
14247 childSize = child.getSize();
14248 childWidth = childSize.width;
14249 childHeight = childSize.height;
14253 childMargins = child.margins;
14255 nonFlexHeight += (childHeight || 0) + childMargins.top + childMargins.bottom;
14258 if (!Ext.isNumber(childWidth)) {
14262 childWidth = child.getWidth();
14265 maxWidth = Math.max(maxWidth, childWidth + childMargins.left + childMargins.right);
14270 height : childHeight || undefined,
14271 width : childWidth || undefined
14276 var availableHeight = Math.max(0, (height - nonFlexHeight - paddingVert));
14279 topOffset += availableHeight / 2;
14280 } else if (isEnd) {
14281 topOffset += availableHeight;
14285 var remainingHeight = availableHeight,
14286 remainingFlex = totalFlex;
14289 for (i = 0; i < visibleCount; i++) {
14290 child = visibleItems[i];
14293 childMargins = child.margins;
14294 horizMargins = childMargins.left + childMargins.right;
14296 topOffset += childMargins.top;
14298 if (isStart && child.flex && !child.height) {
14299 flexedHeight = Math.ceil((child.flex / remainingFlex) * remainingHeight);
14300 remainingHeight -= flexedHeight;
14301 remainingFlex -= child.flex;
14303 calcs.height = flexedHeight;
14304 calcs.dirtySize = true;
14307 calcs.left = leftOffset + childMargins.left;
14308 calcs.top = topOffset;
14310 switch (this.align) {
14312 stretchWidth = availWidth - horizMargins;
14313 calcs.width = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000);
14314 calcs.dirtySize = true;
14317 stretchWidth = maxWidth - horizMargins;
14318 calcs.width = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000);
14319 calcs.dirtySize = true;
14322 var diff = availWidth - calcs.width - horizMargins;
14324 calcs.left = leftOffset + horizMargins + (diff / 2);
14328 topOffset += calcs.height + childMargins.bottom;
14340 Ext.Container.LAYOUTS.vbox = Ext.layout.VBoxLayout;
14343 Ext.layout.HBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
14350 updateInnerCtSize: function(tSize, calcs) {
14351 var innerCtWidth = tSize.width,
14352 innerCtHeight = calcs.meta.maxHeight + this.padding.top + this.padding.bottom;
14354 if (this.align == 'stretch') {
14355 innerCtHeight = tSize.height;
14356 } else if (this.align == 'middle') {
14357 innerCtHeight = Math.max(tSize.height, innerCtHeight);
14360 this.innerCt.setSize(innerCtWidth || undefined, innerCtHeight || undefined);
14367 calculateChildBoxes: function(visibleItems, targetSize) {
14368 var visibleCount = visibleItems.length,
14370 padding = this.padding,
14371 topOffset = padding.top,
14372 leftOffset = padding.left,
14373 paddingVert = topOffset + padding.bottom,
14374 paddingHoriz = leftOffset + padding.right,
14376 width = targetSize.width - this.scrollOffset,
14377 height = targetSize.height,
14378 availHeight = Math.max(0, height - paddingVert),
14380 isStart = this.pack == 'start',
14381 isCenter = this.pack == 'center',
14382 isEnd = this.pack == 'end',
14393 child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedWidth, vertMargins, stretchHeight;
14396 for (i = 0; i < visibleCount; i++) {
14397 child = visibleItems[i];
14398 childHeight = child.height;
14399 childWidth = child.width;
14400 canLayout = !child.hasLayout && Ext.isFunction(child.doLayout);
14403 if (!Ext.isNumber(childWidth)) {
14406 if (child.flex && !childWidth) {
14407 totalFlex += child.flex;
14413 if (!childWidth && canLayout) {
14417 childSize = child.getSize();
14418 childWidth = childSize.width;
14419 childHeight = childSize.height;
14423 childMargins = child.margins;
14425 nonFlexWidth += (childWidth || 0) + childMargins.left + childMargins.right;
14428 if (!Ext.isNumber(childHeight)) {
14432 childHeight = child.getHeight();
14435 maxHeight = Math.max(maxHeight, childHeight + childMargins.top + childMargins.bottom);
14440 height : childHeight || undefined,
14441 width : childWidth || undefined
14446 var availableWidth = Math.max(0, (width - nonFlexWidth - paddingHoriz));
14449 leftOffset += availableWidth / 2;
14450 } else if (isEnd) {
14451 leftOffset += availableWidth;
14455 var remainingWidth = availableWidth,
14456 remainingFlex = totalFlex;
14459 for (i = 0; i < visibleCount; i++) {
14460 child = visibleItems[i];
14463 childMargins = child.margins;
14464 vertMargins = childMargins.top + childMargins.bottom;
14466 leftOffset += childMargins.left;
14468 if (isStart && child.flex && !child.width) {
14469 flexedWidth = Math.ceil((child.flex / remainingFlex) * remainingWidth);
14470 remainingWidth -= flexedWidth;
14471 remainingFlex -= child.flex;
14473 calcs.width = flexedWidth;
14474 calcs.dirtySize = true;
14477 calcs.left = leftOffset;
14478 calcs.top = topOffset + childMargins.top;
14480 switch (this.align) {
14482 stretchHeight = availHeight - vertMargins;
14483 calcs.height = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000);
14484 calcs.dirtySize = true;
14487 stretchHeight = maxHeight - vertMargins;
14488 calcs.height = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000);
14489 calcs.dirtySize = true;
14492 var diff = availHeight - calcs.height - vertMargins;
14494 calcs.top = topOffset + vertMargins + (diff / 2);
14497 leftOffset += calcs.width + childMargins.right;
14503 maxHeight: maxHeight
14509 Ext.Container.LAYOUTS.hbox = Ext.layout.HBoxLayout;
14511 Ext.layout.ToolbarLayout = Ext.extend(Ext.layout.ContainerLayout, {
14512 monitorResize : true,
14520 noItemsMenuText : '<div class="x-toolbar-no-items">(None)</div>',
14523 lastOverflow: false,
14527 '<table cellspacing="0" class="x-toolbar-ct">',
14530 '<td class="x-toolbar-left" align="{0}">',
14531 '<table cellspacing="0">',
14533 '<tr class="x-toolbar-left-row"></tr>',
14537 '<td class="x-toolbar-right" align="right">',
14538 '<table cellspacing="0" class="x-toolbar-right-ct">',
14542 '<table cellspacing="0">',
14544 '<tr class="x-toolbar-right-row"></tr>',
14549 '<table cellspacing="0">',
14551 '<tr class="x-toolbar-extras-row"></tr>',
14565 onLayout : function(ct, target) {
14567 if (!this.leftTr) {
14568 var align = ct.buttonAlign == 'center' ? 'center' : 'left';
14570 target.addClass('x-toolbar-layout-ct');
14571 target.insertHtml('beforeEnd', String.format(this.tableHTML, align));
14573 this.leftTr = target.child('tr.x-toolbar-left-row', true);
14574 this.rightTr = target.child('tr.x-toolbar-right-row', true);
14575 this.extrasTr = target.child('tr.x-toolbar-extras-row', true);
14577 if (this.hiddenItem == undefined) {
14579 this.hiddenItems = [];
14583 var side = ct.buttonAlign == 'right' ? this.rightTr : this.leftTr,
14584 items = ct.items.items,
14588 for (var i = 0, len = items.length, c; i < len; i++, position++) {
14592 side = this.rightTr;
14594 } else if (!c.rendered) {
14595 c.render(this.insertCell(c, side, position));
14597 if (!c.xtbHidden && !this.isValidParent(c, side.childNodes[position])) {
14598 var td = this.insertCell(c, side, position);
14599 td.appendChild(c.getPositionEl().dom);
14600 c.container = Ext.get(td);
14606 this.cleanup(this.leftTr);
14607 this.cleanup(this.rightTr);
14608 this.cleanup(this.extrasTr);
14609 this.fitToSize(target);
14613 cleanup : function(el) {
14614 var cn = el.childNodes, i, c;
14616 for (i = cn.length-1; i >= 0 && (c = cn[i]); i--) {
14617 if (!c.firstChild) {
14624 insertCell : function(c, target, position) {
14625 var td = document.createElement('td');
14626 td.className = 'x-toolbar-cell';
14628 target.insertBefore(td, target.childNodes[position] || null);
14634 hideItem : function(item) {
14635 this.hiddenItems.push(item);
14637 item.xtbHidden = true;
14638 item.xtbWidth = item.getPositionEl().dom.parentNode.offsetWidth;
14643 unhideItem : function(item) {
14645 item.xtbHidden = false;
14646 this.hiddenItems.remove(item);
14650 getItemWidth : function(c) {
14651 return c.hidden ? (c.xtbWidth || 0) : c.getPositionEl().dom.parentNode.offsetWidth;
14655 fitToSize : function(target) {
14656 if (this.container.enableOverflow === false) {
14660 var width = target.dom.clientWidth,
14661 tableWidth = target.dom.firstChild.offsetWidth,
14662 clipWidth = width - this.triggerWidth,
14663 lastWidth = this.lastWidth || 0,
14665 hiddenItems = this.hiddenItems,
14666 hasHiddens = hiddenItems.length != 0,
14667 isLarger = width >= lastWidth;
14669 this.lastWidth = width;
14671 if (tableWidth > width || (hasHiddens && isLarger)) {
14672 var items = this.container.items.items,
14673 len = items.length,
14677 for (var i = 0; i < len; i++) {
14680 if (!item.isFill) {
14681 loopWidth += this.getItemWidth(item);
14682 if (loopWidth > clipWidth) {
14683 if (!(item.hidden || item.xtbHidden)) {
14684 this.hideItem(item);
14686 } else if (item.xtbHidden) {
14687 this.unhideItem(item);
14694 hasHiddens = hiddenItems.length != 0;
14699 if (!this.lastOverflow) {
14700 this.container.fireEvent('overflowchange', this.container, true);
14701 this.lastOverflow = true;
14703 } else if (this.more) {
14705 this.more.destroy();
14708 if (this.lastOverflow) {
14709 this.container.fireEvent('overflowchange', this.container, false);
14710 this.lastOverflow = false;
14716 createMenuConfig : function(component, hideOnClick){
14717 var config = Ext.apply({}, component.initialConfig),
14718 group = component.toggleGroup;
14720 Ext.copyTo(config, component, [
14721 'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu'
14724 Ext.apply(config, {
14725 text : component.overflowText || component.text,
14726 hideOnClick: hideOnClick
14729 if (group || component.enableToggle) {
14730 Ext.apply(config, {
14732 checked: component.pressed,
14734 checkchange: function(item, checked){
14735 component.toggle(checked);
14741 delete config.ownerCt;
14742 delete config.xtype;
14749 addComponentToMenu : function(menu, component) {
14750 if (component instanceof Ext.Toolbar.Separator) {
14753 } else if (Ext.isFunction(component.isXType)) {
14754 if (component.isXType('splitbutton')) {
14755 menu.add(this.createMenuConfig(component, true));
14757 } else if (component.isXType('button')) {
14758 menu.add(this.createMenuConfig(component, !component.menu));
14760 } else if (component.isXType('buttongroup')) {
14761 component.items.each(function(item){
14762 this.addComponentToMenu(menu, item);
14769 clearMenu : function(){
14770 var menu = this.moreMenu;
14771 if (menu && menu.items) {
14772 menu.items.each(function(item){
14779 beforeMoreShow : function(menu) {
14780 var items = this.container.items.items,
14781 len = items.length,
14785 var needsSep = function(group, item){
14786 return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator);
14791 for (var i = 0; i < len; i++) {
14793 if (item.xtbHidden) {
14794 if (prev && (needsSep(item, prev) || needsSep(prev, item))) {
14797 this.addComponentToMenu(menu, item);
14803 if (menu.items.length < 1) {
14804 menu.add(this.noItemsMenuText);
14809 initMore : function(){
14812 this.moreMenu = new Ext.menu.Menu({
14813 ownerCt : this.container,
14815 beforeshow: this.beforeMoreShow,
14821 this.more = new Ext.Button({
14822 iconCls: 'x-toolbar-more-icon',
14823 cls : 'x-toolbar-more',
14824 menu : this.moreMenu,
14825 ownerCt: this.container
14828 var td = this.insertCell(this.more, this.extrasTr, 100);
14829 this.more.render(td);
14833 destroy : function(){
14834 Ext.destroy(this.more, this.moreMenu);
14835 delete this.leftTr;
14836 delete this.rightTr;
14837 delete this.extrasTr;
14838 Ext.layout.ToolbarLayout.superclass.destroy.call(this);
14842 Ext.Container.LAYOUTS.toolbar = Ext.layout.ToolbarLayout;
14844 Ext.layout.MenuLayout = Ext.extend(Ext.layout.ContainerLayout, {
14845 monitorResize : true,
14849 setContainer : function(ct){
14850 this.monitorResize = !ct.floating;
14853 ct.on('autosize', this.doAutoSize, this);
14854 Ext.layout.MenuLayout.superclass.setContainer.call(this, ct);
14857 renderItem : function(c, position, target){
14858 if (!this.itemTpl) {
14859 this.itemTpl = Ext.layout.MenuLayout.prototype.itemTpl = new Ext.XTemplate(
14860 '<li id="{itemId}" class="{itemCls}">',
14861 '<tpl if="needsIcon">',
14862 '<img src="{icon}" class="{iconCls}"/>',
14868 if(c && !c.rendered){
14869 if(Ext.isNumber(position)){
14870 position = target.dom.childNodes[position];
14872 var a = this.getItemArgs(c);
14875 c.render(c.positionEl = position ?
14876 this.itemTpl.insertBefore(position, a, true) :
14877 this.itemTpl.append(target, a, true));
14880 c.positionEl.menuItemId = c.getItemId();
14884 if (!a.isMenuItem && a.needsIcon) {
14885 c.positionEl.addClass('x-menu-list-item-indent');
14887 this.configureItem(c, position);
14888 }else if(c && !this.isValidParent(c, target)){
14889 if(Ext.isNumber(position)){
14890 position = target.dom.childNodes[position];
14892 target.dom.insertBefore(c.getActionEl().dom, position || null);
14896 getItemArgs : function(c) {
14897 var isMenuItem = c instanceof Ext.menu.Item;
14899 isMenuItem: isMenuItem,
14900 needsIcon: !isMenuItem && (c.icon || c.iconCls),
14901 icon: c.icon || Ext.BLANK_IMAGE_URL,
14902 iconCls: 'x-menu-item-icon ' + (c.iconCls || ''),
14903 itemId: 'x-menu-el-' + c.id,
14904 itemCls: 'x-menu-list-item '
14909 isValidParent : function(c, target) {
14910 return c.el.up('li.x-menu-list-item', 5).dom.parentNode === (target.dom || target);
14913 onLayout : function(ct, target){
14914 Ext.layout.MenuLayout.superclass.onLayout.call(this, ct, target);
14918 doAutoSize : function(){
14919 var ct = this.container, w = ct.width;
14923 }else if(Ext.isIE){
14924 ct.setWidth(Ext.isStrict && (Ext.isIE7 || Ext.isIE8) ? 'auto' : ct.minWidth);
14925 var el = ct.getEl(), t = el.dom.offsetWidth;
14926 ct.setWidth(ct.getLayoutTarget().getWidth() + el.getFrameWidth('lr'));
14931 Ext.Container.LAYOUTS['menu'] = Ext.layout.MenuLayout;
14933 Ext.Viewport = Ext.extend(Ext.Container, {
14947 initComponent : function() {
14948 Ext.Viewport.superclass.initComponent.call(this);
14949 document.getElementsByTagName('html')[0].className += ' x-viewport';
14950 this.el = Ext.getBody();
14951 this.el.setHeight = Ext.emptyFn;
14952 this.el.setWidth = Ext.emptyFn;
14953 this.el.setSize = Ext.emptyFn;
14954 this.el.dom.scroll = 'no';
14955 this.allowDomMove = false;
14956 this.autoWidth = true;
14957 this.autoHeight = true;
14958 Ext.EventManager.onWindowResize(this.fireResize, this);
14959 this.renderTo = this.el;
14962 fireResize : function(w, h){
14963 this.fireEvent('resize', this, w, h, w, h);
14966 Ext.reg('viewport', Ext.Viewport);
14968 Ext.Panel = Ext.extend(Ext.Container, {
15013 baseCls : 'x-panel',
15015 collapsedCls : 'x-panel-collapsed',
15017 maskDisabled : true,
15019 animCollapse : Ext.enableFx,
15021 headerAsText : true,
15023 buttonAlign : 'right',
15027 collapseFirst : true,
15029 minButtonWidth : 75,
15034 preventBodyReset : false,
15037 padding: undefined,
15040 resizeEvent: 'bodyresize',
15045 toolTarget : 'header',
15046 collapseEl : 'bwrap',
15048 disabledClass : '',
15051 deferHeight : true,
15057 collapseDefaults : {
15062 initComponent : function(){
15063 Ext.Panel.superclass.initComponent.call(this);
15091 this.baseCls = 'x-plain';
15095 this.toolbars = [];
15098 this.elements += ',tbar';
15099 this.topToolbar = this.createToolbar(this.tbar);
15104 this.elements += ',bbar';
15105 this.bottomToolbar = this.createToolbar(this.bbar);
15109 if(this.header === true){
15110 this.elements += ',header';
15111 this.header = null;
15112 }else if(this.headerCfg || (this.title && this.header !== false)){
15113 this.elements += ',header';
15116 if(this.footerCfg || this.footer === true){
15117 this.elements += ',footer';
15118 this.footer = null;
15122 this.fbar = this.buttons;
15123 this.buttons = null;
15126 this.createFbar(this.fbar);
15129 this.on('render', this.doAutoLoad, this, {delay:10});
15134 createFbar : function(fbar){
15135 var min = this.minButtonWidth;
15136 this.elements += ',footer';
15137 this.fbar = this.createToolbar(fbar, {
15138 buttonAlign: this.buttonAlign,
15139 toolbarCls: 'x-panel-fbar',
15140 enableOverflow: false,
15141 defaults: function(c){
15143 minWidth: c.minWidth || min
15150 this.fbar.items.each(function(c){
15151 c.minWidth = c.minWidth || this.minButtonWidth;
15153 this.buttons = this.fbar.items.items;
15157 createToolbar: function(tb, options){
15160 if(Ext.isArray(tb)){
15165 result = tb.events ? Ext.apply(tb, options) : this.createComponent(Ext.apply({}, tb, options), 'toolbar');
15166 this.toolbars.push(result);
15171 createElement : function(name, pnode){
15173 pnode.appendChild(this[name].dom);
15177 if(name === 'bwrap' || this.elements.indexOf(name) != -1){
15178 if(this[name+'Cfg']){
15179 this[name] = Ext.fly(pnode).createChild(this[name+'Cfg']);
15181 var el = document.createElement('div');
15182 el.className = this[name+'Cls'];
15183 this[name] = Ext.get(pnode.appendChild(el));
15185 if(this[name+'CssClass']){
15186 this[name].addClass(this[name+'CssClass']);
15188 if(this[name+'Style']){
15189 this[name].applyStyles(this[name+'Style']);
15195 onRender : function(ct, position){
15196 Ext.Panel.superclass.onRender.call(this, ct, position);
15197 this.createClasses();
15205 if(this.collapsible && !this.hideCollapseTool){
15206 this.tools = this.tools ? this.tools.slice(0) : [];
15207 this.tools[this.collapseFirst?'unshift':'push']({
15209 handler : this.toggleCollapse,
15216 this.elements += (this.header !== false) ? ',header' : '';
15220 el.addClass(this.baseCls);
15222 this.header = el.down('.'+this.headerCls);
15223 this.bwrap = el.down('.'+this.bwrapCls);
15224 var cp = this.bwrap ? this.bwrap : el;
15225 this.tbar = cp.down('.'+this.tbarCls);
15226 this.body = cp.down('.'+this.bodyCls);
15227 this.bbar = cp.down('.'+this.bbarCls);
15228 this.footer = cp.down('.'+this.footerCls);
15229 this.fromMarkup = true;
15231 if (this.preventBodyReset === true) {
15232 el.addClass('x-panel-reset');
15235 el.addClass(this.cls);
15239 this.elements += ',footer';
15246 el.insertHtml('afterBegin', String.format(Ext.Element.boxMarkup, this.baseCls));
15248 this.createElement('header', d.firstChild.firstChild.firstChild);
15249 this.createElement('bwrap', d);
15252 bw = this.bwrap.dom;
15253 var ml = d.childNodes[1], bl = d.childNodes[2];
15254 bw.appendChild(ml);
15255 bw.appendChild(bl);
15257 var mc = bw.firstChild.firstChild.firstChild;
15258 this.createElement('tbar', mc);
15259 this.createElement('body', mc);
15260 this.createElement('bbar', mc);
15261 this.createElement('footer', bw.lastChild.firstChild.firstChild);
15264 this.bwrap.dom.lastChild.className += ' x-panel-nofooter';
15267 this.ft = Ext.get(this.bwrap.dom.lastChild);
15268 this.mc = Ext.get(mc);
15270 this.createElement('header', d);
15271 this.createElement('bwrap', d);
15274 bw = this.bwrap.dom;
15275 this.createElement('tbar', bw);
15276 this.createElement('body', bw);
15277 this.createElement('bbar', bw);
15278 this.createElement('footer', bw);
15281 this.body.addClass(this.bodyCls + '-noheader');
15283 this.tbar.addClass(this.tbarCls + '-noheader');
15288 if(Ext.isDefined(this.padding)){
15289 this.body.setStyle('padding', this.body.addUnits(this.padding));
15292 if(this.border === false){
15293 this.el.addClass(this.baseCls + '-noborder');
15294 this.body.addClass(this.bodyCls + '-noborder');
15296 this.header.addClass(this.headerCls + '-noborder');
15299 this.footer.addClass(this.footerCls + '-noborder');
15302 this.tbar.addClass(this.tbarCls + '-noborder');
15305 this.bbar.addClass(this.bbarCls + '-noborder');
15309 if(this.bodyBorder === false){
15310 this.body.addClass(this.bodyCls + '-noborder');
15313 this.bwrap.enableDisplayMode('block');
15316 this.header.unselectable();
15319 if(this.headerAsText){
15320 this.header.dom.innerHTML =
15321 '<span class="' + this.headerTextCls + '">'+this.header.dom.innerHTML+'</span>';
15324 this.setIconClass(this.iconCls);
15330 this.makeFloating(this.floating);
15333 if(this.collapsible && this.titleCollapse && this.header){
15334 this.mon(this.header, 'click', this.toggleCollapse, this);
15335 this.header.setStyle('cursor', 'pointer');
15338 this.addTool.apply(this, ts);
15343 this.footer.addClass('x-panel-btns');
15344 this.fbar.ownerCt = this;
15345 this.fbar.render(this.footer);
15346 this.footer.createChild({cls:'x-clear'});
15348 if(this.tbar && this.topToolbar){
15349 this.topToolbar.ownerCt = this;
15350 this.topToolbar.render(this.tbar);
15352 if(this.bbar && this.bottomToolbar){
15353 this.bottomToolbar.ownerCt = this;
15354 this.bottomToolbar.render(this.bbar);
15359 setIconClass : function(cls){
15360 var old = this.iconCls;
15361 this.iconCls = cls;
15362 if(this.rendered && this.header){
15364 this.header.addClass('x-panel-icon');
15365 this.header.replaceClass(old, this.iconCls);
15367 var hd = this.header,
15368 img = hd.child('img.x-panel-inline-icon');
15370 Ext.fly(img).replaceClass(old, this.iconCls);
15372 var hdspan = hd.child('span.' + this.headerTextCls);
15374 Ext.DomHelper.insertBefore(hdspan.dom, {
15375 tag:'img', src: Ext.BLANK_IMAGE_URL, cls:'x-panel-inline-icon '+this.iconCls
15381 this.fireEvent('iconchange', this, cls, old);
15385 makeFloating : function(cfg){
15386 this.floating = true;
15387 this.el = new Ext.Layer(Ext.apply({}, cfg, {
15388 shadow: Ext.isDefined(this.shadow) ? this.shadow : 'sides',
15389 shadowOffset: this.shadowOffset,
15391 shim: this.shim === false ? false : undefined
15396 getTopToolbar : function(){
15397 return this.topToolbar;
15401 getBottomToolbar : function(){
15402 return this.bottomToolbar;
15406 getFooterToolbar : function() {
15411 addButton : function(config, handler, scope){
15413 this.createFbar([]);
15416 if(Ext.isString(config)){
15417 config = {text: config};
15419 config = Ext.apply({
15424 return this.fbar.add(config);
15428 addTool : function(){
15429 if(!this.rendered){
15433 Ext.each(arguments, function(arg){
15434 this.tools.push(arg);
15439 if(!this[this.toolTarget]){
15442 if(!this.toolTemplate){
15444 var tt = new Ext.Template(
15445 '<div class="x-tool x-tool-{id}"> </div>'
15447 tt.disableFormats = true;
15449 Ext.Panel.prototype.toolTemplate = tt;
15451 for(var i = 0, a = arguments, len = a.length; i < len; i++) {
15453 if(!this.tools[tc.id]){
15454 var overCls = 'x-tool-'+tc.id+'-over';
15455 var t = this.toolTemplate.insertFirst(this[this.toolTarget], tc, true);
15456 this.tools[tc.id] = t;
15457 t.enableDisplayMode('block');
15458 this.mon(t, 'click', this.createToolHandler(t, tc, overCls, this));
15460 this.mon(t, tc.on);
15466 if(Ext.isObject(tc.qtip)){
15467 Ext.QuickTips.register(Ext.apply({
15471 t.dom.qtip = tc.qtip;
15474 t.addClassOnOver(overCls);
15479 onLayout : function(shallow, force){
15480 Ext.Panel.superclass.onLayout.apply(this, arguments);
15481 if(this.hasLayout && this.toolbars.length > 0){
15482 Ext.each(this.toolbars, function(tb){
15483 tb.doLayout(undefined, force);
15489 syncHeight : function(){
15490 var h = this.toolbarHeight,
15492 lsh = this.lastSize.height,
15495 if(this.autoHeight || !Ext.isDefined(lsh) || lsh == 'auto'){
15500 if(h != this.getToolbarHeight()){
15501 h = Math.max(0, lsh - this.getFrameHeight());
15504 this.toolbarHeight = this.getToolbarHeight();
15505 this.onBodyResize(sz.width, sz.height);
15510 onShow : function(){
15512 return this.el.show();
15514 Ext.Panel.superclass.onShow.call(this);
15518 onHide : function(){
15520 return this.el.hide();
15522 Ext.Panel.superclass.onHide.call(this);
15526 createToolHandler : function(t, tc, overCls, panel){
15527 return function(e){
15528 t.removeClass(overCls);
15529 if(tc.stopEvent !== false){
15533 tc.handler.call(tc.scope || t, e, t, panel, tc);
15539 afterRender : function(){
15540 if(this.floating && !this.hidden){
15544 this.setTitle(this.title);
15546 Ext.Panel.superclass.afterRender.call(this);
15547 if (this.collapsed) {
15548 this.collapsed = false;
15549 this.collapse(false);
15555 getKeyMap : function(){
15557 this.keyMap = new Ext.KeyMap(this.el, this.keys);
15559 return this.keyMap;
15563 initEvents : function(){
15567 if(this.draggable){
15568 this.initDraggable();
15570 if(this.toolbars.length > 0){
15571 Ext.each(this.toolbars, function(tb){
15575 afterlayout: this.syncHeight,
15576 remove: this.syncHeight
15585 initDraggable : function(){
15587 this.dd = new Ext.Panel.DD(this, Ext.isBoolean(this.draggable) ? null : this.draggable);
15591 beforeEffect : function(anim){
15593 this.el.beforeAction();
15595 if(anim !== false){
15596 this.el.addClass('x-panel-animated');
15601 afterEffect : function(anim){
15603 this.el.removeClass('x-panel-animated');
15607 createEffect : function(a, cb, scope){
15615 }else if(!a.callback){
15618 o.callback = function(){
15620 Ext.callback(a.callback, a.scope);
15623 return Ext.applyIf(o, a);
15627 collapse : function(animate){
15628 if(this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforecollapse', this, animate) === false){
15631 var doAnim = animate === true || (animate !== false && this.animCollapse);
15632 this.beforeEffect(doAnim);
15633 this.onCollapse(doAnim, animate);
15638 onCollapse : function(doAnim, animArg){
15640 this[this.collapseEl].slideOut(this.slideAnchor,
15641 Ext.apply(this.createEffect(animArg||true, this.afterCollapse, this),
15642 this.collapseDefaults));
15644 this[this.collapseEl].hide(this.hideMode);
15645 this.afterCollapse(false);
15650 afterCollapse : function(anim){
15651 this.collapsed = true;
15652 this.el.addClass(this.collapsedCls);
15653 if(anim !== false){
15654 this[this.collapseEl].hide(this.hideMode);
15656 this.afterEffect(anim);
15659 this.cascade(function(c) {
15661 c.lastSize = { width: undefined, height: undefined };
15664 this.fireEvent('collapse', this);
15668 expand : function(animate){
15669 if(!this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforeexpand', this, animate) === false){
15672 var doAnim = animate === true || (animate !== false && this.animCollapse);
15673 this.el.removeClass(this.collapsedCls);
15674 this.beforeEffect(doAnim);
15675 this.onExpand(doAnim, animate);
15680 onExpand : function(doAnim, animArg){
15682 this[this.collapseEl].slideIn(this.slideAnchor,
15683 Ext.apply(this.createEffect(animArg||true, this.afterExpand, this),
15684 this.expandDefaults));
15686 this[this.collapseEl].show(this.hideMode);
15687 this.afterExpand(false);
15692 afterExpand : function(anim){
15693 this.collapsed = false;
15694 if(anim !== false){
15695 this[this.collapseEl].show(this.hideMode);
15697 this.afterEffect(anim);
15698 if (this.deferLayout) {
15699 delete this.deferLayout;
15700 this.doLayout(true);
15702 this.fireEvent('expand', this);
15706 toggleCollapse : function(animate){
15707 this[this.collapsed ? 'expand' : 'collapse'](animate);
15712 onDisable : function(){
15713 if(this.rendered && this.maskDisabled){
15716 Ext.Panel.superclass.onDisable.call(this);
15720 onEnable : function(){
15721 if(this.rendered && this.maskDisabled){
15724 Ext.Panel.superclass.onEnable.call(this);
15728 onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
15732 if(Ext.isDefined(w) || Ext.isDefined(h)){
15733 if(!this.collapsed){
15738 if(Ext.isNumber(w)){
15739 this.body.setWidth(w = this.adjustBodyWidth(w - this.getFrameWidth()));
15740 } else if (w == 'auto') {
15741 w = this.body.setWidth('auto').dom.offsetWidth;
15743 w = this.body.dom.offsetWidth;
15747 this.tbar.setWidth(w);
15748 if(this.topToolbar){
15749 this.topToolbar.setSize(w);
15753 this.bbar.setWidth(w);
15754 if(this.bottomToolbar){
15755 this.bottomToolbar.setSize(w);
15758 this.bbar.setStyle('position', 'static');
15759 this.bbar.setStyle('position', '');
15764 this.footer.setWidth(w);
15766 this.fbar.setSize(Ext.isIE ? (w - this.footer.getFrameWidth('lr')) : 'auto');
15771 if(Ext.isNumber(h)){
15772 h = Math.max(0, h - this.getFrameHeight());
15774 this.body.setHeight(h);
15775 }else if(h == 'auto'){
15776 this.body.setHeight(h);
15779 if(this.disabled && this.el._mask){
15780 this.el._mask.setSize(this.el.dom.clientWidth, this.el.getHeight());
15784 this.queuedBodySize = {width: w, height: h};
15785 if(!this.queuedExpand && this.allowQueuedExpand !== false){
15786 this.queuedExpand = true;
15787 this.on('expand', function(){
15788 delete this.queuedExpand;
15789 this.onResize(this.queuedBodySize.width, this.queuedBodySize.height);
15790 }, this, {single:true});
15793 this.onBodyResize(w, h);
15796 Ext.Panel.superclass.onResize.call(this, adjWidth, adjHeight, rawWidth, rawHeight);
15801 onBodyResize: function(w, h){
15802 this.fireEvent('bodyresize', this, w, h);
15806 getToolbarHeight: function(){
15809 Ext.each(this.toolbars, function(tb){
15810 h += tb.getHeight();
15817 adjustBodyHeight : function(h){
15822 adjustBodyWidth : function(w){
15827 onPosition : function(){
15832 getFrameWidth : function(){
15833 var w = this.el.getFrameWidth('lr') + this.bwrap.getFrameWidth('lr');
15836 var l = this.bwrap.dom.firstChild;
15837 w += (Ext.fly(l).getFrameWidth('l') + Ext.fly(l.firstChild).getFrameWidth('r'));
15838 w += this.mc.getFrameWidth('lr');
15844 getFrameHeight : function() {
15845 var h = Math.max(0, this.getHeight() - this.body.getHeight());
15856 getInnerWidth : function(){
15857 return this.getSize().width - this.getFrameWidth();
15861 getInnerHeight : function(){
15862 return this.body.getHeight();
15867 syncShadow : function(){
15869 this.el.sync(true);
15874 getLayoutTarget : function(){
15879 getContentTarget : function(){
15884 setTitle : function(title, iconCls){
15885 this.title = title;
15886 if(this.header && this.headerAsText){
15887 this.header.child('span').update(title);
15890 this.setIconClass(iconCls);
15892 this.fireEvent('titlechange', this, title);
15897 getUpdater : function(){
15898 return this.body.getUpdater();
15903 var um = this.body.getUpdater();
15904 um.update.apply(um, arguments);
15909 beforeDestroy : function(){
15910 Ext.Panel.superclass.beforeDestroy.call(this);
15912 this.header.removeAllListeners();
15915 for(var k in this.tools){
15916 Ext.destroy(this.tools[k]);
15919 if(this.toolbars.length > 0){
15920 Ext.each(this.toolbars, function(tb){
15921 tb.un('afterlayout', this.syncHeight, this);
15922 tb.un('remove', this.syncHeight, this);
15925 if(Ext.isArray(this.buttons)){
15926 while(this.buttons.length) {
15927 Ext.destroy(this.buttons[0]);
15949 Ext.destroy(this.toolbars);
15953 createClasses : function(){
15954 this.headerCls = this.baseCls + '-header';
15955 this.headerTextCls = this.baseCls + '-header-text';
15956 this.bwrapCls = this.baseCls + '-bwrap';
15957 this.tbarCls = this.baseCls + '-tbar';
15958 this.bodyCls = this.baseCls + '-body';
15959 this.bbarCls = this.baseCls + '-bbar';
15960 this.footerCls = this.baseCls + '-footer';
15964 createGhost : function(cls, useShim, appendTo){
15965 var el = document.createElement('div');
15966 el.className = 'x-panel-ghost ' + (cls ? cls : '');
15968 el.appendChild(this.el.dom.firstChild.cloneNode(true));
15970 Ext.fly(el.appendChild(document.createElement('ul'))).setHeight(this.bwrap.getHeight());
15971 el.style.width = this.el.dom.offsetWidth + 'px';;
15973 this.container.dom.appendChild(el);
15975 Ext.getDom(appendTo).appendChild(el);
15977 if(useShim !== false && this.el.useShim !== false){
15978 var layer = new Ext.Layer({shadow:false, useDisplay:true, constrain:false}, el);
15982 return new Ext.Element(el);
15987 doAutoLoad : function(){
15988 var u = this.body.getUpdater();
15990 u.setRenderer(this.renderer);
15992 u.update(Ext.isObject(this.autoLoad) ? this.autoLoad : {url: this.autoLoad});
15996 getTool : function(id) {
15997 return this.tools[id];
16002 Ext.reg('panel', Ext.Panel);
16004 Ext.Editor = function(field, config){
16006 this.field = Ext.create(field.field, 'textfield');
16007 config = Ext.apply({}, field);
16008 delete config.field;
16010 this.field = field;
16012 Ext.Editor.superclass.constructor.call(this, config);
16015 Ext.extend(Ext.Editor, Ext.Component, {
16034 swallowKeys : true,
16036 completeOnEnter : true,
16038 cancelOnEsc : true,
16042 initComponent : function(){
16043 Ext.Editor.superclass.initComponent.call(this);
16061 onRender : function(ct, position){
16062 this.el = new Ext.Layer({
16063 shadow: this.shadow,
16067 shadowOffset: this.shadowOffset || 4,
16069 constrain: this.constrain
16072 this.el.setZIndex(this.zIndex);
16074 this.el.setStyle("overflow", Ext.isGecko ? "auto" : "hidden");
16075 if(this.field.msgTarget != 'title'){
16076 this.field.msgTarget = 'qtip';
16078 this.field.inEditor = true;
16079 this.mon(this.field, {
16082 specialkey: this.onSpecialKey
16084 if(this.field.grow){
16085 this.mon(this.field, "autosize", this.el.sync, this.el, {delay:1});
16087 this.field.render(this.el).show();
16088 this.field.getEl().dom.name = '';
16089 if(this.swallowKeys){
16090 this.field.el.swallowEvent([
16098 onSpecialKey : function(field, e){
16099 var key = e.getKey(),
16100 complete = this.completeOnEnter && key == e.ENTER,
16101 cancel = this.cancelOnEsc && key == e.ESC;
16102 if(complete || cancel){
16105 this.completeEdit();
16109 if(field.triggerBlur){
16110 field.triggerBlur();
16113 this.fireEvent('specialkey', field, e);
16117 startEdit : function(el, value){
16119 this.completeEdit();
16121 this.boundEl = Ext.get(el);
16122 var v = value !== undefined ? value : this.boundEl.dom.innerHTML;
16123 if(!this.rendered){
16124 this.render(this.parentEl || document.body);
16126 if(this.fireEvent("beforestartedit", this, this.boundEl, v) !== false){
16127 this.startValue = v;
16128 this.field.reset();
16129 this.field.setValue(v);
16130 this.realign(true);
16131 this.editing = true;
16137 doAutoSize : function(){
16139 var sz = this.boundEl.getSize(),
16140 fs = this.field.getSize();
16142 switch(this.autoSize){
16144 this.setSize(sz.width, fs.height);
16147 this.setSize(fs.width, sz.height);
16150 this.setSize(fs.width, fs.height);
16153 this.setSize(sz.width, sz.height);
16159 setSize : function(w, h){
16160 delete this.field.lastSize;
16161 this.field.setSize(w, h);
16164 if(Ext.isGecko2 || Ext.isOpera || (Ext.isIE7 && Ext.isStrict)){
16166 this.el.setSize(w, h);
16173 realign : function(autoSize){
16174 if(autoSize === true){
16177 this.el.alignTo(this.boundEl, this.alignment, this.offsets);
16181 completeEdit : function(remainVisible){
16186 if (this.field.assertValue) {
16187 this.field.assertValue();
16189 var v = this.getValue();
16190 if(!this.field.isValid()){
16191 if(this.revertInvalid !== false){
16192 this.cancelEdit(remainVisible);
16196 if(String(v) === String(this.startValue) && this.ignoreNoChange){
16197 this.hideEdit(remainVisible);
16200 if(this.fireEvent("beforecomplete", this, v, this.startValue) !== false){
16201 v = this.getValue();
16202 if(this.updateEl && this.boundEl){
16203 this.boundEl.update(v);
16205 this.hideEdit(remainVisible);
16206 this.fireEvent("complete", this, v, this.startValue);
16211 onShow : function(){
16213 if(this.hideEl !== false){
16214 this.boundEl.hide();
16216 this.field.show().focus(false, true);
16217 this.fireEvent("startedit", this.boundEl, this.startValue);
16221 cancelEdit : function(remainVisible){
16223 var v = this.getValue();
16224 this.setValue(this.startValue);
16225 this.hideEdit(remainVisible);
16226 this.fireEvent("canceledit", this, v, this.startValue);
16231 hideEdit: function(remainVisible){
16232 if(remainVisible !== true){
16233 this.editing = false;
16239 onBlur : function(){
16241 if(this.allowBlur === true && this.editing && this.selectSameEditor !== true){
16242 this.completeEdit();
16247 onHide : function(){
16249 this.completeEdit();
16253 if(this.field.collapse){
16254 this.field.collapse();
16257 if(this.hideEl !== false){
16258 this.boundEl.show();
16263 setValue : function(v){
16264 this.field.setValue(v);
16268 getValue : function(){
16269 return this.field.getValue();
16272 beforeDestroy : function(){
16273 Ext.destroyMembers(this, 'field');
16275 delete this.parentEl;
16276 delete this.boundEl;
16279 Ext.reg('editor', Ext.Editor);
16281 Ext.ColorPalette = Ext.extend(Ext.Component, {
16284 itemCls : 'x-color-palette',
16288 clickEvent :'click',
16290 ctype : 'Ext.ColorPalette',
16293 allowReselect : false,
16297 '000000', '993300', '333300', '003300', '003366', '000080', '333399', '333333',
16298 '800000', 'FF6600', '808000', '008000', '008080', '0000FF', '666699', '808080',
16299 'FF0000', 'FF9900', '99CC00', '339966', '33CCCC', '3366FF', '800080', '969696',
16300 'FF00FF', 'FFCC00', 'FFFF00', '00FF00', '00FFFF', '00CCFF', '993366', 'C0C0C0',
16301 'FF99CC', 'FFCC99', 'FFFF99', 'CCFFCC', 'CCFFFF', '99CCFF', 'CC99FF', 'FFFFFF'
16308 initComponent : function(){
16309 Ext.ColorPalette.superclass.initComponent.call(this);
16316 this.on('select', this.handler, this.scope, true);
16321 onRender : function(container, position){
16326 Ext.ColorPalette.superclass.onRender.call(this, container, position);
16327 var t = this.tpl || new Ext.XTemplate(
16328 '<tpl for="."><a href="#" class="color-{.}" hidefocus="on"><em><span style="background:#{.}" unselectable="on"> </span></em></a></tpl>'
16330 t.overwrite(this.el, this.colors);
16331 this.mon(this.el, this.clickEvent, this.handleClick, this, {delegate: 'a'});
16332 if(this.clickEvent != 'click'){
16333 this.mon(this.el, 'click', Ext.emptyFn, this, {delegate: 'a', preventDefault: true});
16338 afterRender : function(){
16339 Ext.ColorPalette.superclass.afterRender.call(this);
16341 var s = this.value;
16343 this.select(s, true);
16348 handleClick : function(e, t){
16349 e.preventDefault();
16350 if(!this.disabled){
16351 var c = t.className.match(/(?:^|\s)color-(.{6})(?:\s|$)/)[1];
16352 this.select(c.toUpperCase());
16357 select : function(color, suppressEvent){
16358 color = color.replace('#', '');
16359 if(color != this.value || this.allowReselect){
16362 el.child('a.color-'+this.value).removeClass('x-color-palette-sel');
16364 el.child('a.color-'+color).addClass('x-color-palette-sel');
16365 this.value = color;
16366 if(suppressEvent !== true){
16367 this.fireEvent('select', this, color);
16374 Ext.reg('colorpalette', Ext.ColorPalette);
16375 Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
16377 todayText : 'Today',
16379 okText : ' OK ',
16381 cancelText : 'Cancel',
16385 todayTip : '{0} (Spacebar)',
16387 minText : 'This date is before the minimum date',
16389 maxText : 'This date is after the maximum date',
16393 disabledDaysText : 'Disabled',
16395 disabledDatesText : 'Disabled',
16397 monthNames : Date.monthNames,
16399 dayNames : Date.dayNames,
16401 nextText : 'Next Month (Control+Right)',
16403 prevText : 'Previous Month (Control+Left)',
16405 monthYearText : 'Choose a month (Control+Up/Down to move years)',
16418 focusOnSelect: true,
16425 initComponent : function(){
16426 Ext.DatePicker.superclass.initComponent.call(this);
16428 this.value = this.value ?
16429 this.value.clearTime(true) : new Date().clearTime();
16437 this.on('select', this.handler, this.scope || this);
16440 this.initDisabledDays();
16444 initDisabledDays : function(){
16445 if(!this.disabledDatesRE && this.disabledDates){
16446 var dd = this.disabledDates,
16447 len = dd.length - 1,
16450 Ext.each(dd, function(d, i){
16451 re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i];
16456 this.disabledDatesRE = new RegExp(re + ')');
16461 setDisabledDates : function(dd){
16462 if(Ext.isArray(dd)){
16463 this.disabledDates = dd;
16464 this.disabledDatesRE = null;
16466 this.disabledDatesRE = dd;
16468 this.initDisabledDays();
16469 this.update(this.value, true);
16473 setDisabledDays : function(dd){
16474 this.disabledDays = dd;
16475 this.update(this.value, true);
16479 setMinDate : function(dt){
16481 this.update(this.value, true);
16485 setMaxDate : function(dt){
16487 this.update(this.value, true);
16491 setValue : function(value){
16492 this.value = value.clearTime(true);
16493 this.update(this.value);
16497 getValue : function(){
16502 focus : function(){
16503 this.update(this.activeDate);
16507 onEnable: function(initial){
16508 Ext.DatePicker.superclass.onEnable.call(this);
16509 this.doDisabled(false);
16510 this.update(initial ? this.value : this.activeDate);
16518 onDisable : function(){
16519 Ext.DatePicker.superclass.onDisable.call(this);
16520 this.doDisabled(true);
16521 if(Ext.isIE && !Ext.isIE8){
16523 Ext.each([].concat(this.textNodes, this.el.query('th span')), function(el){
16524 Ext.fly(el).repaint();
16530 doDisabled : function(disabled){
16531 this.keyNav.setDisabled(disabled);
16532 this.prevRepeater.setDisabled(disabled);
16533 this.nextRepeater.setDisabled(disabled);
16534 if(this.showToday){
16535 this.todayKeyListener.setDisabled(disabled);
16536 this.todayBtn.setDisabled(disabled);
16541 onRender : function(container, position){
16543 '<table cellspacing="0">',
16544 '<tr><td class="x-date-left"><a href="#" title="', this.prevText ,'"> </a></td><td class="x-date-middle" align="center"></td><td class="x-date-right"><a href="#" title="', this.nextText ,'"> </a></td></tr>',
16545 '<tr><td colspan="3"><table class="x-date-inner" cellspacing="0"><thead><tr>'],
16546 dn = this.dayNames,
16548 for(i = 0; i < 7; i++){
16549 var d = this.startDay+i;
16553 m.push('<th><span>', dn[d].substr(0,1), '</span></th>');
16555 m[m.length] = '</tr></thead><tbody><tr>';
16556 for(i = 0; i < 42; i++) {
16557 if(i % 7 === 0 && i !== 0){
16558 m[m.length] = '</tr><tr>';
16560 m[m.length] = '<td><a href="#" hidefocus="on" class="x-date-date" tabIndex="1"><em><span></span></em></a></td>';
16562 m.push('</tr></tbody></table></td></tr>',
16563 this.showToday ? '<tr><td colspan="3" class="x-date-bottom" align="center"></td></tr>' : '',
16564 '</table><div class="x-date-mp"></div>');
16566 var el = document.createElement('div');
16567 el.className = 'x-date-picker';
16568 el.innerHTML = m.join('');
16570 container.dom.insertBefore(el, position);
16572 this.el = Ext.get(el);
16573 this.eventEl = Ext.get(el.firstChild);
16575 this.prevRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-left a'), {
16576 handler: this.showPrevMonth,
16578 preventDefault:true,
16582 this.nextRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-right a'), {
16583 handler: this.showNextMonth,
16585 preventDefault:true,
16589 this.monthPicker = this.el.down('div.x-date-mp');
16590 this.monthPicker.enableDisplayMode('block');
16592 this.keyNav = new Ext.KeyNav(this.eventEl, {
16593 'left' : function(e){
16595 this.showPrevMonth();
16597 this.update(this.activeDate.add('d', -1));
16601 'right' : function(e){
16603 this.showNextMonth();
16605 this.update(this.activeDate.add('d', 1));
16609 'up' : function(e){
16611 this.showNextYear();
16613 this.update(this.activeDate.add('d', -7));
16617 'down' : function(e){
16619 this.showPrevYear();
16621 this.update(this.activeDate.add('d', 7));
16625 'pageUp' : function(e){
16626 this.showNextMonth();
16629 'pageDown' : function(e){
16630 this.showPrevMonth();
16633 'enter' : function(e){
16634 e.stopPropagation();
16641 this.el.unselectable();
16643 this.cells = this.el.select('table.x-date-inner tbody td');
16644 this.textNodes = this.el.query('table.x-date-inner tbody span');
16646 this.mbtn = new Ext.Button({
16648 tooltip: this.monthYearText,
16649 renderTo: this.el.child('td.x-date-middle', true)
16651 this.mbtn.el.child('em').addClass('x-btn-arrow');
16653 if(this.showToday){
16654 this.todayKeyListener = this.eventEl.addKeyListener(Ext.EventObject.SPACE, this.selectToday, this);
16655 var today = (new Date()).dateFormat(this.format);
16656 this.todayBtn = new Ext.Button({
16657 renderTo: this.el.child('td.x-date-bottom', true),
16658 text: String.format(this.todayText, today),
16659 tooltip: String.format(this.todayTip, today),
16660 handler: this.selectToday,
16664 this.mon(this.eventEl, 'mousewheel', this.handleMouseWheel, this);
16665 this.mon(this.eventEl, 'click', this.handleDateClick, this, {delegate: 'a.x-date-date'});
16666 this.mon(this.mbtn, 'click', this.showMonthPicker, this);
16667 this.onEnable(true);
16671 createMonthPicker : function(){
16672 if(!this.monthPicker.dom.firstChild){
16673 var buf = ['<table border="0" cellspacing="0">'];
16674 for(var i = 0; i < 6; i++){
16676 '<tr><td class="x-date-mp-month"><a href="#">', Date.getShortMonthName(i), '</a></td>',
16677 '<td class="x-date-mp-month x-date-mp-sep"><a href="#">', Date.getShortMonthName(i + 6), '</a></td>',
16679 '<td class="x-date-mp-ybtn" align="center"><a class="x-date-mp-prev"></a></td><td class="x-date-mp-ybtn" align="center"><a class="x-date-mp-next"></a></td></tr>' :
16680 '<td class="x-date-mp-year"><a href="#"></a></td><td class="x-date-mp-year"><a href="#"></a></td></tr>'
16684 '<tr class="x-date-mp-btns"><td colspan="4"><button type="button" class="x-date-mp-ok">',
16686 '</button><button type="button" class="x-date-mp-cancel">',
16688 '</button></td></tr>',
16691 this.monthPicker.update(buf.join(''));
16693 this.mon(this.monthPicker, 'click', this.onMonthClick, this);
16694 this.mon(this.monthPicker, 'dblclick', this.onMonthDblClick, this);
16696 this.mpMonths = this.monthPicker.select('td.x-date-mp-month');
16697 this.mpYears = this.monthPicker.select('td.x-date-mp-year');
16699 this.mpMonths.each(function(m, a, i){
16702 m.dom.xmonth = 5 + Math.round(i * 0.5);
16704 m.dom.xmonth = Math.round((i-1) * 0.5);
16711 showMonthPicker : function(){
16712 if(!this.disabled){
16713 this.createMonthPicker();
16714 var size = this.el.getSize();
16715 this.monthPicker.setSize(size);
16716 this.monthPicker.child('table').setSize(size);
16718 this.mpSelMonth = (this.activeDate || this.value).getMonth();
16719 this.updateMPMonth(this.mpSelMonth);
16720 this.mpSelYear = (this.activeDate || this.value).getFullYear();
16721 this.updateMPYear(this.mpSelYear);
16723 this.monthPicker.slideIn('t', {duration:0.2});
16728 updateMPYear : function(y){
16730 var ys = this.mpYears.elements;
16731 for(var i = 1; i <= 10; i++){
16732 var td = ys[i-1], y2;
16734 y2 = y + Math.round(i * 0.5);
16735 td.firstChild.innerHTML = y2;
16738 y2 = y - (5-Math.round(i * 0.5));
16739 td.firstChild.innerHTML = y2;
16742 this.mpYears.item(i-1)[y2 == this.mpSelYear ? 'addClass' : 'removeClass']('x-date-mp-sel');
16747 updateMPMonth : function(sm){
16748 this.mpMonths.each(function(m, a, i){
16749 m[m.dom.xmonth == sm ? 'addClass' : 'removeClass']('x-date-mp-sel');
16754 selectMPMonth : function(m){
16759 onMonthClick : function(e, t){
16761 var el = new Ext.Element(t), pn;
16762 if(el.is('button.x-date-mp-cancel')){
16763 this.hideMonthPicker();
16765 else if(el.is('button.x-date-mp-ok')){
16766 var d = new Date(this.mpSelYear, this.mpSelMonth, (this.activeDate || this.value).getDate());
16767 if(d.getMonth() != this.mpSelMonth){
16769 d = new Date(this.mpSelYear, this.mpSelMonth, 1).getLastDateOfMonth();
16772 this.hideMonthPicker();
16774 else if((pn = el.up('td.x-date-mp-month', 2))){
16775 this.mpMonths.removeClass('x-date-mp-sel');
16776 pn.addClass('x-date-mp-sel');
16777 this.mpSelMonth = pn.dom.xmonth;
16779 else if((pn = el.up('td.x-date-mp-year', 2))){
16780 this.mpYears.removeClass('x-date-mp-sel');
16781 pn.addClass('x-date-mp-sel');
16782 this.mpSelYear = pn.dom.xyear;
16784 else if(el.is('a.x-date-mp-prev')){
16785 this.updateMPYear(this.mpyear-10);
16787 else if(el.is('a.x-date-mp-next')){
16788 this.updateMPYear(this.mpyear+10);
16793 onMonthDblClick : function(e, t){
16795 var el = new Ext.Element(t), pn;
16796 if((pn = el.up('td.x-date-mp-month', 2))){
16797 this.update(new Date(this.mpSelYear, pn.dom.xmonth, (this.activeDate || this.value).getDate()));
16798 this.hideMonthPicker();
16800 else if((pn = el.up('td.x-date-mp-year', 2))){
16801 this.update(new Date(pn.dom.xyear, this.mpSelMonth, (this.activeDate || this.value).getDate()));
16802 this.hideMonthPicker();
16807 hideMonthPicker : function(disableAnim){
16808 if(this.monthPicker){
16809 if(disableAnim === true){
16810 this.monthPicker.hide();
16812 this.monthPicker.slideOut('t', {duration:0.2});
16818 showPrevMonth : function(e){
16819 this.update(this.activeDate.add('mo', -1));
16823 showNextMonth : function(e){
16824 this.update(this.activeDate.add('mo', 1));
16828 showPrevYear : function(){
16829 this.update(this.activeDate.add('y', -1));
16833 showNextYear : function(){
16834 this.update(this.activeDate.add('y', 1));
16838 handleMouseWheel : function(e){
16840 if(!this.disabled){
16841 var delta = e.getWheelDelta();
16843 this.showPrevMonth();
16844 } else if(delta < 0){
16845 this.showNextMonth();
16851 handleDateClick : function(e, t){
16853 if(!this.disabled && t.dateValue && !Ext.fly(t.parentNode).hasClass('x-date-disabled')){
16854 this.cancelFocus = this.focusOnSelect === false;
16855 this.setValue(new Date(t.dateValue));
16856 delete this.cancelFocus;
16857 this.fireEvent('select', this, this.value);
16862 selectToday : function(){
16863 if(this.todayBtn && !this.todayBtn.disabled){
16864 this.setValue(new Date().clearTime());
16865 this.fireEvent('select', this, this.value);
16870 update : function(date, forceRefresh){
16872 var vd = this.activeDate, vis = this.isVisible();
16873 this.activeDate = date;
16874 if(!forceRefresh && vd && this.el){
16875 var t = date.getTime();
16876 if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){
16877 this.cells.removeClass('x-date-selected');
16878 this.cells.each(function(c){
16879 if(c.dom.firstChild.dateValue == t){
16880 c.addClass('x-date-selected');
16881 if(vis && !this.cancelFocus){
16882 Ext.fly(c.dom.firstChild).focus(50);
16890 var days = date.getDaysInMonth(),
16891 firstOfMonth = date.getFirstDateOfMonth(),
16892 startingPos = firstOfMonth.getDay()-this.startDay;
16894 if(startingPos < 0){
16897 days += startingPos;
16899 var pm = date.add('mo', -1),
16900 prevStart = pm.getDaysInMonth()-startingPos,
16901 cells = this.cells.elements,
16902 textEls = this.textNodes,
16904 d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart, this.initHour)),
16905 today = new Date().clearTime().getTime(),
16906 sel = date.clearTime(true).getTime(),
16907 min = this.minDate ? this.minDate.clearTime(true) : Number.NEGATIVE_INFINITY,
16908 max = this.maxDate ? this.maxDate.clearTime(true) : Number.POSITIVE_INFINITY,
16909 ddMatch = this.disabledDatesRE,
16910 ddText = this.disabledDatesText,
16911 ddays = this.disabledDays ? this.disabledDays.join('') : false,
16912 ddaysText = this.disabledDaysText,
16913 format = this.format;
16915 if(this.showToday){
16916 var td = new Date().clearTime(),
16917 disable = (td < min || td > max ||
16918 (ddMatch && format && ddMatch.test(td.dateFormat(format))) ||
16919 (ddays && ddays.indexOf(td.getDay()) != -1));
16921 if(!this.disabled){
16922 this.todayBtn.setDisabled(disable);
16923 this.todayKeyListener[disable ? 'disable' : 'enable']();
16927 var setCellClass = function(cal, cell){
16929 var t = d.clearTime(true).getTime();
16930 cell.firstChild.dateValue = t;
16932 cell.className += ' x-date-today';
16933 cell.title = cal.todayText;
16936 cell.className += ' x-date-selected';
16938 Ext.fly(cell.firstChild).focus(50);
16943 cell.className = ' x-date-disabled';
16944 cell.title = cal.minText;
16948 cell.className = ' x-date-disabled';
16949 cell.title = cal.maxText;
16953 if(ddays.indexOf(d.getDay()) != -1){
16954 cell.title = ddaysText;
16955 cell.className = ' x-date-disabled';
16958 if(ddMatch && format){
16959 var fvalue = d.dateFormat(format);
16960 if(ddMatch.test(fvalue)){
16961 cell.title = ddText.replace('%0', fvalue);
16962 cell.className = ' x-date-disabled';
16968 for(; i < startingPos; i++) {
16969 textEls[i].innerHTML = (++prevStart);
16970 d.setDate(d.getDate()+1);
16971 cells[i].className = 'x-date-prevday';
16972 setCellClass(this, cells[i]);
16974 for(; i < days; i++){
16975 var intDay = i - startingPos + 1;
16976 textEls[i].innerHTML = (intDay);
16977 d.setDate(d.getDate()+1);
16978 cells[i].className = 'x-date-active';
16979 setCellClass(this, cells[i]);
16982 for(; i < 42; i++) {
16983 textEls[i].innerHTML = (++extraDays);
16984 d.setDate(d.getDate()+1);
16985 cells[i].className = 'x-date-nextday';
16986 setCellClass(this, cells[i]);
16989 this.mbtn.setText(this.monthNames[date.getMonth()] + ' ' + date.getFullYear());
16991 if(!this.internalRender){
16992 var main = this.el.dom.firstChild,
16993 w = main.offsetWidth;
16994 this.el.setWidth(w + this.el.getBorderWidth('lr'));
16995 Ext.fly(main).setWidth(w);
16996 this.internalRender = true;
17000 if(Ext.isOpera && !this.secondPass){
17001 main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + 'px';
17002 this.secondPass = true;
17003 this.update.defer(10, this, [date]);
17010 beforeDestroy : function() {
17022 delete this.textNodes;
17023 delete this.cells.elements;
17030 Ext.reg('datepicker', Ext.DatePicker);
17032 Ext.LoadMask = function(el, config){
17033 this.el = Ext.get(el);
17034 Ext.apply(this, config);
17038 beforeload: this.onBeforeLoad,
17040 exception: this.onLoad
17042 this.removeMask = Ext.value(this.removeMask, false);
17044 var um = this.el.getUpdater();
17045 um.showLoadIndicator = false;
17048 beforeupdate: this.onBeforeLoad,
17049 update: this.onLoad,
17050 failure: this.onLoad
17052 this.removeMask = Ext.value(this.removeMask, true);
17056 Ext.LoadMask.prototype = {
17060 msg : 'Loading...',
17062 msgCls : 'x-mask-loading',
17068 disable : function(){
17069 this.disabled = true;
17073 enable : function(){
17074 this.disabled = false;
17078 onLoad : function(){
17079 this.el.unmask(this.removeMask);
17083 onBeforeLoad : function(){
17084 if(!this.disabled){
17085 this.el.mask(this.msg, this.msgCls);
17091 this.onBeforeLoad();
17100 destroy : function(){
17102 this.store.un('beforeload', this.onBeforeLoad, this);
17103 this.store.un('load', this.onLoad, this);
17104 this.store.un('exception', this.onLoad, this);
17106 var um = this.el.getUpdater();
17107 um.un('beforeupdate', this.onBeforeLoad, this);
17108 um.un('update', this.onLoad, this);
17109 um.un('failure', this.onLoad, this);
17112 };Ext.ns('Ext.slider');
17115 Ext.slider.Thumb = Ext.extend(Object, {
17118 constructor: function(config) {
17120 Ext.apply(this, config || {}, {
17121 cls: 'x-slider-thumb',
17127 Ext.slider.Thumb.superclass.constructor.call(this, config);
17129 if (this.slider.vertical) {
17130 Ext.apply(this, Ext.slider.Thumb.Vertical);
17135 render: function() {
17136 this.el = this.slider.innerEl.insertFirst({cls: this.cls});
17142 enable: function() {
17143 this.disabled = false;
17144 this.el.removeClass(this.slider.disabledClass);
17148 disable: function() {
17149 this.disabled = true;
17150 this.el.addClass(this.slider.disabledClass);
17154 initEvents: function() {
17157 el.addClassOnOver('x-slider-thumb-over');
17159 this.tracker = new Ext.dd.DragTracker({
17160 onBeforeStart: this.onBeforeDragStart.createDelegate(this),
17161 onStart : this.onDragStart.createDelegate(this),
17162 onDrag : this.onDrag.createDelegate(this),
17163 onEnd : this.onDragEnd.createDelegate(this),
17168 this.tracker.initEl(el);
17172 onBeforeDragStart : function(e) {
17173 if (this.disabled) {
17176 this.slider.promoteThumb(this);
17182 onDragStart: function(e){
17183 this.el.addClass('x-slider-thumb-drag');
17184 this.dragging = true;
17185 this.dragStartValue = this.value;
17187 this.slider.fireEvent('dragstart', this.slider, e, this);
17191 onDrag: function(e) {
17192 var slider = this.slider,
17193 index = this.index,
17194 newValue = this.getNewValue();
17196 if (this.constrain) {
17197 var above = slider.thumbs[index + 1],
17198 below = slider.thumbs[index - 1];
17200 if (below != undefined && newValue <= below.value) newValue = below.value;
17201 if (above != undefined && newValue >= above.value) newValue = above.value;
17204 slider.setValue(index, newValue, false);
17205 slider.fireEvent('drag', slider, e, this);
17208 getNewValue: function() {
17209 var slider = this.slider,
17210 pos = slider.innerEl.translatePoints(this.tracker.getXY());
17212 return Ext.util.Format.round(slider.reverseValue(pos.left), slider.decimalPrecision);
17216 onDragEnd: function(e) {
17217 var slider = this.slider,
17218 value = this.value;
17220 this.el.removeClass('x-slider-thumb-drag');
17222 this.dragging = false;
17223 slider.fireEvent('dragend', slider, e);
17225 if (this.dragStartValue != value) {
17226 slider.fireEvent('changecomplete', slider, value, this);
17231 destroy: function(){
17232 Ext.destroyMembers(this, 'tracker', 'el');
17237 Ext.slider.MultiSlider = Ext.extend(Ext.BoxComponent, {
17246 decimalPrecision: 0,
17253 clickRange: [5,15],
17256 clickToChange : true,
17264 constrainThumbs: true,
17267 topThumbZIndex: 10000,
17270 initComponent : function(){
17271 if(!Ext.isDefined(this.value)){
17272 this.value = this.minValue;
17278 Ext.slider.MultiSlider.superclass.initComponent.call(this);
17280 this.keyIncrement = Math.max(this.increment, this.keyIncrement);
17302 if (this.values == undefined || Ext.isEmpty(this.values)) this.values = [0];
17304 var values = this.values;
17306 for (var i=0; i < values.length; i++) {
17307 this.addThumb(values[i]);
17311 Ext.apply(this, Ext.slider.Vertical);
17316 addThumb: function(value) {
17317 var thumb = new Ext.slider.Thumb({
17320 index : this.thumbs.length,
17321 constrain: this.constrainThumbs
17323 this.thumbs.push(thumb);
17326 if (this.rendered) thumb.render();
17330 promoteThumb: function(topThumb) {
17331 var thumbs = this.thumbs,
17334 for (var i = 0, j = thumbs.length; i < j; i++) {
17337 if (thumb == topThumb) {
17338 zIndex = this.topThumbZIndex;
17343 thumb.el.setStyle('zIndex', zIndex);
17348 onRender : function() {
17350 cls: 'x-slider ' + (this.vertical ? 'x-slider-vert' : 'x-slider-horz'),
17352 cls: 'x-slider-end',
17354 cls:'x-slider-inner',
17355 cn : [{tag:'a', cls:'x-slider-focus', href:"#", tabIndex: '-1', hidefocus:'on'}]
17360 Ext.slider.MultiSlider.superclass.onRender.apply(this, arguments);
17362 this.endEl = this.el.first();
17363 this.innerEl = this.endEl.first();
17364 this.focusEl = this.innerEl.child('.x-slider-focus');
17367 for (var i=0; i < this.thumbs.length; i++) {
17368 this.thumbs[i].render();
17372 var thumb = this.innerEl.child('.x-slider-thumb');
17373 this.halfThumb = (this.vertical ? thumb.getHeight() : thumb.getWidth()) / 2;
17379 initEvents : function(){
17380 this.mon(this.el, {
17382 mousedown: this.onMouseDown,
17383 keydown : this.onKeyDown
17386 this.focusEl.swallowEvent("click", true);
17390 onMouseDown : function(e){
17396 var thumbClicked = false;
17397 for (var i=0; i < this.thumbs.length; i++) {
17398 thumbClicked = thumbClicked || e.target == this.thumbs[i].el.dom;
17401 if (this.clickToChange && !thumbClicked) {
17402 var local = this.innerEl.translatePoints(e.getXY());
17403 this.onClickChange(local);
17409 onClickChange : function(local) {
17410 if (local.top > this.clickRange[0] && local.top < this.clickRange[1]) {
17412 var thumb = this.getNearest(local, 'left'),
17413 index = thumb.index;
17415 this.setValue(index, Ext.util.Format.round(this.reverseValue(local.left), this.decimalPrecision), undefined, true);
17420 getNearest: function(local, prop) {
17421 var localValue = prop == 'top' ? this.innerEl.getHeight() - local[prop] : local[prop],
17422 clickValue = this.reverseValue(localValue),
17423 nearestDistance = (this.maxValue - this.minValue) + 5,
17427 for (var i=0; i < this.thumbs.length; i++) {
17428 var thumb = this.thumbs[i],
17429 value = thumb.value,
17430 dist = Math.abs(value - clickValue);
17432 if (Math.abs(dist <= nearestDistance)) {
17435 nearestDistance = dist;
17442 onKeyDown : function(e){
17444 if(this.disabled || this.thumbs.length !== 1){
17445 e.preventDefault();
17448 var k = e.getKey(),
17454 val = e.ctrlKey ? this.maxValue : this.getValue(0) + this.keyIncrement;
17455 this.setValue(0, val, undefined, true);
17460 val = e.ctrlKey ? this.minValue : this.getValue(0) - this.keyIncrement;
17461 this.setValue(0, val, undefined, true);
17464 e.preventDefault();
17469 doSnap : function(value){
17470 if (!(this.increment && value)) {
17473 var newValue = value,
17474 inc = this.increment,
17478 if (m * 2 >= inc) {
17480 } else if (m * 2 < -inc) {
17484 return newValue.constrain(this.minValue, this.maxValue);
17488 afterRender : function(){
17489 Ext.slider.MultiSlider.superclass.afterRender.apply(this, arguments);
17491 for (var i=0; i < this.thumbs.length; i++) {
17492 var thumb = this.thumbs[i];
17494 if (thumb.value !== undefined) {
17495 var v = this.normalizeValue(thumb.value);
17497 if (v !== thumb.value) {
17499 this.setValue(i, v, false);
17501 this.moveThumb(i, this.translateValue(v), false);
17508 getRatio : function(){
17509 var w = this.innerEl.getWidth(),
17510 v = this.maxValue - this.minValue;
17511 return v == 0 ? w : (w/v);
17515 normalizeValue : function(v){
17516 v = this.doSnap(v);
17517 v = Ext.util.Format.round(v, this.decimalPrecision);
17518 v = v.constrain(this.minValue, this.maxValue);
17523 setMinValue : function(val){
17524 this.minValue = val;
17526 thumbs = this.thumbs,
17527 len = thumbs.length,
17530 for(; i < len; ++i){
17532 t.value = t.value < val ? val : t.value;
17538 setMaxValue : function(val){
17539 this.maxValue = val;
17541 thumbs = this.thumbs,
17542 len = thumbs.length,
17545 for(; i < len; ++i){
17547 t.value = t.value > val ? val : t.value;
17553 setValue : function(index, v, animate, changeComplete) {
17554 var thumb = this.thumbs[index],
17557 v = this.normalizeValue(v);
17559 if (v !== thumb.value && this.fireEvent('beforechange', this, v, thumb.value, thumb) !== false) {
17562 this.moveThumb(index, this.translateValue(v), animate !== false);
17563 this.fireEvent('change', this, v, thumb);
17564 if(changeComplete){
17565 this.fireEvent('changecomplete', this, v, thumb);
17572 translateValue : function(v) {
17573 var ratio = this.getRatio();
17574 return (v * ratio) - (this.minValue * ratio) - this.halfThumb;
17578 reverseValue : function(pos){
17579 var ratio = this.getRatio();
17580 return (pos + (this.minValue * ratio)) / ratio;
17584 moveThumb: function(index, v, animate){
17585 var thumb = this.thumbs[index].el;
17587 if(!animate || this.animate === false){
17590 thumb.shift({left: v, stopFx: true, duration:.35});
17595 focus : function(){
17596 this.focusEl.focus(10);
17600 onResize : function(w, h){
17601 var thumbs = this.thumbs,
17602 len = thumbs.length,
17606 for(; i < len; ++i){
17607 thumbs[i].el.stopFx();
17610 if(Ext.isNumber(w)){
17611 this.innerEl.setWidth(w - (this.el.getPadding('l') + this.endEl.getPadding('r')));
17614 Ext.slider.MultiSlider.superclass.onResize.apply(this, arguments);
17618 onDisable: function(){
17619 Ext.slider.MultiSlider.superclass.onDisable.call(this);
17621 for (var i=0; i < this.thumbs.length; i++) {
17622 var thumb = this.thumbs[i],
17630 var xy = el.getXY();
17633 this.innerEl.addClass(this.disabledClass).dom.disabled = true;
17635 if (!this.thumbHolder) {
17636 this.thumbHolder = this.endEl.createChild({cls: 'x-slider-thumb ' + this.disabledClass});
17639 this.thumbHolder.show().setXY(xy);
17645 onEnable: function(){
17646 Ext.slider.MultiSlider.superclass.onEnable.call(this);
17648 for (var i=0; i < this.thumbs.length; i++) {
17649 var thumb = this.thumbs[i],
17655 this.innerEl.removeClass(this.disabledClass).dom.disabled = false;
17657 if (this.thumbHolder) this.thumbHolder.hide();
17666 syncThumb : function() {
17667 if (this.rendered) {
17668 for (var i=0; i < this.thumbs.length; i++) {
17669 this.moveThumb(i, this.translateValue(this.thumbs[i].value));
17675 getValue : function(index) {
17676 return this.thumbs[index].value;
17680 getValues: function() {
17683 for (var i=0; i < this.thumbs.length; i++) {
17684 values.push(this.thumbs[i].value);
17691 beforeDestroy : function(){
17692 var thumbs = this.thumbs;
17693 for(var i = 0, len = thumbs.length; i < len; ++i){
17694 thumbs[i].destroy();
17697 Ext.destroyMembers(this, 'endEl', 'innerEl', 'focusEl', 'thumbHolder');
17698 Ext.slider.MultiSlider.superclass.beforeDestroy.call(this);
17702 Ext.reg('multislider', Ext.slider.MultiSlider);
17705 Ext.slider.SingleSlider = Ext.extend(Ext.slider.MultiSlider, {
17706 constructor: function(config) {
17707 config = config || {};
17709 Ext.applyIf(config, {
17710 values: [config.value || 0]
17713 Ext.slider.SingleSlider.superclass.constructor.call(this, config);
17717 getValue: function() {
17719 return Ext.slider.SingleSlider.superclass.getValue.call(this, 0);
17723 setValue: function(value, animate) {
17724 var args = Ext.toArray(arguments),
17730 if (len == 1 || (len <= 3 && typeof arguments[1] != 'number')) {
17734 return Ext.slider.SingleSlider.superclass.setValue.apply(this, args);
17738 syncThumb : function() {
17739 return Ext.slider.SingleSlider.superclass.syncThumb.apply(this, [0].concat(arguments));
17743 getNearest : function(){
17745 return this.thumbs[0];
17750 Ext.Slider = Ext.slider.SingleSlider;
17752 Ext.reg('slider', Ext.slider.SingleSlider);
17755 Ext.slider.Vertical = {
17756 onResize : function(w, h){
17757 this.innerEl.setHeight(h - (this.el.getPadding('t') + this.endEl.getPadding('b')));
17761 getRatio : function(){
17762 var h = this.innerEl.getHeight(),
17763 v = this.maxValue - this.minValue;
17767 moveThumb: function(index, v, animate) {
17768 var thumb = this.thumbs[index],
17771 if (!animate || this.animate === false) {
17774 el.shift({bottom: v, stopFx: true, duration:.35});
17778 onClickChange : function(local) {
17779 if (local.left > this.clickRange[0] && local.left < this.clickRange[1]) {
17780 var thumb = this.getNearest(local, 'top'),
17781 index = thumb.index,
17782 value = this.minValue + this.reverseValue(this.innerEl.getHeight() - local.top);
17784 this.setValue(index, Ext.util.Format.round(value, this.decimalPrecision), undefined, true);
17790 Ext.slider.Thumb.Vertical = {
17791 getNewValue: function() {
17792 var slider = this.slider,
17793 innerEl = slider.innerEl,
17794 pos = innerEl.translatePoints(this.tracker.getXY()),
17795 bottom = innerEl.getHeight() - pos.top;
17797 return slider.minValue + Ext.util.Format.round(bottom / slider.getRatio(), slider.decimalPrecision);
17801 Ext.ProgressBar = Ext.extend(Ext.BoxComponent, {
17803 baseCls : 'x-progress',
17812 initComponent : function(){
17813 Ext.ProgressBar.superclass.initComponent.call(this);
17821 onRender : function(ct, position){
17822 var tpl = new Ext.Template(
17823 '<div class="{cls}-wrap">',
17824 '<div class="{cls}-inner">',
17825 '<div class="{cls}-bar">',
17826 '<div class="{cls}-text">',
17827 '<div> </div>',
17830 '<div class="{cls}-text {cls}-text-back">',
17831 '<div> </div>',
17837 this.el = position ? tpl.insertBefore(position, {cls: this.baseCls}, true)
17838 : tpl.append(ct, {cls: this.baseCls}, true);
17841 this.el.dom.id = this.id;
17843 var inner = this.el.dom.firstChild;
17844 this.progressBar = Ext.get(inner.firstChild);
17848 this.textEl = Ext.get(this.textEl);
17849 delete this.textTopEl;
17852 this.textTopEl = Ext.get(this.progressBar.dom.firstChild);
17853 var textBackEl = Ext.get(inner.childNodes[1]);
17854 this.textTopEl.setStyle("z-index", 99).addClass('x-hidden');
17855 this.textEl = new Ext.CompositeElement([this.textTopEl.dom.firstChild, textBackEl.dom.firstChild]);
17856 this.textEl.setWidth(inner.offsetWidth);
17858 this.progressBar.setHeight(inner.offsetHeight);
17862 afterRender : function(){
17863 Ext.ProgressBar.superclass.afterRender.call(this);
17865 this.updateProgress(this.value, this.text);
17867 this.updateText(this.text);
17872 updateProgress : function(value, text, animate){
17873 this.value = value || 0;
17875 this.updateText(text);
17877 if(this.rendered && !this.isDestroyed){
17878 var w = Math.floor(value*this.el.dom.firstChild.offsetWidth);
17879 this.progressBar.setWidth(w, animate === true || (animate !== false && this.animate));
17880 if(this.textTopEl){
17882 this.textTopEl.removeClass('x-hidden').setWidth(w);
17885 this.fireEvent('update', this, value, text);
17890 wait : function(o){
17891 if(!this.waitTimer){
17894 this.updateText(o.text);
17895 this.waitTimer = Ext.TaskMgr.start({
17897 var inc = o.increment || 10;
17899 this.updateProgress(((((i+inc)%inc)+1)*(100/inc))*0.01, null, o.animate);
17901 interval: o.interval || 1000,
17902 duration: o.duration,
17903 onStop: function(){
17905 o.fn.apply(o.scope || this);
17916 isWaiting : function(){
17917 return this.waitTimer !== null;
17921 updateText : function(text){
17922 this.text = text || ' ';
17924 this.textEl.update(this.text);
17930 syncProgressBar : function(){
17932 this.updateProgress(this.value, this.text);
17938 setSize : function(w, h){
17939 Ext.ProgressBar.superclass.setSize.call(this, w, h);
17940 if(this.textTopEl){
17941 var inner = this.el.dom.firstChild;
17942 this.textEl.setSize(inner.offsetWidth, inner.offsetHeight);
17944 this.syncProgressBar();
17949 reset : function(hide){
17950 this.updateProgress(0);
17951 if(this.textTopEl){
17952 this.textTopEl.addClass('x-hidden');
17962 clearTimer : function(){
17963 if(this.waitTimer){
17964 this.waitTimer.onStop = null;
17965 Ext.TaskMgr.stop(this.waitTimer);
17966 this.waitTimer = null;
17970 onDestroy: function(){
17973 if(this.textEl.isComposite){
17974 this.textEl.clear();
17976 Ext.destroyMembers(this, 'textEl', 'progressBar', 'textTopEl');
17978 Ext.ProgressBar.superclass.onDestroy.call(this);
17981 Ext.reg('progress', Ext.ProgressBar);
17985 var Event=Ext.EventManager;
17986 var Dom=Ext.lib.Dom;
17989 Ext.dd.DragDrop = function(id, sGroup, config) {
17991 this.init(id, sGroup, config);
17995 Ext.dd.DragDrop.prototype = {
18012 invalidHandleTypes: null,
18015 invalidHandleIds: null,
18018 invalidHandleClasses: null,
18034 this.locked = true;
18041 unlock: function() {
18042 this.locked = false;
18055 __ygDragDrop: true,
18076 maintainOffset: false,
18085 primaryButtonOnly: true,
18091 hasOuterHandles: false,
18094 b4StartDrag: function(x, y) { },
18097 startDrag: function(x, y) { },
18100 b4Drag: function(e) { },
18103 onDrag: function(e) { },
18106 onDragEnter: function(e, id) { },
18109 b4DragOver: function(e) { },
18112 onDragOver: function(e, id) { },
18115 b4DragOut: function(e) { },
18118 onDragOut: function(e, id) { },
18121 b4DragDrop: function(e) { },
18124 onDragDrop: function(e, id) { },
18127 onInvalidDrop: function(e) { },
18130 b4EndDrag: function(e) { },
18133 endDrag: function(e) { },
18136 b4MouseDown: function(e) { },
18139 onMouseDown: function(e) { },
18142 onMouseUp: function(e) { },
18145 onAvailable: function () {
18149 defaultPadding : {left:0, right:0, top:0, bottom:0},
18152 constrainTo : function(constrainTo, pad, inContent){
18153 if(Ext.isNumber(pad)){
18154 pad = {left: pad, right:pad, top:pad, bottom:pad};
18156 pad = pad || this.defaultPadding;
18157 var b = Ext.get(this.getEl()).getBox(),
18158 ce = Ext.get(constrainTo),
18159 s = ce.getScroll(),
18162 if(cd == document.body){
18163 c = { x: s.left, y: s.top, width: Ext.lib.Dom.getViewWidth(), height: Ext.lib.Dom.getViewHeight()};
18165 var xy = ce.getXY();
18166 c = {x : xy[0], y: xy[1], width: cd.clientWidth, height: cd.clientHeight};
18170 var topSpace = b.y - c.y,
18171 leftSpace = b.x - c.x;
18173 this.resetConstraints();
18174 this.setXConstraint(leftSpace - (pad.left||0),
18175 c.width - leftSpace - b.width - (pad.right||0),
18178 this.setYConstraint(topSpace - (pad.top||0),
18179 c.height - topSpace - b.height - (pad.bottom||0),
18185 getEl: function() {
18186 if (!this._domRef) {
18187 this._domRef = Ext.getDom(this.id);
18190 return this._domRef;
18194 getDragEl: function() {
18195 return Ext.getDom(this.dragElId);
18199 init: function(id, sGroup, config) {
18200 this.initTarget(id, sGroup, config);
18201 Event.on(this.id, "mousedown", this.handleMouseDown, this);
18206 initTarget: function(id, sGroup, config) {
18209 this.config = config || {};
18212 this.DDM = Ext.dd.DDM;
18218 if (typeof id !== "string") {
18226 this.addToGroup((sGroup) ? sGroup : "default");
18230 this.handleElId = id;
18233 this.setDragElId(id);
18236 this.invalidHandleTypes = { A: "A" };
18237 this.invalidHandleIds = {};
18238 this.invalidHandleClasses = [];
18240 this.applyConfig();
18242 this.handleOnAvailable();
18246 applyConfig: function() {
18250 this.padding = this.config.padding || [0, 0, 0, 0];
18251 this.isTarget = (this.config.isTarget !== false);
18252 this.maintainOffset = (this.config.maintainOffset);
18253 this.primaryButtonOnly = (this.config.primaryButtonOnly !== false);
18258 handleOnAvailable: function() {
18259 this.available = true;
18260 this.resetConstraints();
18261 this.onAvailable();
18265 setPadding: function(iTop, iRight, iBot, iLeft) {
18267 if (!iRight && 0 !== iRight) {
18268 this.padding = [iTop, iTop, iTop, iTop];
18269 } else if (!iBot && 0 !== iBot) {
18270 this.padding = [iTop, iRight, iTop, iRight];
18272 this.padding = [iTop, iRight, iBot, iLeft];
18277 setInitPosition: function(diffX, diffY) {
18278 var el = this.getEl();
18280 if (!this.DDM.verifyEl(el)) {
18284 var dx = diffX || 0;
18285 var dy = diffY || 0;
18287 var p = Dom.getXY( el );
18289 this.initPageX = p[0] - dx;
18290 this.initPageY = p[1] - dy;
18292 this.lastPageX = p[0];
18293 this.lastPageY = p[1];
18295 this.setStartPosition(p);
18299 setStartPosition: function(pos) {
18300 var p = pos || Dom.getXY( this.getEl() );
18301 this.deltaSetXY = null;
18303 this.startPageX = p[0];
18304 this.startPageY = p[1];
18308 addToGroup: function(sGroup) {
18309 this.groups[sGroup] = true;
18310 this.DDM.regDragDrop(this, sGroup);
18314 removeFromGroup: function(sGroup) {
18315 if (this.groups[sGroup]) {
18316 delete this.groups[sGroup];
18319 this.DDM.removeDDFromGroup(this, sGroup);
18323 setDragElId: function(id) {
18324 this.dragElId = id;
18328 setHandleElId: function(id) {
18329 if (typeof id !== "string") {
18332 this.handleElId = id;
18333 this.DDM.regHandle(this.id, id);
18337 setOuterHandleElId: function(id) {
18338 if (typeof id !== "string") {
18341 Event.on(id, "mousedown",
18342 this.handleMouseDown, this);
18343 this.setHandleElId(id);
18345 this.hasOuterHandles = true;
18349 unreg: function() {
18350 Event.un(this.id, "mousedown",
18351 this.handleMouseDown);
18352 this._domRef = null;
18353 this.DDM._remove(this);
18356 destroy : function(){
18361 isLocked: function() {
18362 return (this.DDM.isLocked() || this.locked);
18366 handleMouseDown: function(e, oDD){
18367 if (this.primaryButtonOnly && e.button != 0) {
18371 if (this.isLocked()) {
18375 this.DDM.refreshCache(this.groups);
18377 var pt = new Ext.lib.Point(Ext.lib.Event.getPageX(e), Ext.lib.Event.getPageY(e));
18378 if (!this.hasOuterHandles && !this.DDM.isOverTarget(pt, this) ) {
18380 if (this.clickValidator(e)) {
18383 this.setStartPosition();
18385 this.b4MouseDown(e);
18386 this.onMouseDown(e);
18388 this.DDM.handleMouseDown(e, this);
18390 this.DDM.stopEvent(e);
18398 clickValidator: function(e) {
18399 var target = e.getTarget();
18400 return ( this.isValidHandleChild(target) &&
18401 (this.id == this.handleElId ||
18402 this.DDM.handleWasClicked(target, this.id)) );
18406 addInvalidHandleType: function(tagName) {
18407 var type = tagName.toUpperCase();
18408 this.invalidHandleTypes[type] = type;
18412 addInvalidHandleId: function(id) {
18413 if (typeof id !== "string") {
18416 this.invalidHandleIds[id] = id;
18420 addInvalidHandleClass: function(cssClass) {
18421 this.invalidHandleClasses.push(cssClass);
18425 removeInvalidHandleType: function(tagName) {
18426 var type = tagName.toUpperCase();
18428 delete this.invalidHandleTypes[type];
18432 removeInvalidHandleId: function(id) {
18433 if (typeof id !== "string") {
18436 delete this.invalidHandleIds[id];
18440 removeInvalidHandleClass: function(cssClass) {
18441 for (var i=0, len=this.invalidHandleClasses.length; i<len; ++i) {
18442 if (this.invalidHandleClasses[i] == cssClass) {
18443 delete this.invalidHandleClasses[i];
18449 isValidHandleChild: function(node) {
18455 nodeName = node.nodeName.toUpperCase();
18457 nodeName = node.nodeName;
18459 valid = valid && !this.invalidHandleTypes[nodeName];
18460 valid = valid && !this.invalidHandleIds[node.id];
18462 for (var i=0, len=this.invalidHandleClasses.length; valid && i<len; ++i) {
18463 valid = !Ext.fly(node).hasClass(this.invalidHandleClasses[i]);
18472 setXTicks: function(iStartX, iTickSize) {
18474 this.xTickSize = iTickSize;
18478 for (var i = this.initPageX; i >= this.minX; i = i - iTickSize) {
18480 this.xTicks[this.xTicks.length] = i;
18485 for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) {
18487 this.xTicks[this.xTicks.length] = i;
18492 this.xTicks.sort(this.DDM.numericSort) ;
18496 setYTicks: function(iStartY, iTickSize) {
18498 this.yTickSize = iTickSize;
18502 for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) {
18504 this.yTicks[this.yTicks.length] = i;
18509 for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) {
18511 this.yTicks[this.yTicks.length] = i;
18516 this.yTicks.sort(this.DDM.numericSort) ;
18520 setXConstraint: function(iLeft, iRight, iTickSize) {
18521 this.leftConstraint = iLeft;
18522 this.rightConstraint = iRight;
18524 this.minX = this.initPageX - iLeft;
18525 this.maxX = this.initPageX + iRight;
18526 if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); }
18528 this.constrainX = true;
18532 clearConstraints: function() {
18533 this.constrainX = false;
18534 this.constrainY = false;
18539 clearTicks: function() {
18540 this.xTicks = null;
18541 this.yTicks = null;
18542 this.xTickSize = 0;
18543 this.yTickSize = 0;
18547 setYConstraint: function(iUp, iDown, iTickSize) {
18548 this.topConstraint = iUp;
18549 this.bottomConstraint = iDown;
18551 this.minY = this.initPageY - iUp;
18552 this.maxY = this.initPageY + iDown;
18553 if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); }
18555 this.constrainY = true;
18560 resetConstraints: function() {
18562 if (this.initPageX || this.initPageX === 0) {
18564 var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0;
18565 var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0;
18567 this.setInitPosition(dx, dy);
18571 this.setInitPosition();
18574 if (this.constrainX) {
18575 this.setXConstraint( this.leftConstraint,
18576 this.rightConstraint,
18580 if (this.constrainY) {
18581 this.setYConstraint( this.topConstraint,
18582 this.bottomConstraint,
18588 getTick: function(val, tickArray) {
18593 } else if (tickArray[0] >= val) {
18596 return tickArray[0];
18598 for (var i=0, len=tickArray.length; i<len; ++i) {
18600 if (tickArray[next] && tickArray[next] >= val) {
18601 var diff1 = val - tickArray[i];
18602 var diff2 = tickArray[next] - val;
18603 return (diff2 > diff1) ? tickArray[i] : tickArray[next];
18609 return tickArray[tickArray.length - 1];
18614 toString: function() {
18615 return ("DragDrop " + this.id);
18625 if (!Ext.dd.DragDropMgr) {
18628 Ext.dd.DragDropMgr = function() {
18630 var Event = Ext.EventManager;
18653 preventDefault: true,
18656 stopPropagation: true,
18659 initialized: false,
18666 this.initialized = true;
18679 _execOnAll: function(sMethod, args) {
18680 for (var i in this.ids) {
18681 for (var j in this.ids[i]) {
18682 var oDD = this.ids[i][j];
18683 if (! this.isTypeOfDD(oDD)) {
18686 oDD[sMethod].apply(oDD, args);
18692 _onLoad: function() {
18697 Event.on(document, "mouseup", this.handleMouseUp, this, true);
18698 Event.on(document, "mousemove", this.handleMouseMove, this, true);
18699 Event.on(window, "unload", this._onUnload, this, true);
18700 Event.on(window, "resize", this._onResize, this, true);
18706 _onResize: function(e) {
18707 this._execOnAll("resetConstraints", []);
18711 lock: function() { this.locked = true; },
18714 unlock: function() { this.locked = false; },
18717 isLocked: function() { return this.locked; },
18726 clickPixelThresh: 3,
18729 clickTimeThresh: 350,
18732 dragThreshMet: false,
18735 clickTimeout: null,
18744 regDragDrop: function(oDD, sGroup) {
18745 if (!this.initialized) { this.init(); }
18747 if (!this.ids[sGroup]) {
18748 this.ids[sGroup] = {};
18750 this.ids[sGroup][oDD.id] = oDD;
18754 removeDDFromGroup: function(oDD, sGroup) {
18755 if (!this.ids[sGroup]) {
18756 this.ids[sGroup] = {};
18759 var obj = this.ids[sGroup];
18760 if (obj && obj[oDD.id]) {
18761 delete obj[oDD.id];
18766 _remove: function(oDD) {
18767 for (var g in oDD.groups) {
18768 if (g && this.ids[g] && this.ids[g][oDD.id]) {
18769 delete this.ids[g][oDD.id];
18772 delete this.handleIds[oDD.id];
18776 regHandle: function(sDDId, sHandleId) {
18777 if (!this.handleIds[sDDId]) {
18778 this.handleIds[sDDId] = {};
18780 this.handleIds[sDDId][sHandleId] = sHandleId;
18784 isDragDrop: function(id) {
18785 return ( this.getDDById(id) ) ? true : false;
18789 getRelated: function(p_oDD, bTargetsOnly) {
18791 for (var i in p_oDD.groups) {
18792 for (var j in this.ids[i]) {
18793 var dd = this.ids[i][j];
18794 if (! this.isTypeOfDD(dd)) {
18797 if (!bTargetsOnly || dd.isTarget) {
18798 oDDs[oDDs.length] = dd;
18807 isLegalTarget: function (oDD, oTargetDD) {
18808 var targets = this.getRelated(oDD, true);
18809 for (var i=0, len=targets.length;i<len;++i) {
18810 if (targets[i].id == oTargetDD.id) {
18819 isTypeOfDD: function (oDD) {
18820 return (oDD && oDD.__ygDragDrop);
18824 isHandle: function(sDDId, sHandleId) {
18825 return ( this.handleIds[sDDId] &&
18826 this.handleIds[sDDId][sHandleId] );
18830 getDDById: function(id) {
18831 for (var i in this.ids) {
18832 if (this.ids[i][id]) {
18833 return this.ids[i][id];
18840 handleMouseDown: function(e, oDD) {
18842 Ext.QuickTips.disable();
18844 if(this.dragCurrent){
18847 this.handleMouseUp(e);
18850 this.currentTarget = e.getTarget();
18851 this.dragCurrent = oDD;
18853 var el = oDD.getEl();
18856 this.startX = e.getPageX();
18857 this.startY = e.getPageY();
18859 this.deltaX = this.startX - el.offsetLeft;
18860 this.deltaY = this.startY - el.offsetTop;
18862 this.dragThreshMet = false;
18864 this.clickTimeout = setTimeout(
18866 var DDM = Ext.dd.DDM;
18867 DDM.startDrag(DDM.startX, DDM.startY);
18869 this.clickTimeThresh );
18873 startDrag: function(x, y) {
18874 clearTimeout(this.clickTimeout);
18875 if (this.dragCurrent) {
18876 this.dragCurrent.b4StartDrag(x, y);
18877 this.dragCurrent.startDrag(x, y);
18879 this.dragThreshMet = true;
18883 handleMouseUp: function(e) {
18886 Ext.QuickTips.enable();
18888 if (! this.dragCurrent) {
18892 clearTimeout(this.clickTimeout);
18894 if (this.dragThreshMet) {
18895 this.fireEvents(e, true);
18905 stopEvent: function(e){
18906 if(this.stopPropagation) {
18907 e.stopPropagation();
18910 if (this.preventDefault) {
18911 e.preventDefault();
18916 stopDrag: function(e) {
18918 if (this.dragCurrent) {
18919 if (this.dragThreshMet) {
18920 this.dragCurrent.b4EndDrag(e);
18921 this.dragCurrent.endDrag(e);
18924 this.dragCurrent.onMouseUp(e);
18927 this.dragCurrent = null;
18928 this.dragOvers = {};
18932 handleMouseMove: function(e) {
18933 if (! this.dragCurrent) {
18939 if (Ext.isIE && (e.button !== 0 && e.button !== 1 && e.button !== 2)) {
18941 return this.handleMouseUp(e);
18944 if (!this.dragThreshMet) {
18945 var diffX = Math.abs(this.startX - e.getPageX());
18946 var diffY = Math.abs(this.startY - e.getPageY());
18947 if (diffX > this.clickPixelThresh ||
18948 diffY > this.clickPixelThresh) {
18949 this.startDrag(this.startX, this.startY);
18953 if (this.dragThreshMet) {
18954 this.dragCurrent.b4Drag(e);
18955 this.dragCurrent.onDrag(e);
18956 if(!this.dragCurrent.moveOnly){
18957 this.fireEvents(e, false);
18967 fireEvents: function(e, isDrop) {
18968 var dc = this.dragCurrent;
18972 if (!dc || dc.isLocked()) {
18976 var pt = e.getPoint();
18984 var enterEvts = [];
18988 for (var i in this.dragOvers) {
18990 var ddo = this.dragOvers[i];
18992 if (! this.isTypeOfDD(ddo)) {
18996 if (! this.isOverTarget(pt, ddo, this.mode)) {
18997 outEvts.push( ddo );
19000 oldOvers[i] = true;
19001 delete this.dragOvers[i];
19004 for (var sGroup in dc.groups) {
19006 if ("string" != typeof sGroup) {
19010 for (i in this.ids[sGroup]) {
19011 var oDD = this.ids[sGroup][i];
19012 if (! this.isTypeOfDD(oDD)) {
19016 if (oDD.isTarget && !oDD.isLocked() && ((oDD != dc) || (dc.ignoreSelf === false))) {
19017 if (this.isOverTarget(pt, oDD, this.mode)) {
19020 dropEvts.push( oDD );
19025 if (!oldOvers[oDD.id]) {
19026 enterEvts.push( oDD );
19029 overEvts.push( oDD );
19032 this.dragOvers[oDD.id] = oDD;
19040 if (outEvts.length) {
19041 dc.b4DragOut(e, outEvts);
19042 dc.onDragOut(e, outEvts);
19045 if (enterEvts.length) {
19046 dc.onDragEnter(e, enterEvts);
19049 if (overEvts.length) {
19050 dc.b4DragOver(e, overEvts);
19051 dc.onDragOver(e, overEvts);
19054 if (dropEvts.length) {
19055 dc.b4DragDrop(e, dropEvts);
19056 dc.onDragDrop(e, dropEvts);
19062 for (i=0, len=outEvts.length; i<len; ++i) {
19063 dc.b4DragOut(e, outEvts[i].id);
19064 dc.onDragOut(e, outEvts[i].id);
19068 for (i=0,len=enterEvts.length; i<len; ++i) {
19070 dc.onDragEnter(e, enterEvts[i].id);
19074 for (i=0,len=overEvts.length; i<len; ++i) {
19075 dc.b4DragOver(e, overEvts[i].id);
19076 dc.onDragOver(e, overEvts[i].id);
19080 for (i=0, len=dropEvts.length; i<len; ++i) {
19081 dc.b4DragDrop(e, dropEvts[i].id);
19082 dc.onDragDrop(e, dropEvts[i].id);
19088 if (isDrop && !dropEvts.length) {
19089 dc.onInvalidDrop(e);
19095 getBestMatch: function(dds) {
19103 var len = dds.length;
19109 for (var i=0; i<len; ++i) {
19114 if (dd.cursorIsOver) {
19120 winner.overlap.getArea() < dd.overlap.getArea()) {
19131 refreshCache: function(groups) {
19132 for (var sGroup in groups) {
19133 if ("string" != typeof sGroup) {
19136 for (var i in this.ids[sGroup]) {
19137 var oDD = this.ids[sGroup][i];
19139 if (this.isTypeOfDD(oDD)) {
19141 var loc = this.getLocation(oDD);
19143 this.locationCache[oDD.id] = loc;
19145 delete this.locationCache[oDD.id];
19156 verifyEl: function(el) {
19161 parent = el.offsetParent;
19164 parent = el.offsetParent;
19175 getLocation: function(oDD) {
19176 if (! this.isTypeOfDD(oDD)) {
19180 var el = oDD.getEl(), pos, x1, x2, y1, y2, t, r, b, l;
19183 pos= Ext.lib.Dom.getXY(el);
19191 x2 = x1 + el.offsetWidth;
19193 y2 = y1 + el.offsetHeight;
19195 t = y1 - oDD.padding[0];
19196 r = x2 + oDD.padding[1];
19197 b = y2 + oDD.padding[2];
19198 l = x1 - oDD.padding[3];
19200 return new Ext.lib.Region( t, r, b, l );
19204 isOverTarget: function(pt, oTarget, intersect) {
19206 var loc = this.locationCache[oTarget.id];
19207 if (!loc || !this.useCache) {
19208 loc = this.getLocation(oTarget);
19209 this.locationCache[oTarget.id] = loc;
19217 oTarget.cursorIsOver = loc.contains( pt );
19224 var dc = this.dragCurrent;
19225 if (!dc || !dc.getTargetCoord ||
19226 (!intersect && !dc.constrainX && !dc.constrainY)) {
19227 return oTarget.cursorIsOver;
19230 oTarget.overlap = null;
19236 var pos = dc.getTargetCoord(pt.x, pt.y);
19238 var el = dc.getDragEl();
19239 var curRegion = new Ext.lib.Region( pos.y,
19240 pos.x + el.offsetWidth,
19241 pos.y + el.offsetHeight,
19244 var overlap = curRegion.intersect(loc);
19247 oTarget.overlap = overlap;
19248 return (intersect) ? true : oTarget.cursorIsOver;
19255 _onUnload: function(e, me) {
19256 Ext.dd.DragDropMgr.unregAll();
19260 unregAll: function() {
19262 if (this.dragCurrent) {
19264 this.dragCurrent = null;
19267 this._execOnAll("unreg", []);
19269 for (var i in this.elementCache) {
19270 delete this.elementCache[i];
19273 this.elementCache = {};
19281 getElWrapper: function(id) {
19282 var oWrapper = this.elementCache[id];
19283 if (!oWrapper || !oWrapper.el) {
19284 oWrapper = this.elementCache[id] =
19285 new this.ElementWrapper(Ext.getDom(id));
19291 getElement: function(id) {
19292 return Ext.getDom(id);
19296 getCss: function(id) {
19297 var el = Ext.getDom(id);
19298 return (el) ? el.style : null;
19302 ElementWrapper: function(el) {
19304 this.el = el || null;
19306 this.id = this.el && el.id;
19308 this.css = this.el && el.style;
19312 getPosX: function(el) {
19313 return Ext.lib.Dom.getX(el);
19317 getPosY: function(el) {
19318 return Ext.lib.Dom.getY(el);
19322 swapNode: function(n1, n2) {
19326 var p = n2.parentNode;
19327 var s = n2.nextSibling;
19330 p.insertBefore(n1, n2);
19331 } else if (n2 == n1.nextSibling) {
19332 p.insertBefore(n2, n1);
19334 n1.parentNode.replaceChild(n2, n1);
19335 p.insertBefore(n1, s);
19341 getScroll: function () {
19342 var t, l, dde=document.documentElement, db=document.body;
19343 if (dde && (dde.scrollTop || dde.scrollLeft)) {
19345 l = dde.scrollLeft;
19352 return { top: t, left: l };
19356 getStyle: function(el, styleProp) {
19357 return Ext.fly(el).getStyle(styleProp);
19361 getScrollTop: function () {
19362 return this.getScroll().top;
19366 getScrollLeft: function () {
19367 return this.getScroll().left;
19371 moveToEl: function (moveEl, targetEl) {
19372 var aCoord = Ext.lib.Dom.getXY(targetEl);
19373 Ext.lib.Dom.setXY(moveEl, aCoord);
19377 numericSort: function(a, b) {
19385 _addListeners: function() {
19386 var DDM = Ext.dd.DDM;
19387 if ( Ext.lib.Event && document ) {
19390 if (DDM._timeoutCount > 2000) {
19392 setTimeout(DDM._addListeners, 10);
19393 if (document && document.body) {
19394 DDM._timeoutCount += 1;
19401 handleWasClicked: function(node, id) {
19402 if (this.isHandle(id, node.id)) {
19406 var p = node.parentNode;
19409 if (this.isHandle(id, p.id)) {
19425 Ext.dd.DDM = Ext.dd.DragDropMgr;
19426 Ext.dd.DDM._addListeners();
19431 Ext.dd.DD = function(id, sGroup, config) {
19433 this.init(id, sGroup, config);
19437 Ext.extend(Ext.dd.DD, Ext.dd.DragDrop, {
19443 autoOffset: function(iPageX, iPageY) {
19444 var x = iPageX - this.startPageX;
19445 var y = iPageY - this.startPageY;
19446 this.setDelta(x, y);
19450 setDelta: function(iDeltaX, iDeltaY) {
19451 this.deltaX = iDeltaX;
19452 this.deltaY = iDeltaY;
19456 setDragElPos: function(iPageX, iPageY) {
19460 var el = this.getDragEl();
19461 this.alignElWithMouse(el, iPageX, iPageY);
19465 alignElWithMouse: function(el, iPageX, iPageY) {
19466 var oCoord = this.getTargetCoord(iPageX, iPageY);
19467 var fly = el.dom ? el : Ext.fly(el, '_dd');
19468 if (!this.deltaSetXY) {
19469 var aCoord = [oCoord.x, oCoord.y];
19471 var newLeft = fly.getLeft(true);
19472 var newTop = fly.getTop(true);
19473 this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ];
19475 fly.setLeftTop(oCoord.x + this.deltaSetXY[0], oCoord.y + this.deltaSetXY[1]);
19478 this.cachePosition(oCoord.x, oCoord.y);
19479 this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
19484 cachePosition: function(iPageX, iPageY) {
19486 this.lastPageX = iPageX;
19487 this.lastPageY = iPageY;
19489 var aCoord = Ext.lib.Dom.getXY(this.getEl());
19490 this.lastPageX = aCoord[0];
19491 this.lastPageY = aCoord[1];
19496 autoScroll: function(x, y, h, w) {
19500 var clientH = Ext.lib.Dom.getViewHeight();
19503 var clientW = Ext.lib.Dom.getViewWidth();
19506 var st = this.DDM.getScrollTop();
19509 var sl = this.DDM.getScrollLeft();
19520 var toBot = (clientH + st - y - this.deltaY);
19523 var toRight = (clientW + sl - x - this.deltaX);
19533 var scrAmt = (document.all) ? 80 : 30;
19537 if ( bot > clientH && toBot < thresh ) {
19538 window.scrollTo(sl, st + scrAmt);
19543 if ( y < st && st > 0 && y - st < thresh ) {
19544 window.scrollTo(sl, st - scrAmt);
19549 if ( right > clientW && toRight < thresh ) {
19550 window.scrollTo(sl + scrAmt, st);
19555 if ( x < sl && sl > 0 && x - sl < thresh ) {
19556 window.scrollTo(sl - scrAmt, st);
19562 getTargetCoord: function(iPageX, iPageY) {
19563 var x = iPageX - this.deltaX;
19564 var y = iPageY - this.deltaY;
19566 if (this.constrainX) {
19567 if (x < this.minX) { x = this.minX; }
19568 if (x > this.maxX) { x = this.maxX; }
19571 if (this.constrainY) {
19572 if (y < this.minY) { y = this.minY; }
19573 if (y > this.maxY) { y = this.maxY; }
19576 x = this.getTick(x, this.xTicks);
19577 y = this.getTick(y, this.yTicks);
19584 applyConfig: function() {
19585 Ext.dd.DD.superclass.applyConfig.call(this);
19586 this.scroll = (this.config.scroll !== false);
19590 b4MouseDown: function(e) {
19592 this.autoOffset(e.getPageX(),
19597 b4Drag: function(e) {
19598 this.setDragElPos(e.getPageX(),
19602 toString: function() {
19603 return ("DD " + this.id);
19613 Ext.dd.DDProxy = function(id, sGroup, config) {
19615 this.init(id, sGroup, config);
19621 Ext.dd.DDProxy.dragElId = "ygddfdiv";
19623 Ext.extend(Ext.dd.DDProxy, Ext.dd.DD, {
19629 centerFrame: false,
19632 createFrame: function() {
19634 var body = document.body;
19636 if (!body || !body.firstChild) {
19637 setTimeout( function() { self.createFrame(); }, 50 );
19641 var div = this.getDragEl();
19644 div = document.createElement("div");
19645 div.id = this.dragElId;
19648 s.position = "absolute";
19649 s.visibility = "hidden";
19651 s.border = "2px solid #aaa";
19657 body.insertBefore(div, body.firstChild);
19662 initFrame: function() {
19663 this.createFrame();
19666 applyConfig: function() {
19667 Ext.dd.DDProxy.superclass.applyConfig.call(this);
19669 this.resizeFrame = (this.config.resizeFrame !== false);
19670 this.centerFrame = (this.config.centerFrame);
19671 this.setDragElId(this.config.dragElId || Ext.dd.DDProxy.dragElId);
19675 showFrame: function(iPageX, iPageY) {
19676 var el = this.getEl();
19677 var dragEl = this.getDragEl();
19678 var s = dragEl.style;
19680 this._resizeProxy();
19682 if (this.centerFrame) {
19683 this.setDelta( Math.round(parseInt(s.width, 10)/2),
19684 Math.round(parseInt(s.height, 10)/2) );
19687 this.setDragElPos(iPageX, iPageY);
19689 Ext.fly(dragEl).show();
19693 _resizeProxy: function() {
19694 if (this.resizeFrame) {
19695 var el = this.getEl();
19696 Ext.fly(this.getDragEl()).setSize(el.offsetWidth, el.offsetHeight);
19701 b4MouseDown: function(e) {
19702 var x = e.getPageX();
19703 var y = e.getPageY();
19704 this.autoOffset(x, y);
19705 this.setDragElPos(x, y);
19709 b4StartDrag: function(x, y) {
19711 this.showFrame(x, y);
19715 b4EndDrag: function(e) {
19716 Ext.fly(this.getDragEl()).hide();
19722 endDrag: function(e) {
19724 var lel = this.getEl();
19725 var del = this.getDragEl();
19728 del.style.visibility = "";
19733 lel.style.visibility = "hidden";
19734 Ext.dd.DDM.moveToEl(lel, del);
19735 del.style.visibility = "hidden";
19736 lel.style.visibility = "";
19741 beforeMove : function(){
19745 afterDrag : function(){
19749 toString: function() {
19750 return ("DDProxy " + this.id);
19755 Ext.dd.DDTarget = function(id, sGroup, config) {
19757 this.initTarget(id, sGroup, config);
19762 Ext.extend(Ext.dd.DDTarget, Ext.dd.DragDrop, {
19764 getDragEl: Ext.emptyFn,
19766 isValidHandleChild: Ext.emptyFn,
19768 startDrag: Ext.emptyFn,
19770 endDrag: Ext.emptyFn,
19772 onDrag: Ext.emptyFn,
19774 onDragDrop: Ext.emptyFn,
19776 onDragEnter: Ext.emptyFn,
19778 onDragOut: Ext.emptyFn,
19780 onDragOver: Ext.emptyFn,
19782 onInvalidDrop: Ext.emptyFn,
19784 onMouseDown: Ext.emptyFn,
19786 onMouseUp: Ext.emptyFn,
19788 setXConstraint: Ext.emptyFn,
19790 setYConstraint: Ext.emptyFn,
19792 resetConstraints: Ext.emptyFn,
19794 clearConstraints: Ext.emptyFn,
19796 clearTicks: Ext.emptyFn,
19798 setInitPosition: Ext.emptyFn,
19800 setDragElId: Ext.emptyFn,
19802 setHandleElId: Ext.emptyFn,
19804 setOuterHandleElId: Ext.emptyFn,
19806 addInvalidHandleClass: Ext.emptyFn,
19808 addInvalidHandleId: Ext.emptyFn,
19810 addInvalidHandleType: Ext.emptyFn,
19812 removeInvalidHandleClass: Ext.emptyFn,
19814 removeInvalidHandleId: Ext.emptyFn,
19816 removeInvalidHandleType: Ext.emptyFn,
19818 toString: function() {
19819 return ("DDTarget " + this.id);
19822 Ext.dd.DragTracker = Ext.extend(Ext.util.Observable, {
19830 constructor : function(config){
19831 Ext.apply(this, config);
19847 this.dragRegion = new Ext.lib.Region(0,0,0,0);
19850 this.initEl(this.el);
19852 Ext.dd.DragTracker.superclass.constructor.call(this, config);
19855 initEl: function(el){
19856 this.el = Ext.get(el);
19857 el.on('mousedown', this.onMouseDown, this,
19858 this.delegate ? {delegate: this.delegate} : undefined);
19861 destroy : function(){
19862 this.el.un('mousedown', this.onMouseDown, this);
19866 onMouseDown: function(e, target){
19867 if(this.fireEvent('mousedown', this, e) !== false && this.onBeforeStart(e) !== false){
19868 this.startXY = this.lastXY = e.getXY();
19869 this.dragTarget = this.delegate ? target : this.el.dom;
19870 if(this.preventDefault !== false){
19871 e.preventDefault();
19873 var doc = Ext.getDoc();
19874 doc.on('mouseup', this.onMouseUp, this);
19875 doc.on('mousemove', this.onMouseMove, this);
19876 doc.on('selectstart', this.stopSelect, this);
19877 if(this.autoStart){
19878 this.timer = this.triggerStart.defer(this.autoStart === true ? 1000 : this.autoStart, this);
19883 onMouseMove: function(e, target){
19885 if(this.active && Ext.isIE && !e.browserEvent.button){
19886 e.preventDefault();
19891 e.preventDefault();
19892 var xy = e.getXY(), s = this.startXY;
19895 if(Math.abs(s[0]-xy[0]) > this.tolerance || Math.abs(s[1]-xy[1]) > this.tolerance){
19896 this.triggerStart();
19901 this.fireEvent('mousemove', this, e);
19903 this.fireEvent('drag', this, e);
19906 onMouseUp: function(e) {
19907 var doc = Ext.getDoc();
19908 doc.un('mousemove', this.onMouseMove, this);
19909 doc.un('mouseup', this.onMouseUp, this);
19910 doc.un('selectstart', this.stopSelect, this);
19911 e.preventDefault();
19913 var wasActive = this.active;
19914 this.active = false;
19915 delete this.elRegion;
19916 this.fireEvent('mouseup', this, e);
19919 this.fireEvent('dragend', this, e);
19923 triggerStart: function(isTimer) {
19925 this.active = true;
19926 this.onStart(this.startXY);
19927 this.fireEvent('dragstart', this, this.startXY);
19930 clearStart : function() {
19932 clearTimeout(this.timer);
19937 stopSelect : function(e) {
19943 onBeforeStart : function(e) {
19948 onStart : function(xy) {
19953 onDrag : function(e) {
19958 onEnd : function(e) {
19963 getDragTarget : function(){
19964 return this.dragTarget;
19967 getDragCt : function(){
19971 getXY : function(constrain){
19973 this.constrainModes[constrain].call(this, this.lastXY) : this.lastXY;
19976 getOffset : function(constrain){
19977 var xy = this.getXY(constrain);
19978 var s = this.startXY;
19979 return [s[0]-xy[0], s[1]-xy[1]];
19983 'point' : function(xy){
19985 if(!this.elRegion){
19986 this.elRegion = this.getDragCt().getRegion();
19989 var dr = this.dragRegion;
19996 dr.constrainTo(this.elRegion);
19998 return [dr.left, dr.top];
20002 Ext.dd.ScrollManager = function(){
20003 var ddm = Ext.dd.DragDropMgr;
20008 var onStop = function(e){
20013 var triggerRefresh = function(){
20014 if(ddm.dragCurrent){
20015 ddm.refreshCache(ddm.dragCurrent.groups);
20019 var doScroll = function(){
20020 if(ddm.dragCurrent){
20021 var dds = Ext.dd.ScrollManager;
20022 var inc = proc.el.ddScrollConfig ?
20023 proc.el.ddScrollConfig.increment : dds.increment;
20025 if(proc.el.scroll(proc.dir, inc)){
20029 proc.el.scroll(proc.dir, inc, true, dds.animDuration, triggerRefresh);
20034 var clearProc = function(){
20036 clearInterval(proc.id);
20043 var startProc = function(el, dir){
20047 var freq = (el.ddScrollConfig && el.ddScrollConfig.frequency) ?
20048 el.ddScrollConfig.frequency : Ext.dd.ScrollManager.frequency;
20049 proc.id = setInterval(doScroll, freq);
20052 var onFire = function(e, isDrop){
20053 if(isDrop || !ddm.dragCurrent){ return; }
20054 var dds = Ext.dd.ScrollManager;
20055 if(!dragEl || dragEl != ddm.dragCurrent){
20056 dragEl = ddm.dragCurrent;
20058 dds.refreshCache();
20061 var xy = Ext.lib.Event.getXY(e);
20062 var pt = new Ext.lib.Point(xy[0], xy[1]);
20063 for(var id in els){
20064 var el = els[id], r = el._region;
20065 var c = el.ddScrollConfig ? el.ddScrollConfig : dds;
20066 if(r && r.contains(pt) && el.isScrollable()){
20067 if(r.bottom - pt.y <= c.vthresh){
20069 startProc(el, "down");
20072 }else if(r.right - pt.x <= c.hthresh){
20074 startProc(el, "left");
20077 }else if(pt.y - r.top <= c.vthresh){
20079 startProc(el, "up");
20082 }else if(pt.x - r.left <= c.hthresh){
20084 startProc(el, "right");
20093 ddm.fireEvents = ddm.fireEvents.createSequence(onFire, ddm);
20094 ddm.stopDrag = ddm.stopDrag.createSequence(onStop, ddm);
20098 register : function(el){
20099 if(Ext.isArray(el)){
20100 for(var i = 0, len = el.length; i < len; i++) {
20101 this.register(el[i]);
20110 unregister : function(el){
20111 if(Ext.isArray(el)){
20112 for(var i = 0, len = el.length; i < len; i++) {
20113 this.unregister(el[i]);
20139 refreshCache : function(){
20140 for(var id in els){
20141 if(typeof els[id] == 'object'){
20142 els[id]._region = els[id].getRegion();
20148 Ext.dd.Registry = function(){
20151 var autoIdSeed = 0;
20153 var getId = function(el, autogen){
20154 if(typeof el == "string"){
20158 if(!id && autogen !== false){
20159 id = "extdd-" + (++autoIdSeed);
20167 register : function(el, data){
20169 if(typeof el == "string"){
20170 el = document.getElementById(el);
20173 elements[getId(el)] = data;
20174 if(data.isHandle !== false){
20175 handles[data.ddel.id] = data;
20178 var hs = data.handles;
20179 for(var i = 0, len = hs.length; i < len; i++){
20180 handles[getId(hs[i])] = data;
20186 unregister : function(el){
20187 var id = getId(el, false);
20188 var data = elements[id];
20190 delete elements[id];
20192 var hs = data.handles;
20193 for(var i = 0, len = hs.length; i < len; i++){
20194 delete handles[getId(hs[i], false)];
20201 getHandle : function(id){
20202 if(typeof id != "string"){
20205 return handles[id];
20209 getHandleFromEvent : function(e){
20210 var t = Ext.lib.Event.getTarget(e);
20211 return t ? handles[t.id] : null;
20215 getTarget : function(id){
20216 if(typeof id != "string"){
20219 return elements[id];
20223 getTargetFromEvent : function(e){
20224 var t = Ext.lib.Event.getTarget(e);
20225 return t ? elements[t.id] || handles[t.id] : null;
20229 Ext.dd.StatusProxy = function(config){
20230 Ext.apply(this, config);
20231 this.id = this.id || Ext.id();
20232 this.el = new Ext.Layer({
20234 id: this.id, tag: "div", cls: "x-dd-drag-proxy "+this.dropNotAllowed, children: [
20235 {tag: "div", cls: "x-dd-drop-icon"},
20236 {tag: "div", cls: "x-dd-drag-ghost"}
20239 shadow: !config || config.shadow !== false
20241 this.ghost = Ext.get(this.el.dom.childNodes[1]);
20242 this.dropStatus = this.dropNotAllowed;
20245 Ext.dd.StatusProxy.prototype = {
20247 dropAllowed : "x-dd-drop-ok",
20249 dropNotAllowed : "x-dd-drop-nodrop",
20252 setStatus : function(cssClass){
20253 cssClass = cssClass || this.dropNotAllowed;
20254 if(this.dropStatus != cssClass){
20255 this.el.replaceClass(this.dropStatus, cssClass);
20256 this.dropStatus = cssClass;
20261 reset : function(clearGhost){
20262 this.el.dom.className = "x-dd-drag-proxy " + this.dropNotAllowed;
20263 this.dropStatus = this.dropNotAllowed;
20265 this.ghost.update("");
20270 update : function(html){
20271 if(typeof html == "string"){
20272 this.ghost.update(html);
20274 this.ghost.update("");
20275 html.style.margin = "0";
20276 this.ghost.dom.appendChild(html);
20278 var el = this.ghost.dom.firstChild;
20280 Ext.fly(el).setStyle('float', 'none');
20285 getEl : function(){
20290 getGhost : function(){
20295 hide : function(clear){
20304 if(this.anim && this.anim.isAnimated && this.anim.isAnimated()){
20320 repair : function(xy, callback, scope){
20321 this.callback = callback;
20322 this.scope = scope;
20323 if(xy && this.animRepair !== false){
20324 this.el.addClass("x-dd-drag-repair");
20325 this.el.hideUnders(true);
20326 this.anim = this.el.shift({
20327 duration: this.repairDuration || .5,
20331 callback: this.afterRepair,
20335 this.afterRepair();
20340 afterRepair : function(){
20342 if(typeof this.callback == "function"){
20343 this.callback.call(this.scope || this);
20345 this.callback = null;
20349 destroy: function(){
20350 Ext.destroy(this.ghost, this.el);
20353 Ext.dd.DragSource = function(el, config){
20354 this.el = Ext.get(el);
20355 if(!this.dragData){
20356 this.dragData = {};
20359 Ext.apply(this, config);
20362 this.proxy = new Ext.dd.StatusProxy();
20364 Ext.dd.DragSource.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group,
20365 {dragElId : this.proxy.id, resizeFrame: false, isTarget: false, scroll: this.scroll === true});
20367 this.dragging = false;
20370 Ext.extend(Ext.dd.DragSource, Ext.dd.DDProxy, {
20373 dropAllowed : "x-dd-drop-ok",
20375 dropNotAllowed : "x-dd-drop-nodrop",
20378 getDragData : function(e){
20379 return this.dragData;
20383 onDragEnter : function(e, id){
20384 var target = Ext.dd.DragDropMgr.getDDById(id);
20385 this.cachedTarget = target;
20386 if(this.beforeDragEnter(target, e, id) !== false){
20387 if(target.isNotifyTarget){
20388 var status = target.notifyEnter(this, e, this.dragData);
20389 this.proxy.setStatus(status);
20391 this.proxy.setStatus(this.dropAllowed);
20394 if(this.afterDragEnter){
20396 this.afterDragEnter(target, e, id);
20402 beforeDragEnter : function(target, e, id){
20407 alignElWithMouse: function() {
20408 Ext.dd.DragSource.superclass.alignElWithMouse.apply(this, arguments);
20413 onDragOver : function(e, id){
20414 var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
20415 if(this.beforeDragOver(target, e, id) !== false){
20416 if(target.isNotifyTarget){
20417 var status = target.notifyOver(this, e, this.dragData);
20418 this.proxy.setStatus(status);
20421 if(this.afterDragOver){
20423 this.afterDragOver(target, e, id);
20429 beforeDragOver : function(target, e, id){
20434 onDragOut : function(e, id){
20435 var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
20436 if(this.beforeDragOut(target, e, id) !== false){
20437 if(target.isNotifyTarget){
20438 target.notifyOut(this, e, this.dragData);
20440 this.proxy.reset();
20441 if(this.afterDragOut){
20443 this.afterDragOut(target, e, id);
20446 this.cachedTarget = null;
20450 beforeDragOut : function(target, e, id){
20455 onDragDrop : function(e, id){
20456 var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
20457 if(this.beforeDragDrop(target, e, id) !== false){
20458 if(target.isNotifyTarget){
20459 if(target.notifyDrop(this, e, this.dragData)){
20460 this.onValidDrop(target, e, id);
20462 this.onInvalidDrop(target, e, id);
20465 this.onValidDrop(target, e, id);
20468 if(this.afterDragDrop){
20470 this.afterDragDrop(target, e, id);
20473 delete this.cachedTarget;
20477 beforeDragDrop : function(target, e, id){
20482 onValidDrop : function(target, e, id){
20484 if(this.afterValidDrop){
20486 this.afterValidDrop(target, e, id);
20491 getRepairXY : function(e, data){
20492 return this.el.getXY();
20496 onInvalidDrop : function(target, e, id){
20497 this.beforeInvalidDrop(target, e, id);
20498 if(this.cachedTarget){
20499 if(this.cachedTarget.isNotifyTarget){
20500 this.cachedTarget.notifyOut(this, e, this.dragData);
20502 this.cacheTarget = null;
20504 this.proxy.repair(this.getRepairXY(e, this.dragData), this.afterRepair, this);
20506 if(this.afterInvalidDrop){
20508 this.afterInvalidDrop(e, id);
20513 afterRepair : function(){
20515 this.el.highlight(this.hlColor || "c3daf9");
20517 this.dragging = false;
20521 beforeInvalidDrop : function(target, e, id){
20526 handleMouseDown : function(e){
20527 if(this.dragging) {
20530 var data = this.getDragData(e);
20531 if(data && this.onBeforeDrag(data, e) !== false){
20532 this.dragData = data;
20534 Ext.dd.DragSource.superclass.handleMouseDown.apply(this, arguments);
20539 onBeforeDrag : function(data, e){
20544 onStartDrag : Ext.emptyFn,
20547 startDrag : function(x, y){
20548 this.proxy.reset();
20549 this.dragging = true;
20550 this.proxy.update("");
20551 this.onInitDrag(x, y);
20556 onInitDrag : function(x, y){
20557 var clone = this.el.dom.cloneNode(true);
20558 clone.id = Ext.id();
20559 this.proxy.update(clone);
20560 this.onStartDrag(x, y);
20565 getProxy : function(){
20570 hideProxy : function(){
20572 this.proxy.reset(true);
20573 this.dragging = false;
20577 triggerCacheRefresh : function(){
20578 Ext.dd.DDM.refreshCache(this.groups);
20582 b4EndDrag: function(e) {
20586 endDrag : function(e){
20587 this.onEndDrag(this.dragData, e);
20591 onEndDrag : function(data, e){
20595 autoOffset : function(x, y) {
20596 this.setDelta(-12, -20);
20599 destroy: function(){
20600 Ext.dd.DragSource.superclass.destroy.call(this);
20601 Ext.destroy(this.proxy);
20604 Ext.dd.DropTarget = Ext.extend(Ext.dd.DDTarget, {
20606 constructor : function(el, config){
20607 this.el = Ext.get(el);
20609 Ext.apply(this, config);
20611 if(this.containerScroll){
20612 Ext.dd.ScrollManager.register(this.el);
20615 Ext.dd.DropTarget.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group,
20622 dropAllowed : "x-dd-drop-ok",
20624 dropNotAllowed : "x-dd-drop-nodrop",
20630 isNotifyTarget : true,
20633 notifyEnter : function(dd, e, data){
20634 if(this.overClass){
20635 this.el.addClass(this.overClass);
20637 return this.dropAllowed;
20641 notifyOver : function(dd, e, data){
20642 return this.dropAllowed;
20646 notifyOut : function(dd, e, data){
20647 if(this.overClass){
20648 this.el.removeClass(this.overClass);
20653 notifyDrop : function(dd, e, data){
20657 destroy : function(){
20658 Ext.dd.DropTarget.superclass.destroy.call(this);
20659 if(this.containerScroll){
20660 Ext.dd.ScrollManager.unregister(this.el);
20664 Ext.dd.DragZone = Ext.extend(Ext.dd.DragSource, {
20666 constructor : function(el, config){
20667 Ext.dd.DragZone.superclass.constructor.call(this, el, config);
20668 if(this.containerScroll){
20669 Ext.dd.ScrollManager.register(this.el);
20678 getDragData : function(e){
20679 return Ext.dd.Registry.getHandleFromEvent(e);
20683 onInitDrag : function(x, y){
20684 this.proxy.update(this.dragData.ddel.cloneNode(true));
20685 this.onStartDrag(x, y);
20690 afterRepair : function(){
20692 Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9");
20694 this.dragging = false;
20698 getRepairXY : function(e){
20699 return Ext.Element.fly(this.dragData.ddel).getXY();
20702 destroy : function(){
20703 Ext.dd.DragZone.superclass.destroy.call(this);
20704 if(this.containerScroll){
20705 Ext.dd.ScrollManager.unregister(this.el);
20709 Ext.dd.DropZone = function(el, config){
20710 Ext.dd.DropZone.superclass.constructor.call(this, el, config);
20713 Ext.extend(Ext.dd.DropZone, Ext.dd.DropTarget, {
20715 getTargetFromEvent : function(e){
20716 return Ext.dd.Registry.getTargetFromEvent(e);
20720 onNodeEnter : function(n, dd, e, data){
20725 onNodeOver : function(n, dd, e, data){
20726 return this.dropAllowed;
20730 onNodeOut : function(n, dd, e, data){
20735 onNodeDrop : function(n, dd, e, data){
20740 onContainerOver : function(dd, e, data){
20741 return this.dropNotAllowed;
20745 onContainerDrop : function(dd, e, data){
20750 notifyEnter : function(dd, e, data){
20751 return this.dropNotAllowed;
20755 notifyOver : function(dd, e, data){
20756 var n = this.getTargetFromEvent(e);
20758 if(this.lastOverNode){
20759 this.onNodeOut(this.lastOverNode, dd, e, data);
20760 this.lastOverNode = null;
20762 return this.onContainerOver(dd, e, data);
20764 if(this.lastOverNode != n){
20765 if(this.lastOverNode){
20766 this.onNodeOut(this.lastOverNode, dd, e, data);
20768 this.onNodeEnter(n, dd, e, data);
20769 this.lastOverNode = n;
20771 return this.onNodeOver(n, dd, e, data);
20775 notifyOut : function(dd, e, data){
20776 if(this.lastOverNode){
20777 this.onNodeOut(this.lastOverNode, dd, e, data);
20778 this.lastOverNode = null;
20783 notifyDrop : function(dd, e, data){
20784 if(this.lastOverNode){
20785 this.onNodeOut(this.lastOverNode, dd, e, data);
20786 this.lastOverNode = null;
20788 var n = this.getTargetFromEvent(e);
20790 this.onNodeDrop(n, dd, e, data) :
20791 this.onContainerDrop(dd, e, data);
20795 triggerCacheRefresh : function(){
20796 Ext.dd.DDM.refreshCache(this.groups);
20799 Ext.Element.addMethods({
20801 initDD : function(group, config, overrides){
20802 var dd = new Ext.dd.DD(Ext.id(this.dom), group, config);
20803 return Ext.apply(dd, overrides);
20807 initDDProxy : function(group, config, overrides){
20808 var dd = new Ext.dd.DDProxy(Ext.id(this.dom), group, config);
20809 return Ext.apply(dd, overrides);
20813 initDDTarget : function(group, config, overrides){
20814 var dd = new Ext.dd.DDTarget(Ext.id(this.dom), group, config);
20815 return Ext.apply(dd, overrides);
20819 Ext.data.Api = (function() {
20825 var validActions = {};
20833 destroy : 'destroy'
20845 isAction : function(action) {
20846 return (Ext.data.Api.actions[action]) ? true : false;
20850 getVerb : function(name) {
20851 if (validActions[name]) {
20852 return validActions[name];
20854 for (var verb in this.actions) {
20855 if (this.actions[verb] === name) {
20856 validActions[name] = verb;
20860 return (validActions[name] !== undefined) ? validActions[name] : null;
20864 isValid : function(api){
20866 var crud = this.actions;
20867 for (var action in api) {
20868 if (!(action in crud)) {
20869 invalid.push(action);
20872 return (!invalid.length) ? true : invalid;
20876 hasUniqueUrl : function(proxy, verb) {
20877 var url = (proxy.api[verb]) ? proxy.api[verb].url : null;
20879 for (var action in proxy.api) {
20880 if ((unique = (action === verb) ? true : (proxy.api[action].url != url) ? true : false) === false) {
20888 prepare : function(proxy) {
20892 for (var verb in this.actions) {
20893 var action = this.actions[verb];
20894 proxy.api[action] = proxy.api[action] || proxy.url || proxy.directFn;
20895 if (typeof(proxy.api[action]) == 'string') {
20896 proxy.api[action] = {
20897 url: proxy.api[action],
20898 method: (proxy.restful === true) ? Ext.data.Api.restActions[action] : undefined
20905 restify : function(proxy) {
20906 proxy.restful = true;
20907 for (var verb in this.restActions) {
20908 proxy.api[this.actions[verb]].method ||
20909 (proxy.api[this.actions[verb]].method = this.restActions[verb]);
20913 proxy.onWrite = proxy.onWrite.createInterceptor(function(action, o, response, rs) {
20914 var reader = o.reader;
20915 var res = new Ext.data.Response({
20920 switch (response.status) {
20925 if (Ext.isEmpty(res.raw.responseText)) {
20926 res.success = true;
20933 res.success = true;
20940 if (res.success === true) {
20941 this.fireEvent("write", this, action, res.data, res, rs, o.request.arg);
20943 this.fireEvent('exception', this, 'remote', action, o, res, rs);
20945 o.request.callback.call(o.request.scope, res.data, res, res.success);
20954 Ext.data.Response = function(params, response) {
20955 Ext.apply(this, params, {
20959 Ext.data.Response.prototype = {
20966 getMessage : function() {
20967 return this.message;
20969 getSuccess : function() {
20970 return this.success;
20972 getStatus : function() {
20973 return this.status;
20975 getRoot : function() {
20978 getRawResponse : function() {
20984 Ext.data.Api.Error = Ext.extend(Ext.Error, {
20985 constructor : function(message, arg) {
20987 Ext.Error.call(this, message);
20989 name: 'Ext.data.Api'
20991 Ext.apply(Ext.data.Api.Error.prototype, {
20993 'action-url-undefined': 'No fallback url defined for this action. When defining a DataProxy api, please be sure to define an url for each CRUD action in Ext.data.Api.actions or define a default url in addition to your api-configuration.',
20994 'invalid': 'received an invalid API-configuration. Please ensure your proxy API-configuration contains only the actions defined in Ext.data.Api.actions',
20995 'invalid-url': 'Invalid url. Please review your proxy configuration.',
20996 'execute': 'Attempted to execute an unknown action. Valid API actions are defined in Ext.data.Api.actions"'
21003 Ext.data.SortTypes = {
21005 none : function(s){
21010 stripTagsRE : /<\/?[^>]+>/gi,
21013 asText : function(s){
21014 return String(s).replace(this.stripTagsRE, "");
21018 asUCText : function(s){
21019 return String(s).toUpperCase().replace(this.stripTagsRE, "");
21023 asUCString : function(s) {
21024 return String(s).toUpperCase();
21028 asDate : function(s) {
21033 return s.getTime();
21035 return Date.parse(String(s));
21039 asFloat : function(s) {
21040 var val = parseFloat(String(s).replace(/,/g, ""));
21041 return isNaN(val) ? 0 : val;
21045 asInt : function(s) {
21046 var val = parseInt(String(s).replace(/,/g, ""), 10);
21047 return isNaN(val) ? 0 : val;
21050 Ext.data.Record = function(data, id){
21052 this.id = (id || id === 0) ? id : Ext.data.Record.id(this);
21053 this.data = data || {};
21057 Ext.data.Record.create = function(o){
21058 var f = Ext.extend(Ext.data.Record, {});
21059 var p = f.prototype;
21060 p.fields = new Ext.util.MixedCollection(false, function(field){
21063 for(var i = 0, len = o.length; i < len; i++){
21064 p.fields.add(new Ext.data.Field(o[i]));
21066 f.getField = function(name){
21067 return p.fields.get(name);
21072 Ext.data.Record.PREFIX = 'ext-record';
21073 Ext.data.Record.AUTO_ID = 1;
21074 Ext.data.Record.EDIT = 'edit';
21075 Ext.data.Record.REJECT = 'reject';
21076 Ext.data.Record.COMMIT = 'commit';
21080 Ext.data.Record.id = function(rec) {
21081 rec.phantom = true;
21082 return [Ext.data.Record.PREFIX, '-', Ext.data.Record.AUTO_ID++].join('');
21085 Ext.data.Record.prototype = {
21101 join : function(store){
21103 this.store = store;
21107 set : function(name, value){
21108 var encode = Ext.isPrimitive(value) ? String : Ext.encode;
21109 if(encode(this.data[name]) == encode(value)) {
21113 if(!this.modified){
21114 this.modified = {};
21116 if(this.modified[name] === undefined){
21117 this.modified[name] = this.data[name];
21119 this.data[name] = value;
21126 afterEdit : function(){
21127 if (this.store != undefined && typeof this.store.afterEdit == "function") {
21128 this.store.afterEdit(this);
21133 afterReject : function(){
21135 this.store.afterReject(this);
21140 afterCommit : function(){
21142 this.store.afterCommit(this);
21147 get : function(name){
21148 return this.data[name];
21152 beginEdit : function(){
21153 this.editing = true;
21154 this.modified = this.modified || {};
21158 cancelEdit : function(){
21159 this.editing = false;
21160 delete this.modified;
21164 endEdit : function(){
21165 this.editing = false;
21172 reject : function(silent){
21173 var m = this.modified;
21175 if(typeof m[n] != "function"){
21176 this.data[n] = m[n];
21179 this.dirty = false;
21180 delete this.modified;
21181 this.editing = false;
21182 if(silent !== true){
21183 this.afterReject();
21188 commit : function(silent){
21189 this.dirty = false;
21190 delete this.modified;
21191 this.editing = false;
21192 if(silent !== true){
21193 this.afterCommit();
21198 getChanges : function(){
21199 var m = this.modified, cs = {};
21201 if(m.hasOwnProperty(n)){
21202 cs[n] = this.data[n];
21209 hasError : function(){
21210 return this.error !== null;
21214 clearError : function(){
21219 copy : function(newId) {
21220 return new this.constructor(Ext.apply({}, this.data), newId || this.id);
21224 isModified : function(fieldName){
21225 return !!(this.modified && this.modified.hasOwnProperty(fieldName));
21229 isValid : function() {
21230 return this.fields.find(function(f) {
21231 return (f.allowBlank === false && Ext.isEmpty(this.data[f.name])) ? true : false;
21232 },this) ? false : true;
21236 markDirty : function(){
21238 if(!this.modified){
21239 this.modified = {};
21241 this.fields.each(function(f) {
21242 this.modified[f.name] = this.data[f.name];
21247 Ext.StoreMgr = Ext.apply(new Ext.util.MixedCollection(), {
21251 register : function(){
21252 for(var i = 0, s; (s = arguments[i]); i++){
21258 unregister : function(){
21259 for(var i = 0, s; (s = arguments[i]); i++){
21260 this.remove(this.lookup(s));
21265 lookup : function(id){
21266 if(Ext.isArray(id)){
21267 var fields = ['field1'], expand = !Ext.isArray(id[0]);
21269 for(var i = 2, len = id[0].length; i <= len; ++i){
21270 fields.push('field' + i);
21273 return new Ext.data.ArrayStore({
21276 expandData: expand,
21282 return Ext.isObject(id) ? (id.events ? id : Ext.create(id, 'store')) : this.get(id);
21286 getKey : function(o){
21290 Ext.data.Store = Ext.extend(Ext.util.Observable, {
21298 writer : undefined,
21302 remoteSort : false,
21305 autoDestroy : false,
21308 pruneModifiedRecords : false,
21311 lastOptions : null,
21323 paramNames : undefined,
21326 defaultParamNames : {
21334 isDestroyed: false,
21337 hasMultiSort: false,
21340 batchKey : '_ext_batch_',
21342 constructor : function(config){
21343 this.data = new Ext.util.MixedCollection(false);
21344 this.data.getKey = function(o){
21352 if(config && config.data){
21353 this.inlineData = config.data;
21354 delete config.data;
21357 Ext.apply(this, config);
21360 this.baseParams = Ext.isObject(this.baseParams) ? this.baseParams : {};
21362 this.paramNames = Ext.applyIf(this.paramNames || {}, this.defaultParamNames);
21364 if((this.url || this.api) && !this.proxy){
21365 this.proxy = new Ext.data.HttpProxy({url: this.url, api: this.api});
21368 if (this.restful === true && this.proxy) {
21371 this.batch = false;
21372 Ext.data.Api.restify(this.proxy);
21376 if(!this.recordType){
21377 this.recordType = this.reader.recordType;
21379 if(this.reader.onMetaChange){
21380 this.reader.onMetaChange = this.reader.onMetaChange.createSequence(this.onMetaChange, this);
21383 if (this.writer instanceof(Ext.data.DataWriter) === false) {
21384 this.writer = this.buildWriter(this.writer);
21386 this.writer.meta = this.reader.meta;
21387 this.pruneModifiedRecords = true;
21393 if(this.recordType){
21395 this.fields = this.recordType.prototype.fields;
21397 this.modified = [];
21433 this.relayEvents(this.proxy, ['loadexception', 'exception']);
21439 add: this.createRecords,
21440 remove: this.destroyRecord,
21441 update: this.updateRecord,
21442 clear: this.onClear
21446 this.sortToggle = {};
21447 if(this.sortField){
21448 this.setDefaultSort(this.sortField, this.sortDir);
21449 }else if(this.sortInfo){
21450 this.setDefaultSort(this.sortInfo.field, this.sortInfo.direction);
21453 Ext.data.Store.superclass.constructor.call(this);
21456 this.storeId = this.id;
21460 Ext.StoreMgr.register(this);
21462 if(this.inlineData){
21463 this.loadData(this.inlineData);
21464 delete this.inlineData;
21465 }else if(this.autoLoad){
21466 this.load.defer(10, this, [
21467 typeof this.autoLoad == 'object' ?
21468 this.autoLoad : undefined]);
21471 this.batchCounter = 0;
21476 buildWriter : function(config) {
21477 var klass = undefined,
21478 type = (config.format || 'json').toLowerCase();
21481 klass = Ext.data.JsonWriter;
21484 klass = Ext.data.XmlWriter;
21487 klass = Ext.data.JsonWriter;
21489 return new klass(config);
21493 destroy : function(){
21494 if(!this.isDestroyed){
21496 Ext.StoreMgr.unregister(this);
21500 Ext.destroy(this.proxy);
21501 this.reader = this.writer = null;
21502 this.purgeListeners();
21503 this.isDestroyed = true;
21508 add : function(records){
21509 records = [].concat(records);
21510 if(records.length < 1){
21513 for(var i = 0, len = records.length; i < len; i++){
21514 records[i].join(this);
21516 var index = this.data.length;
21517 this.data.addAll(records);
21519 this.snapshot.addAll(records);
21521 this.fireEvent('add', this, records, index);
21525 addSorted : function(record){
21526 var index = this.findInsertIndex(record);
21527 this.insert(index, record);
21531 remove : function(record){
21532 if(Ext.isArray(record)){
21533 Ext.each(record, function(r){
21538 var index = this.data.indexOf(record);
21541 this.data.removeAt(index);
21543 if(this.pruneModifiedRecords){
21544 this.modified.remove(record);
21547 this.snapshot.remove(record);
21550 this.fireEvent('remove', this, record, index);
21555 removeAt : function(index){
21556 this.remove(this.getAt(index));
21560 removeAll : function(silent){
21562 this.each(function(rec){
21567 this.snapshot.clear();
21569 if(this.pruneModifiedRecords){
21570 this.modified = [];
21572 if (silent !== true) {
21573 this.fireEvent('clear', this, items);
21578 onClear: function(store, records){
21579 Ext.each(records, function(rec, index){
21580 this.destroyRecord(this, rec, index);
21585 insert : function(index, records){
21586 records = [].concat(records);
21587 for(var i = 0, len = records.length; i < len; i++){
21588 this.data.insert(index, records[i]);
21589 records[i].join(this);
21592 this.snapshot.addAll(records);
21594 this.fireEvent('add', this, records, index);
21598 indexOf : function(record){
21599 return this.data.indexOf(record);
21603 indexOfId : function(id){
21604 return this.data.indexOfKey(id);
21608 getById : function(id){
21609 return (this.snapshot || this.data).key(id);
21613 getAt : function(index){
21614 return this.data.itemAt(index);
21618 getRange : function(start, end){
21619 return this.data.getRange(start, end);
21623 storeOptions : function(o){
21624 o = Ext.apply({}, o);
21627 this.lastOptions = o;
21631 clearData: function(){
21632 this.data.each(function(rec) {
21639 load : function(options) {
21640 options = Ext.apply({}, options);
21641 this.storeOptions(options);
21642 if(this.sortInfo && this.remoteSort){
21643 var pn = this.paramNames;
21644 options.params = Ext.apply({}, options.params);
21645 options.params[pn.sort] = this.sortInfo.field;
21646 options.params[pn.dir] = this.sortInfo.direction;
21649 return this.execute('read', null, options);
21651 this.handleException(e);
21657 updateRecord : function(store, record, action) {
21658 if (action == Ext.data.Record.EDIT && this.autoSave === true && (!record.phantom || (record.phantom && record.isValid()))) {
21664 createRecords : function(store, rs, index) {
21665 for (var i = 0, len = rs.length; i < len; i++) {
21666 if (rs[i].phantom && rs[i].isValid()) {
21668 this.modified.push(rs[i]);
21671 if (this.autoSave === true) {
21677 destroyRecord : function(store, record, index) {
21678 if (this.modified.indexOf(record) != -1) {
21679 this.modified.remove(record);
21681 if (!record.phantom) {
21682 this.removed.push(record);
21687 record.lastIndex = index;
21689 if (this.autoSave === true) {
21696 execute : function(action, rs, options, batch) {
21698 if (!Ext.data.Api.isAction(action)) {
21699 throw new Ext.data.Api.Error('execute', action);
21702 options = Ext.applyIf(options||{}, {
21705 if(batch !== undefined){
21706 this.addToBatch(batch);
21710 var doRequest = true;
21712 if (action === 'read') {
21713 doRequest = this.fireEvent('beforeload', this, options);
21714 Ext.applyIf(options.params, this.baseParams);
21719 if (this.writer.listful === true && this.restful !== true) {
21720 rs = (Ext.isArray(rs)) ? rs : [rs];
21723 else if (Ext.isArray(rs) && rs.length == 1) {
21727 if ((doRequest = this.fireEvent('beforewrite', this, action, rs, options)) !== false) {
21728 this.writer.apply(options.params, this.baseParams, action, rs);
21731 if (doRequest !== false) {
21733 if (this.writer && this.proxy.url && !this.proxy.restful && !Ext.data.Api.hasUniqueUrl(this.proxy, action)) {
21734 options.params.xaction = action;
21741 this.proxy.request(Ext.data.Api.actions[action], rs, options.params, this.reader, this.createCallback(action, rs, batch), this, options);
21747 save : function() {
21748 if (!this.writer) {
21749 throw new Ext.data.Store.Error('writer-undefined');
21758 if(this.removed.length){
21759 queue.push(['destroy', this.removed]);
21763 var rs = [].concat(this.getModifiedRecords());
21767 for(var i = rs.length-1; i >= 0; i--){
21768 if(rs[i].phantom === true){
21769 var rec = rs.splice(i, 1).shift();
21771 phantoms.push(rec);
21773 }else if(!rs[i].isValid()){
21778 if(phantoms.length){
21779 queue.push(['create', phantoms]);
21784 queue.push(['update', rs]);
21787 len = queue.length;
21789 batch = ++this.batchCounter;
21790 for(var i = 0; i < len; ++i){
21792 data[trans[0]] = trans[1];
21794 if(this.fireEvent('beforesave', this, data) !== false){
21795 for(var i = 0; i < len; ++i){
21797 this.doTransaction(trans[0], trans[1], batch);
21806 doTransaction : function(action, rs, batch) {
21807 function transaction(records) {
21809 this.execute(action, records, undefined, batch);
21811 this.handleException(e);
21814 if(this.batch === false){
21815 for(var i = 0, len = rs.length; i < len; i++){
21816 transaction.call(this, rs[i]);
21819 transaction.call(this, rs);
21824 addToBatch : function(batch){
21825 var b = this.batches,
21826 key = this.batchKey + batch,
21839 removeFromBatch : function(batch, action, data){
21840 var b = this.batches,
21841 key = this.batchKey + batch,
21848 arr = o.data[action] || [];
21849 o.data[action] = arr.concat(data);
21853 this.fireEvent('save', this, batch, data);
21862 createCallback : function(action, rs, batch) {
21863 var actions = Ext.data.Api.actions;
21864 return (action == 'read') ? this.loadRecords : function(data, response, success) {
21866 this['on' + Ext.util.Format.capitalize(action) + 'Records'](success, rs, [].concat(data));
21868 if (success === true) {
21869 this.fireEvent('write', this, action, data, response, rs);
21871 this.removeFromBatch(batch, action, data);
21878 clearModified : function(rs) {
21879 if (Ext.isArray(rs)) {
21880 for (var n=rs.length-1;n>=0;n--) {
21881 this.modified.splice(this.modified.indexOf(rs[n]), 1);
21884 this.modified.splice(this.modified.indexOf(rs), 1);
21889 reMap : function(record) {
21890 if (Ext.isArray(record)) {
21891 for (var i = 0, len = record.length; i < len; i++) {
21892 this.reMap(record[i]);
21895 delete this.data.map[record._phid];
21896 this.data.map[record.id] = record;
21897 var index = this.data.keys.indexOf(record._phid);
21898 this.data.keys.splice(index, 1, record.id);
21899 delete record._phid;
21904 onCreateRecords : function(success, rs, data) {
21905 if (success === true) {
21907 this.reader.realize(rs, data);
21911 this.handleException(e);
21912 if (Ext.isArray(rs)) {
21914 this.onCreateRecords(success, rs, data);
21921 onUpdateRecords : function(success, rs, data) {
21922 if (success === true) {
21924 this.reader.update(rs, data);
21926 this.handleException(e);
21927 if (Ext.isArray(rs)) {
21929 this.onUpdateRecords(success, rs, data);
21936 onDestroyRecords : function(success, rs, data) {
21938 rs = (rs instanceof Ext.data.Record) ? [rs] : [].concat(rs);
21939 for (var i=0,len=rs.length;i<len;i++) {
21940 this.removed.splice(this.removed.indexOf(rs[i]), 1);
21942 if (success === false) {
21945 for (i=rs.length-1;i>=0;i--) {
21946 this.insert(rs[i].lastIndex, rs[i]);
21952 handleException : function(e) {
21954 Ext.handleError(e);
21958 reload : function(options){
21959 this.load(Ext.applyIf(options||{}, this.lastOptions));
21964 loadRecords : function(o, options, success){
21965 if (this.isDestroyed === true) {
21968 if(!o || success === false){
21969 if(success !== false){
21970 this.fireEvent('load', this, [], options);
21972 if(options.callback){
21973 options.callback.call(options.scope || this, [], options, false, o);
21977 var r = o.records, t = o.totalRecords || r.length;
21978 if(!options || options.add !== true){
21979 if(this.pruneModifiedRecords){
21980 this.modified = [];
21982 for(var i = 0, len = r.length; i < len; i++){
21986 this.data = this.snapshot;
21987 delete this.snapshot;
21990 this.data.addAll(r);
21991 this.totalLength = t;
21993 this.fireEvent('datachanged', this);
21995 this.totalLength = Math.max(t, this.data.length+r.length);
21998 this.fireEvent('load', this, r, options);
21999 if(options.callback){
22000 options.callback.call(options.scope || this, r, options, true);
22005 loadData : function(o, append){
22006 var r = this.reader.readRecords(o);
22007 this.loadRecords(r, {add: append}, true);
22011 getCount : function(){
22012 return this.data.length || 0;
22016 getTotalCount : function(){
22017 return this.totalLength || 0;
22021 getSortState : function(){
22022 return this.sortInfo;
22026 applySort : function(){
22027 if ((this.sortInfo || this.multiSortInfo) && !this.remoteSort) {
22033 sortData : function() {
22034 var sortInfo = this.hasMultiSort ? this.multiSortInfo : this.sortInfo,
22035 direction = sortInfo.direction || "ASC",
22036 sorters = sortInfo.sorters,
22040 if (!this.hasMultiSort) {
22041 sorters = [{direction: direction, field: sortInfo.field}];
22045 for (var i=0, j = sorters.length; i < j; i++) {
22046 sortFns.push(this.createSortFunction(sorters[i].field, sorters[i].direction));
22049 if (sortFns.length == 0) {
22055 var directionModifier = direction.toUpperCase() == "DESC" ? -1 : 1;
22058 var fn = function(r1, r2) {
22059 var result = sortFns[0].call(this, r1, r2);
22062 if (sortFns.length > 1) {
22063 for (var i=1, j = sortFns.length; i < j; i++) {
22064 result = result || sortFns[i].call(this, r1, r2);
22068 return directionModifier * result;
22072 this.data.sort(direction, fn);
22073 if (this.snapshot && this.snapshot != this.data) {
22074 this.snapshot.sort(direction, fn);
22079 createSortFunction: function(field, direction) {
22080 direction = direction || "ASC";
22081 var directionModifier = direction.toUpperCase() == "DESC" ? -1 : 1;
22083 var sortType = this.fields.get(field).sortType;
22087 return function(r1, r2) {
22088 var v1 = sortType(r1.data[field]),
22089 v2 = sortType(r2.data[field]);
22091 return directionModifier * (v1 > v2 ? 1 : (v1 < v2 ? -1 : 0));
22096 setDefaultSort : function(field, dir) {
22097 dir = dir ? dir.toUpperCase() : 'ASC';
22098 this.sortInfo = {field: field, direction: dir};
22099 this.sortToggle[field] = dir;
22103 sort : function(fieldName, dir) {
22104 if (Ext.isArray(arguments[0])) {
22105 return this.multiSort.call(this, fieldName, dir);
22107 return this.singleSort(fieldName, dir);
22112 singleSort: function(fieldName, dir) {
22113 var field = this.fields.get(fieldName);
22114 if (!field) return false;
22116 var name = field.name,
22117 sortInfo = this.sortInfo || null,
22118 sortToggle = this.sortToggle ? this.sortToggle[name] : null;
22121 if (sortInfo && sortInfo.field == name) {
22122 dir = (this.sortToggle[name] || 'ASC').toggle('ASC', 'DESC');
22124 dir = field.sortDir;
22128 this.sortToggle[name] = dir;
22129 this.sortInfo = {field: name, direction: dir};
22130 this.hasMultiSort = false;
22132 if (this.remoteSort) {
22133 if (!this.load(this.lastOptions)) {
22135 this.sortToggle[name] = sortToggle;
22138 this.sortInfo = sortInfo;
22143 this.fireEvent('datachanged', this);
22148 multiSort: function(sorters, direction) {
22149 this.hasMultiSort = true;
22150 direction = direction || "ASC";
22153 if (this.multiSortInfo && direction == this.multiSortInfo.direction) {
22154 direction = direction.toggle("ASC", "DESC");
22158 this.multiSortInfo = {
22160 direction: direction
22163 if (this.remoteSort) {
22164 this.singleSort(sorters[0].field, sorters[0].direction);
22168 this.fireEvent('datachanged', this);
22173 each : function(fn, scope){
22174 this.data.each(fn, scope);
22178 getModifiedRecords : function(){
22179 return this.modified;
22183 sum : function(property, start, end){
22184 var rs = this.data.items, v = 0;
22185 start = start || 0;
22186 end = (end || end === 0) ? end : rs.length-1;
22188 for(var i = start; i <= end; i++){
22189 v += (rs[i].data[property] || 0);
22195 createFilterFn : function(property, value, anyMatch, caseSensitive, exactMatch){
22196 if(Ext.isEmpty(value, false)){
22199 value = this.data.createValueMatcher(value, anyMatch, caseSensitive, exactMatch);
22200 return function(r) {
22201 return value.test(r.data[property]);
22206 createMultipleFilterFn: function(filters) {
22207 return function(record) {
22208 var isMatch = true;
22210 for (var i=0, j = filters.length; i < j; i++) {
22211 var filter = filters[i],
22213 scope = filter.scope;
22215 isMatch = isMatch && fn.call(scope, record);
22223 filter : function(property, value, anyMatch, caseSensitive, exactMatch){
22225 if (Ext.isObject(property)) {
22226 property = [property];
22229 if (Ext.isArray(property)) {
22233 for (var i=0, j = property.length; i < j; i++) {
22234 var filter = property[i],
22236 scope = filter.scope || this;
22239 if (!Ext.isFunction(func)) {
22240 func = this.createFilterFn(filter.property, filter.value, filter.anyMatch, filter.caseSensitive, filter.exactMatch);
22243 filters.push({fn: func, scope: scope});
22246 var fn = this.createMultipleFilterFn(filters);
22249 var fn = this.createFilterFn(property, value, anyMatch, caseSensitive, exactMatch);
22252 return fn ? this.filterBy(fn) : this.clearFilter();
22256 filterBy : function(fn, scope){
22257 this.snapshot = this.snapshot || this.data;
22258 this.data = this.queryBy(fn, scope||this);
22259 this.fireEvent('datachanged', this);
22263 clearFilter : function(suppressEvent){
22264 if(this.isFiltered()){
22265 this.data = this.snapshot;
22266 delete this.snapshot;
22267 if(suppressEvent !== true){
22268 this.fireEvent('datachanged', this);
22274 isFiltered : function(){
22275 return !!this.snapshot && this.snapshot != this.data;
22279 query : function(property, value, anyMatch, caseSensitive){
22280 var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
22281 return fn ? this.queryBy(fn) : this.data.clone();
22285 queryBy : function(fn, scope){
22286 var data = this.snapshot || this.data;
22287 return data.filterBy(fn, scope||this);
22291 find : function(property, value, start, anyMatch, caseSensitive){
22292 var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
22293 return fn ? this.data.findIndexBy(fn, null, start) : -1;
22297 findExact: function(property, value, start){
22298 return this.data.findIndexBy(function(rec){
22299 return rec.get(property) === value;
22304 findBy : function(fn, scope, start){
22305 return this.data.findIndexBy(fn, scope, start);
22309 collect : function(dataIndex, allowNull, bypassFilter){
22310 var d = (bypassFilter === true && this.snapshot) ?
22311 this.snapshot.items : this.data.items;
22312 var v, sv, r = [], l = {};
22313 for(var i = 0, len = d.length; i < len; i++){
22314 v = d[i].data[dataIndex];
22316 if((allowNull || !Ext.isEmpty(v)) && !l[sv]){
22325 afterEdit : function(record){
22326 if(this.modified.indexOf(record) == -1){
22327 this.modified.push(record);
22329 this.fireEvent('update', this, record, Ext.data.Record.EDIT);
22333 afterReject : function(record){
22334 this.modified.remove(record);
22335 this.fireEvent('update', this, record, Ext.data.Record.REJECT);
22339 afterCommit : function(record){
22340 this.modified.remove(record);
22341 this.fireEvent('update', this, record, Ext.data.Record.COMMIT);
22345 commitChanges : function(){
22346 var m = this.modified.slice(0);
22347 this.modified = [];
22348 for(var i = 0, len = m.length; i < len; i++){
22354 rejectChanges : function(){
22355 var m = this.modified.slice(0);
22356 this.modified = [];
22357 for(var i = 0, len = m.length; i < len; i++){
22360 var m = this.removed.slice(0).reverse();
22362 for(var i = 0, len = m.length; i < len; i++){
22363 this.insert(m[i].lastIndex||0, m[i]);
22369 onMetaChange : function(meta){
22370 this.recordType = this.reader.recordType;
22371 this.fields = this.recordType.prototype.fields;
22372 delete this.snapshot;
22373 if(this.reader.meta.sortInfo){
22374 this.sortInfo = this.reader.meta.sortInfo;
22375 }else if(this.sortInfo && !this.fields.get(this.sortInfo.field)){
22376 delete this.sortInfo;
22379 this.writer.meta = this.reader.meta;
22381 this.modified = [];
22382 this.fireEvent('metachange', this, this.reader.meta);
22386 findInsertIndex : function(record){
22387 this.suspendEvents();
22388 var data = this.data.clone();
22389 this.data.add(record);
22391 var index = this.data.indexOf(record);
22393 this.resumeEvents();
22398 setBaseParam : function (name, value){
22399 this.baseParams = this.baseParams || {};
22400 this.baseParams[name] = value;
22404 Ext.reg('store', Ext.data.Store);
22407 Ext.data.Store.Error = Ext.extend(Ext.Error, {
22408 name: 'Ext.data.Store'
22410 Ext.apply(Ext.data.Store.Error.prototype, {
22412 'writer-undefined' : 'Attempted to execute a write-action without a DataWriter installed.'
22416 Ext.data.Field = Ext.extend(Object, {
22418 constructor : function(config){
22419 if(Ext.isString(config)){
22420 config = {name: config};
22422 Ext.apply(this, config);
22424 var types = Ext.data.Types,
22425 st = this.sortType,
22429 if(Ext.isString(this.type)){
22430 this.type = Ext.data.Types[this.type.toUpperCase()] || types.AUTO;
22433 this.type = types.AUTO;
22437 if(Ext.isString(st)){
22438 this.sortType = Ext.data.SortTypes[st];
22439 }else if(Ext.isEmpty(st)){
22440 this.sortType = this.type.sortType;
22444 this.convert = this.type.convert;
22465 Ext.data.DataReader = function(meta, recordType){
22469 this.recordType = Ext.isArray(recordType) ?
22470 Ext.data.Record.create(recordType) : recordType;
22473 if (this.recordType){
22474 this.buildExtractors();
22478 Ext.data.DataReader.prototype = {
22481 getTotal: Ext.emptyFn,
22483 getRoot: Ext.emptyFn,
22485 getMessage: Ext.emptyFn,
22487 getSuccess: Ext.emptyFn,
22489 getId: Ext.emptyFn,
22491 buildExtractors : Ext.emptyFn,
22493 extractValues : Ext.emptyFn,
22496 realize: function(rs, data){
22497 if (Ext.isArray(rs)) {
22498 for (var i = rs.length - 1; i >= 0; i--) {
22500 if (Ext.isArray(data)) {
22501 this.realize(rs.splice(i,1).shift(), data.splice(i,1).shift());
22506 this.realize(rs.splice(i,1).shift(), data);
22512 if (Ext.isArray(data) && data.length == 1) {
22513 data = data.shift();
22515 if (!this.isData(data)) {
22518 throw new Ext.data.DataReader.Error('realize', rs);
22520 rs.phantom = false;
22522 rs.id = this.getId(data);
22530 update : function(rs, data) {
22531 if (Ext.isArray(rs)) {
22532 for (var i=rs.length-1; i >= 0; i--) {
22533 if (Ext.isArray(data)) {
22534 this.update(rs.splice(i,1).shift(), data.splice(i,1).shift());
22539 this.update(rs.splice(i,1).shift(), data);
22545 if (Ext.isArray(data) && data.length == 1) {
22546 data = data.shift();
22548 if (this.isData(data)) {
22549 rs.data = Ext.apply(rs.data, data);
22556 extractData : function(root, returnRecords) {
22558 var rawName = (this instanceof Ext.data.JsonReader) ? 'json' : 'node';
22564 if (this.isData(root) && !(this instanceof Ext.data.XmlReader)) {
22567 var f = this.recordType.prototype.fields,
22571 if (returnRecords === true) {
22572 var Record = this.recordType;
22573 for (var i = 0; i < root.length; i++) {
22575 var record = new Record(this.extractValues(n, fi, fl), this.getId(n));
22576 record[rawName] = n;
22581 for (var i = 0; i < root.length; i++) {
22582 var data = this.extractValues(root[i], fi, fl);
22583 data[this.meta.idProperty] = this.getId(root[i]);
22591 isData : function(data) {
22592 return (data && Ext.isObject(data) && !Ext.isEmpty(this.getId(data))) ? true : false;
22596 onMetaChange : function(meta){
22599 this.recordType = Ext.data.Record.create(meta.fields);
22600 this.buildExtractors();
22605 Ext.data.DataReader.Error = Ext.extend(Ext.Error, {
22606 constructor : function(message, arg) {
22608 Ext.Error.call(this, message);
22610 name: 'Ext.data.DataReader'
22612 Ext.apply(Ext.data.DataReader.Error.prototype, {
22614 'update': "#update received invalid data from server. Please see docs for DataReader#update and review your DataReader configuration.",
22615 'realize': "#realize was called with invalid remote-data. Please see the docs for DataReader#realize and review your DataReader configuration.",
22616 'invalid-response': "#readResponse received an invalid response from the server."
22620 Ext.data.DataWriter = function(config){
22621 Ext.apply(this, config);
22623 Ext.data.DataWriter.prototype = {
22626 writeAllFields : false,
22631 apply : function(params, baseParams, action, rs) {
22633 renderer = action + 'Record';
22635 if (Ext.isArray(rs)) {
22636 Ext.each(rs, function(rec){
22637 data.push(this[renderer](rec));
22640 else if (rs instanceof Ext.data.Record) {
22641 data = this[renderer](rs);
22643 this.render(params, baseParams, data);
22647 render : Ext.emptyFn,
22650 updateRecord : Ext.emptyFn,
22653 createRecord : Ext.emptyFn,
22656 destroyRecord : Ext.emptyFn,
22659 toHash : function(rec, config) {
22660 var map = rec.fields.map,
22662 raw = (this.writeAllFields === false && rec.phantom === false) ? rec.getChanges() : rec.data,
22664 Ext.iterate(raw, function(prop, value){
22665 if((m = map[prop])){
22666 data[m.mapping ? m.mapping : m.name] = value;
22673 if (rec.fields.containsKey(this.meta.idProperty) && Ext.isEmpty(rec.data[this.meta.idProperty])) {
22674 delete data[this.meta.idProperty];
22677 data[this.meta.idProperty] = rec.id
22683 toArray : function(data) {
22685 Ext.iterate(data, function(k, v) {fields.push({name: k, value: v});},this);
22689 Ext.data.DataProxy = function(conn){
22698 this.api = conn.api;
22699 this.url = conn.url;
22700 this.restful = conn.restful;
22701 this.listeners = conn.listeners;
22704 this.prettyUrls = conn.prettyUrls;
22722 Ext.data.DataProxy.superclass.constructor.call(this);
22726 Ext.data.Api.prepare(this);
22728 if (e instanceof Ext.data.Api.Error) {
22733 Ext.data.DataProxy.relayEvents(this, ['beforewrite', 'write', 'exception']);
22736 Ext.extend(Ext.data.DataProxy, Ext.util.Observable, {
22741 setApi : function() {
22742 if (arguments.length == 1) {
22743 var valid = Ext.data.Api.isValid(arguments[0]);
22744 if (valid === true) {
22745 this.api = arguments[0];
22748 throw new Ext.data.Api.Error('invalid', valid);
22751 else if (arguments.length == 2) {
22752 if (!Ext.data.Api.isAction(arguments[0])) {
22753 throw new Ext.data.Api.Error('invalid', arguments[0]);
22755 this.api[arguments[0]] = arguments[1];
22757 Ext.data.Api.prepare(this);
22761 isApiAction : function(action) {
22762 return (this.api[action]) ? true : false;
22766 request : function(action, rs, params, reader, callback, scope, options) {
22767 if (!this.api[action] && !this.load) {
22768 throw new Ext.data.DataProxy.Error('action-undefined', action);
22770 params = params || {};
22771 if ((action === Ext.data.Api.actions.read) ? this.fireEvent("beforeload", this, params) : this.fireEvent("beforewrite", this, action, rs, params) !== false) {
22772 this.doRequest.apply(this, arguments);
22775 callback.call(scope || this, null, options, false);
22784 doRequest : function(action, rs, params, reader, callback, scope, options) {
22788 this.load(params, reader, callback, scope, options);
22792 onRead : Ext.emptyFn,
22794 onWrite : Ext.emptyFn,
22796 buildUrl : function(action, record) {
22797 record = record || null;
22802 var url = (this.conn && this.conn.url) ? this.conn.url : (this.api[action]) ? this.api[action].url : this.url;
22804 throw new Ext.data.Api.Error('invalid-url', action);
22813 var provides = null;
22814 var m = url.match(/(.*)(\.json|\.xml|\.html)$/);
22820 if ((this.restful === true || this.prettyUrls === true) && record instanceof Ext.data.Record && !record.phantom) {
22821 url += '/' + record.id;
22823 return (provides === null) ? url : url + provides;
22827 destroy: function(){
22828 this.purgeListeners();
22834 Ext.apply(Ext.data.DataProxy, Ext.util.Observable.prototype);
22835 Ext.util.Observable.call(Ext.data.DataProxy);
22838 Ext.data.DataProxy.Error = Ext.extend(Ext.Error, {
22839 constructor : function(message, arg) {
22841 Ext.Error.call(this, message);
22843 name: 'Ext.data.DataProxy'
22845 Ext.apply(Ext.data.DataProxy.Error.prototype, {
22847 'action-undefined': "DataProxy attempted to execute an API-action but found an undefined url / function. Please review your Proxy url/api-configuration.",
22848 'api-invalid': 'Recieved an invalid API-configuration. Please ensure your proxy API-configuration contains only the actions from Ext.data.Api.actions.'
22854 Ext.data.Request = function(params) {
22855 Ext.apply(this, params);
22857 Ext.data.Request.prototype = {
22859 action : undefined,
22865 callback : Ext.emptyFn,
22872 Ext.data.Response = function(params) {
22873 Ext.apply(this, params);
22875 Ext.data.Response.prototype = {
22879 success : undefined,
22881 message : undefined,
22890 Ext.data.ScriptTagProxy = function(config){
22891 Ext.apply(this, config);
22893 Ext.data.ScriptTagProxy.superclass.constructor.call(this, config);
22895 this.head = document.getElementsByTagName("head")[0];
22900 Ext.data.ScriptTagProxy.TRANS_ID = 1000;
22902 Ext.extend(Ext.data.ScriptTagProxy, Ext.data.DataProxy, {
22907 callbackParam : "callback",
22912 doRequest : function(action, rs, params, reader, callback, scope, arg) {
22913 var p = Ext.urlEncode(Ext.apply(params, this.extraParams));
22915 var url = this.buildUrl(action, rs);
22917 throw new Ext.data.Api.Error('invalid-url', url);
22919 url = Ext.urlAppend(url, p);
22922 url = Ext.urlAppend(url, '_dc=' + (new Date().getTime()));
22924 var transId = ++Ext.data.ScriptTagProxy.TRANS_ID;
22928 cb : "stcCallback"+transId,
22929 scriptId : "stcScript"+transId,
22933 callback : callback,
22937 window[trans.cb] = this.createCallback(action, rs, trans);
22938 url += String.format("&{0}={1}", this.callbackParam, trans.cb);
22939 if(this.autoAbort !== false){
22943 trans.timeoutId = this.handleFailure.defer(this.timeout, this, [trans]);
22945 var script = document.createElement("script");
22946 script.setAttribute("src", url);
22947 script.setAttribute("type", "text/javascript");
22948 script.setAttribute("id", trans.scriptId);
22949 this.head.appendChild(script);
22951 this.trans = trans;
22955 createCallback : function(action, rs, trans) {
22957 return function(res) {
22958 self.trans = false;
22959 self.destroyTrans(trans, true);
22960 if (action === Ext.data.Api.actions.read) {
22961 self.onRead.call(self, action, trans, res);
22963 self.onWrite.call(self, action, trans, res, rs);
22968 onRead : function(action, trans, res) {
22971 result = trans.reader.readRecords(res);
22974 this.fireEvent("loadexception", this, trans, res, e);
22976 this.fireEvent('exception', this, 'response', action, trans, res, e);
22977 trans.callback.call(trans.scope||window, null, trans.arg, false);
22980 if (result.success === false) {
22982 this.fireEvent('loadexception', this, trans, res);
22984 this.fireEvent('exception', this, 'remote', action, trans, res, null);
22986 this.fireEvent("load", this, res, trans.arg);
22988 trans.callback.call(trans.scope||window, result, trans.arg, result.success);
22991 onWrite : function(action, trans, response, rs) {
22992 var reader = trans.reader;
22995 var res = reader.readResponse(action, response);
22997 this.fireEvent('exception', this, 'response', action, trans, res, e);
22998 trans.callback.call(trans.scope||window, null, res, false);
23001 if(!res.success === true){
23002 this.fireEvent('exception', this, 'remote', action, trans, res, rs);
23003 trans.callback.call(trans.scope||window, null, res, false);
23006 this.fireEvent("write", this, action, res.data, res, rs, trans.arg );
23007 trans.callback.call(trans.scope||window, res.data, res, true);
23011 isLoading : function(){
23012 return this.trans ? true : false;
23016 abort : function(){
23017 if(this.isLoading()){
23018 this.destroyTrans(this.trans);
23023 destroyTrans : function(trans, isLoaded){
23024 this.head.removeChild(document.getElementById(trans.scriptId));
23025 clearTimeout(trans.timeoutId);
23027 window[trans.cb] = undefined;
23029 delete window[trans.cb];
23033 window[trans.cb] = function(){
23034 window[trans.cb] = undefined;
23036 delete window[trans.cb];
23043 handleFailure : function(trans){
23044 this.trans = false;
23045 this.destroyTrans(trans, false);
23046 if (trans.action === Ext.data.Api.actions.read) {
23048 this.fireEvent("loadexception", this, null, trans.arg);
23051 this.fireEvent('exception', this, 'response', trans.action, {
23055 trans.callback.call(trans.scope||window, null, trans.arg, false);
23059 destroy: function(){
23061 Ext.data.ScriptTagProxy.superclass.destroy.call(this);
23064 Ext.data.HttpProxy = function(conn){
23065 Ext.data.HttpProxy.superclass.constructor.call(this, conn);
23074 this.conn.url = null;
23076 this.useAjax = !conn || !conn.events;
23079 var actions = Ext.data.Api.actions;
23080 this.activeRequest = {};
23081 for (var verb in actions) {
23082 this.activeRequest[actions[verb]] = undefined;
23086 Ext.extend(Ext.data.HttpProxy, Ext.data.DataProxy, {
23088 getConnection : function() {
23089 return this.useAjax ? Ext.Ajax : this.conn;
23093 setUrl : function(url, makePermanent) {
23094 this.conn.url = url;
23095 if (makePermanent === true) {
23098 Ext.data.Api.prepare(this);
23103 doRequest : function(action, rs, params, reader, cb, scope, arg) {
23105 method: (this.api[action]) ? this.api[action]['method'] : undefined,
23112 callback : this.createCallback(action, rs),
23118 if (params.jsonData) {
23119 o.jsonData = params.jsonData;
23120 } else if (params.xmlData) {
23121 o.xmlData = params.xmlData;
23123 o.params = params || {};
23128 this.conn.url = this.buildUrl(action, rs);
23132 Ext.applyIf(o, this.conn);
23135 if (this.activeRequest[action]) {
23142 this.activeRequest[action] = Ext.Ajax.request(o);
23144 this.conn.request(o);
23147 this.conn.url = null;
23151 createCallback : function(action, rs) {
23152 return function(o, success, response) {
23153 this.activeRequest[action] = undefined;
23155 if (action === Ext.data.Api.actions.read) {
23158 this.fireEvent('loadexception', this, o, response);
23160 this.fireEvent('exception', this, 'response', action, o, response);
23161 o.request.callback.call(o.request.scope, null, o.request.arg, false);
23164 if (action === Ext.data.Api.actions.read) {
23165 this.onRead(action, o, response);
23167 this.onWrite(action, o, response, rs);
23173 onRead : function(action, o, response) {
23176 result = o.reader.read(response);
23180 this.fireEvent('loadexception', this, o, response, e);
23182 this.fireEvent('exception', this, 'response', action, o, response, e);
23183 o.request.callback.call(o.request.scope, null, o.request.arg, false);
23186 if (result.success === false) {
23189 this.fireEvent('loadexception', this, o, response);
23192 var res = o.reader.readResponse(action, response);
23193 this.fireEvent('exception', this, 'remote', action, o, res, null);
23196 this.fireEvent('load', this, o, o.request.arg);
23201 o.request.callback.call(o.request.scope, result, o.request.arg, result.success);
23204 onWrite : function(action, o, response, rs) {
23205 var reader = o.reader;
23208 res = reader.readResponse(action, response);
23210 this.fireEvent('exception', this, 'response', action, o, response, e);
23211 o.request.callback.call(o.request.scope, null, o.request.arg, false);
23214 if (res.success === true) {
23215 this.fireEvent('write', this, action, res.data, res, rs, o.request.arg);
23217 this.fireEvent('exception', this, 'remote', action, o, res, rs);
23222 o.request.callback.call(o.request.scope, res.data, res, res.success);
23226 destroy: function(){
23229 }else if(this.activeRequest){
23230 var actions = Ext.data.Api.actions;
23231 for (var verb in actions) {
23232 if(this.activeRequest[actions[verb]]){
23233 Ext.Ajax.abort(this.activeRequest[actions[verb]]);
23237 Ext.data.HttpProxy.superclass.destroy.call(this);
23240 Ext.data.MemoryProxy = function(data){
23243 api[Ext.data.Api.actions.read] = true;
23244 Ext.data.MemoryProxy.superclass.constructor.call(this, {
23250 Ext.extend(Ext.data.MemoryProxy, Ext.data.DataProxy, {
23254 doRequest : function(action, rs, params, reader, callback, scope, arg) {
23256 params = params || {};
23259 result = reader.readRecords(this.data);
23262 this.fireEvent("loadexception", this, null, arg, e);
23264 this.fireEvent('exception', this, 'response', action, arg, null, e);
23265 callback.call(scope, null, arg, false);
23268 callback.call(scope, result, arg, true);
23271 Ext.data.Types = new function(){
23272 var st = Ext.data.SortTypes;
23275 stripRe: /[\$,%]/g,
23279 convert: function(v){ return v; },
23286 convert: function(v){ return (v === undefined || v === null) ? '' : String(v); },
23287 sortType: st.asUCString,
23293 convert: function(v){
23294 return v !== undefined && v !== null && v !== '' ?
23295 parseInt(String(v).replace(Ext.data.Types.stripRe, ''), 10) : 0;
23303 convert: function(v){
23304 return v !== undefined && v !== null && v !== '' ?
23305 parseFloat(String(v).replace(Ext.data.Types.stripRe, ''), 10) : 0;
23313 convert: function(v){ return v === true || v === 'true' || v == 1; },
23320 convert: function(v){
23321 var df = this.dateFormat;
23329 if(df == 'timestamp'){
23330 return new Date(v*1000);
23333 return new Date(parseInt(v, 10));
23335 return Date.parseDate(v, df);
23337 var parsed = Date.parse(v);
23338 return parsed ? new Date(parsed) : null;
23340 sortType: st.asDate,
23347 BOOLEAN: this.BOOL,
23354 Ext.data.JsonWriter = Ext.extend(Ext.data.DataWriter, {
23358 encodeDelete: false,
23360 constructor : function(config){
23361 Ext.data.JsonWriter.superclass.constructor.call(this, config);
23365 render : function(params, baseParams, data) {
23366 if (this.encode === true) {
23368 Ext.apply(params, baseParams);
23369 params[this.meta.root] = Ext.encode(data);
23372 var jdata = Ext.apply({}, baseParams);
23373 jdata[this.meta.root] = data;
23374 params.jsonData = jdata;
23378 createRecord : function(rec) {
23379 return this.toHash(rec);
23382 updateRecord : function(rec) {
23383 return this.toHash(rec);
23387 destroyRecord : function(rec){
23388 if(this.encodeDelete){
23390 data[this.meta.idProperty] = rec.id;
23397 Ext.data.JsonReader = function(meta, recordType){
23403 Ext.applyIf(meta, {
23405 successProperty: 'success',
23406 totalProperty: 'total'
23409 Ext.data.JsonReader.superclass.constructor.call(this, meta, recordType || meta.fields);
23411 Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
23414 read : function(response){
23415 var json = response.responseText;
23416 var o = Ext.decode(json);
23418 throw {message: 'JsonReader.read: Json object not found'};
23420 return this.readRecords(o);
23425 readResponse : function(action, response) {
23426 var o = (response.responseText !== undefined) ? Ext.decode(response.responseText) : response;
23428 throw new Ext.data.JsonReader.Error('response');
23431 var root = this.getRoot(o);
23432 if (action === Ext.data.Api.actions.create) {
23433 var def = Ext.isDefined(root);
23434 if (def && Ext.isEmpty(root)) {
23435 throw new Ext.data.JsonReader.Error('root-empty', this.meta.root);
23438 throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root);
23443 var res = new Ext.data.Response({
23445 success: this.getSuccess(o),
23446 data: (root) ? this.extractData(root, false) : [],
23447 message: this.getMessage(o),
23452 if (Ext.isEmpty(res.success)) {
23453 throw new Ext.data.JsonReader.Error('successProperty-response', this.meta.successProperty);
23459 readRecords : function(o){
23463 this.onMetaChange(o.metaData);
23465 var s = this.meta, Record = this.recordType,
23466 f = Record.prototype.fields, fi = f.items, fl = f.length, v;
23468 var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;
23469 if(s.totalProperty){
23470 v = parseInt(this.getTotal(o), 10);
23475 if(s.successProperty){
23476 v = this.getSuccess(o);
23477 if(v === false || v === 'false'){
23485 records : this.extractData(root, true),
23486 totalRecords : totalRecords
23491 buildExtractors : function() {
23495 var s = this.meta, Record = this.recordType,
23496 f = Record.prototype.fields, fi = f.items, fl = f.length;
23498 if(s.totalProperty) {
23499 this.getTotal = this.createAccessor(s.totalProperty);
23501 if(s.successProperty) {
23502 this.getSuccess = this.createAccessor(s.successProperty);
23504 if (s.messageProperty) {
23505 this.getMessage = this.createAccessor(s.messageProperty);
23507 this.getRoot = s.root ? this.createAccessor(s.root) : function(p){return p;};
23508 if (s.id || s.idProperty) {
23509 var g = this.createAccessor(s.id || s.idProperty);
23510 this.getId = function(rec) {
23512 return (r === undefined || r === '') ? null : r;
23515 this.getId = function(){return null;};
23518 for(var i = 0; i < fl; i++){
23520 var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
23521 ef.push(this.createAccessor(map));
23527 simpleAccess : function(obj, subsc) {
23532 createAccessor : function(){
23534 return function(expr) {
23535 if(Ext.isEmpty(expr)){
23536 return Ext.emptyFn;
23538 if(Ext.isFunction(expr)){
23541 var i = String(expr).search(re);
23543 return new Function('obj', 'return obj' + (i > 0 ? '.' : '') + expr);
23545 return function(obj){
23553 extractValues : function(data, items, len) {
23554 var f, values = {};
23555 for(var j = 0; j < len; j++){
23557 var v = this.ef[j](data);
23558 values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
23565 Ext.data.JsonReader.Error = Ext.extend(Ext.Error, {
23566 constructor : function(message, arg) {
23568 Ext.Error.call(this, message);
23570 name : 'Ext.data.JsonReader'
23572 Ext.apply(Ext.data.JsonReader.Error.prototype, {
23574 'response': 'An error occurred while json-decoding your server response',
23575 'successProperty-response': 'Could not locate your "successProperty" in your server response. Please review your JsonReader config to ensure the config-property "successProperty" matches the property in your server-response. See the JsonReader docs.',
23576 'root-undefined-config': 'Your JsonReader was configured without a "root" property. Please review your JsonReader config and make sure to define the root property. See the JsonReader docs.',
23577 'idProperty-undefined' : 'Your JsonReader was configured without an "idProperty" Please review your JsonReader configuration and ensure the "idProperty" is set (e.g.: "id"). See the JsonReader docs.',
23578 'root-empty': 'Data was expected to be returned by the server in the "root" property of the response. Please review your JsonReader configuration to ensure the "root" property matches that returned in the server-response. See JsonReader docs.'
23582 Ext.data.ArrayReader = Ext.extend(Ext.data.JsonReader, {
23587 readRecords : function(o){
23588 this.arrayData = o;
23590 sid = s ? Ext.num(s.idIndex, s.id) : null,
23591 recordType = this.recordType,
23592 fields = recordType.prototype.fields,
23597 var root = this.getRoot(o);
23599 for(var i = 0, len = root.length; i < len; i++) {
23602 id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);
23603 for(var j = 0, jlen = fields.length; j < jlen; j++) {
23604 var f = fields.items[j],
23605 k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;
23606 v = n[k] !== undefined ? n[k] : f.defaultValue;
23607 v = f.convert(v, n);
23608 values[f.name] = v;
23610 var record = new recordType(values, id);
23612 records[records.length] = record;
23615 var totalRecords = records.length;
23617 if(s.totalProperty) {
23618 v = parseInt(this.getTotal(o), 10);
23623 if(s.successProperty){
23624 v = this.getSuccess(o);
23625 if(v === false || v === 'false'){
23633 totalRecords : totalRecords
23637 Ext.data.ArrayStore = Ext.extend(Ext.data.Store, {
23639 constructor: function(config){
23640 Ext.data.ArrayStore.superclass.constructor.call(this, Ext.apply(config, {
23641 reader: new Ext.data.ArrayReader(config)
23645 loadData : function(data, append){
23646 if(this.expandData === true){
23648 for(var i = 0, len = data.length; i < len; i++){
23649 r[r.length] = [data[i]];
23653 Ext.data.ArrayStore.superclass.loadData.call(this, data, append);
23656 Ext.reg('arraystore', Ext.data.ArrayStore);
23659 Ext.data.SimpleStore = Ext.data.ArrayStore;
23660 Ext.reg('simplestore', Ext.data.SimpleStore);
23661 Ext.data.JsonStore = Ext.extend(Ext.data.Store, {
23663 constructor: function(config){
23664 Ext.data.JsonStore.superclass.constructor.call(this, Ext.apply(config, {
23665 reader: new Ext.data.JsonReader(config)
23669 Ext.reg('jsonstore', Ext.data.JsonStore);
23670 Ext.data.XmlWriter = function(params) {
23671 Ext.data.XmlWriter.superclass.constructor.apply(this, arguments);
23673 this.tpl = (typeof(this.tpl) === 'string') ? new Ext.XTemplate(this.tpl).compile() : this.tpl.compile();
23675 Ext.extend(Ext.data.XmlWriter, Ext.data.DataWriter, {
23677 documentRoot: 'xrequest',
23679 forceDocumentRoot: false,
23683 xmlVersion : '1.0',
23685 xmlEncoding: 'ISO-8859-15',
23688 tpl: '<tpl for="."><\u003fxml version="{version}" encoding="{encoding}"\u003f><tpl if="documentRoot"><{documentRoot}><tpl for="baseParams"><tpl for="."><{name}>{value}</{name}></tpl></tpl></tpl><tpl if="records.length>1"><{root}></tpl><tpl for="records"><{parent.record}><tpl for="."><{name}>{value}</{name}></tpl></{parent.record}></tpl><tpl if="records.length>1"></{root}></tpl><tpl if="documentRoot"></{documentRoot}></tpl></tpl>',
23692 render : function(params, baseParams, data) {
23693 baseParams = this.toArray(baseParams);
23694 params.xmlData = this.tpl.applyTemplate({
23695 version: this.xmlVersion,
23696 encoding: this.xmlEncoding,
23697 documentRoot: (baseParams.length > 0 || this.forceDocumentRoot === true) ? this.documentRoot : false,
23698 record: this.meta.record,
23700 baseParams: baseParams,
23701 records: (Ext.isArray(data[0])) ? data : [data]
23706 createRecord : function(rec) {
23707 return this.toArray(this.toHash(rec));
23711 updateRecord : function(rec) {
23712 return this.toArray(this.toHash(rec));
23716 destroyRecord : function(rec) {
23718 data[this.meta.idProperty] = rec.id;
23719 return this.toArray(data);
23723 Ext.data.XmlReader = function(meta, recordType){
23727 Ext.applyIf(meta, {
23728 idProperty: meta.idProperty || meta.idPath || meta.id,
23729 successProperty: meta.successProperty || meta.success
23732 Ext.data.XmlReader.superclass.constructor.call(this, meta, recordType || meta.fields);
23734 Ext.extend(Ext.data.XmlReader, Ext.data.DataReader, {
23736 read : function(response){
23737 var doc = response.responseXML;
23739 throw {message: "XmlReader.read: XML Document not available"};
23741 return this.readRecords(doc);
23745 readRecords : function(doc){
23747 this.xmlData = doc;
23749 var root = doc.documentElement || doc,
23754 if(this.meta.totalProperty){
23755 totalRecords = this.getTotal(root, 0);
23757 if(this.meta.successProperty){
23758 success = this.getSuccess(root);
23761 var records = this.extractData(q.select(this.meta.record, root), true);
23767 totalRecords : totalRecords || records.length
23772 readResponse : function(action, response) {
23773 var q = Ext.DomQuery,
23774 doc = response.responseXML,
23775 root = doc.documentElement || doc;
23778 var res = new Ext.data.Response({
23780 success : this.getSuccess(root),
23781 message: this.getMessage(root),
23782 data: this.extractData(q.select(this.meta.record, root) || q.select(this.meta.root, root), false),
23786 if (Ext.isEmpty(res.success)) {
23787 throw new Ext.data.DataReader.Error('successProperty-response', this.meta.successProperty);
23791 if (action === Ext.data.Api.actions.create) {
23792 var def = Ext.isDefined(res.data);
23793 if (def && Ext.isEmpty(res.data)) {
23794 throw new Ext.data.JsonReader.Error('root-empty', this.meta.root);
23797 throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root);
23803 getSuccess : function() {
23808 buildExtractors : function() {
23813 Record = this.recordType,
23814 f = Record.prototype.fields,
23818 if(s.totalProperty) {
23819 this.getTotal = this.createAccessor(s.totalProperty);
23821 if(s.successProperty) {
23822 this.getSuccess = this.createAccessor(s.successProperty);
23824 if (s.messageProperty) {
23825 this.getMessage = this.createAccessor(s.messageProperty);
23827 this.getRoot = function(res) {
23828 return (!Ext.isEmpty(res[this.meta.record])) ? res[this.meta.record] : res[this.meta.root];
23830 if (s.idPath || s.idProperty) {
23831 var g = this.createAccessor(s.idPath || s.idProperty);
23832 this.getId = function(rec) {
23833 var id = g(rec) || rec.id;
23834 return (id === undefined || id === '') ? null : id;
23837 this.getId = function(){return null;};
23840 for(var i = 0; i < fl; i++){
23842 var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
23843 ef.push(this.createAccessor(map));
23849 createAccessor : function(){
23850 var q = Ext.DomQuery;
23851 return function(key) {
23853 case this.meta.totalProperty:
23854 return function(root, def){
23855 return q.selectNumber(key, root, def);
23858 case this.meta.successProperty:
23859 return function(root, def) {
23860 var sv = q.selectValue(key, root, true);
23861 var success = sv !== false && sv !== 'false';
23866 return function(root, def) {
23867 return q.selectValue(key, root, def);
23875 extractValues : function(data, items, len) {
23876 var f, values = {};
23877 for(var j = 0; j < len; j++){
23879 var v = this.ef[j](data);
23880 values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
23885 Ext.data.XmlStore = Ext.extend(Ext.data.Store, {
23887 constructor: function(config){
23888 Ext.data.XmlStore.superclass.constructor.call(this, Ext.apply(config, {
23889 reader: new Ext.data.XmlReader(config)
23893 Ext.reg('xmlstore', Ext.data.XmlStore);
23894 Ext.data.GroupingStore = Ext.extend(Ext.data.Store, {
23897 constructor: function(config) {
23898 config = config || {};
23904 this.hasMultiSort = true;
23905 this.multiSortInfo = this.multiSortInfo || {sorters: []};
23907 var sorters = this.multiSortInfo.sorters,
23908 groupField = config.groupField || this.groupField,
23909 sortInfo = config.sortInfo || this.sortInfo,
23910 groupDir = config.groupDir || this.groupDir;
23915 field : groupField,
23916 direction: groupDir
23922 sorters.push(sortInfo);
23925 Ext.data.GroupingStore.superclass.constructor.call(this, config);
23932 this.applyGroupField();
23937 remoteGroup : false,
23944 clearGrouping : function(){
23945 this.groupField = false;
23947 if(this.remoteGroup){
23948 if(this.baseParams){
23949 delete this.baseParams.groupBy;
23950 delete this.baseParams.groupDir;
23952 var lo = this.lastOptions;
23953 if(lo && lo.params){
23954 delete lo.params.groupBy;
23955 delete lo.params.groupDir;
23961 this.fireEvent('datachanged', this);
23966 groupBy : function(field, forceRegroup, direction) {
23967 direction = direction ? (String(direction).toUpperCase() == 'DESC' ? 'DESC' : 'ASC') : this.groupDir;
23969 if (this.groupField == field && this.groupDir == direction && !forceRegroup) {
23975 var sorters = this.multiSortInfo.sorters;
23976 if (sorters.length > 0 && sorters[0].field == this.groupField) {
23980 this.groupField = field;
23981 this.groupDir = direction;
23982 this.applyGroupField();
23984 var fireGroupEvent = function() {
23985 this.fireEvent('groupchange', this, this.getGroupState());
23988 if (this.groupOnSort) {
23989 this.sort(field, direction);
23990 fireGroupEvent.call(this);
23994 if (this.remoteGroup) {
23995 this.on('load', fireGroupEvent, this, {single: true});
23998 this.sort(sorters);
23999 fireGroupEvent.call(this);
24005 sort : function(fieldName, dir) {
24006 if (this.remoteSort) {
24007 return Ext.data.GroupingStore.superclass.sort.call(this, fieldName, dir);
24013 if (Ext.isArray(arguments[0])) {
24014 sorters = arguments[0];
24015 } else if (fieldName == undefined) {
24018 sorters = this.sortInfo ? [this.sortInfo] : [];
24022 var field = this.fields.get(fieldName);
24023 if (!field) return false;
24025 var name = field.name,
24026 sortInfo = this.sortInfo || null,
24027 sortToggle = this.sortToggle ? this.sortToggle[name] : null;
24030 if (sortInfo && sortInfo.field == name) {
24031 dir = (this.sortToggle[name] || 'ASC').toggle('ASC', 'DESC');
24033 dir = field.sortDir;
24037 this.sortToggle[name] = dir;
24038 this.sortInfo = {field: name, direction: dir};
24040 sorters = [this.sortInfo];
24044 if (this.groupField) {
24045 sorters.unshift({direction: this.groupDir, field: this.groupField});
24048 return this.multiSort.call(this, sorters, dir);
24052 applyGroupField: function(){
24053 if (this.remoteGroup) {
24054 if(!this.baseParams){
24055 this.baseParams = {};
24058 Ext.apply(this.baseParams, {
24059 groupBy : this.groupField,
24060 groupDir: this.groupDir
24063 var lo = this.lastOptions;
24064 if (lo && lo.params) {
24065 lo.params.groupDir = this.groupDir;
24068 delete lo.params.groupBy;
24074 applyGrouping : function(alwaysFireChange){
24075 if(this.groupField !== false){
24076 this.groupBy(this.groupField, true, this.groupDir);
24079 if(alwaysFireChange === true){
24080 this.fireEvent('datachanged', this);
24087 getGroupState : function(){
24088 return this.groupOnSort && this.groupField !== false ?
24089 (this.sortInfo ? this.sortInfo.field : undefined) : this.groupField;
24092 Ext.reg('groupingstore', Ext.data.GroupingStore);
24094 Ext.data.DirectProxy = function(config){
24095 Ext.apply(this, config);
24096 if(typeof this.paramOrder == 'string'){
24097 this.paramOrder = this.paramOrder.split(/[\s,|]/);
24099 Ext.data.DirectProxy.superclass.constructor.call(this, config);
24102 Ext.extend(Ext.data.DirectProxy, Ext.data.DataProxy, {
24104 paramOrder: undefined,
24107 paramsAsHash: true,
24110 directFn : undefined,
24113 doRequest : function(action, rs, params, reader, callback, scope, options) {
24115 directFn = this.api[action] || this.directFn;
24118 case Ext.data.Api.actions.create:
24119 args.push(params.jsonData);
24121 case Ext.data.Api.actions.read:
24123 if(directFn.directCfg.method.len > 0){
24124 if(this.paramOrder){
24125 for(var i = 0, len = this.paramOrder.length; i < len; i++){
24126 args.push(params[this.paramOrder[i]]);
24128 }else if(this.paramsAsHash){
24133 case Ext.data.Api.actions.update:
24134 args.push(params.jsonData);
24136 case Ext.data.Api.actions.destroy:
24137 args.push(params.jsonData);
24142 params : params || {},
24144 callback : callback,
24151 args.push(this.createCallback(action, rs, trans), this);
24152 directFn.apply(window, args);
24156 createCallback : function(action, rs, trans) {
24158 return function(result, res) {
24161 if (action === Ext.data.Api.actions.read) {
24162 me.fireEvent("loadexception", me, trans, res, null);
24164 me.fireEvent('exception', me, 'remote', action, trans, res, null);
24165 trans.request.callback.call(trans.request.scope, null, trans.request.arg, false);
24168 if (action === Ext.data.Api.actions.read) {
24169 me.onRead(action, trans, result, res);
24171 me.onWrite(action, trans, result, res, rs);
24177 onRead : function(action, trans, result, res) {
24180 records = trans.reader.readRecords(result);
24184 this.fireEvent("loadexception", this, trans, res, ex);
24186 this.fireEvent('exception', this, 'response', action, trans, res, ex);
24187 trans.request.callback.call(trans.request.scope, null, trans.request.arg, false);
24190 this.fireEvent("load", this, res, trans.request.arg);
24191 trans.request.callback.call(trans.request.scope, records, trans.request.arg, true);
24194 onWrite : function(action, trans, result, res, rs) {
24195 var data = trans.reader.extractData(trans.reader.getRoot(result), false);
24196 var success = trans.reader.getSuccess(result);
24197 success = (success !== false);
24199 this.fireEvent("write", this, action, data, res, rs, trans.request.arg);
24201 this.fireEvent('exception', this, 'remote', action, trans, result, rs);
24203 trans.request.callback.call(trans.request.scope, data, res, success);
24207 Ext.data.DirectStore = Ext.extend(Ext.data.Store, {
24208 constructor : function(config){
24210 var c = Ext.apply({}, {
24211 batchTransactions: false
24213 Ext.data.DirectStore.superclass.constructor.call(this, Ext.apply(c, {
24214 proxy: Ext.isDefined(c.proxy) ? c.proxy : new Ext.data.DirectProxy(Ext.copyTo({}, c, 'paramOrder,paramsAsHash,directFn,api')),
24215 reader: (!Ext.isDefined(c.reader) && c.fields) ? new Ext.data.JsonReader(Ext.copyTo({}, c, 'totalProperty,root,idProperty'), c.fields) : c.reader
24219 Ext.reg('directstore', Ext.data.DirectStore);
24221 Ext.Direct = Ext.extend(Ext.util.Observable, {
24229 SERVER: 'exception'
24233 constructor: function(){
24240 this.transactions = {};
24241 this.providers = {};
24245 addProvider : function(provider){
24248 for(var i = 0, len = a.length; i < len; i++){
24249 this.addProvider(a[i]);
24255 if(!provider.events){
24256 provider = new Ext.Direct.PROVIDERS[provider.type](provider);
24258 provider.id = provider.id || Ext.id();
24259 this.providers[provider.id] = provider;
24261 provider.on('data', this.onProviderData, this);
24262 provider.on('exception', this.onProviderException, this);
24265 if(!provider.isConnected()){
24266 provider.connect();
24273 getProvider : function(id){
24274 return this.providers[id];
24277 removeProvider : function(id){
24278 var provider = id.id ? id : this.providers[id];
24279 provider.un('data', this.onProviderData, this);
24280 provider.un('exception', this.onProviderException, this);
24281 delete this.providers[provider.id];
24285 addTransaction: function(t){
24286 this.transactions[t.tid] = t;
24290 removeTransaction: function(t){
24291 delete this.transactions[t.tid || t];
24295 getTransaction: function(tid){
24296 return this.transactions[tid.tid || tid];
24299 onProviderData : function(provider, e){
24300 if(Ext.isArray(e)){
24301 for(var i = 0, len = e.length; i < len; i++){
24302 this.onProviderData(provider, e[i]);
24306 if(e.name && e.name != 'event' && e.name != 'exception'){
24307 this.fireEvent(e.name, e);
24308 }else if(e.type == 'exception'){
24309 this.fireEvent('exception', e);
24311 this.fireEvent('event', e, provider);
24314 createEvent : function(response, extraProps){
24315 return new Ext.Direct.eventTypes[response.type](Ext.apply(response, extraProps));
24319 Ext.Direct = new Ext.Direct();
24321 Ext.Direct.TID = 1;
24322 Ext.Direct.PROVIDERS = {};
24323 Ext.Direct.Transaction = function(config){
24324 Ext.apply(this, config);
24325 this.tid = ++Ext.Direct.TID;
24326 this.retryCount = 0;
24328 Ext.Direct.Transaction.prototype = {
24330 this.provider.queueTransaction(this);
24338 getProvider: function(){
24339 return this.provider;
24341 };Ext.Direct.Event = function(config){
24342 Ext.apply(this, config);
24345 Ext.Direct.Event.prototype = {
24347 getData: function(){
24352 Ext.Direct.RemotingEvent = Ext.extend(Ext.Direct.Event, {
24354 getTransaction: function(){
24355 return this.transaction || Ext.Direct.getTransaction(this.tid);
24359 Ext.Direct.ExceptionEvent = Ext.extend(Ext.Direct.RemotingEvent, {
24364 Ext.Direct.eventTypes = {
24365 'rpc': Ext.Direct.RemotingEvent,
24366 'event': Ext.Direct.Event,
24367 'exception': Ext.Direct.ExceptionEvent
24370 Ext.direct.Provider = Ext.extend(Ext.util.Observable, {
24379 constructor : function(config){
24380 Ext.apply(this, config);
24391 Ext.direct.Provider.superclass.constructor.call(this, config);
24395 isConnected: function(){
24400 connect: Ext.emptyFn,
24403 disconnect: Ext.emptyFn
24406 Ext.direct.JsonProvider = Ext.extend(Ext.direct.Provider, {
24407 parseResponse: function(xhr){
24408 if(!Ext.isEmpty(xhr.responseText)){
24409 if(typeof xhr.responseText == 'object'){
24410 return xhr.responseText;
24412 return Ext.decode(xhr.responseText);
24417 getEvents: function(xhr){
24420 data = this.parseResponse(xhr);
24422 var event = new Ext.Direct.ExceptionEvent({
24425 code: Ext.Direct.exceptions.PARSE,
24426 message: 'Error parsing json response: \n\n ' + data
24431 if(Ext.isArray(data)){
24432 for(var i = 0, len = data.length; i < len; i++){
24433 events.push(Ext.Direct.createEvent(data[i]));
24436 events.push(Ext.Direct.createEvent(data));
24441 Ext.direct.PollingProvider = Ext.extend(Ext.direct.JsonProvider, {
24454 constructor : function(config){
24455 Ext.direct.PollingProvider.superclass.constructor.call(this, config);
24465 isConnected: function(){
24466 return !!this.pollTask;
24470 connect: function(){
24471 if(this.url && !this.pollTask){
24472 this.pollTask = Ext.TaskMgr.start({
24474 if(this.fireEvent('beforepoll', this) !== false){
24475 if(typeof this.url == 'function'){
24476 this.url(this.baseParams);
24480 callback: this.onData,
24482 params: this.baseParams
24487 interval: this.interval,
24490 this.fireEvent('connect', this);
24491 }else if(!this.url){
24492 throw 'Error initializing PollingProvider, no url configured.';
24497 disconnect: function(){
24499 Ext.TaskMgr.stop(this.pollTask);
24500 delete this.pollTask;
24501 this.fireEvent('disconnect', this);
24506 onData: function(opt, success, xhr){
24508 var events = this.getEvents(xhr);
24509 for(var i = 0, len = events.length; i < len; i++){
24511 this.fireEvent('data', this, e);
24514 var e = new Ext.Direct.ExceptionEvent({
24516 code: Ext.Direct.exceptions.TRANSPORT,
24517 message: 'Unable to connect to the server.',
24520 this.fireEvent('data', this, e);
24525 Ext.Direct.PROVIDERS['polling'] = Ext.direct.PollingProvider;
24526 Ext.direct.RemotingProvider = Ext.extend(Ext.direct.JsonProvider, {
24542 timeout: undefined,
24544 constructor : function(config){
24545 Ext.direct.RemotingProvider.superclass.constructor.call(this, config);
24552 this.namespace = (Ext.isString(this.namespace)) ? Ext.ns(this.namespace) : this.namespace || window;
24553 this.transactions = {};
24554 this.callBuffer = [];
24558 initAPI : function(){
24559 var o = this.actions;
24561 var cls = this.namespace[c] || (this.namespace[c] = {}),
24563 for(var i = 0, len = ms.length; i < len; i++){
24565 cls[m.name] = this.createMethod(c, m);
24571 isConnected: function(){
24572 return !!this.connected;
24575 connect: function(){
24578 this.connected = true;
24579 this.fireEvent('connect', this);
24580 }else if(!this.url){
24581 throw 'Error initializing RemotingProvider, no url configured.';
24585 disconnect: function(){
24586 if(this.connected){
24587 this.connected = false;
24588 this.fireEvent('disconnect', this);
24592 onData: function(opt, success, xhr){
24594 var events = this.getEvents(xhr);
24595 for(var i = 0, len = events.length; i < len; i++){
24597 t = this.getTransaction(e);
24598 this.fireEvent('data', this, e);
24600 this.doCallback(t, e, true);
24601 Ext.Direct.removeTransaction(t);
24605 var ts = [].concat(opt.ts);
24606 for(var i = 0, len = ts.length; i < len; i++){
24607 var t = this.getTransaction(ts[i]);
24608 if(t && t.retryCount < this.maxRetries){
24611 var e = new Ext.Direct.ExceptionEvent({
24614 code: Ext.Direct.exceptions.TRANSPORT,
24615 message: 'Unable to connect to the server.',
24618 this.fireEvent('data', this, e);
24620 this.doCallback(t, e, false);
24621 Ext.Direct.removeTransaction(t);
24628 getCallData: function(t){
24638 doSend : function(data){
24641 callback: this.onData,
24644 timeout: this.timeout
24647 if(Ext.isArray(data)){
24649 for(var i = 0, len = data.length; i < len; i++){
24650 callData.push(this.getCallData(data[i]));
24653 callData = this.getCallData(data);
24656 if(this.enableUrlEncode){
24658 params[Ext.isString(this.enableUrlEncode) ? this.enableUrlEncode : 'data'] = Ext.encode(callData);
24661 o.jsonData = callData;
24663 Ext.Ajax.request(o);
24666 combineAndSend : function(){
24667 var len = this.callBuffer.length;
24669 this.doSend(len == 1 ? this.callBuffer[0] : this.callBuffer);
24670 this.callBuffer = [];
24674 queueTransaction: function(t){
24676 this.processForm(t);
24679 this.callBuffer.push(t);
24680 if(this.enableBuffer){
24681 if(!this.callTask){
24682 this.callTask = new Ext.util.DelayedTask(this.combineAndSend, this);
24684 this.callTask.delay(Ext.isNumber(this.enableBuffer) ? this.enableBuffer : 10);
24686 this.combineAndSend();
24690 doCall : function(c, m, args){
24691 var data = null, hs = args[m.len], scope = args[m.len+1];
24694 data = args.slice(0, m.len);
24697 var t = new Ext.Direct.Transaction({
24703 cb: scope && Ext.isFunction(hs) ? hs.createDelegate(scope) : hs
24706 if(this.fireEvent('beforecall', this, t, m) !== false){
24707 Ext.Direct.addTransaction(t);
24708 this.queueTransaction(t);
24709 this.fireEvent('call', this, t, m);
24713 doForm : function(c, m, form, callback, scope){
24714 var t = new Ext.Direct.Transaction({
24718 args:[form, callback, scope],
24719 cb: scope && Ext.isFunction(callback) ? callback.createDelegate(scope) : callback,
24723 if(this.fireEvent('beforecall', this, t, m) !== false){
24724 Ext.Direct.addTransaction(t);
24725 var isUpload = String(form.getAttribute("enctype")).toLowerCase() == 'multipart/form-data',
24731 extUpload: String(isUpload)
24737 form: Ext.getDom(form),
24738 isUpload: isUpload,
24739 params: callback && Ext.isObject(callback.params) ? Ext.apply(params, callback.params) : params
24741 this.fireEvent('call', this, t, m);
24742 this.processForm(t);
24746 processForm: function(t){
24750 callback: this.onData,
24753 isUpload: t.isUpload,
24758 createMethod : function(c, m){
24760 if(!m.formHandler){
24762 this.doCall(c, m, Array.prototype.slice.call(arguments, 0));
24763 }.createDelegate(this);
24765 f = function(form, callback, scope){
24766 this.doForm(c, m, form, callback, scope);
24767 }.createDelegate(this);
24776 getTransaction: function(opt){
24777 return opt && opt.tid ? Ext.Direct.getTransaction(opt.tid) : null;
24780 doCallback: function(t, e){
24781 var fn = e.status ? 'success' : 'failure';
24784 result = Ext.isDefined(e.result) ? e.result : e.data;
24785 if(Ext.isFunction(hs)){
24788 Ext.callback(hs[fn], hs.scope, [result, e]);
24789 Ext.callback(hs.callback, hs.scope, [result, e]);
24794 Ext.Direct.PROVIDERS['remoting'] = Ext.direct.RemotingProvider;
24795 Ext.Resizable = Ext.extend(Ext.util.Observable, {
24797 constructor: function(el, config){
24798 this.el = Ext.get(el);
24799 if(config && config.wrap){
24800 config.resizeChild = this.el;
24801 this.el = this.el.wrap(typeof config.wrap == 'object' ? config.wrap : {cls:'xresizable-wrap'});
24802 this.el.id = this.el.dom.id = config.resizeChild.id + '-rzwrap';
24803 this.el.setStyle('overflow', 'hidden');
24804 this.el.setPositioning(config.resizeChild.getPositioning());
24805 config.resizeChild.clearPositioning();
24806 if(!config.width || !config.height){
24807 var csize = config.resizeChild.getSize();
24808 this.el.setSize(csize.width, csize.height);
24810 if(config.pinned && !config.adjustments){
24811 config.adjustments = 'auto';
24816 this.proxy = this.el.createProxy({tag: 'div', cls: 'x-resizable-proxy', id: this.el.id + '-rzproxy'}, Ext.getBody());
24817 this.proxy.unselectable();
24818 this.proxy.enableDisplayMode('block');
24820 Ext.apply(this, config);
24823 this.disableTrackOver = true;
24824 this.el.addClass('x-resizable-pinned');
24827 var position = this.el.getStyle('position');
24828 if(position != 'absolute' && position != 'fixed'){
24829 this.el.setStyle('position', 'relative');
24832 this.handles = 's,e,se';
24833 if(this.multiDirectional){
24834 this.handles += ',n,w';
24837 if(this.handles == 'all'){
24838 this.handles = 'n s e w ne nw se sw';
24840 var hs = this.handles.split(/\s*?[,;]\s*?| /);
24841 var ps = Ext.Resizable.positions;
24842 for(var i = 0, len = hs.length; i < len; i++){
24843 if(hs[i] && ps[hs[i]]){
24844 var pos = ps[hs[i]];
24845 this[pos] = new Ext.Resizable.Handle(this, pos, this.disableTrackOver, this.transparent, this.handleCls);
24849 this.corner = this.southeast;
24851 if(this.handles.indexOf('n') != -1 || this.handles.indexOf('w') != -1){
24852 this.updateBox = true;
24855 this.activeHandle = null;
24857 if(this.resizeChild){
24858 if(typeof this.resizeChild == 'boolean'){
24859 this.resizeChild = Ext.get(this.el.dom.firstChild, true);
24861 this.resizeChild = Ext.get(this.resizeChild, true);
24865 if(this.adjustments == 'auto'){
24866 var rc = this.resizeChild;
24867 var hw = this.west, he = this.east, hn = this.north, hs = this.south;
24868 if(rc && (hw || hn)){
24869 rc.position('relative');
24870 rc.setLeft(hw ? hw.el.getWidth() : 0);
24871 rc.setTop(hn ? hn.el.getHeight() : 0);
24873 this.adjustments = [
24874 (he ? -he.el.getWidth() : 0) + (hw ? -hw.el.getWidth() : 0),
24875 (hn ? -hn.el.getHeight() : 0) + (hs ? -hs.el.getHeight() : 0) -1
24879 if(this.draggable){
24880 this.dd = this.dynamic ?
24881 this.el.initDD(null) : this.el.initDDProxy(null, {dragElId: this.proxy.id});
24882 this.dd.setHandleElId(this.resizeChild ? this.resizeChild.id : this.el.id);
24883 if(this.constrainTo){
24884 this.dd.constrainTo(this.constrainTo);
24895 if(this.width !== null && this.height !== null){
24896 this.resizeTo(this.width, this.height);
24898 this.updateChildSize();
24901 this.el.dom.style.zoom = 1;
24903 Ext.Resizable.superclass.constructor.call(this);
24907 adjustments : [0, 0],
24912 disableTrackOver : false,
24920 easing : 'easeOutStrong',
24927 multiDirectional : false,
24933 heightIncrement : 0,
24935 widthIncrement : 0,
24951 preserveRatio : false,
24953 resizeChild : false,
24955 transparent: false,
24962 resizeTo : function(width, height){
24963 this.el.setSize(width, height);
24964 this.updateChildSize();
24965 this.fireEvent('resize', this, width, height, null);
24969 startSizing : function(e, handle){
24970 this.fireEvent('beforeresize', this, e);
24974 this.overlay = this.el.createProxy({tag: 'div', cls: 'x-resizable-overlay', html: ' '}, Ext.getBody());
24975 this.overlay.unselectable();
24976 this.overlay.enableDisplayMode('block');
24979 mousemove: this.onMouseMove,
24980 mouseup: this.onMouseUp
24983 this.overlay.setStyle('cursor', handle.el.getStyle('cursor'));
24985 this.resizing = true;
24986 this.startBox = this.el.getBox();
24987 this.startPoint = e.getXY();
24988 this.offsets = [(this.startBox.x + this.startBox.width) - this.startPoint[0],
24989 (this.startBox.y + this.startBox.height) - this.startPoint[1]];
24991 this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
24992 this.overlay.show();
24994 if(this.constrainTo) {
24995 var ct = Ext.get(this.constrainTo);
24996 this.resizeRegion = ct.getRegion().adjust(
24997 ct.getFrameWidth('t'),
24998 ct.getFrameWidth('l'),
24999 -ct.getFrameWidth('b'),
25000 -ct.getFrameWidth('r')
25004 this.proxy.setStyle('visibility', 'hidden');
25006 this.proxy.setBox(this.startBox);
25008 this.proxy.setStyle('visibility', 'visible');
25014 onMouseDown : function(handle, e){
25017 this.activeHandle = handle;
25018 this.startSizing(e, handle);
25023 onMouseUp : function(e){
25024 this.activeHandle = null;
25025 var size = this.resizeElement();
25026 this.resizing = false;
25028 this.overlay.hide();
25030 this.fireEvent('resize', this, size.width, size.height, e);
25034 updateChildSize : function(){
25035 if(this.resizeChild){
25037 var child = this.resizeChild;
25038 var adj = this.adjustments;
25039 if(el.dom.offsetWidth){
25040 var b = el.getSize(true);
25041 child.setSize(b.width+adj[0], b.height+adj[1]);
25048 setTimeout(function(){
25049 if(el.dom.offsetWidth){
25050 var b = el.getSize(true);
25051 child.setSize(b.width+adj[0], b.height+adj[1]);
25059 snap : function(value, inc, min){
25060 if(!inc || !value){
25063 var newValue = value;
25064 var m = value % inc;
25067 newValue = value + (inc-m);
25069 newValue = value - m;
25072 return Math.max(min, newValue);
25076 resizeElement : function(){
25077 var box = this.proxy.getBox();
25078 if(this.updateBox){
25079 this.el.setBox(box, false, this.animate, this.duration, null, this.easing);
25081 this.el.setSize(box.width, box.height, this.animate, this.duration, null, this.easing);
25083 this.updateChildSize();
25087 if(this.draggable && this.constrainTo){
25088 this.dd.resetConstraints();
25089 this.dd.constrainTo(this.constrainTo);
25095 constrain : function(v, diff, m, mx){
25098 }else if(v - diff > mx){
25105 onMouseMove : function(e){
25106 if(this.enabled && this.activeHandle){
25109 if(this.resizeRegion && !this.resizeRegion.contains(e.getPoint())) {
25114 var curSize = this.curSize || this.startBox,
25115 x = this.startBox.x, y = this.startBox.y,
25119 h = curSize.height,
25122 mw = this.minWidth,
25123 mh = this.minHeight,
25124 mxw = this.maxWidth,
25125 mxh = this.maxHeight,
25126 wi = this.widthIncrement,
25127 hi = this.heightIncrement,
25128 eventXY = e.getXY(),
25129 diffX = -(this.startPoint[0] - Math.max(this.minX, eventXY[0])),
25130 diffY = -(this.startPoint[1] - Math.max(this.minY, eventXY[1])),
25131 pos = this.activeHandle.position,
25138 w = Math.min(Math.max(mw, w), mxw);
25142 h = Math.min(Math.max(mh, h), mxh);
25147 w = Math.min(Math.max(mw, w), mxw);
25148 h = Math.min(Math.max(mh, h), mxh);
25151 diffY = this.constrain(h, diffY, mh, mxh);
25156 diffX = this.constrain(w, diffX, mw, mxw);
25162 w = Math.min(Math.max(mw, w), mxw);
25163 diffY = this.constrain(h, diffY, mh, mxh);
25168 diffX = this.constrain(w, diffX, mw, mxw);
25169 diffY = this.constrain(h, diffY, mh, mxh);
25176 diffX = this.constrain(w, diffX, mw, mxw);
25178 h = Math.min(Math.max(mh, h), mxh);
25184 var sw = this.snap(w, wi, mw);
25185 var sh = this.snap(h, hi, mh);
25186 if(sw != w || sh != h){
25209 if(this.preserveRatio){
25214 h = Math.min(Math.max(mh, h), mxh);
25219 w = Math.min(Math.max(mw, w), mxw);
25224 w = Math.min(Math.max(mw, w), mxw);
25230 w = Math.min(Math.max(mw, w), mxw);
25236 h = Math.min(Math.max(mh, h), mxh);
25244 h = Math.min(Math.max(mh, h), mxh);
25254 h = Math.min(Math.max(mh, h), mxh);
25262 this.proxy.setBounds(x, y, w, h);
25264 this.resizeElement();
25271 handleOver : function(){
25273 this.el.addClass('x-resizable-over');
25278 handleOut : function(){
25279 if(!this.resizing){
25280 this.el.removeClass('x-resizable-over');
25285 getEl : function(){
25290 getResizeChild : function(){
25291 return this.resizeChild;
25295 destroy : function(removeEl){
25296 Ext.destroy(this.dd, this.overlay, this.proxy);
25297 this.overlay = null;
25300 var ps = Ext.Resizable.positions;
25302 if(typeof ps[k] != 'function' && this[ps[k]]){
25303 this[ps[k]].destroy();
25307 this.el.update('');
25308 Ext.destroy(this.el);
25311 this.purgeListeners();
25314 syncHandleHeight : function(){
25315 var h = this.el.getHeight(true);
25317 this.west.el.setHeight(h);
25320 this.east.el.setHeight(h);
25327 Ext.Resizable.positions = {
25328 n: 'north', s: 'south', e: 'east', w: 'west', se: 'southeast', sw: 'southwest', nw: 'northwest', ne: 'northeast'
25331 Ext.Resizable.Handle = Ext.extend(Object, {
25332 constructor : function(rz, pos, disableTrackOver, transparent, cls){
25335 var tpl = Ext.DomHelper.createTemplate(
25336 {tag: 'div', cls: 'x-resizable-handle x-resizable-handle-{0}'}
25339 Ext.Resizable.Handle.prototype.tpl = tpl;
25341 this.position = pos;
25343 this.el = this.tpl.append(rz.el.dom, [this.position], true);
25344 this.el.unselectable();
25346 this.el.setOpacity(0);
25348 if(!Ext.isEmpty(cls)){
25349 this.el.addClass(cls);
25351 this.el.on('mousedown', this.onMouseDown, this);
25352 if(!disableTrackOver){
25355 mouseover: this.onMouseOver,
25356 mouseout: this.onMouseOut
25362 afterResize : function(rz){
25366 onMouseDown : function(e){
25367 this.rz.onMouseDown(this, e);
25370 onMouseOver : function(e){
25371 this.rz.handleOver(this, e);
25374 onMouseOut : function(e){
25375 this.rz.handleOut(this, e);
25378 destroy : function(){
25379 Ext.destroy(this.el);
25384 Ext.Window = Ext.extend(Ext.Panel, {
25397 baseCls : 'x-window',
25405 closeAction : 'close',
25409 constrainHeader : false,
25413 minimizable : false,
25415 maximizable : false,
25421 expandOnShow : true,
25424 collapsible : false,
25427 initHidden : undefined,
25437 elements : 'header,body',
25444 initComponent : function(){
25446 Ext.Window.superclass.initComponent.call(this);
25460 if(Ext.isDefined(this.initHidden)){
25461 this.hidden = this.initHidden;
25463 if(this.hidden === false){
25464 this.hidden = true;
25470 getState : function(){
25471 return Ext.apply(Ext.Window.superclass.getState.call(this) || {}, this.getBox(true));
25475 onRender : function(ct, position){
25476 Ext.Window.superclass.onRender.call(this, ct, position);
25479 this.el.addClass('x-window-plain');
25483 this.focusEl = this.el.createChild({
25484 tag: 'a', href:'#', cls:'x-dlg-focus',
25485 tabIndex:'-1', html: ' '});
25486 this.focusEl.swallowEvent('click', true);
25488 this.proxy = this.el.createProxy('x-window-proxy');
25489 this.proxy.enableDisplayMode('block');
25492 this.mask = this.container.createChild({cls:'ext-el-mask'}, this.el.dom);
25493 this.mask.enableDisplayMode('block');
25495 this.mon(this.mask, 'click', this.focus, this);
25497 if(this.maximizable){
25498 this.mon(this.header, 'dblclick', this.toggleMaximize, this);
25503 initEvents : function(){
25504 Ext.Window.superclass.initEvents.call(this);
25505 if(this.animateTarget){
25506 this.setAnimateTarget(this.animateTarget);
25509 if(this.resizable){
25510 this.resizer = new Ext.Resizable(this.el, {
25511 minWidth: this.minWidth,
25512 minHeight:this.minHeight,
25513 handles: this.resizeHandles || 'all',
25515 resizeElement : this.resizerAction,
25516 handleCls: 'x-window-handle'
25518 this.resizer.window = this;
25519 this.mon(this.resizer, 'beforeresize', this.beforeResize, this);
25522 if(this.draggable){
25523 this.header.addClass('x-window-draggable');
25525 this.mon(this.el, 'mousedown', this.toFront, this);
25526 this.manager = this.manager || Ext.WindowMgr;
25527 this.manager.register(this);
25528 if(this.maximized){
25529 this.maximized = false;
25533 var km = this.getKeyMap();
25534 km.on(27, this.onEsc, this);
25539 initDraggable : function(){
25541 this.dd = new Ext.Window.DD(this);
25545 onEsc : function(k, e){
25547 this[this.closeAction]();
25551 beforeDestroy : function(){
25554 this.clearAnchor();
25563 Ext.Window.superclass.beforeDestroy.call(this);
25567 onDestroy : function(){
25569 this.manager.unregister(this);
25571 Ext.Window.superclass.onDestroy.call(this);
25575 initTools : function(){
25576 if(this.minimizable){
25579 handler: this.minimize.createDelegate(this, [])
25582 if(this.maximizable){
25585 handler: this.maximize.createDelegate(this, [])
25589 handler: this.restore.createDelegate(this, []),
25596 handler: this[this.closeAction].createDelegate(this, [])
25602 resizerAction : function(){
25603 var box = this.proxy.getBox();
25605 this.window.handleResize(box);
25610 beforeResize : function(){
25611 this.resizer.minHeight = Math.max(this.minHeight, this.getFrameHeight() + 40);
25612 this.resizer.minWidth = Math.max(this.minWidth, this.getFrameWidth() + 40);
25613 this.resizeBox = this.el.getBox();
25617 updateHandles : function(){
25618 if(Ext.isIE && this.resizer){
25619 this.resizer.syncHandleHeight();
25625 handleResize : function(box){
25626 var rz = this.resizeBox;
25627 if(rz.x != box.x || rz.y != box.y){
25628 this.updateBox(box);
25631 if (Ext.isIE6 && Ext.isStrict) {
25636 this.updateHandles();
25641 focus : function(){
25642 var f = this.focusEl,
25643 db = this.defaultButton,
25647 if(Ext.isDefined(db)){
25648 if(Ext.isNumber(db) && this.fbar){
25649 f = this.fbar.items.get(db);
25650 }else if(Ext.isString(db)){
25651 f = Ext.getCmp(db);
25656 ct = Ext.getDom(this.container);
25658 if (!Ext.lib.Region.getRegion(ct).contains(Ext.lib.Region.getRegion(el.dom))){
25663 f = f || this.focusEl;
25664 f.focus.defer(10, f);
25668 setAnimateTarget : function(el){
25670 this.animateTarget = el;
25674 beforeShow : function(){
25675 delete this.el.lastXY;
25676 delete this.el.lastLT;
25677 if(this.x === undefined || this.y === undefined){
25678 var xy = this.el.getAlignToXY(this.container, 'c-c');
25679 var pos = this.el.translatePoints(xy[0], xy[1]);
25680 this.x = this.x === undefined? pos.left : this.x;
25681 this.y = this.y === undefined? pos.top : this.y;
25683 this.el.setLeftTop(this.x, this.y);
25685 if(this.expandOnShow){
25686 this.expand(false);
25690 Ext.getBody().addClass('x-body-masked');
25691 this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
25697 show : function(animateTarget, cb, scope){
25698 if(!this.rendered){
25699 this.render(Ext.getBody());
25701 if(this.hidden === false){
25705 if(this.fireEvent('beforeshow', this) === false){
25709 this.on('show', cb, scope, {single:true});
25711 this.hidden = false;
25712 if(Ext.isDefined(animateTarget)){
25713 this.setAnimateTarget(animateTarget);
25716 if(this.animateTarget){
25725 afterShow : function(isAnim){
25726 if (this.isDestroyed){
25730 this.el.setStyle('display', 'block');
25732 if(this.maximized){
25733 this.fitContainer();
25735 if(Ext.isMac && Ext.isGecko2){
25736 this.cascade(this.setAutoScroll);
25739 if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
25740 Ext.EventManager.onWindowResize(this.onWindowResize, this);
25742 this.doConstrain();
25745 this.keyMap.enable();
25748 this.updateHandles();
25749 if(isAnim && (Ext.isIE || Ext.isWebKit)){
25750 var sz = this.getSize();
25751 this.onResize(sz.width, sz.height);
25754 this.fireEvent('show', this);
25758 animShow : function(){
25760 this.proxy.setBox(this.animateTarget.getBox());
25761 this.proxy.setOpacity(0);
25762 var b = this.getBox();
25763 this.el.setStyle('display', 'none');
25764 this.proxy.shift(Ext.apply(b, {
25765 callback: this.afterShow.createDelegate(this, [true], false),
25767 easing: 'easeNone',
25774 hide : function(animateTarget, cb, scope){
25775 if(this.hidden || this.fireEvent('beforehide', this) === false){
25779 this.on('hide', cb, scope, {single:true});
25781 this.hidden = true;
25782 if(animateTarget !== undefined){
25783 this.setAnimateTarget(animateTarget);
25787 Ext.getBody().removeClass('x-body-masked');
25789 if(this.animateTarget){
25799 afterHide : function(){
25801 if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
25802 Ext.EventManager.removeResizeListener(this.onWindowResize, this);
25805 this.keyMap.disable();
25808 this.fireEvent('hide', this);
25812 animHide : function(){
25813 this.proxy.setOpacity(0.5);
25815 var tb = this.getBox(false);
25816 this.proxy.setBox(tb);
25818 this.proxy.shift(Ext.apply(this.animateTarget.getBox(), {
25819 callback: this.afterHide,
25822 easing: 'easeNone',
25828 onShow : Ext.emptyFn,
25831 onHide : Ext.emptyFn,
25834 onWindowResize : function(){
25835 if(this.maximized){
25836 this.fitContainer();
25839 this.mask.setSize('100%', '100%');
25840 var force = this.mask.dom.offsetHeight;
25841 this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
25843 this.doConstrain();
25847 doConstrain : function(){
25848 if(this.constrain || this.constrainHeader){
25850 if(this.constrain){
25852 right:this.el.shadowOffset,
25853 left:this.el.shadowOffset,
25854 bottom:this.el.shadowOffset
25857 var s = this.getSize();
25859 right:-(s.width - 100),
25860 bottom:-(s.height - 25)
25864 var xy = this.el.getConstrainToXY(this.container, true, offsets);
25866 this.setPosition(xy[0], xy[1]);
25872 ghost : function(cls){
25873 var ghost = this.createGhost(cls);
25874 var box = this.getBox(true);
25875 ghost.setLeftTop(box.x, box.y);
25876 ghost.setWidth(box.width);
25878 this.activeGhost = ghost;
25883 unghost : function(show, matchPosition){
25884 if(!this.activeGhost) {
25887 if(show !== false){
25889 this.focus.defer(10, this);
25890 if(Ext.isMac && Ext.isGecko2){
25891 this.cascade(this.setAutoScroll);
25894 if(matchPosition !== false){
25895 this.setPosition(this.activeGhost.getLeft(true), this.activeGhost.getTop(true));
25897 this.activeGhost.hide();
25898 this.activeGhost.remove();
25899 delete this.activeGhost;
25903 minimize : function(){
25904 this.fireEvent('minimize', this);
25909 close : function(){
25910 if(this.fireEvent('beforeclose', this) !== false){
25914 this.hide(null, this.doClose, this);
25920 doClose : function(){
25921 this.fireEvent('close', this);
25926 maximize : function(){
25927 if(!this.maximized){
25928 this.expand(false);
25929 this.restoreSize = this.getSize();
25930 this.restorePos = this.getPosition(true);
25931 if (this.maximizable){
25932 this.tools.maximize.hide();
25933 this.tools.restore.show();
25935 this.maximized = true;
25936 this.el.disableShadow();
25941 if(this.collapsible){
25942 this.tools.toggle.hide();
25944 this.el.addClass('x-window-maximized');
25945 this.container.addClass('x-window-maximized-ct');
25947 this.setPosition(0, 0);
25948 this.fitContainer();
25949 this.fireEvent('maximize', this);
25955 restore : function(){
25956 if(this.maximized){
25957 var t = this.tools;
25958 this.el.removeClass('x-window-maximized');
25965 this.setPosition(this.restorePos[0], this.restorePos[1]);
25966 this.setSize(this.restoreSize.width, this.restoreSize.height);
25967 delete this.restorePos;
25968 delete this.restoreSize;
25969 this.maximized = false;
25970 this.el.enableShadow(true);
25975 if(this.collapsible && t.toggle){
25978 this.container.removeClass('x-window-maximized-ct');
25980 this.doConstrain();
25981 this.fireEvent('restore', this);
25987 toggleMaximize : function(){
25988 return this[this.maximized ? 'restore' : 'maximize']();
25992 fitContainer : function(){
25993 var vs = this.container.getViewSize(false);
25994 this.setSize(vs.width, vs.height);
25999 setZIndex : function(index){
26001 this.mask.setStyle('z-index', index);
26003 this.el.setZIndex(++index);
26007 this.resizer.proxy.setStyle('z-index', ++index);
26010 this.lastZIndex = index;
26014 alignTo : function(element, position, offsets){
26015 var xy = this.el.getAlignToXY(element, position, offsets);
26016 this.setPagePosition(xy[0], xy[1]);
26021 anchorTo : function(el, alignment, offsets, monitorScroll){
26022 this.clearAnchor();
26023 this.anchorTarget = {
26025 alignment: alignment,
26029 Ext.EventManager.onWindowResize(this.doAnchor, this);
26030 var tm = typeof monitorScroll;
26031 if(tm != 'undefined'){
26032 Ext.EventManager.on(window, 'scroll', this.doAnchor, this,
26033 {buffer: tm == 'number' ? monitorScroll : 50});
26035 return this.doAnchor();
26039 doAnchor : function(){
26040 var o = this.anchorTarget;
26041 this.alignTo(o.el, o.alignment, o.offsets);
26046 clearAnchor : function(){
26047 if(this.anchorTarget){
26048 Ext.EventManager.removeResizeListener(this.doAnchor, this);
26049 Ext.EventManager.un(window, 'scroll', this.doAnchor, this);
26050 delete this.anchorTarget;
26056 toFront : function(e){
26057 if(this.manager.bringToFront(this)){
26058 if(!e || !e.getTarget().focus){
26066 setActive : function(active){
26068 if(!this.maximized){
26069 this.el.enableShadow(true);
26071 this.fireEvent('activate', this);
26073 this.el.disableShadow();
26074 this.fireEvent('deactivate', this);
26079 toBack : function(){
26080 this.manager.sendToBack(this);
26085 center : function(){
26086 var xy = this.el.getAlignToXY(this.container, 'c-c');
26087 this.setPagePosition(xy[0], xy[1]);
26093 Ext.reg('window', Ext.Window);
26096 Ext.Window.DD = function(win){
26098 Ext.Window.DD.superclass.constructor.call(this, win.el.id, 'WindowDD-'+win.id);
26099 this.setHandleElId(win.header.id);
26100 this.scroll = false;
26103 Ext.extend(Ext.Window.DD, Ext.dd.DD, {
26105 headerOffsets:[100, 25],
26106 startDrag : function(){
26108 this.proxy = w.ghost();
26109 if(w.constrain !== false){
26110 var so = w.el.shadowOffset;
26111 this.constrainTo(w.container, {right: so, left: so, bottom: so});
26112 }else if(w.constrainHeader !== false){
26113 var s = this.proxy.getSize();
26114 this.constrainTo(w.container, {right: -(s.width-this.headerOffsets[0]), bottom: -(s.height-this.headerOffsets[1])});
26117 b4Drag : Ext.emptyFn,
26119 onDrag : function(e){
26120 this.alignElWithMouse(this.proxy, e.getPageX(), e.getPageY());
26123 endDrag : function(e){
26124 this.win.unghost();
26125 this.win.saveState();
26129 Ext.WindowGroup = function(){
26131 var accessList = [];
26135 var sortWindows = function(d1, d2){
26136 return (!d1._lastAccess || d1._lastAccess < d2._lastAccess) ? -1 : 1;
26140 var orderWindows = function(){
26141 var a = accessList, len = a.length;
26143 a.sort(sortWindows);
26144 var seed = a[0].manager.zseed;
26145 for(var i = 0; i < len; i++){
26147 if(win && !win.hidden){
26148 win.setZIndex(seed + (i*10));
26156 var setActiveWin = function(win){
26159 front.setActive(false);
26163 win.setActive(true);
26169 var activateLast = function(){
26170 for(var i = accessList.length-1; i >=0; --i) {
26171 if(!accessList[i].hidden){
26172 setActiveWin(accessList[i]);
26177 setActiveWin(null);
26185 register : function(win){
26187 win.manager.unregister(win);
26189 win.manager = this;
26191 list[win.id] = win;
26192 accessList.push(win);
26193 win.on('hide', activateLast);
26197 unregister : function(win){
26198 delete win.manager;
26199 delete list[win.id];
26200 win.un('hide', activateLast);
26201 accessList.remove(win);
26205 get : function(id){
26206 return typeof id == "object" ? id : list[id];
26210 bringToFront : function(win){
26211 win = this.get(win);
26213 win._lastAccess = new Date().getTime();
26221 sendToBack : function(win){
26222 win = this.get(win);
26223 win._lastAccess = -(new Date().getTime());
26229 hideAll : function(){
26230 for(var id in list){
26231 if(list[id] && typeof list[id] != "function" && list[id].isVisible()){
26238 getActive : function(){
26243 getBy : function(fn, scope){
26245 for(var i = accessList.length-1; i >=0; --i) {
26246 var win = accessList[i];
26247 if(fn.call(scope||win, win) !== false){
26255 each : function(fn, scope){
26256 for(var id in list){
26257 if(list[id] && typeof list[id] != "function"){
26258 if(fn.call(scope || list[id], list[id]) === false){
26269 Ext.WindowMgr = new Ext.WindowGroup();
26270 Ext.MessageBox = function(){
26271 var dlg, opt, mask, waitTimer,
26272 bodyEl, msgEl, textboxEl, textareaEl, progressBar, pp, iconEl, spacerEl,
26273 buttons, activeTextEl, bwidth, bufferIcon = '', iconCls = '',
26274 buttonNames = ['ok', 'yes', 'no', 'cancel'];
26277 var handleButton = function(button){
26278 buttons[button].blur();
26279 if(dlg.isVisible()){
26282 Ext.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value, opt], 1);
26287 var handleHide = function(){
26288 if(opt && opt.cls){
26289 dlg.el.removeClass(opt.cls);
26291 progressBar.reset();
26295 var handleEsc = function(d, k, e){
26296 if(opt && opt.closable !== false){
26306 var updateButtons = function(b){
26310 Ext.each(buttonNames, function(name){
26311 buttons[name].hide();
26315 dlg.footer.dom.style.display = '';
26316 Ext.iterate(buttons, function(name, btn){
26320 btn.setText(Ext.isString(cfg) ? cfg : Ext.MessageBox.buttonText[name]);
26321 width += btn.getEl().getWidth() + 15;
26331 getDialog : function(titleText){
26336 Ext.each(buttonNames, function(name){
26337 btns.push(buttons[name] = new Ext.Button({
26338 text: this.buttonText[name],
26339 handler: handleButton.createCallback(name),
26340 hideMode: 'offsets'
26343 dlg = new Ext.Window({
26348 constrainHeader:true,
26349 minimizable : false,
26350 maximizable : false,
26354 buttonAlign:"center",
26361 close : function(){
26362 if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){
26363 handleButton("no");
26365 handleButton("cancel");
26368 fbar: new Ext.Toolbar({
26370 enableOverflow: false
26373 dlg.render(document.body);
26374 dlg.getEl().addClass('x-window-dlg');
26376 bodyEl = dlg.body.createChild({
26377 html:'<div class="ext-mb-icon"></div><div class="ext-mb-content"><span class="ext-mb-text"></span><br /><div class="ext-mb-fix-cursor"><input type="text" class="ext-mb-input" /><textarea class="ext-mb-textarea"></textarea></div></div>'
26379 iconEl = Ext.get(bodyEl.dom.firstChild);
26380 var contentEl = bodyEl.dom.childNodes[1];
26381 msgEl = Ext.get(contentEl.firstChild);
26382 textboxEl = Ext.get(contentEl.childNodes[2].firstChild);
26383 textboxEl.enableDisplayMode();
26384 textboxEl.addKeyListener([10,13], function(){
26385 if(dlg.isVisible() && opt && opt.buttons){
26386 if(opt.buttons.ok){
26387 handleButton("ok");
26388 }else if(opt.buttons.yes){
26389 handleButton("yes");
26393 textareaEl = Ext.get(contentEl.childNodes[2].childNodes[1]);
26394 textareaEl.enableDisplayMode();
26395 progressBar = new Ext.ProgressBar({
26398 bodyEl.createChild({cls:'x-clear'});
26404 updateText : function(text){
26405 if(!dlg.isVisible() && !opt.width){
26406 dlg.setSize(this.maxWidth, 100);
26408 msgEl.update(text || ' ');
26410 var iw = iconCls != '' ? (iconEl.getWidth() + iconEl.getMargins('lr')) : 0,
26411 mw = msgEl.getWidth() + msgEl.getMargins('lr'),
26412 fw = dlg.getFrameWidth('lr'),
26413 bw = dlg.body.getFrameWidth('lr'),
26416 if (Ext.isIE && iw > 0){
26421 w = Math.max(Math.min(opt.width || iw+mw+fw+bw, opt.maxWidth || this.maxWidth),
26422 Math.max(opt.minWidth || this.minWidth, bwidth || 0));
26424 if(opt.prompt === true){
26425 activeTextEl.setWidth(w-iw-fw-bw);
26427 if(opt.progress === true || opt.wait === true){
26428 progressBar.setSize(w-iw-fw-bw);
26430 if(Ext.isIE && w == bwidth){
26433 dlg.setSize(w, 'auto').center();
26438 updateProgress : function(value, progressText, msg){
26439 progressBar.updateProgress(value, progressText);
26441 this.updateText(msg);
26447 isVisible : function(){
26448 return dlg && dlg.isVisible();
26453 var proxy = dlg ? dlg.activeGhost : null;
26454 if(this.isVisible() || proxy){
26460 dlg.unghost(false, false);
26467 show : function(options){
26468 if(this.isVisible()){
26472 var d = this.getDialog(opt.title || " ");
26474 d.setTitle(opt.title || " ");
26475 var allowClose = (opt.closable !== false && opt.progress !== true && opt.wait !== true);
26476 d.tools.close.setDisplayed(allowClose);
26477 activeTextEl = textboxEl;
26478 opt.prompt = opt.prompt || (opt.multiline ? true : false);
26483 textareaEl.setHeight(Ext.isNumber(opt.multiline) ? opt.multiline : this.defaultTextHeight);
26484 activeTextEl = textareaEl;
26493 activeTextEl.dom.value = opt.value || "";
26495 d.focusEl = activeTextEl;
26497 var bs = opt.buttons;
26500 db = buttons["ok"];
26501 }else if(bs && bs.yes){
26502 db = buttons["yes"];
26508 if(Ext.isDefined(opt.iconCls)){
26509 d.setIconClass(opt.iconCls);
26511 this.setIcon(Ext.isDefined(opt.icon) ? opt.icon : bufferIcon);
26512 bwidth = updateButtons(opt.buttons);
26513 progressBar.setVisible(opt.progress === true || opt.wait === true);
26514 this.updateProgress(0, opt.progressText);
26515 this.updateText(opt.msg);
26517 d.el.addClass(opt.cls);
26519 d.proxyDrag = opt.proxyDrag === true;
26520 d.modal = opt.modal !== false;
26521 d.mask = opt.modal !== false ? mask : false;
26522 if(!d.isVisible()){
26524 document.body.appendChild(dlg.el.dom);
26525 d.setAnimateTarget(opt.animEl);
26527 d.on('show', function(){
26528 if(allowClose === true){
26531 d.keyMap.disable();
26533 }, this, {single:true});
26534 d.show(opt.animEl);
26536 if(opt.wait === true){
26537 progressBar.wait(opt.waitConfig);
26543 setIcon : function(icon){
26548 bufferIcon = undefined;
26549 if(icon && icon != ''){
26550 iconEl.removeClass('x-hidden');
26551 iconEl.replaceClass(iconCls, icon);
26552 bodyEl.addClass('x-dlg-icon');
26555 iconEl.replaceClass(iconCls, 'x-hidden');
26556 bodyEl.removeClass('x-dlg-icon');
26563 progress : function(title, msg, progressText){
26570 minWidth: this.minProgressWidth,
26571 progressText: progressText
26577 wait : function(msg, title, config){
26585 minWidth: this.minProgressWidth,
26592 alert : function(title, msg, fn, scope){
26599 minWidth: this.minWidth
26605 confirm : function(title, msg, fn, scope){
26609 buttons: this.YESNO,
26612 icon: this.QUESTION,
26613 minWidth: this.minWidth
26619 prompt : function(title, msg, fn, scope, multiline, value){
26623 buttons: this.OKCANCEL,
26625 minWidth: this.minPromptWidth,
26628 multiline: multiline,
26637 CANCEL : {cancel:true},
26639 OKCANCEL : {ok:true, cancel:true},
26641 YESNO : {yes:true, no:true},
26643 YESNOCANCEL : {yes:true, no:true, cancel:true},
26645 INFO : 'ext-mb-info',
26647 WARNING : 'ext-mb-warning',
26649 QUESTION : 'ext-mb-question',
26651 ERROR : 'ext-mb-error',
26654 defaultTextHeight : 75,
26660 minProgressWidth : 250,
26662 minPromptWidth: 250,
26674 Ext.Msg = Ext.MessageBox;
26675 Ext.dd.PanelProxy = function(panel, config){
26676 this.panel = panel;
26677 this.id = this.panel.id +'-ddproxy';
26678 Ext.apply(this, config);
26681 Ext.dd.PanelProxy.prototype = {
26683 insertProxy : true,
26686 setStatus : Ext.emptyFn,
26687 reset : Ext.emptyFn,
26688 update : Ext.emptyFn,
26689 stop : Ext.emptyFn,
26693 getEl : function(){
26698 getGhost : function(){
26703 getProxy : function(){
26711 this.proxy.remove();
26714 this.panel.el.dom.style.display = '';
26715 this.ghost.remove();
26723 this.ghost = this.panel.createGhost(undefined, undefined, Ext.getBody());
26724 this.ghost.setXY(this.panel.el.getXY());
26725 if(this.insertProxy){
26726 this.proxy = this.panel.el.insertSibling({cls:'x-panel-dd-spacer'});
26727 this.proxy.setSize(this.panel.getSize());
26729 this.panel.el.dom.style.display = 'none';
26734 repair : function(xy, callback, scope){
26736 if(typeof callback == "function"){
26737 callback.call(scope || this);
26742 moveProxy : function(parentNode, before){
26744 parentNode.insertBefore(this.proxy.dom, before);
26750 Ext.Panel.DD = function(panel, cfg){
26751 this.panel = panel;
26752 this.dragData = {panel: panel};
26753 this.proxy = new Ext.dd.PanelProxy(panel, cfg);
26754 Ext.Panel.DD.superclass.constructor.call(this, panel.el, cfg);
26755 var h = panel.header;
26757 this.setHandleElId(h.id);
26759 (h ? h : this.panel.body).setStyle('cursor', 'move');
26760 this.scroll = false;
26763 Ext.extend(Ext.Panel.DD, Ext.dd.DragSource, {
26764 showFrame: Ext.emptyFn,
26765 startDrag: Ext.emptyFn,
26766 b4StartDrag: function(x, y) {
26769 b4MouseDown: function(e) {
26770 var x = e.getPageX();
26771 var y = e.getPageY();
26772 this.autoOffset(x, y);
26774 onInitDrag : function(x, y){
26775 this.onStartDrag(x, y);
26778 createFrame : Ext.emptyFn,
26779 getDragEl : function(e){
26780 return this.proxy.ghost.dom;
26782 endDrag : function(e){
26784 this.panel.saveState();
26787 autoOffset : function(x, y) {
26788 x -= this.startPageX;
26789 y -= this.startPageY;
26790 this.setDelta(x, y);
26793 Ext.state.Provider = Ext.extend(Ext.util.Observable, {
26795 constructor : function(){
26797 this.addEvents("statechange");
26799 Ext.state.Provider.superclass.constructor.call(this);
26803 get : function(name, defaultValue){
26804 return typeof this.state[name] == "undefined" ?
26805 defaultValue : this.state[name];
26809 clear : function(name){
26810 delete this.state[name];
26811 this.fireEvent("statechange", this, name, null);
26815 set : function(name, value){
26816 this.state[name] = value;
26817 this.fireEvent("statechange", this, name, value);
26821 decodeValue : function(cookie){
26823 var re = /^(a|n|d|b|s|o|e)\:(.*)$/,
26824 matches = re.exec(unescape(cookie)),
26829 if(!matches || !matches[1]){
26838 return parseFloat(v);
26840 return new Date(Date.parse(v));
26846 Ext.each(v.split('^'), function(val){
26847 all.push(this.decodeValue(val));
26854 Ext.each(v.split('^'), function(val){
26855 kv = val.split('=');
26856 all[kv[0]] = this.decodeValue(kv[1]);
26866 encodeValue : function(v){
26874 }else if(typeof v == 'number'){
26876 }else if(typeof v == 'boolean'){
26877 enc = 'b:' + (v ? '1' : '0');
26878 }else if(Ext.isDate(v)){
26879 enc = 'd:' + v.toGMTString();
26880 }else if(Ext.isArray(v)){
26881 for(len = v.length; i < len; i++){
26882 flat += this.encodeValue(v[i]);
26888 }else if(typeof v == 'object'){
26890 if(typeof v[key] != 'function' && v[key] !== undefined){
26891 flat += key + '=' + this.encodeValue(v[key]) + '^';
26894 enc = 'o:' + flat.substring(0, flat.length-1);
26898 return escape(enc);
26902 Ext.state.Manager = function(){
26903 var provider = new Ext.state.Provider();
26907 setProvider : function(stateProvider){
26908 provider = stateProvider;
26912 get : function(key, defaultValue){
26913 return provider.get(key, defaultValue);
26917 set : function(key, value){
26918 provider.set(key, value);
26922 clear : function(key){
26923 provider.clear(key);
26927 getProvider : function(){
26933 Ext.state.CookieProvider = Ext.extend(Ext.state.Provider, {
26935 constructor : function(config){
26936 Ext.state.CookieProvider.superclass.constructor.call(this);
26938 this.expires = new Date(new Date().getTime()+(1000*60*60*24*7));
26939 this.domain = null;
26940 this.secure = false;
26941 Ext.apply(this, config);
26942 this.state = this.readCookies();
26946 set : function(name, value){
26947 if(typeof value == "undefined" || value === null){
26951 this.setCookie(name, value);
26952 Ext.state.CookieProvider.superclass.set.call(this, name, value);
26956 clear : function(name){
26957 this.clearCookie(name);
26958 Ext.state.CookieProvider.superclass.clear.call(this, name);
26962 readCookies : function(){
26964 c = document.cookie + ";",
26965 re = /\s?(.*?)=(.*?);/g,
26969 while((matches = re.exec(c)) != null){
26971 value = matches[2];
26972 if(name && name.substring(0,3) == "ys-"){
26973 cookies[name.substr(3)] = this.decodeValue(value);
26980 setCookie : function(name, value){
26981 document.cookie = "ys-"+ name + "=" + this.encodeValue(value) +
26982 ((this.expires == null) ? "" : ("; expires=" + this.expires.toGMTString())) +
26983 ((this.path == null) ? "" : ("; path=" + this.path)) +
26984 ((this.domain == null) ? "" : ("; domain=" + this.domain)) +
26985 ((this.secure == true) ? "; secure" : "");
26989 clearCookie : function(name){
26990 document.cookie = "ys-" + name + "=null; expires=Thu, 01-Jan-70 00:00:01 GMT" +
26991 ((this.path == null) ? "" : ("; path=" + this.path)) +
26992 ((this.domain == null) ? "" : ("; domain=" + this.domain)) +
26993 ((this.secure == true) ? "; secure" : "");
26996 Ext.DataView = Ext.extend(Ext.BoxComponent, {
27006 selectedClass : "x-view-selected",
27011 deferEmptyText: true,
27016 blockRefresh: false,
27022 initComponent : function(){
27023 Ext.DataView.superclass.initComponent.call(this);
27024 if(Ext.isString(this.tpl) || Ext.isArray(this.tpl)){
27025 this.tpl = new Ext.XTemplate(this.tpl);
27044 "containercontextmenu",
27052 this.store = Ext.StoreMgr.lookup(this.store);
27053 this.all = new Ext.CompositeElementLite();
27054 this.selected = new Ext.CompositeElementLite();
27058 afterRender : function(){
27059 Ext.DataView.superclass.afterRender.call(this);
27061 this.mon(this.getTemplateTarget(), {
27062 "click": this.onClick,
27063 "dblclick": this.onDblClick,
27064 "contextmenu": this.onContextMenu,
27068 if(this.overClass || this.trackOver){
27069 this.mon(this.getTemplateTarget(), {
27070 "mouseover": this.onMouseOver,
27071 "mouseout": this.onMouseOut,
27077 this.bindStore(this.store, true);
27082 refresh : function() {
27083 this.clearSelections(false, true);
27084 var el = this.getTemplateTarget();
27086 var records = this.store.getRange();
27087 if(records.length < 1){
27088 if(!this.deferEmptyText || this.hasSkippedEmptyText){
27089 el.update(this.emptyText);
27093 this.tpl.overwrite(el, this.collectData(records, 0));
27094 this.all.fill(Ext.query(this.itemSelector, el.dom));
27095 this.updateIndexes(0);
27097 this.hasSkippedEmptyText = true;
27100 getTemplateTarget: function(){
27105 prepareData : function(data){
27110 collectData : function(records, startIndex){
27112 for(var i = 0, len = records.length; i < len; i++){
27113 r[r.length] = this.prepareData(records[i].data, startIndex+i, records[i]);
27119 bufferRender : function(records){
27120 var div = document.createElement('div');
27121 this.tpl.overwrite(div, this.collectData(records));
27122 return Ext.query(this.itemSelector, div);
27126 onUpdate : function(ds, record){
27127 var index = this.store.indexOf(record);
27129 var sel = this.isSelected(index);
27130 var original = this.all.elements[index];
27131 var node = this.bufferRender([record], index)[0];
27133 this.all.replaceElement(index, node, true);
27135 this.selected.replaceElement(original, node);
27136 this.all.item(index).addClass(this.selectedClass);
27138 this.updateIndexes(index, index);
27143 onAdd : function(ds, records, index){
27144 if(this.all.getCount() === 0){
27148 var nodes = this.bufferRender(records, index), n, a = this.all.elements;
27149 if(index < this.all.getCount()){
27150 n = this.all.item(index).insertSibling(nodes, 'before', true);
27151 a.splice.apply(a, [index, 0].concat(nodes));
27153 n = this.all.last().insertSibling(nodes, 'after', true);
27154 a.push.apply(a, nodes);
27156 this.updateIndexes(index);
27160 onRemove : function(ds, record, index){
27161 this.deselect(index);
27162 this.all.removeElement(index, true);
27163 this.updateIndexes(index);
27164 if (this.store.getCount() === 0){
27170 refreshNode : function(index){
27171 this.onUpdate(this.store, this.store.getAt(index));
27175 updateIndexes : function(startIndex, endIndex){
27176 var ns = this.all.elements;
27177 startIndex = startIndex || 0;
27178 endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length - 1));
27179 for(var i = startIndex; i <= endIndex; i++){
27180 ns[i].viewIndex = i;
27185 getStore : function(){
27190 bindStore : function(store, initial){
27191 if(!initial && this.store){
27192 if(store !== this.store && this.store.autoDestroy){
27193 this.store.destroy();
27195 this.store.un("beforeload", this.onBeforeLoad, this);
27196 this.store.un("datachanged", this.onDataChanged, this);
27197 this.store.un("add", this.onAdd, this);
27198 this.store.un("remove", this.onRemove, this);
27199 this.store.un("update", this.onUpdate, this);
27200 this.store.un("clear", this.refresh, this);
27207 store = Ext.StoreMgr.lookup(store);
27210 beforeload: this.onBeforeLoad,
27211 datachanged: this.onDataChanged,
27213 remove: this.onRemove,
27214 update: this.onUpdate,
27215 clear: this.refresh
27218 this.store = store;
27225 onDataChanged: function() {
27226 if (this.blockRefresh !== true) {
27227 this.refresh.apply(this, arguments);
27232 findItemFromChild : function(node){
27233 return Ext.fly(node).findParent(this.itemSelector, this.getTemplateTarget());
27237 onClick : function(e){
27238 var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
27240 var index = this.indexOf(item);
27241 if(this.onItemClick(item, index, e) !== false){
27242 this.fireEvent("click", this, index, item, e);
27245 if(this.fireEvent("containerclick", this, e) !== false){
27246 this.onContainerClick(e);
27251 onContainerClick : function(e){
27252 this.clearSelections();
27256 onContextMenu : function(e){
27257 var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
27259 this.fireEvent("contextmenu", this, this.indexOf(item), item, e);
27261 this.fireEvent("containercontextmenu", this, e);
27266 onDblClick : function(e){
27267 var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
27269 this.fireEvent("dblclick", this, this.indexOf(item), item, e);
27274 onMouseOver : function(e){
27275 var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
27276 if(item && item !== this.lastItem){
27277 this.lastItem = item;
27278 Ext.fly(item).addClass(this.overClass);
27279 this.fireEvent("mouseenter", this, this.indexOf(item), item, e);
27284 onMouseOut : function(e){
27286 if(!e.within(this.lastItem, true, true)){
27287 Ext.fly(this.lastItem).removeClass(this.overClass);
27288 this.fireEvent("mouseleave", this, this.indexOf(this.lastItem), this.lastItem, e);
27289 delete this.lastItem;
27295 onItemClick : function(item, index, e){
27296 if(this.fireEvent("beforeclick", this, index, item, e) === false){
27299 if(this.multiSelect){
27300 this.doMultiSelection(item, index, e);
27301 e.preventDefault();
27302 }else if(this.singleSelect){
27303 this.doSingleSelection(item, index, e);
27304 e.preventDefault();
27310 doSingleSelection : function(item, index, e){
27311 if(e.ctrlKey && this.isSelected(index)){
27312 this.deselect(index);
27314 this.select(index, false);
27319 doMultiSelection : function(item, index, e){
27320 if(e.shiftKey && this.last !== false){
27321 var last = this.last;
27322 this.selectRange(last, index, e.ctrlKey);
27325 if((e.ctrlKey||this.simpleSelect) && this.isSelected(index)){
27326 this.deselect(index);
27328 this.select(index, e.ctrlKey || e.shiftKey || this.simpleSelect);
27334 getSelectionCount : function(){
27335 return this.selected.getCount();
27339 getSelectedNodes : function(){
27340 return this.selected.elements;
27344 getSelectedIndexes : function(){
27345 var indexes = [], s = this.selected.elements;
27346 for(var i = 0, len = s.length; i < len; i++){
27347 indexes.push(s[i].viewIndex);
27353 getSelectedRecords : function(){
27354 var r = [], s = this.selected.elements;
27355 for(var i = 0, len = s.length; i < len; i++){
27356 r[r.length] = this.store.getAt(s[i].viewIndex);
27362 getRecords : function(nodes){
27363 var r = [], s = nodes;
27364 for(var i = 0, len = s.length; i < len; i++){
27365 r[r.length] = this.store.getAt(s[i].viewIndex);
27371 getRecord : function(node){
27372 return this.store.getAt(node.viewIndex);
27376 clearSelections : function(suppressEvent, skipUpdate){
27377 if((this.multiSelect || this.singleSelect) && this.selected.getCount() > 0){
27379 this.selected.removeClass(this.selectedClass);
27381 this.selected.clear();
27383 if(!suppressEvent){
27384 this.fireEvent("selectionchange", this, this.selected.elements);
27390 isSelected : function(node){
27391 return this.selected.contains(this.getNode(node));
27395 deselect : function(node){
27396 if(this.isSelected(node)){
27397 node = this.getNode(node);
27398 this.selected.removeElement(node);
27399 if(this.last == node.viewIndex){
27402 Ext.fly(node).removeClass(this.selectedClass);
27403 this.fireEvent("selectionchange", this, this.selected.elements);
27408 select : function(nodeInfo, keepExisting, suppressEvent){
27409 if(Ext.isArray(nodeInfo)){
27411 this.clearSelections(true);
27413 for(var i = 0, len = nodeInfo.length; i < len; i++){
27414 this.select(nodeInfo[i], true, true);
27416 if(!suppressEvent){
27417 this.fireEvent("selectionchange", this, this.selected.elements);
27420 var node = this.getNode(nodeInfo);
27422 this.clearSelections(true);
27424 if(node && !this.isSelected(node)){
27425 if(this.fireEvent("beforeselect", this, node, this.selected.elements) !== false){
27426 Ext.fly(node).addClass(this.selectedClass);
27427 this.selected.add(node);
27428 this.last = node.viewIndex;
27429 if(!suppressEvent){
27430 this.fireEvent("selectionchange", this, this.selected.elements);
27438 selectRange : function(start, end, keepExisting){
27440 this.clearSelections(true);
27442 this.select(this.getNodes(start, end), true);
27446 getNode : function(nodeInfo){
27447 if(Ext.isString(nodeInfo)){
27448 return document.getElementById(nodeInfo);
27449 }else if(Ext.isNumber(nodeInfo)){
27450 return this.all.elements[nodeInfo];
27451 }else if(nodeInfo instanceof Ext.data.Record){
27452 var idx = this.store.indexOf(nodeInfo);
27453 return this.all.elements[idx];
27459 getNodes : function(start, end){
27460 var ns = this.all.elements;
27461 start = start || 0;
27462 end = !Ext.isDefined(end) ? Math.max(ns.length - 1, 0) : end;
27465 for(i = start; i <= end && ns[i]; i++){
27469 for(i = start; i >= end && ns[i]; i--){
27477 indexOf : function(node){
27478 node = this.getNode(node);
27479 if(Ext.isNumber(node.viewIndex)){
27480 return node.viewIndex;
27482 return this.all.indexOf(node);
27486 onBeforeLoad : function(){
27487 if(this.loadingText){
27488 this.clearSelections(false, true);
27489 this.getTemplateTarget().update('<div class="loading-indicator">'+this.loadingText+'</div>');
27494 onDestroy : function(){
27496 this.selected.clear();
27497 Ext.DataView.superclass.onDestroy.call(this);
27498 this.bindStore(null);
27503 Ext.DataView.prototype.setStore = Ext.DataView.prototype.bindStore;
27505 Ext.reg('dataview', Ext.DataView);
27507 Ext.list.ListView = Ext.extend(Ext.DataView, {
27511 itemSelector: 'dl',
27513 selectedClass:'x-list-selected',
27515 overClass:'x-list-over',
27518 scrollOffset : undefined,
27520 columnResize: true,
27527 maxColumnWidth: Ext.isIE ? 99 : 100,
27529 initComponent : function(){
27530 if(this.columnResize){
27531 this.colResizer = new Ext.list.ColumnResizer(this.colResizer);
27532 this.colResizer.init(this);
27534 if(this.columnSort){
27535 this.colSorter = new Ext.list.Sorter(this.columnSort);
27536 this.colSorter.init(this);
27538 if(!this.internalTpl){
27539 this.internalTpl = new Ext.XTemplate(
27540 '<div class="x-list-header"><div class="x-list-header-inner">',
27541 '<tpl for="columns">',
27542 '<div style="width:{[values.width*100]}%;text-align:{align};"><em unselectable="on" id="',this.id, '-xlhd-{#}">',
27546 '<div class="x-clear"></div>',
27548 '<div class="x-list-body"><div class="x-list-body-inner">',
27553 this.tpl = new Ext.XTemplate(
27554 '<tpl for="rows">',
27556 '<tpl for="parent.columns">',
27557 '<dt style="width:{[values.width*100]}%;text-align:{align};">',
27558 '<em unselectable="on"<tpl if="cls"> class="{cls}</tpl>">',
27559 '{[values.tpl.apply(parent)]}',
27562 '<div class="x-clear"></div>',
27568 var cs = this.columns,
27569 allocatedWidth = 0,
27574 for(var i = 0; i < len; i++){
27577 c.xtype = c.xtype ? (/^lv/.test(c.xtype) ? c.xtype : 'lv' + c.xtype) : 'lvcolumn';
27581 allocatedWidth += c.width*100;
27587 cs = this.columns = columns;
27590 if(colsWithWidth < len){
27591 var remaining = len - colsWithWidth;
27592 if(allocatedWidth < this.maxColumnWidth){
27593 var perCol = ((this.maxColumnWidth-allocatedWidth) / remaining)/100;
27594 for(var j = 0; j < len; j++){
27602 Ext.list.ListView.superclass.initComponent.call(this);
27605 onRender : function(){
27609 Ext.list.ListView.superclass.onRender.apply(this, arguments);
27611 this.internalTpl.overwrite(this.el, {columns: this.columns});
27613 this.innerBody = Ext.get(this.el.dom.childNodes[1].firstChild);
27614 this.innerHd = Ext.get(this.el.dom.firstChild.firstChild);
27616 if(this.hideHeaders){
27617 this.el.dom.firstChild.style.display = 'none';
27621 getTemplateTarget : function(){
27622 return this.innerBody;
27626 collectData : function(){
27627 var rs = Ext.list.ListView.superclass.collectData.apply(this, arguments);
27629 columns: this.columns,
27634 verifyInternalSize : function(){
27636 this.onResize(this.lastSize.width, this.lastSize.height);
27641 onResize : function(w, h){
27642 var bd = this.innerBody.dom;
27643 var hd = this.innerHd.dom;
27647 var bdp = bd.parentNode;
27648 if(Ext.isNumber(w)){
27649 var sw = w - Ext.num(this.scrollOffset, Ext.getScrollBarWidth());
27650 if(this.reserveScrollOffset || ((bdp.offsetWidth - bdp.clientWidth) > 10)){
27651 bd.style.width = sw + 'px';
27652 hd.style.width = sw + 'px';
27654 bd.style.width = w + 'px';
27655 hd.style.width = w + 'px';
27656 setTimeout(function(){
27657 if((bdp.offsetWidth - bdp.clientWidth) > 10){
27658 bd.style.width = sw + 'px';
27659 hd.style.width = sw + 'px';
27664 if(Ext.isNumber(h)){
27665 bdp.style.height = (h - hd.parentNode.offsetHeight) + 'px';
27669 updateIndexes : function(){
27670 Ext.list.ListView.superclass.updateIndexes.apply(this, arguments);
27671 this.verifyInternalSize();
27674 findHeaderIndex : function(hd){
27676 var pn = hd.parentNode, cs = pn.parentNode.childNodes;
27677 for(var i = 0, c; c = cs[i]; i++){
27685 setHdWidths : function(){
27686 var els = this.innerHd.dom.getElementsByTagName('div');
27687 for(var i = 0, cs = this.columns, len = cs.length; i < len; i++){
27688 els[i].style.width = (cs[i].width*100) + '%';
27693 Ext.reg('listview', Ext.list.ListView);
27696 Ext.ListView = Ext.list.ListView;
27697 Ext.list.Column = Ext.extend(Object, {
27716 constructor : function(c){
27718 c.tpl = new Ext.XTemplate('{' + c.dataIndex + '}');
27720 else if(Ext.isString(c.tpl)){
27721 c.tpl = new Ext.XTemplate(c.tpl);
27724 Ext.apply(this, c);
27728 Ext.reg('lvcolumn', Ext.list.Column);
27731 Ext.list.NumberColumn = Ext.extend(Ext.list.Column, {
27733 format: '0,000.00',
27735 constructor : function(c) {
27736 c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':number("' + (c.format || this.format) + '")}');
27737 Ext.list.NumberColumn.superclass.constructor.call(this, c);
27741 Ext.reg('lvnumbercolumn', Ext.list.NumberColumn);
27744 Ext.list.DateColumn = Ext.extend(Ext.list.Column, {
27746 constructor : function(c) {
27747 c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':date("' + (c.format || this.format) + '")}');
27748 Ext.list.DateColumn.superclass.constructor.call(this, c);
27751 Ext.reg('lvdatecolumn', Ext.list.DateColumn);
27754 Ext.list.BooleanColumn = Ext.extend(Ext.list.Column, {
27758 falseText: 'false',
27760 undefinedText: ' ',
27762 constructor : function(c) {
27763 c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':this.format}');
27765 var t = this.trueText, f = this.falseText, u = this.undefinedText;
27766 c.tpl.format = function(v){
27767 if(v === undefined){
27770 if(!v || v === 'false'){
27776 Ext.list.DateColumn.superclass.constructor.call(this, c);
27780 Ext.reg('lvbooleancolumn', Ext.list.BooleanColumn);
27781 Ext.list.ColumnResizer = Ext.extend(Ext.util.Observable, {
27785 constructor: function(config){
27786 Ext.apply(this, config);
27787 Ext.list.ColumnResizer.superclass.constructor.call(this);
27789 init : function(listView){
27790 this.view = listView;
27791 listView.on('render', this.initEvents, this);
27794 initEvents : function(view){
27795 view.mon(view.innerHd, 'mousemove', this.handleHdMove, this);
27796 this.tracker = new Ext.dd.DragTracker({
27797 onBeforeStart: this.onBeforeStart.createDelegate(this),
27798 onStart: this.onStart.createDelegate(this),
27799 onDrag: this.onDrag.createDelegate(this),
27800 onEnd: this.onEnd.createDelegate(this),
27804 this.tracker.initEl(view.innerHd);
27805 view.on('beforedestroy', this.tracker.destroy, this.tracker);
27808 handleHdMove : function(e, t){
27811 hd = e.getTarget('em', 3, true);
27813 var r = hd.getRegion(),
27815 pn = hd.dom.parentNode;
27817 if(x - r.left <= hw && pn != pn.parentNode.firstChild){
27818 this.activeHd = Ext.get(pn.previousSibling.firstChild);
27819 ss.cursor = Ext.isWebKit ? 'e-resize' : 'col-resize';
27820 } else if(r.right - x <= hw && pn != pn.parentNode.lastChild.previousSibling){
27821 this.activeHd = hd;
27822 ss.cursor = Ext.isWebKit ? 'w-resize' : 'col-resize';
27824 delete this.activeHd;
27830 onBeforeStart : function(e){
27831 this.dragHd = this.activeHd;
27832 return !!this.dragHd;
27835 onStart: function(e){
27836 this.view.disableHeaders = true;
27837 this.proxy = this.view.el.createChild({cls:'x-list-resizer'});
27838 this.proxy.setHeight(this.view.el.getHeight());
27840 var x = this.tracker.getXY()[0],
27841 w = this.view.innerHd.getWidth();
27843 this.hdX = this.dragHd.getX();
27844 this.hdIndex = this.view.findHeaderIndex(this.dragHd);
27846 this.proxy.setX(this.hdX);
27847 this.proxy.setWidth(x-this.hdX);
27849 this.minWidth = w*this.minPct;
27850 this.maxWidth = w - (this.minWidth*(this.view.columns.length-1-this.hdIndex));
27853 onDrag: function(e){
27854 var cursorX = this.tracker.getXY()[0];
27855 this.proxy.setWidth((cursorX-this.hdX).constrain(this.minWidth, this.maxWidth));
27858 onEnd: function(e){
27860 var nw = this.proxy.getWidth();
27861 this.proxy.remove();
27863 var index = this.hdIndex,
27867 w = this.view.innerHd.getWidth(),
27868 minPct = this.minPct * 100,
27869 pct = Math.ceil((nw * vw.maxColumnWidth) / w),
27870 diff = (cs[index].width * 100) - pct,
27871 eachItem = Math.floor(diff / (len-1-index)),
27872 mod = diff - (eachItem * (len-1-index));
27874 for(var i = index+1; i < len; i++){
27875 var cw = (cs[i].width * 100) + eachItem,
27876 ncw = Math.max(minPct, cw);
27880 cs[i].width = ncw / 100;
27882 cs[index].width = pct / 100;
27883 cs[index+1].width += (mod / 100);
27884 delete this.dragHd;
27887 setTimeout(function(){
27888 vw.disableHeaders = false;
27894 Ext.ListView.ColumnResizer = Ext.list.ColumnResizer;
27895 Ext.list.Sorter = Ext.extend(Ext.util.Observable, {
27897 sortClasses : ["sort-asc", "sort-desc"],
27899 constructor: function(config){
27900 Ext.apply(this, config);
27901 Ext.list.Sorter.superclass.constructor.call(this);
27904 init : function(listView){
27905 this.view = listView;
27906 listView.on('render', this.initEvents, this);
27909 initEvents : function(view){
27910 view.mon(view.innerHd, 'click', this.onHdClick, this);
27911 view.innerHd.setStyle('cursor', 'pointer');
27912 view.mon(view.store, 'datachanged', this.updateSortState, this);
27913 this.updateSortState.defer(10, this, [view.store]);
27916 updateSortState : function(store){
27917 var state = store.getSortState();
27921 this.sortState = state;
27922 var cs = this.view.columns, sortColumn = -1;
27923 for(var i = 0, len = cs.length; i < len; i++){
27924 if(cs[i].dataIndex == state.field){
27929 if(sortColumn != -1){
27930 var sortDir = state.direction;
27931 this.updateSortIcon(sortColumn, sortDir);
27935 updateSortIcon : function(col, dir){
27936 var sc = this.sortClasses;
27937 var hds = this.view.innerHd.select('em').removeClass(sc);
27938 hds.item(col).addClass(sc[dir == "DESC" ? 1 : 0]);
27941 onHdClick : function(e){
27942 var hd = e.getTarget('em', 3);
27943 if(hd && !this.view.disableHeaders){
27944 var index = this.view.findHeaderIndex(hd);
27945 this.view.store.sort(this.view.columns[index].dataIndex);
27951 Ext.ListView.Sorter = Ext.list.Sorter;
27952 Ext.TabPanel = Ext.extend(Ext.Panel, {
27956 deferredRender : true,
27962 resizeTabs : false,
27964 enableTabScroll : false,
27966 scrollIncrement : 0,
27968 scrollRepeatInterval : 400,
27970 scrollDuration : 0.35,
27974 tabPosition : 'top',
27976 baseCls : 'x-tab-panel',
27980 autoTabSelector : 'div.x-tab',
27982 activeTab : undefined,
27988 wheelIncrement : 20,
27991 idDelimiter : '__',
27994 itemCls : 'x-tab-item',
27998 headerAsText : false,
28003 initComponent : function(){
28004 this.frame = false;
28005 Ext.TabPanel.superclass.initComponent.call(this);
28015 this.setLayout(new Ext.layout.CardLayout(Ext.apply({
28016 layoutOnCardChange: this.layoutOnTabChange,
28017 deferredRender: this.deferredRender
28018 }, this.layoutConfig)));
28020 if(this.tabPosition == 'top'){
28021 this.elements += ',header';
28022 this.stripTarget = 'header';
28024 this.elements += ',footer';
28025 this.stripTarget = 'footer';
28028 this.stack = Ext.TabPanel.AccessStack();
28034 onRender : function(ct, position){
28035 Ext.TabPanel.superclass.onRender.call(this, ct, position);
28038 var pos = this.tabPosition == 'top' ? 'header' : 'footer';
28039 this[pos].addClass('x-tab-panel-'+pos+'-plain');
28042 var st = this[this.stripTarget];
28044 this.stripWrap = st.createChild({cls:'x-tab-strip-wrap', cn:{
28045 tag:'ul', cls:'x-tab-strip x-tab-strip-'+this.tabPosition}});
28047 var beforeEl = (this.tabPosition=='bottom' ? this.stripWrap : null);
28048 st.createChild({cls:'x-tab-strip-spacer'}, beforeEl);
28049 this.strip = new Ext.Element(this.stripWrap.dom.firstChild);
28052 this.edge = this.strip.createChild({tag:'li', cls:'x-tab-edge', cn: [{tag: 'span', cls: 'x-tab-strip-text', cn: ' '}]});
28053 this.strip.createChild({cls:'x-clear'});
28055 this.body.addClass('x-tab-panel-body-'+this.tabPosition);
28059 var tt = new Ext.Template(
28060 '<li class="{cls}" id="{id}"><a class="x-tab-strip-close"></a>',
28061 '<a class="x-tab-right" href="#"><em class="x-tab-left">',
28062 '<span class="x-tab-strip-inner"><span class="x-tab-strip-text {iconCls}">{text}</span></span>',
28065 tt.disableFormats = true;
28067 Ext.TabPanel.prototype.itemTpl = tt;
28070 this.items.each(this.initTab, this);
28074 afterRender : function(){
28075 Ext.TabPanel.superclass.afterRender.call(this);
28077 this.readTabs(false);
28079 if(this.activeTab !== undefined){
28080 var item = Ext.isObject(this.activeTab) ? this.activeTab : this.items.get(this.activeTab);
28081 delete this.activeTab;
28082 this.setActiveTab(item);
28087 initEvents : function(){
28088 Ext.TabPanel.superclass.initEvents.call(this);
28089 this.mon(this.strip, {
28091 mousedown: this.onStripMouseDown,
28092 contextmenu: this.onStripContextMenu
28094 if(this.enableTabScroll){
28095 this.mon(this.strip, 'mousewheel', this.onWheel, this);
28100 findTargets : function(e){
28102 itemEl = e.getTarget('li:not(.x-tab-edge)', this.strip);
28105 item = this.getComponent(itemEl.id.split(this.idDelimiter)[1]);
28115 close : e.getTarget('.x-tab-strip-close', this.strip),
28122 onStripMouseDown : function(e){
28123 if(e.button !== 0){
28126 e.preventDefault();
28127 var t = this.findTargets(e);
28129 if (t.item.fireEvent('beforeclose', t.item) !== false) {
28130 t.item.fireEvent('close', t.item);
28131 this.remove(t.item);
28135 if(t.item && t.item != this.activeTab){
28136 this.setActiveTab(t.item);
28141 onStripContextMenu : function(e){
28142 e.preventDefault();
28143 var t = this.findTargets(e);
28145 this.fireEvent('contextmenu', this, t.item, e);
28150 readTabs : function(removeExisting){
28151 if(removeExisting === true){
28152 this.items.each(function(item){
28156 var tabs = this.el.query(this.autoTabSelector);
28157 for(var i = 0, len = tabs.length; i < len; i++){
28159 title = tab.getAttribute('title');
28160 tab.removeAttribute('title');
28169 initTab : function(item, index){
28170 var before = this.strip.dom.childNodes[index],
28171 p = this.getTemplateArgs(item),
28173 this.itemTpl.insertBefore(before, p) :
28174 this.itemTpl.append(this.strip, p),
28175 cls = 'x-tab-strip-over',
28176 tabEl = Ext.get(el);
28178 tabEl.hover(function(){
28179 if(!item.disabled){
28180 tabEl.addClass(cls);
28183 tabEl.removeClass(cls);
28187 tabEl.child('span.x-tab-strip-text', true).qtip = item.tabTip;
28192 tabEl.select('a').on('click', function(e){
28194 this.onStripMouseDown(e);
28196 }, this, {preventDefault: true});
28200 disable: this.onItemDisabled,
28201 enable: this.onItemEnabled,
28202 titlechange: this.onItemTitleChanged,
28203 iconchange: this.onItemIconChanged,
28204 beforeshow: this.onBeforeShowItem
28211 getTemplateArgs : function(item) {
28212 var cls = item.closable ? 'x-tab-strip-closable' : '';
28214 cls += ' x-item-disabled';
28217 cls += ' x-tab-with-icon';
28220 cls += ' ' + item.tabCls;
28224 id: this.id + this.idDelimiter + item.getItemId(),
28227 iconCls: item.iconCls || ''
28232 onAdd : function(c){
28233 Ext.TabPanel.superclass.onAdd.call(this, c);
28235 var items = this.items;
28236 this.initTab(c, items.indexOf(c));
28237 this.delegateUpdates();
28242 onBeforeAdd : function(item){
28243 var existing = item.events ? (this.items.containsKey(item.getItemId()) ? item : null) : this.items.get(item);
28245 this.setActiveTab(item);
28248 Ext.TabPanel.superclass.onBeforeAdd.apply(this, arguments);
28249 var es = item.elements;
28250 item.elements = es ? es.replace(',header', '') : es;
28251 item.border = (item.border === true);
28255 onRemove : function(c){
28256 var te = Ext.get(c.tabEl);
28259 te.select('a').removeAllListeners();
28262 Ext.TabPanel.superclass.onRemove.call(this, c);
28263 this.stack.remove(c);
28265 c.un('disable', this.onItemDisabled, this);
28266 c.un('enable', this.onItemEnabled, this);
28267 c.un('titlechange', this.onItemTitleChanged, this);
28268 c.un('iconchange', this.onItemIconChanged, this);
28269 c.un('beforeshow', this.onBeforeShowItem, this);
28270 if(c == this.activeTab){
28271 var next = this.stack.next();
28273 this.setActiveTab(next);
28274 }else if(this.items.getCount() > 0){
28275 this.setActiveTab(0);
28277 this.setActiveTab(null);
28280 if(!this.destroying){
28281 this.delegateUpdates();
28286 onBeforeShowItem : function(item){
28287 if(item != this.activeTab){
28288 this.setActiveTab(item);
28294 onItemDisabled : function(item){
28295 var el = this.getTabEl(item);
28297 Ext.fly(el).addClass('x-item-disabled');
28299 this.stack.remove(item);
28303 onItemEnabled : function(item){
28304 var el = this.getTabEl(item);
28306 Ext.fly(el).removeClass('x-item-disabled');
28311 onItemTitleChanged : function(item){
28312 var el = this.getTabEl(item);
28314 Ext.fly(el).child('span.x-tab-strip-text', true).innerHTML = item.title;
28319 onItemIconChanged : function(item, iconCls, oldCls){
28320 var el = this.getTabEl(item);
28323 el.child('span.x-tab-strip-text').replaceClass(oldCls, iconCls);
28324 el[Ext.isEmpty(iconCls) ? 'removeClass' : 'addClass']('x-tab-with-icon');
28329 getTabEl : function(item){
28330 var c = this.getComponent(item);
28331 return c ? c.tabEl : null;
28335 onResize : function(){
28336 Ext.TabPanel.superclass.onResize.apply(this, arguments);
28337 this.delegateUpdates();
28341 beginUpdate : function(){
28342 this.suspendUpdates = true;
28346 endUpdate : function(){
28347 this.suspendUpdates = false;
28348 this.delegateUpdates();
28352 hideTabStripItem : function(item){
28353 item = this.getComponent(item);
28354 var el = this.getTabEl(item);
28356 el.style.display = 'none';
28357 this.delegateUpdates();
28359 this.stack.remove(item);
28363 unhideTabStripItem : function(item){
28364 item = this.getComponent(item);
28365 var el = this.getTabEl(item);
28367 el.style.display = '';
28368 this.delegateUpdates();
28373 delegateUpdates : function(){
28374 if(this.suspendUpdates){
28377 if(this.resizeTabs && this.rendered){
28378 this.autoSizeTabs();
28380 if(this.enableTabScroll && this.rendered){
28381 this.autoScrollTabs();
28386 autoSizeTabs : function(){
28387 var count = this.items.length,
28388 ce = this.tabPosition != 'bottom' ? 'header' : 'footer',
28389 ow = this[ce].dom.offsetWidth,
28390 aw = this[ce].dom.clientWidth;
28392 if(!this.resizeTabs || count < 1 || !aw){
28396 var each = Math.max(Math.min(Math.floor((aw-4) / count) - this.tabMargin, this.tabWidth), this.minTabWidth);
28397 this.lastTabWidth = each;
28398 var lis = this.strip.query('li:not(.x-tab-edge)');
28399 for(var i = 0, len = lis.length; i < len; i++) {
28401 inner = Ext.fly(li).child('.x-tab-strip-inner', true),
28402 tw = li.offsetWidth,
28403 iw = inner.offsetWidth;
28404 inner.style.width = (each - (tw-iw)) + 'px';
28409 adjustBodyWidth : function(w){
28411 this.header.setWidth(w);
28414 this.footer.setWidth(w);
28420 setActiveTab : function(item){
28421 item = this.getComponent(item);
28422 if(this.fireEvent('beforetabchange', this, item, this.activeTab) === false){
28425 if(!this.rendered){
28426 this.activeTab = item;
28429 if(this.activeTab != item){
28430 if(this.activeTab){
28431 var oldEl = this.getTabEl(this.activeTab);
28433 Ext.fly(oldEl).removeClass('x-tab-strip-active');
28436 this.activeTab = item;
28438 var el = this.getTabEl(item);
28439 Ext.fly(el).addClass('x-tab-strip-active');
28440 this.stack.add(item);
28442 this.layout.setActiveItem(item);
28443 if(this.scrolling){
28444 this.scrollToTab(item, this.animScroll);
28447 this.fireEvent('tabchange', this, item);
28452 getActiveTab : function(){
28453 return this.activeTab || null;
28457 getItem : function(item){
28458 return this.getComponent(item);
28462 autoScrollTabs : function(){
28463 this.pos = this.tabPosition=='bottom' ? this.footer : this.header;
28464 var count = this.items.length,
28465 ow = this.pos.dom.offsetWidth,
28466 tw = this.pos.dom.clientWidth,
28467 wrap = this.stripWrap,
28469 cw = wd.offsetWidth,
28470 pos = this.getScrollPos(),
28471 l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos;
28473 if(!this.enableTabScroll || cw < 20){
28476 if(count == 0 || l <= tw){
28480 if(this.scrolling){
28481 this.scrolling = false;
28482 this.pos.removeClass('x-tab-scrolling');
28483 this.scrollLeft.hide();
28484 this.scrollRight.hide();
28486 if(Ext.isAir || Ext.isWebKit){
28487 wd.style.marginLeft = '';
28488 wd.style.marginRight = '';
28492 if(!this.scrolling){
28493 this.pos.addClass('x-tab-scrolling');
28495 if(Ext.isAir || Ext.isWebKit){
28496 wd.style.marginLeft = '18px';
28497 wd.style.marginRight = '18px';
28500 tw -= wrap.getMargins('lr');
28501 wrap.setWidth(tw > 20 ? tw : 20);
28502 if(!this.scrolling){
28503 if(!this.scrollLeft){
28504 this.createScrollers();
28506 this.scrollLeft.show();
28507 this.scrollRight.show();
28510 this.scrolling = true;
28512 wd.scrollLeft = l-tw;
28514 this.scrollToTab(this.activeTab, false);
28516 this.updateScrollButtons();
28521 createScrollers : function(){
28522 this.pos.addClass('x-tab-scrolling-' + this.tabPosition);
28523 var h = this.stripWrap.dom.offsetHeight;
28526 var sl = this.pos.insertFirst({
28527 cls:'x-tab-scroller-left'
28530 sl.addClassOnOver('x-tab-scroller-left-over');
28531 this.leftRepeater = new Ext.util.ClickRepeater(sl, {
28532 interval : this.scrollRepeatInterval,
28533 handler: this.onScrollLeft,
28536 this.scrollLeft = sl;
28539 var sr = this.pos.insertFirst({
28540 cls:'x-tab-scroller-right'
28543 sr.addClassOnOver('x-tab-scroller-right-over');
28544 this.rightRepeater = new Ext.util.ClickRepeater(sr, {
28545 interval : this.scrollRepeatInterval,
28546 handler: this.onScrollRight,
28549 this.scrollRight = sr;
28553 getScrollWidth : function(){
28554 return this.edge.getOffsetsTo(this.stripWrap)[0] + this.getScrollPos();
28558 getScrollPos : function(){
28559 return parseInt(this.stripWrap.dom.scrollLeft, 10) || 0;
28563 getScrollArea : function(){
28564 return parseInt(this.stripWrap.dom.clientWidth, 10) || 0;
28568 getScrollAnim : function(){
28569 return {duration:this.scrollDuration, callback: this.updateScrollButtons, scope: this};
28573 getScrollIncrement : function(){
28574 return this.scrollIncrement || (this.resizeTabs ? this.lastTabWidth+2 : 100);
28579 scrollToTab : function(item, animate){
28583 var el = this.getTabEl(item),
28584 pos = this.getScrollPos(),
28585 area = this.getScrollArea(),
28586 left = Ext.fly(el).getOffsetsTo(this.stripWrap)[0] + pos,
28587 right = left + el.offsetWidth;
28589 this.scrollTo(left, animate);
28590 }else if(right > (pos + area)){
28591 this.scrollTo(right - area, animate);
28596 scrollTo : function(pos, animate){
28597 this.stripWrap.scrollTo('left', pos, animate ? this.getScrollAnim() : false);
28599 this.updateScrollButtons();
28603 onWheel : function(e){
28604 var d = e.getWheelDelta()*this.wheelIncrement*-1;
28607 var pos = this.getScrollPos(),
28609 sw = this.getScrollWidth()-this.getScrollArea();
28611 var s = Math.max(0, Math.min(sw, newpos));
28613 this.scrollTo(s, false);
28618 onScrollRight : function(){
28619 var sw = this.getScrollWidth()-this.getScrollArea(),
28620 pos = this.getScrollPos(),
28621 s = Math.min(sw, pos + this.getScrollIncrement());
28623 this.scrollTo(s, this.animScroll);
28628 onScrollLeft : function(){
28629 var pos = this.getScrollPos(),
28630 s = Math.max(0, pos - this.getScrollIncrement());
28632 this.scrollTo(s, this.animScroll);
28637 updateScrollButtons : function(){
28638 var pos = this.getScrollPos();
28639 this.scrollLeft[pos === 0 ? 'addClass' : 'removeClass']('x-tab-scroller-left-disabled');
28640 this.scrollRight[pos >= (this.getScrollWidth()-this.getScrollArea()) ? 'addClass' : 'removeClass']('x-tab-scroller-right-disabled');
28644 beforeDestroy : function() {
28645 Ext.destroy(this.leftRepeater, this.rightRepeater);
28646 this.deleteMembers('strip', 'edge', 'scrollLeft', 'scrollRight', 'stripWrap');
28647 this.activeTab = null;
28648 Ext.TabPanel.superclass.beforeDestroy.apply(this);
28664 Ext.reg('tabpanel', Ext.TabPanel);
28667 Ext.TabPanel.prototype.activate = Ext.TabPanel.prototype.setActiveTab;
28670 Ext.TabPanel.AccessStack = function(){
28673 add : function(item){
28675 if(items.length > 10){
28680 remove : function(item){
28682 for(var i = 0, len = items.length; i < len; i++) {
28683 if(items[i] != item){
28691 return items.pop();
28696 Ext.Button = Ext.extend(Ext.BoxComponent, {
28709 enableToggle : false,
28713 menuAlign : 'tl-bl?',
28721 menuClassTarget : 'tr:nth(2)',
28724 clickEvent : 'click',
28727 handleMouseEvents : true,
28730 tooltipType : 'qtip',
28733 buttonSelector : 'button:first-child',
28741 iconAlign : 'left',
28744 arrowAlign : 'right',
28751 initComponent : function(){
28752 Ext.Button.superclass.initComponent.call(this);
28773 this.menu = Ext.menu.MenuMgr.get(this.menu);
28775 if(Ext.isString(this.toggleGroup)){
28776 this.enableToggle = true;
28781 getTemplateArgs : function(){
28782 return [this.type, 'x-btn-' + this.scale + ' x-btn-icon-' + this.scale + '-' + this.iconAlign, this.getMenuClass(), this.cls, this.id];
28786 setButtonClass : function(){
28787 if(this.useSetClass){
28788 if(!Ext.isEmpty(this.oldCls)){
28789 this.el.removeClass([this.oldCls, 'x-btn-pressed']);
28791 this.oldCls = (this.iconCls || this.icon) ? (this.text ? 'x-btn-text-icon' : 'x-btn-icon') : 'x-btn-noicon';
28792 this.el.addClass([this.oldCls, this.pressed ? 'x-btn-pressed' : null]);
28797 getMenuClass : function(){
28798 return this.menu ? (this.arrowAlign != 'bottom' ? 'x-btn-arrow' : 'x-btn-arrow-bottom') : '';
28802 onRender : function(ct, position){
28803 if(!this.template){
28804 if(!Ext.Button.buttonTemplate){
28806 Ext.Button.buttonTemplate = new Ext.Template(
28807 '<table id="{4}" cellspacing="0" class="x-btn {3}"><tbody class="{1}">',
28808 '<tr><td class="x-btn-tl"><i> </i></td><td class="x-btn-tc"></td><td class="x-btn-tr"><i> </i></td></tr>',
28809 '<tr><td class="x-btn-ml"><i> </i></td><td class="x-btn-mc"><em class="{2}" unselectable="on"><button type="{0}"></button></em></td><td class="x-btn-mr"><i> </i></td></tr>',
28810 '<tr><td class="x-btn-bl"><i> </i></td><td class="x-btn-bc"></td><td class="x-btn-br"><i> </i></td></tr>',
28811 '</tbody></table>');
28812 Ext.Button.buttonTemplate.compile();
28814 this.template = Ext.Button.buttonTemplate;
28817 var btn, targs = this.getTemplateArgs();
28820 btn = this.template.insertBefore(position, targs, true);
28822 btn = this.template.append(ct, targs, true);
28825 this.btnEl = btn.child(this.buttonSelector);
28826 this.mon(this.btnEl, {
28828 focus: this.onFocus,
28832 this.initButtonEl(btn, this.btnEl);
28834 Ext.ButtonToggleMgr.register(this);
28838 initButtonEl : function(btn, btnEl){
28840 this.setIcon(this.icon);
28841 this.setText(this.text);
28842 this.setIconClass(this.iconCls);
28843 if(Ext.isDefined(this.tabIndex)){
28844 btnEl.dom.tabIndex = this.tabIndex;
28847 this.setTooltip(this.tooltip, true);
28850 if(this.handleMouseEvents){
28853 mouseover: this.onMouseOver,
28854 mousedown: this.onMouseDown
28862 this.mon(this.menu, {
28864 show: this.onMenuShow,
28865 hide: this.onMenuHide
28870 var repeater = new Ext.util.ClickRepeater(btn, Ext.isObject(this.repeat) ? this.repeat : {});
28871 this.mon(repeater, 'click', this.onRepeatClick, this);
28873 this.mon(btn, this.clickEvent, this.onClick, this);
28878 afterRender : function(){
28879 Ext.Button.superclass.afterRender.call(this);
28880 this.useSetClass = true;
28881 this.setButtonClass();
28882 this.doc = Ext.getDoc();
28883 this.doAutoWidth();
28887 setIconClass : function(cls){
28888 this.iconCls = cls;
28890 this.btnEl.dom.className = '';
28891 this.btnEl.addClass(['x-btn-text', cls || '']);
28892 this.setButtonClass();
28898 setTooltip : function(tooltip, initial){
28903 if(Ext.isObject(tooltip)){
28904 Ext.QuickTips.register(Ext.apply({
28905 target: this.btnEl.id
28907 this.tooltip = tooltip;
28909 this.btnEl.dom[this.tooltipType] = tooltip;
28912 this.tooltip = tooltip;
28918 clearTip : function(){
28919 if(Ext.isObject(this.tooltip)){
28920 Ext.QuickTips.unregister(this.btnEl);
28925 beforeDestroy : function(){
28929 if(this.menu && this.destroyMenu !== false) {
28930 Ext.destroy(this.btnEl, this.menu);
28932 Ext.destroy(this.repeater);
28936 onDestroy : function(){
28938 this.doc.un('mouseover', this.monitorMouseOver, this);
28939 this.doc.un('mouseup', this.onMouseUp, this);
28942 Ext.ButtonToggleMgr.unregister(this);
28944 Ext.Button.superclass.onDestroy.call(this);
28948 doAutoWidth : function(){
28949 if(this.autoWidth !== false && this.el && this.text && this.width === undefined){
28950 this.el.setWidth('auto');
28951 if(Ext.isIE7 && Ext.isStrict){
28952 var ib = this.btnEl;
28953 if(ib && ib.getWidth() > 20){
28955 ib.setWidth(Ext.util.TextMetrics.measure(ib, this.text).width+ib.getFrameWidth('lr'));
28959 if(this.el.getWidth() < this.minWidth){
28960 this.el.setWidth(this.minWidth);
28967 setHandler : function(handler, scope){
28968 this.handler = handler;
28969 this.scope = scope;
28974 setText : function(text){
28977 this.btnEl.update(text || ' ');
28978 this.setButtonClass();
28980 this.doAutoWidth();
28985 setIcon : function(icon){
28988 this.btnEl.setStyle('background-image', icon ? 'url(' + icon + ')' : '');
28989 this.setButtonClass();
28995 getText : function(){
29000 toggle : function(state, suppressEvent){
29001 state = state === undefined ? !this.pressed : !!state;
29002 if(state != this.pressed){
29004 this.el[state ? 'addClass' : 'removeClass']('x-btn-pressed');
29006 this.pressed = state;
29007 if(!suppressEvent){
29008 this.fireEvent('toggle', this, state);
29009 if(this.toggleHandler){
29010 this.toggleHandler.call(this.scope || this, this, state);
29018 onDisable : function(){
29019 this.onDisableChange(true);
29023 onEnable : function(){
29024 this.onDisableChange(false);
29027 onDisableChange : function(disabled){
29029 if(!Ext.isIE6 || !this.text){
29030 this.el[disabled ? 'addClass' : 'removeClass'](this.disabledClass);
29032 this.el.dom.disabled = disabled;
29034 this.disabled = disabled;
29038 showMenu : function(){
29039 if(this.rendered && this.menu){
29041 Ext.QuickTips.getQuickTip().cancelShow(this.btnEl);
29043 if(this.menu.isVisible()){
29046 this.menu.ownerCt = this;
29047 this.menu.show(this.el, this.menuAlign);
29053 hideMenu : function(){
29054 if(this.hasVisibleMenu()){
29061 hasVisibleMenu : function(){
29062 return this.menu && this.menu.ownerCt == this && this.menu.isVisible();
29066 onRepeatClick : function(repeat, e){
29071 onClick : function(e){
29073 e.preventDefault();
29075 if(e.button !== 0){
29078 if(!this.disabled){
29079 if(this.enableToggle && (this.allowDepress !== false || !this.pressed)){
29082 if(this.menu && !this.hasVisibleMenu() && !this.ignoreNextClick){
29085 this.fireEvent('click', this, e);
29088 this.handler.call(this.scope || this, this, e);
29094 isMenuTriggerOver : function(e, internal){
29095 return this.menu && !internal;
29099 isMenuTriggerOut : function(e, internal){
29100 return this.menu && !internal;
29104 onMouseOver : function(e){
29105 if(!this.disabled){
29106 var internal = e.within(this.el, true);
29108 this.el.addClass('x-btn-over');
29109 if(!this.monitoringMouseOver){
29110 this.doc.on('mouseover', this.monitorMouseOver, this);
29111 this.monitoringMouseOver = true;
29113 this.fireEvent('mouseover', this, e);
29115 if(this.isMenuTriggerOver(e, internal)){
29116 this.fireEvent('menutriggerover', this, this.menu, e);
29122 monitorMouseOver : function(e){
29123 if(e.target != this.el.dom && !e.within(this.el)){
29124 if(this.monitoringMouseOver){
29125 this.doc.un('mouseover', this.monitorMouseOver, this);
29126 this.monitoringMouseOver = false;
29128 this.onMouseOut(e);
29133 onMouseOut : function(e){
29134 var internal = e.within(this.el) && e.target != this.el.dom;
29135 this.el.removeClass('x-btn-over');
29136 this.fireEvent('mouseout', this, e);
29137 if(this.isMenuTriggerOut(e, internal)){
29138 this.fireEvent('menutriggerout', this, this.menu, e);
29142 focus : function() {
29143 this.btnEl.focus();
29146 blur : function() {
29151 onFocus : function(e){
29152 if(!this.disabled){
29153 this.el.addClass('x-btn-focus');
29157 onBlur : function(e){
29158 this.el.removeClass('x-btn-focus');
29162 getClickEl : function(e, isUp){
29167 onMouseDown : function(e){
29168 if(!this.disabled && e.button === 0){
29169 this.getClickEl(e).addClass('x-btn-click');
29170 this.doc.on('mouseup', this.onMouseUp, this);
29174 onMouseUp : function(e){
29175 if(e.button === 0){
29176 this.getClickEl(e, true).removeClass('x-btn-click');
29177 this.doc.un('mouseup', this.onMouseUp, this);
29181 onMenuShow : function(e){
29182 if(this.menu.ownerCt == this){
29183 this.menu.ownerCt = this;
29184 this.ignoreNextClick = 0;
29185 this.el.addClass('x-btn-menu-active');
29186 this.fireEvent('menushow', this, this.menu);
29190 onMenuHide : function(e){
29191 if(this.menu.ownerCt == this){
29192 this.el.removeClass('x-btn-menu-active');
29193 this.ignoreNextClick = this.restoreClick.defer(250, this);
29194 this.fireEvent('menuhide', this, this.menu);
29195 delete this.menu.ownerCt;
29200 restoreClick : function(){
29201 this.ignoreNextClick = 0;
29211 Ext.reg('button', Ext.Button);
29214 Ext.ButtonToggleMgr = function(){
29217 function toggleGroup(btn, state){
29219 var g = groups[btn.toggleGroup];
29220 for(var i = 0, l = g.length; i < l; i++){
29222 g[i].toggle(false);
29229 register : function(btn){
29230 if(!btn.toggleGroup){
29233 var g = groups[btn.toggleGroup];
29235 g = groups[btn.toggleGroup] = [];
29238 btn.on('toggle', toggleGroup);
29241 unregister : function(btn){
29242 if(!btn.toggleGroup){
29245 var g = groups[btn.toggleGroup];
29248 btn.un('toggle', toggleGroup);
29253 getPressed : function(group){
29254 var g = groups[group];
29256 for(var i = 0, len = g.length; i < len; i++){
29257 if(g[i].pressed === true){
29267 Ext.SplitButton = Ext.extend(Ext.Button, {
29269 arrowSelector : 'em',
29273 initComponent : function(){
29274 Ext.SplitButton.superclass.initComponent.call(this);
29276 this.addEvents("arrowclick");
29280 onRender : function(){
29281 Ext.SplitButton.superclass.onRender.apply(this, arguments);
29282 if(this.arrowTooltip){
29283 this.el.child(this.arrowSelector).dom[this.tooltipType] = this.arrowTooltip;
29288 setArrowHandler : function(handler, scope){
29289 this.arrowHandler = handler;
29290 this.scope = scope;
29293 getMenuClass : function(){
29294 return 'x-btn-split' + (this.arrowAlign == 'bottom' ? '-bottom' : '');
29297 isClickOnArrow : function(e){
29298 if (this.arrowAlign != 'bottom') {
29299 var visBtn = this.el.child('em.x-btn-split');
29300 var right = visBtn.getRegion().right - visBtn.getPadding('r');
29301 return e.getPageX() > right;
29303 return e.getPageY() > this.btnEl.getRegion().bottom;
29308 onClick : function(e, t){
29309 e.preventDefault();
29310 if(!this.disabled){
29311 if(this.isClickOnArrow(e)){
29312 if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
29315 this.fireEvent("arrowclick", this, e);
29316 if(this.arrowHandler){
29317 this.arrowHandler.call(this.scope || this, this, e);
29320 if(this.enableToggle){
29323 this.fireEvent("click", this, e);
29325 this.handler.call(this.scope || this, this, e);
29332 isMenuTriggerOver : function(e){
29333 return this.menu && e.target.tagName == this.arrowSelector;
29337 isMenuTriggerOut : function(e, internal){
29338 return this.menu && e.target.tagName != this.arrowSelector;
29342 Ext.reg('splitbutton', Ext.SplitButton);
29343 Ext.CycleButton = Ext.extend(Ext.SplitButton, {
29352 getItemText : function(item){
29353 if(item && this.showText === true){
29355 if(this.prependText){
29356 text += this.prependText;
29365 setActiveItem : function(item, suppressEvent){
29366 if(!Ext.isObject(item)){
29367 item = this.menu.getComponent(item);
29370 if(!this.rendered){
29371 this.text = this.getItemText(item);
29372 this.iconCls = item.iconCls;
29374 var t = this.getItemText(item);
29378 this.setIconClass(item.iconCls);
29380 this.activeItem = item;
29382 item.setChecked(true, false);
29384 if(this.forceIcon){
29385 this.setIconClass(this.forceIcon);
29387 if(!suppressEvent){
29388 this.fireEvent('change', this, item);
29394 getActiveItem : function(){
29395 return this.activeItem;
29399 initComponent : function(){
29405 if(this.changeHandler){
29406 this.on('change', this.changeHandler, this.scope||this);
29407 delete this.changeHandler;
29410 this.itemCount = this.items.length;
29412 this.menu = {cls:'x-cycle-menu', items:[]};
29414 Ext.each(this.items, function(item, i){
29416 group: item.group || this.id,
29418 checkHandler: this.checkHandler,
29420 checked: item.checked || false
29422 this.menu.items.push(item);
29427 Ext.CycleButton.superclass.initComponent.call(this);
29428 this.on('click', this.toggleSelected, this);
29429 this.setActiveItem(checked, true);
29433 checkHandler : function(item, pressed){
29435 this.setActiveItem(item);
29440 toggleSelected : function(){
29448 var nextIdx, checkItem;
29449 for (var i = 1; i < this.itemCount; i++) {
29450 nextIdx = (this.activeItem.itemIndex + i) % this.itemCount;
29452 checkItem = m.items.itemAt(nextIdx);
29454 if (!checkItem.disabled) {
29455 checkItem.setChecked(true);
29461 Ext.reg('cycle', Ext.CycleButton);
29462 Ext.Toolbar = function(config){
29463 if(Ext.isArray(config)){
29464 config = {items: config, layout: 'toolbar'};
29466 config = Ext.apply({
29469 if(config.buttons) {
29470 config.items = config.buttons;
29473 Ext.Toolbar.superclass.constructor.call(this, config);
29478 var T = Ext.Toolbar;
29480 Ext.extend(T, Ext.Container, {
29482 defaultType: 'button',
29486 enableOverflow : false,
29492 internalDefaults: {removeMode: 'container', hideParent: true},
29493 toolbarCls: 'x-toolbar',
29495 initComponent : function(){
29496 T.superclass.initComponent.call(this);
29499 this.addEvents('overflowchange');
29503 onRender : function(ct, position){
29505 if(!this.autoCreate){
29506 this.autoCreate = {
29507 cls: this.toolbarCls + ' x-small-editor'
29510 this.el = ct.createChild(Ext.apply({ id: this.id },this.autoCreate), position);
29511 Ext.Toolbar.superclass.onRender.apply(this, arguments);
29518 lookupComponent : function(c){
29519 if(Ext.isString(c)){
29521 c = new T.Separator();
29522 }else if(c == ' '){
29523 c = new T.Spacer();
29524 }else if(c == '->'){
29527 c = new T.TextItem(c);
29529 this.applyDefaults(c);
29531 if(c.isFormField || c.render){
29532 c = this.createComponent(c);
29534 c = new T.Item({autoEl: c});
29535 }else if(c.tagName){
29536 c = new T.Item({el:c});
29537 }else if(Ext.isObject(c)){
29538 c = c.xtype ? this.createComponent(c) : this.constructButton(c);
29545 applyDefaults : function(c){
29546 if(!Ext.isString(c)){
29547 c = Ext.Toolbar.superclass.applyDefaults.call(this, c);
29548 var d = this.internalDefaults;
29550 Ext.applyIf(c.initialConfig, d);
29560 addSeparator : function(){
29561 return this.add(new T.Separator());
29565 addSpacer : function(){
29566 return this.add(new T.Spacer());
29570 addFill : function(){
29571 this.add(new T.Fill());
29575 addElement : function(el){
29576 return this.addItem(new T.Item({el:el}));
29580 addItem : function(item){
29581 return this.add.apply(this, arguments);
29585 addButton : function(config){
29586 if(Ext.isArray(config)){
29588 for(var i = 0, len = config.length; i < len; i++) {
29589 buttons.push(this.addButton(config[i]));
29593 return this.add(this.constructButton(config));
29597 addText : function(text){
29598 return this.addItem(new T.TextItem(text));
29602 addDom : function(config){
29603 return this.add(new T.Item({autoEl: config}));
29607 addField : function(field){
29608 return this.add(field);
29612 insertButton : function(index, item){
29613 if(Ext.isArray(item)){
29615 for(var i = 0, len = item.length; i < len; i++) {
29616 buttons.push(this.insertButton(index + i, item[i]));
29620 return Ext.Toolbar.superclass.insert.call(this, index, item);
29624 trackMenu : function(item, remove){
29625 if(this.trackMenus && item.menu){
29626 var method = remove ? 'mun' : 'mon';
29627 this[method](item, 'menutriggerover', this.onButtonTriggerOver, this);
29628 this[method](item, 'menushow', this.onButtonMenuShow, this);
29629 this[method](item, 'menuhide', this.onButtonMenuHide, this);
29634 constructButton : function(item){
29635 var b = item.events ? item : this.createComponent(item, item.split ? 'splitbutton' : this.defaultType);
29640 onAdd : function(c){
29641 Ext.Toolbar.superclass.onAdd.call(this);
29649 onRemove : function(c){
29650 Ext.Toolbar.superclass.onRemove.call(this);
29651 this.trackMenu(c, true);
29655 onDisable : function(){
29656 this.items.each(function(item){
29664 onEnable : function(){
29665 this.items.each(function(item){
29673 onButtonTriggerOver : function(btn){
29674 if(this.activeMenuBtn && this.activeMenuBtn != btn){
29675 this.activeMenuBtn.hideMenu();
29677 this.activeMenuBtn = btn;
29682 onButtonMenuShow : function(btn){
29683 this.activeMenuBtn = btn;
29687 onButtonMenuHide : function(btn){
29688 delete this.activeMenuBtn;
29691 Ext.reg('toolbar', Ext.Toolbar);
29694 T.Item = Ext.extend(Ext.BoxComponent, {
29696 enable:Ext.emptyFn,
29697 disable:Ext.emptyFn,
29701 Ext.reg('tbitem', T.Item);
29704 T.Separator = Ext.extend(T.Item, {
29705 onRender : function(ct, position){
29706 this.el = ct.createChild({tag:'span', cls:'xtb-sep'}, position);
29709 Ext.reg('tbseparator', T.Separator);
29712 T.Spacer = Ext.extend(T.Item, {
29715 onRender : function(ct, position){
29716 this.el = ct.createChild({tag:'div', cls:'xtb-spacer', style: this.width?'width:'+this.width+'px':''}, position);
29719 Ext.reg('tbspacer', T.Spacer);
29722 T.Fill = Ext.extend(T.Item, {
29724 render : Ext.emptyFn,
29727 Ext.reg('tbfill', T.Fill);
29730 T.TextItem = Ext.extend(T.Item, {
29733 constructor: function(config){
29734 T.TextItem.superclass.constructor.call(this, Ext.isString(config) ? {text: config} : config);
29738 onRender : function(ct, position) {
29739 this.autoEl = {cls: 'xtb-text', html: this.text || ''};
29740 T.TextItem.superclass.onRender.call(this, ct, position);
29744 setText : function(t) {
29752 Ext.reg('tbtext', T.TextItem);
29755 T.Button = Ext.extend(Ext.Button, {});
29756 T.SplitButton = Ext.extend(Ext.SplitButton, {});
29757 Ext.reg('tbbutton', T.Button);
29758 Ext.reg('tbsplit', T.SplitButton);
29762 Ext.ButtonGroup = Ext.extend(Ext.Panel, {
29765 baseCls: 'x-btn-group',
29768 defaultType: 'button',
29771 internalDefaults: {removeMode: 'container', hideParent: true},
29773 initComponent : function(){
29774 this.layoutConfig = this.layoutConfig || {};
29775 Ext.applyIf(this.layoutConfig, {
29776 columns : this.columns
29779 this.addClass('x-btn-group-notitle');
29781 this.on('afterlayout', this.onAfterLayout, this);
29782 Ext.ButtonGroup.superclass.initComponent.call(this);
29785 applyDefaults : function(c){
29786 c = Ext.ButtonGroup.superclass.applyDefaults.call(this, c);
29787 var d = this.internalDefaults;
29789 Ext.applyIf(c.initialConfig, d);
29797 onAfterLayout : function(){
29798 var bodyWidth = this.body.getFrameWidth('lr') + this.body.dom.firstChild.offsetWidth;
29799 this.body.setWidth(bodyWidth);
29800 this.el.setWidth(bodyWidth + this.getFrameWidth());
29805 Ext.reg('buttongroup', Ext.ButtonGroup);
29809 var T = Ext.Toolbar;
29811 Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {
29818 displayMsg : 'Displaying {0} - {1} of {2}',
29820 emptyMsg : 'No data to display',
29822 beforePageText : 'Page',
29824 afterPageText : 'of {0}',
29826 firstText : 'First Page',
29828 prevText : 'Previous Page',
29830 nextText : 'Next Page',
29832 lastText : 'Last Page',
29834 refreshText : 'Refresh',
29842 initComponent : function(){
29843 var pagingItems = [this.first = new T.Button({
29844 tooltip: this.firstText,
29845 overflowText: this.firstText,
29846 iconCls: 'x-tbar-page-first',
29848 handler: this.moveFirst,
29850 }), this.prev = new T.Button({
29851 tooltip: this.prevText,
29852 overflowText: this.prevText,
29853 iconCls: 'x-tbar-page-prev',
29855 handler: this.movePrevious,
29857 }), '-', this.beforePageText,
29858 this.inputItem = new Ext.form.NumberField({
29859 cls: 'x-tbar-page-number',
29860 allowDecimals: false,
29861 allowNegative: false,
29862 enableKeyEvents: true,
29863 selectOnFocus: true,
29864 submitValue: false,
29867 keydown: this.onPagingKeyDown,
29868 blur: this.onPagingBlur
29870 }), this.afterTextItem = new T.TextItem({
29871 text: String.format(this.afterPageText, 1)
29872 }), '-', this.next = new T.Button({
29873 tooltip: this.nextText,
29874 overflowText: this.nextText,
29875 iconCls: 'x-tbar-page-next',
29877 handler: this.moveNext,
29879 }), this.last = new T.Button({
29880 tooltip: this.lastText,
29881 overflowText: this.lastText,
29882 iconCls: 'x-tbar-page-last',
29884 handler: this.moveLast,
29886 }), '-', this.refresh = new T.Button({
29887 tooltip: this.refreshText,
29888 overflowText: this.refreshText,
29889 iconCls: 'x-tbar-loading',
29890 handler: this.doRefresh,
29895 var userItems = this.items || this.buttons || [];
29896 if (this.prependButtons) {
29897 this.items = userItems.concat(pagingItems);
29899 this.items = pagingItems.concat(userItems);
29901 delete this.buttons;
29902 if(this.displayInfo){
29903 this.items.push('->');
29904 this.items.push(this.displayItem = new T.TextItem({}));
29906 Ext.PagingToolbar.superclass.initComponent.call(this);
29913 this.on('afterlayout', this.onFirstLayout, this, {single: true});
29915 this.bindStore(this.store, true);
29919 onFirstLayout : function(){
29921 this.onLoad.apply(this, this.dsLoaded);
29926 updateInfo : function(){
29927 if(this.displayItem){
29928 var count = this.store.getCount();
29929 var msg = count == 0 ?
29933 this.cursor+1, this.cursor+count, this.store.getTotalCount()
29935 this.displayItem.setText(msg);
29940 onLoad : function(store, r, o){
29941 if(!this.rendered){
29942 this.dsLoaded = [store, r, o];
29945 var p = this.getParams();
29946 this.cursor = (o.params && o.params[p.start]) ? o.params[p.start] : 0;
29947 var d = this.getPageData(), ap = d.activePage, ps = d.pages;
29949 this.afterTextItem.setText(String.format(this.afterPageText, d.pages));
29950 this.inputItem.setValue(ap);
29951 this.first.setDisabled(ap == 1);
29952 this.prev.setDisabled(ap == 1);
29953 this.next.setDisabled(ap == ps);
29954 this.last.setDisabled(ap == ps);
29955 this.refresh.enable();
29957 this.fireEvent('change', this, d);
29961 getPageData : function(){
29962 var total = this.store.getTotalCount();
29965 activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize),
29966 pages : total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)
29971 changePage : function(page){
29972 this.doLoad(((page-1) * this.pageSize).constrain(0, this.store.getTotalCount()));
29976 onLoadError : function(){
29977 if(!this.rendered){
29980 this.refresh.enable();
29984 readPage : function(d){
29985 var v = this.inputItem.getValue(), pageNum;
29986 if (!v || isNaN(pageNum = parseInt(v, 10))) {
29987 this.inputItem.setValue(d.activePage);
29993 onPagingFocus : function(){
29994 this.inputItem.select();
29998 onPagingBlur : function(e){
29999 this.inputItem.setValue(this.getPageData().activePage);
30003 onPagingKeyDown : function(field, e){
30004 var k = e.getKey(), d = this.getPageData(), pageNum;
30005 if (k == e.RETURN) {
30007 pageNum = this.readPage(d);
30008 if(pageNum !== false){
30009 pageNum = Math.min(Math.max(1, pageNum), d.pages) - 1;
30010 this.doLoad(pageNum * this.pageSize);
30012 }else if (k == e.HOME || k == e.END){
30014 pageNum = k == e.HOME ? 1 : d.pages;
30015 field.setValue(pageNum);
30016 }else if (k == e.UP || k == e.PAGEUP || k == e.DOWN || k == e.PAGEDOWN){
30018 if((pageNum = this.readPage(d))){
30019 var increment = e.shiftKey ? 10 : 1;
30020 if(k == e.DOWN || k == e.PAGEDOWN){
30023 pageNum += increment;
30024 if(pageNum >= 1 & pageNum <= d.pages){
30025 field.setValue(pageNum);
30032 getParams : function(){
30034 return this.paramNames || this.store.paramNames;
30038 beforeLoad : function(){
30039 if(this.rendered && this.refresh){
30040 this.refresh.disable();
30045 doLoad : function(start){
30046 var o = {}, pn = this.getParams();
30047 o[pn.start] = start;
30048 o[pn.limit] = this.pageSize;
30049 if(this.fireEvent('beforechange', this, o) !== false){
30050 this.store.load({params:o});
30055 moveFirst : function(){
30060 movePrevious : function(){
30061 this.doLoad(Math.max(0, this.cursor-this.pageSize));
30065 moveNext : function(){
30066 this.doLoad(this.cursor+this.pageSize);
30070 moveLast : function(){
30071 var total = this.store.getTotalCount(),
30072 extra = total % this.pageSize;
30074 this.doLoad(extra ? (total - extra) : total - this.pageSize);
30078 doRefresh : function(){
30079 this.doLoad(this.cursor);
30083 bindStore : function(store, initial){
30085 if(!initial && this.store){
30086 if(store !== this.store && this.store.autoDestroy){
30087 this.store.destroy();
30089 this.store.un('beforeload', this.beforeLoad, this);
30090 this.store.un('load', this.onLoad, this);
30091 this.store.un('exception', this.onLoadError, this);
30098 store = Ext.StoreMgr.lookup(store);
30101 beforeload: this.beforeLoad,
30103 exception: this.onLoadError
30107 this.store = store;
30109 this.onLoad(store, null, {});
30114 unbind : function(store){
30115 this.bindStore(null);
30119 bind : function(store){
30120 this.bindStore(store);
30124 onDestroy : function(){
30125 this.bindStore(null);
30126 Ext.PagingToolbar.superclass.onDestroy.call(this);
30131 Ext.reg('paging', Ext.PagingToolbar);
30132 Ext.History = (function () {
30133 var iframe, hiddenField;
30137 function getHash() {
30138 var href = top.location.href, i = href.indexOf("#");
30139 return i >= 0 ? href.substr(i + 1) : null;
30142 function doSave() {
30143 hiddenField.value = currentToken;
30146 function handleStateChange(token) {
30147 currentToken = token;
30148 Ext.History.fireEvent('change', token);
30151 function updateIFrame (token) {
30152 var html = ['<html><body><div id="state">',Ext.util.Format.htmlEncode(token),'</div></body></html>'].join('');
30154 var doc = iframe.contentWindow.document;
30164 function checkIFrame() {
30165 if (!iframe.contentWindow || !iframe.contentWindow.document) {
30166 setTimeout(checkIFrame, 10);
30170 var doc = iframe.contentWindow.document;
30171 var elem = doc.getElementById("state");
30172 var token = elem ? elem.innerText : null;
30174 var hash = getHash();
30176 setInterval(function () {
30178 doc = iframe.contentWindow.document;
30179 elem = doc.getElementById("state");
30181 var newtoken = elem ? elem.innerText : null;
30183 var newHash = getHash();
30185 if (newtoken !== token) {
30187 handleStateChange(token);
30188 top.location.hash = token;
30191 } else if (newHash !== hash) {
30193 updateIFrame(newHash);
30200 Ext.History.fireEvent('ready', Ext.History);
30203 function startUp() {
30204 currentToken = hiddenField.value ? hiddenField.value : getHash();
30209 var hash = getHash();
30210 setInterval(function () {
30211 var newHash = getHash();
30212 if (newHash !== hash) {
30214 handleStateChange(hash);
30219 Ext.History.fireEvent('ready', Ext.History);
30225 fieldId: 'x-history-field',
30227 iframeId: 'x-history-frame',
30232 init: function (onReady, scope) {
30234 Ext.callback(onReady, scope, [this]);
30238 Ext.onReady(function(){
30239 Ext.History.init(onReady, scope);
30243 hiddenField = Ext.getDom(Ext.History.fieldId);
30245 iframe = Ext.getDom(Ext.History.iframeId);
30254 this.on('ready', onReady, scope, {single:true});
30260 add: function (token, preventDup) {
30261 if(preventDup !== false){
30262 if(this.getToken() == token){
30267 return updateIFrame(token);
30269 top.location.hash = token;
30280 forward: function(){
30285 getToken: function() {
30286 return ready ? currentToken : getHash();
30290 Ext.apply(Ext.History, new Ext.util.Observable());
30291 Ext.Tip = Ext.extend(Ext.Panel, {
30301 defaultAlign : "tl-bl?",
30303 quickShowInterval : 250,
30309 floating:{shadow:true,shim:true,useDisplay:true,constrain:false},
30312 closeAction: 'hide',
30315 initComponent : function(){
30316 Ext.Tip.superclass.initComponent.call(this);
30317 if(this.closable && !this.title){
30318 this.elements += ',header';
30323 afterRender : function(){
30324 Ext.Tip.superclass.afterRender.call(this);
30328 handler: this[this.closeAction],
30335 showAt : function(xy){
30336 Ext.Tip.superclass.show.call(this);
30337 if(this.measureWidth !== false && (!this.initialConfig || typeof this.initialConfig.width != 'number')){
30338 this.doAutoWidth();
30340 if(this.constrainPosition){
30341 xy = this.el.adjustForConstraints(xy);
30343 this.setPagePosition(xy[0], xy[1]);
30347 doAutoWidth : function(adjust){
30348 adjust = adjust || 0;
30349 var bw = this.body.getTextWidth();
30351 bw = Math.max(bw, this.header.child('span').getTextWidth(this.title));
30353 bw += this.getFrameWidth() + (this.closable ? 20 : 0) + this.body.getPadding("lr") + adjust;
30354 this.setWidth(bw.constrain(this.minWidth, this.maxWidth));
30357 if(Ext.isIE7 && !this.repainted){
30359 this.repainted = true;
30364 showBy : function(el, pos){
30365 if(!this.rendered){
30366 this.render(Ext.getBody());
30368 this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign));
30371 initDraggable : function(){
30372 this.dd = new Ext.Tip.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);
30373 this.header.addClass('x-tip-draggable');
30377 Ext.reg('tip', Ext.Tip);
30380 Ext.Tip.DD = function(tip, config){
30381 Ext.apply(this, config);
30383 Ext.Tip.DD.superclass.constructor.call(this, tip.el.id, 'WindowDD-'+tip.id);
30384 this.setHandleElId(tip.header.id);
30385 this.scroll = false;
30388 Ext.extend(Ext.Tip.DD, Ext.dd.DD, {
30391 headerOffsets:[100, 25],
30392 startDrag : function(){
30393 this.tip.el.disableShadow();
30395 endDrag : function(e){
30396 this.tip.el.enableShadow(true);
30399 Ext.ToolTip = Ext.extend(Ext.Tip, {
30408 dismissDelay : 5000,
30411 trackMouse : false,
30413 anchorToTarget : true,
30421 constrainPosition : false,
30424 initComponent : function(){
30425 Ext.ToolTip.superclass.initComponent.call(this);
30426 this.lastActive = new Date();
30427 this.initTarget(this.target);
30428 this.origAnchor = this.anchor;
30432 onRender : function(ct, position){
30433 Ext.ToolTip.superclass.onRender.call(this, ct, position);
30434 this.anchorCls = 'x-tip-anchor-' + this.getAnchorPosition();
30435 this.anchorEl = this.el.createChild({
30436 cls: 'x-tip-anchor ' + this.anchorCls
30441 afterRender : function(){
30442 Ext.ToolTip.superclass.afterRender.call(this);
30443 this.anchorEl.setStyle('z-index', this.el.getZIndex() + 1).setVisibilityMode(Ext.Element.DISPLAY);
30447 initTarget : function(target){
30449 if((t = Ext.get(target))){
30451 var tg = Ext.get(this.target);
30452 this.mun(tg, 'mouseover', this.onTargetOver, this);
30453 this.mun(tg, 'mouseout', this.onTargetOut, this);
30454 this.mun(tg, 'mousemove', this.onMouseMove, this);
30457 mouseover: this.onTargetOver,
30458 mouseout: this.onTargetOut,
30459 mousemove: this.onMouseMove,
30465 this.anchorTarget = this.target;
30470 onMouseMove : function(e){
30471 var t = this.delegate ? e.getTarget(this.delegate) : this.triggerElement = true;
30473 this.targetXY = e.getXY();
30474 if (t === this.triggerElement) {
30475 if(!this.hidden && this.trackMouse){
30476 this.setPagePosition(this.getTargetXY());
30480 this.lastActive = new Date(0);
30481 this.onTargetOver(e);
30483 } else if (!this.closable && this.isVisible()) {
30489 getTargetXY : function(){
30491 this.anchorTarget = this.triggerElement;
30494 this.targetCounter++;
30495 var offsets = this.getOffsets(),
30496 xy = (this.anchorToTarget && !this.trackMouse) ? this.el.getAlignToXY(this.anchorTarget, this.getAnchorAlign()) : this.targetXY,
30497 dw = Ext.lib.Dom.getViewWidth() - 5,
30498 dh = Ext.lib.Dom.getViewHeight() - 5,
30499 de = document.documentElement,
30500 bd = document.body,
30501 scrollX = (de.scrollLeft || bd.scrollLeft || 0) + 5,
30502 scrollY = (de.scrollTop || bd.scrollTop || 0) + 5,
30503 axy = [xy[0] + offsets[0], xy[1] + offsets[1]],
30504 sz = this.getSize();
30506 this.anchorEl.removeClass(this.anchorCls);
30508 if(this.targetCounter < 2){
30509 if(axy[0] < scrollX){
30510 if(this.anchorToTarget){
30511 this.defaultAlign = 'l-r';
30512 if(this.mouseOffset){this.mouseOffset[0] *= -1;}
30514 this.anchor = 'left';
30515 return this.getTargetXY();
30517 if(axy[0]+sz.width > dw){
30518 if(this.anchorToTarget){
30519 this.defaultAlign = 'r-l';
30520 if(this.mouseOffset){this.mouseOffset[0] *= -1;}
30522 this.anchor = 'right';
30523 return this.getTargetXY();
30525 if(axy[1] < scrollY){
30526 if(this.anchorToTarget){
30527 this.defaultAlign = 't-b';
30528 if(this.mouseOffset){this.mouseOffset[1] *= -1;}
30530 this.anchor = 'top';
30531 return this.getTargetXY();
30533 if(axy[1]+sz.height > dh){
30534 if(this.anchorToTarget){
30535 this.defaultAlign = 'b-t';
30536 if(this.mouseOffset){this.mouseOffset[1] *= -1;}
30538 this.anchor = 'bottom';
30539 return this.getTargetXY();
30543 this.anchorCls = 'x-tip-anchor-'+this.getAnchorPosition();
30544 this.anchorEl.addClass(this.anchorCls);
30545 this.targetCounter = 0;
30548 var mouseOffset = this.getMouseOffset();
30549 return [this.targetXY[0]+mouseOffset[0], this.targetXY[1]+mouseOffset[1]];
30553 getMouseOffset : function(){
30554 var offset = this.anchor ? [0,0] : [15,18];
30555 if(this.mouseOffset){
30556 offset[0] += this.mouseOffset[0];
30557 offset[1] += this.mouseOffset[1];
30563 getAnchorPosition : function(){
30565 this.tipAnchor = this.anchor.charAt(0);
30567 var m = this.defaultAlign.match(/^([a-z]+)-([a-z]+)(\?)?$/);
30569 throw 'AnchorTip.defaultAlign is invalid';
30571 this.tipAnchor = m[1].charAt(0);
30574 switch(this.tipAnchor){
30575 case 't': return 'top';
30576 case 'b': return 'bottom';
30577 case 'r': return 'right';
30583 getAnchorAlign : function(){
30584 switch(this.anchor){
30585 case 'top' : return 'tl-bl';
30586 case 'left' : return 'tl-tr';
30587 case 'right': return 'tr-tl';
30588 default : return 'bl-tl';
30593 getOffsets : function(){
30595 ap = this.getAnchorPosition().charAt(0);
30596 if(this.anchorToTarget && !this.trackMouse){
30602 offsets = [0, -13];
30605 offsets = [-13, 0];
30614 offsets = [-15-this.anchorOffset, 30];
30617 offsets = [-19-this.anchorOffset, -13-this.el.dom.offsetHeight];
30620 offsets = [-15-this.el.dom.offsetWidth, -13-this.anchorOffset];
30623 offsets = [25, -13-this.anchorOffset];
30627 var mouseOffset = this.getMouseOffset();
30628 offsets[0] += mouseOffset[0];
30629 offsets[1] += mouseOffset[1];
30635 onTargetOver : function(e){
30636 if(this.disabled || e.within(this.target.dom, true)){
30639 var t = e.getTarget(this.delegate);
30641 this.triggerElement = t;
30642 this.clearTimer('hide');
30643 this.targetXY = e.getXY();
30649 delayShow : function(){
30650 if(this.hidden && !this.showTimer){
30651 if(this.lastActive.getElapsed() < this.quickShowInterval){
30654 this.showTimer = this.show.defer(this.showDelay, this);
30656 }else if(!this.hidden && this.autoHide !== false){
30662 onTargetOut : function(e){
30663 if(this.disabled || e.within(this.target.dom, true)){
30666 this.clearTimer('show');
30667 if(this.autoHide !== false){
30673 delayHide : function(){
30674 if(!this.hidden && !this.hideTimer){
30675 this.hideTimer = this.hide.defer(this.hideDelay, this);
30681 this.clearTimer('dismiss');
30682 this.lastActive = new Date();
30684 this.anchorEl.hide();
30686 Ext.ToolTip.superclass.hide.call(this);
30687 delete this.triggerElement;
30695 this.showAt([-1000,-1000]);
30696 this.origConstrainPosition = this.constrainPosition;
30697 this.constrainPosition = false;
30698 this.anchor = this.origAnchor;
30700 this.showAt(this.getTargetXY());
30704 this.anchorEl.show();
30705 this.constrainPosition = this.origConstrainPosition;
30707 this.anchorEl.hide();
30712 showAt : function(xy){
30713 this.lastActive = new Date();
30714 this.clearTimers();
30715 Ext.ToolTip.superclass.showAt.call(this, xy);
30716 if(this.dismissDelay && this.autoHide !== false){
30717 this.dismissTimer = this.hide.defer(this.dismissDelay, this);
30719 if(this.anchor && !this.anchorEl.isVisible()){
30721 this.anchorEl.show();
30723 this.anchorEl.hide();
30728 syncAnchor : function(){
30729 var anchorPos, targetPos, offset;
30730 switch(this.tipAnchor.charAt(0)){
30734 offset = [20+this.anchorOffset, 2];
30739 offset = [-2, 11+this.anchorOffset];
30744 offset = [20+this.anchorOffset, -2];
30749 offset = [2, 11+this.anchorOffset];
30752 this.anchorEl.alignTo(this.el, anchorPos+'-'+targetPos, offset);
30756 setPagePosition : function(x, y){
30757 Ext.ToolTip.superclass.setPagePosition.call(this, x, y);
30764 clearTimer : function(name){
30765 name = name + 'Timer';
30766 clearTimeout(this[name]);
30771 clearTimers : function(){
30772 this.clearTimer('show');
30773 this.clearTimer('dismiss');
30774 this.clearTimer('hide');
30778 onShow : function(){
30779 Ext.ToolTip.superclass.onShow.call(this);
30780 Ext.getDoc().on('mousedown', this.onDocMouseDown, this);
30784 onHide : function(){
30785 Ext.ToolTip.superclass.onHide.call(this);
30786 Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
30790 onDocMouseDown : function(e){
30791 if(this.autoHide !== true && !this.closable && !e.within(this.el.dom)){
30793 this.doEnable.defer(100, this);
30798 doEnable : function(){
30799 if(!this.isDestroyed){
30805 onDisable : function(){
30806 this.clearTimers();
30811 adjustPosition : function(x, y){
30812 if(this.contstrainPosition){
30813 var ay = this.targetXY[1], h = this.getSize().height;
30814 if(y <= ay && (y+h) >= ay){
30818 return {x : x, y: y};
30821 beforeDestroy : function(){
30822 this.clearTimers();
30823 Ext.destroy(this.anchorEl);
30824 delete this.anchorEl;
30825 delete this.target;
30826 delete this.anchorTarget;
30827 delete this.triggerElement;
30828 Ext.ToolTip.superclass.beforeDestroy.call(this);
30832 onDestroy : function(){
30833 Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
30834 Ext.ToolTip.superclass.onDestroy.call(this);
30838 Ext.reg('tooltip', Ext.ToolTip);
30839 Ext.QuickTip = Ext.extend(Ext.ToolTip, {
30842 interceptTitles : false,
30847 attribute : "qtip",
30858 initComponent : function(){
30859 this.target = this.target || Ext.getDoc();
30860 this.targets = this.targets || {};
30861 Ext.QuickTip.superclass.initComponent.call(this);
30865 register : function(config){
30866 var cs = Ext.isArray(config) ? config : arguments;
30867 for(var i = 0, len = cs.length; i < len; i++){
30869 var target = c.target;
30871 if(Ext.isArray(target)){
30872 for(var j = 0, jlen = target.length; j < jlen; j++){
30873 this.targets[Ext.id(target[j])] = c;
30876 this.targets[Ext.id(target)] = c;
30883 unregister : function(el){
30884 delete this.targets[Ext.id(el)];
30888 cancelShow: function(el){
30889 var at = this.activeTarget;
30890 el = Ext.get(el).dom;
30891 if(this.isVisible()){
30892 if(at && at.el == el){
30895 }else if(at && at.el == el){
30896 this.clearTimer('show');
30900 getTipCfg: function(e) {
30901 var t = e.getTarget(),
30904 if(this.interceptTitles && t.title && Ext.isString(t.title)){
30907 t.removeAttribute("title");
30908 e.preventDefault();
30910 cfg = this.tagConfig;
30911 ttp = t.qtip || Ext.fly(t).getAttribute(cfg.attribute, cfg.namespace);
30917 onTargetOver : function(e){
30921 this.targetXY = e.getXY();
30922 var t = e.getTarget();
30923 if(!t || t.nodeType !== 1 || t == document || t == document.body){
30926 if(this.activeTarget && ((t == this.activeTarget.el) || Ext.fly(this.activeTarget.el).contains(t))){
30927 this.clearTimer('hide');
30931 if(t && this.targets[t.id]){
30932 this.activeTarget = this.targets[t.id];
30933 this.activeTarget.el = t;
30934 this.anchor = this.activeTarget.anchor;
30936 this.anchorTarget = t;
30941 var ttp, et = Ext.fly(t), cfg = this.tagConfig, ns = cfg.namespace;
30942 if(ttp = this.getTipCfg(e)){
30943 var autoHide = et.getAttribute(cfg.hide, ns);
30944 this.activeTarget = {
30947 width: et.getAttribute(cfg.width, ns),
30948 autoHide: autoHide != "user" && autoHide !== 'false',
30949 title: et.getAttribute(cfg.title, ns),
30950 cls: et.getAttribute(cfg.cls, ns),
30951 align: et.getAttribute(cfg.align, ns)
30954 this.anchor = et.getAttribute(cfg.anchor, ns);
30956 this.anchorTarget = t;
30963 onTargetOut : function(e){
30966 if (this.activeTarget && e.within(this.activeTarget.el) && !this.getTipCfg(e)) {
30970 this.clearTimer('show');
30971 if(this.autoHide !== false){
30977 showAt : function(xy){
30978 var t = this.activeTarget;
30980 if(!this.rendered){
30981 this.render(Ext.getBody());
30982 this.activeTarget = t;
30985 this.setWidth(t.width);
30986 this.body.setWidth(this.adjustBodyWidth(t.width - this.getFrameWidth()));
30987 this.measureWidth = false;
30989 this.measureWidth = true;
30991 this.setTitle(t.title || '');
30992 this.body.update(t.text);
30993 this.autoHide = t.autoHide;
30994 this.dismissDelay = t.dismissDelay || this.dismissDelay;
30996 this.el.removeClass(this.lastCls);
30997 delete this.lastCls;
31000 this.el.addClass(t.cls);
31001 this.lastCls = t.cls;
31004 this.constrainPosition = false;
31006 xy = this.el.getAlignToXY(t.el, t.align);
31007 this.constrainPosition = false;
31009 this.constrainPosition = true;
31012 Ext.QuickTip.superclass.showAt.call(this, xy);
31017 delete this.activeTarget;
31018 Ext.QuickTip.superclass.hide.call(this);
31021 Ext.reg('quicktip', Ext.QuickTip);
31022 Ext.QuickTips = function(){
31023 var tip, locks = [];
31026 init : function(autoRender){
31029 Ext.onReady(function(){
31030 Ext.QuickTips.init(autoRender);
31034 tip = new Ext.QuickTip({elements:'header,body'});
31035 if(autoRender !== false){
31036 tip.render(Ext.getBody());
31042 enable : function(){
31045 if(locks.length < 1){
31052 disable : function(){
31060 isEnabled : function(){
31061 return tip !== undefined && !tip.disabled;
31065 getQuickTip : function(){
31070 register : function(){
31071 tip.register.apply(tip, arguments);
31075 unregister : function(){
31076 tip.unregister.apply(tip, arguments);
31081 tip.register.apply(tip, arguments);
31085 Ext.slider.Tip = Ext.extend(Ext.Tip, {
31087 offsets : [0, -10],
31089 init: function(slider) {
31092 dragstart: this.onSlide,
31093 drag : this.onSlide,
31094 dragend : this.hide,
31095 destroy : this.destroy
31100 onSlide : function(slider, e, thumb) {
31102 this.body.update(this.getText(thumb));
31103 this.doAutoWidth();
31104 this.el.alignTo(thumb.el, 'b-t?', this.offsets);
31108 getText : function(thumb) {
31109 return String(thumb.value);
31114 Ext.ux.SliderTip = Ext.slider.Tip;
31115 Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
31116 rootVisible : true,
31117 animate : Ext.enableFx,
31120 hlDrop : Ext.enableFx,
31121 pathSeparator : '/',
31126 initComponent : function(){
31127 Ext.tree.TreePanel.superclass.initComponent.call(this);
31129 if(!this.eventModel){
31130 this.eventModel = new Ext.tree.TreeEventModel(this);
31134 var l = this.loader;
31136 l = new Ext.tree.TreeLoader({
31137 dataUrl: this.dataUrl,
31138 requestMethod: this.requestMethod
31140 }else if(Ext.isObject(l) && !l.load){
31141 l = new Ext.tree.TreeLoader(l);
31145 this.nodeHash = {};
31151 this.setRootNode(r);
31181 'beforeexpandnode',
31183 'beforecollapsenode',
31203 'containerdblclick',
31207 'containercontextmenu',
31209 'beforechildrenrendered',
31223 if(this.singleExpand){
31224 this.on('beforeexpandnode', this.restrictExpand, this);
31229 proxyNodeEvent : function(ename, a1, a2, a3, a4, a5, a6){
31230 if(ename == 'collapse' || ename == 'expand' || ename == 'beforecollapse' || ename == 'beforeexpand' || ename == 'move' || ename == 'beforemove'){
31231 ename = ename+'node';
31234 return this.fireEvent(ename, a1, a2, a3, a4, a5, a6);
31239 getRootNode : function(){
31244 setRootNode : function(node){
31245 this.destroyRoot();
31247 node = this.loader.createNode(node);
31250 node.ownerTree = this;
31251 node.isRoot = true;
31252 this.registerNode(node);
31253 if(!this.rootVisible){
31254 var uiP = node.attributes.uiProvider;
31255 node.ui = uiP ? new uiP(node) : new Ext.tree.RootTreeNodeUI(node);
31258 this.clearInnerCt();
31264 clearInnerCt : function(){
31265 this.innerCt.update('');
31269 renderRoot : function(){
31270 this.root.render();
31271 if(!this.rootVisible){
31272 this.root.renderChildren();
31277 getNodeById : function(id){
31278 return this.nodeHash[id];
31282 registerNode : function(node){
31283 this.nodeHash[node.id] = node;
31287 unregisterNode : function(node){
31288 delete this.nodeHash[node.id];
31292 toString : function(){
31293 return '[Tree'+(this.id?' '+this.id:'')+']';
31297 restrictExpand : function(node){
31298 var p = node.parentNode;
31300 if(p.expandedChild && p.expandedChild.parentNode == p){
31301 p.expandedChild.collapse();
31303 p.expandedChild = node;
31308 getChecked : function(a, startNode){
31309 startNode = startNode || this.root;
31311 var f = function(){
31312 if(this.attributes.checked){
31313 r.push(!a ? this : (a == 'id' ? this.id : this.attributes[a]));
31316 startNode.cascade(f);
31321 getLoader : function(){
31322 return this.loader;
31326 expandAll : function(){
31327 this.root.expand(true);
31331 collapseAll : function(){
31332 this.root.collapse(true);
31336 getSelectionModel : function(){
31337 if(!this.selModel){
31338 this.selModel = new Ext.tree.DefaultSelectionModel();
31340 return this.selModel;
31344 expandPath : function(path, attr, callback){
31345 if(Ext.isEmpty(path)){
31347 callback(false, undefined);
31351 attr = attr || 'id';
31352 var keys = path.split(this.pathSeparator);
31353 var curNode = this.root;
31354 if(curNode.attributes[attr] != keys[1]){
31356 callback(false, null);
31361 var f = function(){
31362 if(++index == keys.length){
31364 callback(true, curNode);
31368 var c = curNode.findChild(attr, keys[index]);
31371 callback(false, curNode);
31376 c.expand(false, false, f);
31378 curNode.expand(false, false, f);
31382 selectPath : function(path, attr, callback){
31383 if(Ext.isEmpty(path)){
31385 callback(false, undefined);
31389 attr = attr || 'id';
31390 var keys = path.split(this.pathSeparator),
31392 if(keys.length > 1){
31393 var f = function(success, node){
31394 if(success && node){
31395 var n = node.findChild(attr, v);
31401 }else if(callback){
31402 callback(false, n);
31406 callback(false, n);
31410 this.expandPath(keys.join(this.pathSeparator), attr, f);
31412 this.root.select();
31414 callback(true, this.root);
31420 getTreeEl : function(){
31425 onRender : function(ct, position){
31426 Ext.tree.TreePanel.superclass.onRender.call(this, ct, position);
31427 this.el.addClass('x-tree');
31428 this.innerCt = this.body.createChild({tag:'ul',
31429 cls:'x-tree-root-ct ' +
31430 (this.useArrows ? 'x-tree-arrows' : this.lines ? 'x-tree-lines' : 'x-tree-no-lines')});
31434 initEvents : function(){
31435 Ext.tree.TreePanel.superclass.initEvents.call(this);
31437 if(this.containerScroll){
31438 Ext.dd.ScrollManager.register(this.body);
31440 if((this.enableDD || this.enableDrop) && !this.dropZone){
31442 this.dropZone = new Ext.tree.TreeDropZone(this, this.dropConfig || {
31443 ddGroup: this.ddGroup || 'TreeDD', appendOnly: this.ddAppendOnly === true
31446 if((this.enableDD || this.enableDrag) && !this.dragZone){
31448 this.dragZone = new Ext.tree.TreeDragZone(this, this.dragConfig || {
31449 ddGroup: this.ddGroup || 'TreeDD',
31450 scroll: this.ddScroll
31453 this.getSelectionModel().init(this);
31457 afterRender : function(){
31458 Ext.tree.TreePanel.superclass.afterRender.call(this);
31462 beforeDestroy : function(){
31464 Ext.dd.ScrollManager.unregister(this.body);
31465 Ext.destroy(this.dropZone, this.dragZone);
31467 this.destroyRoot();
31468 Ext.destroy(this.loader);
31469 this.nodeHash = this.root = this.loader = null;
31470 Ext.tree.TreePanel.superclass.beforeDestroy.call(this);
31474 destroyRoot : function(){
31475 if(this.root && this.root.destroy){
31476 this.root.destroy(true);
31532 Ext.tree.TreePanel.nodeTypes = {};
31534 Ext.reg('treepanel', Ext.tree.TreePanel);Ext.tree.TreeEventModel = function(tree){
31536 this.tree.on('render', this.initEvents, this);
31539 Ext.tree.TreeEventModel.prototype = {
31540 initEvents : function(){
31543 if(t.trackMouseOver !== false){
31546 mouseover: this.delegateOver,
31547 mouseout: this.delegateOut
31550 t.mon(t.getTreeEl(), {
31552 click: this.delegateClick,
31553 dblclick: this.delegateDblClick,
31554 contextmenu: this.delegateContextMenu
31558 getNode : function(e){
31560 if(t = e.getTarget('.x-tree-node-el', 10)){
31561 var id = Ext.fly(t, '_treeEvents').getAttribute('tree-node-id', 'ext');
31563 return this.tree.getNodeById(id);
31569 getNodeTarget : function(e){
31570 var t = e.getTarget('.x-tree-node-icon', 1);
31572 t = e.getTarget('.x-tree-node-el', 6);
31577 delegateOut : function(e, t){
31578 if(!this.beforeEvent(e)){
31581 if(e.getTarget('.x-tree-ec-icon', 1)){
31582 var n = this.getNode(e);
31583 this.onIconOut(e, n);
31584 if(n == this.lastEcOver){
31585 delete this.lastEcOver;
31588 if((t = this.getNodeTarget(e)) && !e.within(t, true)){
31589 this.onNodeOut(e, this.getNode(e));
31593 delegateOver : function(e, t){
31594 if(!this.beforeEvent(e)){
31597 if(Ext.isGecko && !this.trackingDoc){
31598 Ext.getBody().on('mouseover', this.trackExit, this);
31599 this.trackingDoc = true;
31601 if(this.lastEcOver){
31602 this.onIconOut(e, this.lastEcOver);
31603 delete this.lastEcOver;
31605 if(e.getTarget('.x-tree-ec-icon', 1)){
31606 this.lastEcOver = this.getNode(e);
31607 this.onIconOver(e, this.lastEcOver);
31609 if(t = this.getNodeTarget(e)){
31610 this.onNodeOver(e, this.getNode(e));
31614 trackExit : function(e){
31615 if(this.lastOverNode){
31616 if(this.lastOverNode.ui && !e.within(this.lastOverNode.ui.getEl())){
31617 this.onNodeOut(e, this.lastOverNode);
31619 delete this.lastOverNode;
31620 Ext.getBody().un('mouseover', this.trackExit, this);
31621 this.trackingDoc = false;
31626 delegateClick : function(e, t){
31627 if(this.beforeEvent(e)){
31628 if(e.getTarget('input[type=checkbox]', 1)){
31629 this.onCheckboxClick(e, this.getNode(e));
31630 }else if(e.getTarget('.x-tree-ec-icon', 1)){
31631 this.onIconClick(e, this.getNode(e));
31632 }else if(this.getNodeTarget(e)){
31633 this.onNodeClick(e, this.getNode(e));
31636 this.checkContainerEvent(e, 'click');
31640 delegateDblClick : function(e, t){
31641 if(this.beforeEvent(e)){
31642 if(this.getNodeTarget(e)){
31643 this.onNodeDblClick(e, this.getNode(e));
31646 this.checkContainerEvent(e, 'dblclick');
31650 delegateContextMenu : function(e, t){
31651 if(this.beforeEvent(e)){
31652 if(this.getNodeTarget(e)){
31653 this.onNodeContextMenu(e, this.getNode(e));
31656 this.checkContainerEvent(e, 'contextmenu');
31660 checkContainerEvent: function(e, type){
31665 this.onContainerEvent(e, type);
31668 onContainerEvent: function(e, type){
31669 this.tree.fireEvent('container' + type, this.tree, e);
31672 onNodeClick : function(e, node){
31673 node.ui.onClick(e);
31676 onNodeOver : function(e, node){
31677 this.lastOverNode = node;
31681 onNodeOut : function(e, node){
31685 onIconOver : function(e, node){
31686 node.ui.addClass('x-tree-ec-over');
31689 onIconOut : function(e, node){
31690 node.ui.removeClass('x-tree-ec-over');
31693 onIconClick : function(e, node){
31694 node.ui.ecClick(e);
31697 onCheckboxClick : function(e, node){
31698 node.ui.onCheckChange(e);
31701 onNodeDblClick : function(e, node){
31702 node.ui.onDblClick(e);
31705 onNodeContextMenu : function(e, node){
31706 node.ui.onContextMenu(e);
31709 beforeEvent : function(e){
31710 var node = this.getNode(e);
31711 if(this.disabled || !node || !node.ui){
31718 disable: function(){
31719 this.disabled = true;
31722 enable: function(){
31723 this.disabled = false;
31726 Ext.tree.DefaultSelectionModel = Ext.extend(Ext.util.Observable, {
31728 constructor : function(config){
31729 this.selNode = null;
31739 Ext.apply(this, config);
31740 Ext.tree.DefaultSelectionModel.superclass.constructor.call(this);
31743 init : function(tree){
31745 tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);
31746 tree.on('click', this.onNodeClick, this);
31749 onNodeClick : function(node, e){
31754 select : function(node, selectNextNode){
31756 if (!Ext.fly(node.ui.wrap).isVisible() && selectNextNode) {
31757 return selectNextNode.call(this, node);
31759 var last = this.selNode;
31761 node.ui.onSelectedChange(true);
31762 }else if(this.fireEvent('beforeselect', this, node, last) !== false){
31763 if(last && last.ui){
31764 last.ui.onSelectedChange(false);
31766 this.selNode = node;
31767 node.ui.onSelectedChange(true);
31768 this.fireEvent('selectionchange', this, node, last);
31774 unselect : function(node, silent){
31775 if(this.selNode == node){
31776 this.clearSelections(silent);
31781 clearSelections : function(silent){
31782 var n = this.selNode;
31784 n.ui.onSelectedChange(false);
31785 this.selNode = null;
31786 if(silent !== true){
31787 this.fireEvent('selectionchange', this, null);
31794 getSelectedNode : function(){
31795 return this.selNode;
31799 isSelected : function(node){
31800 return this.selNode == node;
31804 selectPrevious : function( s){
31805 if(!(s = s || this.selNode || this.lastSelNode)){
31809 var ps = s.previousSibling;
31811 if(!ps.isExpanded() || ps.childNodes.length < 1){
31812 return this.select(ps, this.selectPrevious);
31814 var lc = ps.lastChild;
31815 while(lc && lc.isExpanded() && Ext.fly(lc.ui.wrap).isVisible() && lc.childNodes.length > 0){
31818 return this.select(lc, this.selectPrevious);
31820 } else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){
31821 return this.select(s.parentNode, this.selectPrevious);
31827 selectNext : function( s){
31828 if(!(s = s || this.selNode || this.lastSelNode)){
31832 if(s.firstChild && s.isExpanded() && Ext.fly(s.ui.wrap).isVisible()){
31833 return this.select(s.firstChild, this.selectNext);
31834 }else if(s.nextSibling){
31835 return this.select(s.nextSibling, this.selectNext);
31836 }else if(s.parentNode){
31838 s.parentNode.bubble(function(){
31839 if(this.nextSibling){
31840 newS = this.getOwnerTree().selModel.select(this.nextSibling, this.selectNext);
31849 onKeyDown : function(e){
31850 var s = this.selNode || this.lastSelNode;
31856 var k = e.getKey();
31864 this.selectPrevious();
31867 e.preventDefault();
31868 if(s.hasChildNodes()){
31869 if(!s.isExpanded()){
31871 }else if(s.firstChild){
31872 this.select(s.firstChild, e);
31877 e.preventDefault();
31878 if(s.hasChildNodes() && s.isExpanded()){
31880 }else if(s.parentNode && (this.tree.rootVisible || s.parentNode != this.tree.getRootNode())){
31881 this.select(s.parentNode, e);
31889 Ext.tree.MultiSelectionModel = Ext.extend(Ext.util.Observable, {
31891 constructor : function(config){
31892 this.selNodes = [];
31898 Ext.apply(this, config);
31899 Ext.tree.MultiSelectionModel.superclass.constructor.call(this);
31902 init : function(tree){
31904 tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);
31905 tree.on('click', this.onNodeClick, this);
31908 onNodeClick : function(node, e){
31909 if(e.ctrlKey && this.isSelected(node)){
31910 this.unselect(node);
31912 this.select(node, e, e.ctrlKey);
31917 select : function(node, e, keepExisting){
31918 if(keepExisting !== true){
31919 this.clearSelections(true);
31921 if(this.isSelected(node)){
31922 this.lastSelNode = node;
31925 this.selNodes.push(node);
31926 this.selMap[node.id] = node;
31927 this.lastSelNode = node;
31928 node.ui.onSelectedChange(true);
31929 this.fireEvent('selectionchange', this, this.selNodes);
31934 unselect : function(node){
31935 if(this.selMap[node.id]){
31936 node.ui.onSelectedChange(false);
31937 var sn = this.selNodes;
31938 var index = sn.indexOf(node);
31940 this.selNodes.splice(index, 1);
31942 delete this.selMap[node.id];
31943 this.fireEvent('selectionchange', this, this.selNodes);
31948 clearSelections : function(suppressEvent){
31949 var sn = this.selNodes;
31951 for(var i = 0, len = sn.length; i < len; i++){
31952 sn[i].ui.onSelectedChange(false);
31954 this.selNodes = [];
31956 if(suppressEvent !== true){
31957 this.fireEvent('selectionchange', this, this.selNodes);
31963 isSelected : function(node){
31964 return this.selMap[node.id] ? true : false;
31968 getSelectedNodes : function(){
31969 return this.selNodes.concat([]);
31972 onKeyDown : Ext.tree.DefaultSelectionModel.prototype.onKeyDown,
31974 selectNext : Ext.tree.DefaultSelectionModel.prototype.selectNext,
31976 selectPrevious : Ext.tree.DefaultSelectionModel.prototype.selectPrevious
31978 Ext.data.Tree = function(root){
31979 this.nodeHash = {};
31983 this.setRootNode(root);
32004 Ext.data.Tree.superclass.constructor.call(this);
32007 Ext.extend(Ext.data.Tree, Ext.util.Observable, {
32009 pathSeparator: "/",
32012 proxyNodeEvent : function(){
32013 return this.fireEvent.apply(this, arguments);
32017 getRootNode : function(){
32022 setRootNode : function(node){
32024 node.ownerTree = this;
32025 node.isRoot = true;
32026 this.registerNode(node);
32031 getNodeById : function(id){
32032 return this.nodeHash[id];
32036 registerNode : function(node){
32037 this.nodeHash[node.id] = node;
32041 unregisterNode : function(node){
32042 delete this.nodeHash[node.id];
32045 toString : function(){
32046 return "[Tree"+(this.id?" "+this.id:"")+"]";
32051 Ext.data.Node = function(attributes){
32053 this.attributes = attributes || {};
32054 this.leaf = this.attributes.leaf;
32056 this.id = this.attributes.id;
32058 this.id = Ext.id(null, "xnode-");
32059 this.attributes.id = this.id;
32062 this.childNodes = [];
32063 if(!this.childNodes.indexOf){
32064 this.childNodes.indexOf = function(o){
32065 for(var i = 0, len = this.length; i < len; i++){
32074 this.parentNode = null;
32076 this.firstChild = null;
32078 this.lastChild = null;
32080 this.previousSibling = null;
32082 this.nextSibling = null;
32094 "beforeappend" : true,
32096 "beforeremove" : true,
32098 "beforemove" : true,
32100 "beforeinsert" : true
32102 this.listeners = this.attributes.listeners;
32103 Ext.data.Node.superclass.constructor.call(this);
32106 Ext.extend(Ext.data.Node, Ext.util.Observable, {
32108 fireEvent : function(evtName){
32110 if(Ext.data.Node.superclass.fireEvent.apply(this, arguments) === false){
32114 var ot = this.getOwnerTree();
32116 if(ot.proxyNodeEvent.apply(ot, arguments) === false){
32124 isLeaf : function(){
32125 return this.leaf === true;
32129 setFirstChild : function(node){
32130 this.firstChild = node;
32134 setLastChild : function(node){
32135 this.lastChild = node;
32140 isLast : function(){
32141 return (!this.parentNode ? true : this.parentNode.lastChild == this);
32145 isFirst : function(){
32146 return (!this.parentNode ? true : this.parentNode.firstChild == this);
32150 hasChildNodes : function(){
32151 return !this.isLeaf() && this.childNodes.length > 0;
32155 isExpandable : function(){
32156 return this.attributes.expandable || this.hasChildNodes();
32160 appendChild : function(node){
32162 if(Ext.isArray(node)){
32164 }else if(arguments.length > 1){
32169 for(var i = 0, len = multi.length; i < len; i++) {
32170 this.appendChild(multi[i]);
32173 if(this.fireEvent("beforeappend", this.ownerTree, this, node) === false){
32176 var index = this.childNodes.length;
32177 var oldParent = node.parentNode;
32180 if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index) === false){
32183 oldParent.removeChild(node);
32185 index = this.childNodes.length;
32187 this.setFirstChild(node);
32189 this.childNodes.push(node);
32190 node.parentNode = this;
32191 var ps = this.childNodes[index-1];
32193 node.previousSibling = ps;
32194 ps.nextSibling = node;
32196 node.previousSibling = null;
32198 node.nextSibling = null;
32199 this.setLastChild(node);
32200 node.setOwnerTree(this.getOwnerTree());
32201 this.fireEvent("append", this.ownerTree, this, node, index);
32203 node.fireEvent("move", this.ownerTree, node, oldParent, this, index);
32210 removeChild : function(node, destroy){
32211 var index = this.childNodes.indexOf(node);
32215 if(this.fireEvent("beforeremove", this.ownerTree, this, node) === false){
32220 this.childNodes.splice(index, 1);
32223 if(node.previousSibling){
32224 node.previousSibling.nextSibling = node.nextSibling;
32226 if(node.nextSibling){
32227 node.nextSibling.previousSibling = node.previousSibling;
32231 if(this.firstChild == node){
32232 this.setFirstChild(node.nextSibling);
32234 if(this.lastChild == node){
32235 this.setLastChild(node.previousSibling);
32238 this.fireEvent("remove", this.ownerTree, this, node);
32240 node.destroy(true);
32248 clear : function(destroy){
32250 this.setOwnerTree(null, destroy);
32251 this.parentNode = this.previousSibling = this.nextSibling = null;
32253 this.firstChild = this.lastChild = null;
32258 destroy : function( silent){
32260 if(silent === true){
32261 this.purgeListeners();
32263 Ext.each(this.childNodes, function(n){
32266 this.childNodes = null;
32273 insertBefore : function(node, refNode){
32275 return this.appendChild(node);
32278 if(node == refNode){
32282 if(this.fireEvent("beforeinsert", this.ownerTree, this, node, refNode) === false){
32285 var index = this.childNodes.indexOf(refNode);
32286 var oldParent = node.parentNode;
32287 var refIndex = index;
32290 if(oldParent == this && this.childNodes.indexOf(node) < index){
32296 if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index, refNode) === false){
32299 oldParent.removeChild(node);
32301 if(refIndex === 0){
32302 this.setFirstChild(node);
32304 this.childNodes.splice(refIndex, 0, node);
32305 node.parentNode = this;
32306 var ps = this.childNodes[refIndex-1];
32308 node.previousSibling = ps;
32309 ps.nextSibling = node;
32311 node.previousSibling = null;
32313 node.nextSibling = refNode;
32314 refNode.previousSibling = node;
32315 node.setOwnerTree(this.getOwnerTree());
32316 this.fireEvent("insert", this.ownerTree, this, node, refNode);
32318 node.fireEvent("move", this.ownerTree, node, oldParent, this, refIndex, refNode);
32324 remove : function(destroy){
32325 if (this.parentNode) {
32326 this.parentNode.removeChild(this, destroy);
32332 removeAll : function(destroy){
32333 var cn = this.childNodes,
32335 while((n = cn[0])){
32336 this.removeChild(n, destroy);
32342 item : function(index){
32343 return this.childNodes[index];
32347 replaceChild : function(newChild, oldChild){
32348 var s = oldChild ? oldChild.nextSibling : null;
32349 this.removeChild(oldChild);
32350 this.insertBefore(newChild, s);
32355 indexOf : function(child){
32356 return this.childNodes.indexOf(child);
32360 getOwnerTree : function(){
32362 if(!this.ownerTree){
32366 this.ownerTree = p.ownerTree;
32372 return this.ownerTree;
32376 getDepth : function(){
32379 while(p.parentNode){
32387 setOwnerTree : function(tree, destroy){
32389 if(tree != this.ownerTree){
32390 if(this.ownerTree){
32391 this.ownerTree.unregisterNode(this);
32393 this.ownerTree = tree;
32395 if(destroy !== true){
32396 Ext.each(this.childNodes, function(n){
32397 n.setOwnerTree(tree);
32401 tree.registerNode(this);
32407 setId: function(id){
32408 if(id !== this.id){
32409 var t = this.ownerTree;
32411 t.unregisterNode(this);
32413 this.id = this.attributes.id = id;
32415 t.registerNode(this);
32417 this.onIdChange(id);
32422 onIdChange: Ext.emptyFn,
32425 getPath : function(attr){
32426 attr = attr || "id";
32427 var p = this.parentNode;
32428 var b = [this.attributes[attr]];
32430 b.unshift(p.attributes[attr]);
32433 var sep = this.getOwnerTree().pathSeparator;
32434 return sep + b.join(sep);
32438 bubble : function(fn, scope, args){
32441 if(fn.apply(scope || p, args || [p]) === false){
32449 cascade : function(fn, scope, args){
32450 if(fn.apply(scope || this, args || [this]) !== false){
32451 var cs = this.childNodes;
32452 for(var i = 0, len = cs.length; i < len; i++) {
32453 cs[i].cascade(fn, scope, args);
32459 eachChild : function(fn, scope, args){
32460 var cs = this.childNodes;
32461 for(var i = 0, len = cs.length; i < len; i++) {
32462 if(fn.apply(scope || this, args || [cs[i]]) === false){
32469 findChild : function(attribute, value, deep){
32470 return this.findChildBy(function(){
32471 return this.attributes[attribute] == value;
32476 findChildBy : function(fn, scope, deep){
32477 var cs = this.childNodes,
32482 for(; i < len; i++){
32484 if(fn.call(scope || n, n) === true){
32487 res = n.findChildBy(fn, scope, deep);
32498 sort : function(fn, scope){
32499 var cs = this.childNodes;
32500 var len = cs.length;
32502 var sortFn = scope ? function(){fn.apply(scope, arguments);} : fn;
32504 for(var i = 0; i < len; i++){
32506 n.previousSibling = cs[i-1];
32507 n.nextSibling = cs[i+1];
32509 this.setFirstChild(n);
32512 this.setLastChild(n);
32519 contains : function(node){
32520 return node.isAncestor(this);
32524 isAncestor : function(node){
32525 var p = this.parentNode;
32535 toString : function(){
32536 return "[Node"+(this.id?" "+this.id:"")+"]";
32539 Ext.tree.TreeNode = function(attributes){
32540 attributes = attributes || {};
32541 if(Ext.isString(attributes)){
32542 attributes = {text: attributes};
32544 this.childrenRendered = false;
32545 this.rendered = false;
32546 Ext.tree.TreeNode.superclass.constructor.call(this, attributes);
32547 this.expanded = attributes.expanded === true;
32548 this.isTarget = attributes.isTarget !== false;
32549 this.draggable = attributes.draggable !== false && attributes.allowDrag !== false;
32550 this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false;
32553 this.text = attributes.text;
32555 this.disabled = attributes.disabled === true;
32557 this.hidden = attributes.hidden === true;
32585 'beforechildrenrendered'
32588 var uiClass = this.attributes.uiProvider || this.defaultUI || Ext.tree.TreeNodeUI;
32591 this.ui = new uiClass(this);
32593 Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
32594 preventHScroll : true,
32596 isExpanded : function(){
32597 return this.expanded;
32601 getUI : function(){
32605 getLoader : function(){
32607 return this.loader || ((owner = this.getOwnerTree()) && owner.loader ? owner.loader : (this.loader = new Ext.tree.TreeLoader()));
32611 setFirstChild : function(node){
32612 var of = this.firstChild;
32613 Ext.tree.TreeNode.superclass.setFirstChild.call(this, node);
32614 if(this.childrenRendered && of && node != of){
32615 of.renderIndent(true, true);
32618 this.renderIndent(true, true);
32623 setLastChild : function(node){
32624 var ol = this.lastChild;
32625 Ext.tree.TreeNode.superclass.setLastChild.call(this, node);
32626 if(this.childrenRendered && ol && node != ol){
32627 ol.renderIndent(true, true);
32630 this.renderIndent(true, true);
32636 appendChild : function(n){
32637 if(!n.render && !Ext.isArray(n)){
32638 n = this.getLoader().createNode(n);
32640 var node = Ext.tree.TreeNode.superclass.appendChild.call(this, n);
32641 if(node && this.childrenRendered){
32644 this.ui.updateExpandIcon();
32649 removeChild : function(node, destroy){
32650 this.ownerTree.getSelectionModel().unselect(node);
32651 Ext.tree.TreeNode.superclass.removeChild.apply(this, arguments);
32655 if(node.ui.rendered){
32658 if(this.childNodes.length < 1){
32659 this.collapse(false, false);
32661 this.ui.updateExpandIcon();
32663 if(!this.firstChild && !this.isHiddenRoot()){
32664 this.childrenRendered = false;
32671 insertBefore : function(node, refNode){
32673 node = this.getLoader().createNode(node);
32675 var newNode = Ext.tree.TreeNode.superclass.insertBefore.call(this, node, refNode);
32676 if(newNode && refNode && this.childrenRendered){
32679 this.ui.updateExpandIcon();
32684 setText : function(text){
32685 var oldText = this.text;
32686 this.text = this.attributes.text = text;
32688 this.ui.onTextChange(this, text, oldText);
32690 this.fireEvent('textchange', this, text, oldText);
32694 select : function(){
32695 var t = this.getOwnerTree();
32697 t.getSelectionModel().select(this);
32702 unselect : function(silent){
32703 var t = this.getOwnerTree();
32705 t.getSelectionModel().unselect(this, silent);
32710 isSelected : function(){
32711 var t = this.getOwnerTree();
32712 return t ? t.getSelectionModel().isSelected(this) : false;
32716 expand : function(deep, anim, callback, scope){
32717 if(!this.expanded){
32718 if(this.fireEvent('beforeexpand', this, deep, anim) === false){
32721 if(!this.childrenRendered){
32722 this.renderChildren();
32724 this.expanded = true;
32725 if(!this.isHiddenRoot() && (this.getOwnerTree().animate && anim !== false) || anim){
32726 this.ui.animExpand(function(){
32727 this.fireEvent('expand', this);
32728 this.runCallback(callback, scope || this, [this]);
32730 this.expandChildNodes(true);
32732 }.createDelegate(this));
32736 this.fireEvent('expand', this);
32737 this.runCallback(callback, scope || this, [this]);
32740 this.runCallback(callback, scope || this, [this]);
32743 this.expandChildNodes(true);
32747 runCallback : function(cb, scope, args){
32748 if(Ext.isFunction(cb)){
32749 cb.apply(scope, args);
32753 isHiddenRoot : function(){
32754 return this.isRoot && !this.getOwnerTree().rootVisible;
32758 collapse : function(deep, anim, callback, scope){
32759 if(this.expanded && !this.isHiddenRoot()){
32760 if(this.fireEvent('beforecollapse', this, deep, anim) === false){
32763 this.expanded = false;
32764 if((this.getOwnerTree().animate && anim !== false) || anim){
32765 this.ui.animCollapse(function(){
32766 this.fireEvent('collapse', this);
32767 this.runCallback(callback, scope || this, [this]);
32769 this.collapseChildNodes(true);
32771 }.createDelegate(this));
32774 this.ui.collapse();
32775 this.fireEvent('collapse', this);
32776 this.runCallback(callback, scope || this, [this]);
32778 }else if(!this.expanded){
32779 this.runCallback(callback, scope || this, [this]);
32782 var cs = this.childNodes;
32783 for(var i = 0, len = cs.length; i < len; i++) {
32784 cs[i].collapse(true, false);
32790 delayedExpand : function(delay){
32791 if(!this.expandProcId){
32792 this.expandProcId = this.expand.defer(delay, this);
32797 cancelExpand : function(){
32798 if(this.expandProcId){
32799 clearTimeout(this.expandProcId);
32801 this.expandProcId = false;
32805 toggle : function(){
32814 ensureVisible : function(callback, scope){
32815 var tree = this.getOwnerTree();
32816 tree.expandPath(this.parentNode ? this.parentNode.getPath() : this.getPath(), false, function(){
32817 var node = tree.getNodeById(this.id);
32818 tree.getTreeEl().scrollChildIntoView(node.ui.anchor);
32819 this.runCallback(callback, scope || this, [this]);
32820 }.createDelegate(this));
32824 expandChildNodes : function(deep){
32825 var cs = this.childNodes;
32826 for(var i = 0, len = cs.length; i < len; i++) {
32827 cs[i].expand(deep);
32832 collapseChildNodes : function(deep){
32833 var cs = this.childNodes;
32834 for(var i = 0, len = cs.length; i < len; i++) {
32835 cs[i].collapse(deep);
32840 disable : function(){
32841 this.disabled = true;
32843 if(this.rendered && this.ui.onDisableChange){
32844 this.ui.onDisableChange(this, true);
32846 this.fireEvent('disabledchange', this, true);
32850 enable : function(){
32851 this.disabled = false;
32852 if(this.rendered && this.ui.onDisableChange){
32853 this.ui.onDisableChange(this, false);
32855 this.fireEvent('disabledchange', this, false);
32859 renderChildren : function(suppressEvent){
32860 if(suppressEvent !== false){
32861 this.fireEvent('beforechildrenrendered', this);
32863 var cs = this.childNodes;
32864 for(var i = 0, len = cs.length; i < len; i++){
32865 cs[i].render(true);
32867 this.childrenRendered = true;
32871 sort : function(fn, scope){
32872 Ext.tree.TreeNode.superclass.sort.apply(this, arguments);
32873 if(this.childrenRendered){
32874 var cs = this.childNodes;
32875 for(var i = 0, len = cs.length; i < len; i++){
32876 cs[i].render(true);
32882 render : function(bulkRender){
32883 this.ui.render(bulkRender);
32884 if(!this.rendered){
32886 this.getOwnerTree().registerNode(this);
32887 this.rendered = true;
32889 this.expanded = false;
32890 this.expand(false, false);
32896 renderIndent : function(deep, refresh){
32898 this.ui.childIndent = null;
32900 this.ui.renderIndent();
32901 if(deep === true && this.childrenRendered){
32902 var cs = this.childNodes;
32903 for(var i = 0, len = cs.length; i < len; i++){
32904 cs[i].renderIndent(true, refresh);
32909 beginUpdate : function(){
32910 this.childrenRendered = false;
32913 endUpdate : function(){
32914 if(this.expanded && this.rendered){
32915 this.renderChildren();
32920 destroy : function(silent){
32921 if(silent === true){
32922 this.unselect(true);
32924 Ext.tree.TreeNode.superclass.destroy.call(this, silent);
32925 Ext.destroy(this.ui, this.loader);
32926 this.ui = this.loader = null;
32930 onIdChange : function(id){
32931 this.ui.onIdChange(id);
32935 Ext.tree.TreePanel.nodeTypes.node = Ext.tree.TreeNode;
32936 Ext.tree.AsyncTreeNode = function(config){
32937 this.loaded = config && config.loaded === true;
32938 this.loading = false;
32939 Ext.tree.AsyncTreeNode.superclass.constructor.apply(this, arguments);
32941 this.addEvents('beforeload', 'load');
32945 Ext.extend(Ext.tree.AsyncTreeNode, Ext.tree.TreeNode, {
32946 expand : function(deep, anim, callback, scope){
32949 var f = function(){
32951 clearInterval(timer);
32952 this.expand(deep, anim, callback, scope);
32954 }.createDelegate(this);
32955 timer = setInterval(f, 200);
32959 if(this.fireEvent("beforeload", this) === false){
32962 this.loading = true;
32963 this.ui.beforeLoad(this);
32964 var loader = this.loader || this.attributes.loader || this.getOwnerTree().getLoader();
32966 loader.load(this, this.loadComplete.createDelegate(this, [deep, anim, callback, scope]), this);
32970 Ext.tree.AsyncTreeNode.superclass.expand.call(this, deep, anim, callback, scope);
32974 isLoading : function(){
32975 return this.loading;
32978 loadComplete : function(deep, anim, callback, scope){
32979 this.loading = false;
32980 this.loaded = true;
32981 this.ui.afterLoad(this);
32982 this.fireEvent("load", this);
32983 this.expand(deep, anim, callback, scope);
32987 isLoaded : function(){
32988 return this.loaded;
32991 hasChildNodes : function(){
32992 if(!this.isLeaf() && !this.loaded){
32995 return Ext.tree.AsyncTreeNode.superclass.hasChildNodes.call(this);
33000 reload : function(callback, scope){
33001 this.collapse(false, false);
33002 while(this.firstChild){
33003 this.removeChild(this.firstChild).destroy();
33005 this.childrenRendered = false;
33006 this.loaded = false;
33007 if(this.isHiddenRoot()){
33008 this.expanded = false;
33010 this.expand(false, false, callback, scope);
33014 Ext.tree.TreePanel.nodeTypes.async = Ext.tree.AsyncTreeNode;
33015 Ext.tree.TreeNodeUI = function(node){
33017 this.rendered = false;
33018 this.animating = false;
33019 this.wasLeaf = true;
33020 this.ecc = 'x-tree-ec-icon x-tree-elbow';
33021 this.emptyIcon = Ext.BLANK_IMAGE_URL;
33024 Ext.tree.TreeNodeUI.prototype = {
33026 removeChild : function(node){
33028 this.ctNode.removeChild(node.ui.getEl());
33033 beforeLoad : function(){
33034 this.addClass("x-tree-node-loading");
33038 afterLoad : function(){
33039 this.removeClass("x-tree-node-loading");
33043 onTextChange : function(node, text, oldText){
33045 this.textNode.innerHTML = text;
33050 onDisableChange : function(node, state){
33051 this.disabled = state;
33052 if (this.checkbox) {
33053 this.checkbox.disabled = state;
33056 this.addClass("x-tree-node-disabled");
33058 this.removeClass("x-tree-node-disabled");
33063 onSelectedChange : function(state){
33066 this.addClass("x-tree-selected");
33069 this.removeClass("x-tree-selected");
33074 onMove : function(tree, node, oldParent, newParent, index, refNode){
33075 this.childIndent = null;
33077 var targetNode = newParent.ui.getContainer();
33079 this.holder = document.createElement("div");
33080 this.holder.appendChild(this.wrap);
33083 var insertBefore = refNode ? refNode.ui.getEl() : null;
33085 targetNode.insertBefore(this.wrap, insertBefore);
33087 targetNode.appendChild(this.wrap);
33089 this.node.renderIndent(true, oldParent != newParent);
33094 addClass : function(cls){
33096 Ext.fly(this.elNode).addClass(cls);
33101 removeClass : function(cls){
33103 Ext.fly(this.elNode).removeClass(cls);
33108 remove : function(){
33110 this.holder = document.createElement("div");
33111 this.holder.appendChild(this.wrap);
33116 fireEvent : function(){
33117 return this.node.fireEvent.apply(this.node, arguments);
33121 initEvents : function(){
33122 this.node.on("move", this.onMove, this);
33124 if(this.node.disabled){
33125 this.onDisableChange(this.node, true);
33127 if(this.node.hidden){
33130 var ot = this.node.getOwnerTree();
33131 var dd = ot.enableDD || ot.enableDrag || ot.enableDrop;
33132 if(dd && (!this.node.isRoot || ot.rootVisible)){
33133 Ext.dd.Registry.register(this.elNode, {
33135 handles: this.getDDHandles(),
33142 getDDHandles : function(){
33143 return [this.iconNode, this.textNode, this.elNode];
33148 this.node.hidden = true;
33150 this.wrap.style.display = "none";
33156 this.node.hidden = false;
33158 this.wrap.style.display = "";
33163 onContextMenu : function(e){
33164 if (this.node.hasListener("contextmenu") || this.node.getOwnerTree().hasListener("contextmenu")) {
33165 e.preventDefault();
33167 this.fireEvent("contextmenu", this.node, e);
33172 onClick : function(e){
33177 if(this.fireEvent("beforeclick", this.node, e) !== false){
33178 var a = e.getTarget('a');
33179 if(!this.disabled && this.node.attributes.href && a){
33180 this.fireEvent("click", this.node, e);
33182 }else if(a && e.ctrlKey){
33185 e.preventDefault();
33190 if(this.node.attributes.singleClickExpand && !this.animating && this.node.isExpandable()){
33191 this.node.toggle();
33194 this.fireEvent("click", this.node, e);
33201 onDblClick : function(e){
33202 e.preventDefault();
33206 if(this.fireEvent("beforedblclick", this.node, e) !== false){
33208 this.toggleCheck();
33210 if(!this.animating && this.node.isExpandable()){
33211 this.node.toggle();
33213 this.fireEvent("dblclick", this.node, e);
33217 onOver : function(e){
33218 this.addClass('x-tree-node-over');
33221 onOut : function(e){
33222 this.removeClass('x-tree-node-over');
33226 onCheckChange : function(){
33227 var checked = this.checkbox.checked;
33229 this.checkbox.defaultChecked = checked;
33230 this.node.attributes.checked = checked;
33231 this.fireEvent('checkchange', this.node, checked);
33235 ecClick : function(e){
33236 if(!this.animating && this.node.isExpandable()){
33237 this.node.toggle();
33242 startDrop : function(){
33243 this.dropping = true;
33247 endDrop : function(){
33248 setTimeout(function(){
33249 this.dropping = false;
33250 }.createDelegate(this), 50);
33254 expand : function(){
33255 this.updateExpandIcon();
33256 this.ctNode.style.display = "";
33260 focus : function(){
33261 if(!this.node.preventHScroll){
33262 try{this.anchor.focus();
33266 var noscroll = this.node.getOwnerTree().getTreeEl().dom;
33267 var l = noscroll.scrollLeft;
33268 this.anchor.focus();
33269 noscroll.scrollLeft = l;
33275 toggleCheck : function(value){
33276 var cb = this.checkbox;
33278 cb.checked = (value === undefined ? !cb.checked : value);
33279 this.onCheckChange();
33286 this.anchor.blur();
33291 animExpand : function(callback){
33292 var ct = Ext.get(this.ctNode);
33294 if(!this.node.isExpandable()){
33295 this.updateExpandIcon();
33296 this.ctNode.style.display = "";
33297 Ext.callback(callback);
33300 this.animating = true;
33301 this.updateExpandIcon();
33304 callback : function(){
33305 this.animating = false;
33306 Ext.callback(callback);
33309 duration: this.node.ownerTree.duration || .25
33314 highlight : function(){
33315 var tree = this.node.getOwnerTree();
33316 Ext.fly(this.wrap).highlight(
33317 tree.hlColor || "C3DAF9",
33318 {endColor: tree.hlBaseColor}
33323 collapse : function(){
33324 this.updateExpandIcon();
33325 this.ctNode.style.display = "none";
33329 animCollapse : function(callback){
33330 var ct = Ext.get(this.ctNode);
33331 ct.enableDisplayMode('block');
33334 this.animating = true;
33335 this.updateExpandIcon();
33338 callback : function(){
33339 this.animating = false;
33340 Ext.callback(callback);
33343 duration: this.node.ownerTree.duration || .25
33348 getContainer : function(){
33349 return this.ctNode;
33353 getEl : function(){
33358 appendDDGhost : function(ghostNode){
33359 ghostNode.appendChild(this.elNode.cloneNode(true));
33363 getDDRepairXY : function(){
33364 return Ext.lib.Dom.getXY(this.iconNode);
33368 onRender : function(){
33373 render : function(bulkRender){
33374 var n = this.node, a = n.attributes;
33375 var targetNode = n.parentNode ?
33376 n.parentNode.ui.getContainer() : n.ownerTree.innerCt.dom;
33378 if(!this.rendered){
33379 this.rendered = true;
33381 this.renderElements(n, a, targetNode, bulkRender);
33384 if(this.textNode.setAttributeNS){
33385 this.textNode.setAttributeNS("ext", "qtip", a.qtip);
33387 this.textNode.setAttributeNS("ext", "qtitle", a.qtipTitle);
33390 this.textNode.setAttribute("ext:qtip", a.qtip);
33392 this.textNode.setAttribute("ext:qtitle", a.qtipTitle);
33395 }else if(a.qtipCfg){
33396 a.qtipCfg.target = Ext.id(this.textNode);
33397 Ext.QuickTips.register(a.qtipCfg);
33400 if(!this.node.expanded){
33401 this.updateExpandIcon(true);
33404 if(bulkRender === true) {
33405 targetNode.appendChild(this.wrap);
33411 renderElements : function(n, a, targetNode, bulkRender){
33413 this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
33415 var cb = Ext.isBoolean(a.checked),
33417 href = a.href ? a.href : Ext.isGecko ? "" : "#",
33418 buf = ['<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls,'" unselectable="on">',
33419 '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
33420 '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
33421 '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />',
33422 cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
33423 '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
33424 a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span unselectable="on">',n.text,"</span></a></div>",
33425 '<ul class="x-tree-node-ct" style="display:none;"></ul>',
33428 if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){
33429 this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
33431 this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
33434 this.elNode = this.wrap.childNodes[0];
33435 this.ctNode = this.wrap.childNodes[1];
33436 var cs = this.elNode.childNodes;
33437 this.indentNode = cs[0];
33438 this.ecNode = cs[1];
33439 this.iconNode = cs[2];
33442 this.checkbox = cs[3];
33444 this.checkbox.defaultChecked = this.checkbox.checked;
33447 this.anchor = cs[index];
33448 this.textNode = cs[index].firstChild;
33452 getAnchor : function(){
33453 return this.anchor;
33457 getTextEl : function(){
33458 return this.textNode;
33462 getIconEl : function(){
33463 return this.iconNode;
33467 isChecked : function(){
33468 return this.checkbox ? this.checkbox.checked : false;
33472 updateExpandIcon : function(){
33477 cls = n.isLast() ? "x-tree-elbow-end" : "x-tree-elbow",
33478 hasChild = n.hasChildNodes();
33479 if(hasChild || n.attributes.expandable){
33482 c1 = "x-tree-node-collapsed";
33483 c2 = "x-tree-node-expanded";
33486 c1 = "x-tree-node-expanded";
33487 c2 = "x-tree-node-collapsed";
33490 this.removeClass("x-tree-node-leaf");
33491 this.wasLeaf = false;
33493 if(this.c1 != c1 || this.c2 != c2){
33494 Ext.fly(this.elNode).replaceClass(c1, c2);
33495 this.c1 = c1; this.c2 = c2;
33499 Ext.fly(this.elNode).replaceClass("x-tree-node-expanded", "x-tree-node-collapsed");
33502 this.wasLeaf = true;
33505 var ecc = "x-tree-ec-icon "+cls;
33506 if(this.ecc != ecc){
33507 this.ecNode.className = ecc;
33514 onIdChange: function(id){
33516 this.elNode.setAttribute('ext:tree-node-id', id);
33521 getChildIndent : function(){
33522 if(!this.childIndent){
33526 if(!p.isRoot || (p.isRoot && p.ownerTree.rootVisible)){
33528 buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-elbow-line" />');
33530 buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-icon" />');
33535 this.childIndent = buf.join("");
33537 return this.childIndent;
33541 renderIndent : function(){
33544 p = this.node.parentNode;
33546 indent = p.ui.getChildIndent();
33548 if(this.indentMarkup != indent){
33549 this.indentNode.innerHTML = indent;
33550 this.indentMarkup = indent;
33552 this.updateExpandIcon();
33556 destroy : function(){
33558 Ext.dd.Registry.unregister(this.elNode.id);
33561 Ext.each(['textnode', 'anchor', 'checkbox', 'indentNode', 'ecNode', 'iconNode', 'elNode', 'ctNode', 'wrap', 'holder'], function(el){
33563 Ext.fly(this[el]).remove();
33572 Ext.tree.RootTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
33574 render : function(){
33575 if(!this.rendered){
33576 var targetNode = this.node.ownerTree.innerCt.dom;
33577 this.node.expanded = true;
33578 targetNode.innerHTML = '<div class="x-tree-root-node"></div>';
33579 this.wrap = this.ctNode = targetNode.firstChild;
33582 collapse : Ext.emptyFn,
33583 expand : Ext.emptyFn
33585 Ext.tree.TreeLoader = function(config){
33586 this.baseParams = {};
33587 Ext.apply(this, config);
33597 Ext.tree.TreeLoader.superclass.constructor.call(this);
33598 if(Ext.isString(this.paramOrder)){
33599 this.paramOrder = this.paramOrder.split(/[\s,|]/);
33603 Ext.extend(Ext.tree.TreeLoader, Ext.util.Observable, {
33614 clearOnLoad : true,
33617 paramOrder: undefined,
33620 paramsAsHash: false,
33623 nodeParameter: 'node',
33626 directFn : undefined,
33629 load : function(node, callback, scope){
33630 if(this.clearOnLoad){
33631 while(node.firstChild){
33632 node.removeChild(node.firstChild);
33635 if(this.doPreload(node)){
33636 this.runCallback(callback, scope || node, [node]);
33637 }else if(this.directFn || this.dataUrl || this.url){
33638 this.requestData(node, callback, scope || node);
33642 doPreload : function(node){
33643 if(node.attributes.children){
33644 if(node.childNodes.length < 1){
33645 var cs = node.attributes.children;
33646 node.beginUpdate();
33647 for(var i = 0, len = cs.length; i < len; i++){
33648 var cn = node.appendChild(this.createNode(cs[i]));
33649 if(this.preloadChildren){
33650 this.doPreload(cn);
33660 getParams: function(node){
33661 var bp = Ext.apply({}, this.baseParams),
33662 np = this.nodeParameter,
33663 po = this.paramOrder;
33665 np && (bp[ np ] = node.id);
33668 var buf = [node.id];
33671 if(np && po.indexOf(np) > -1){
33675 for(var i = 0, len = po.length; i < len; i++){
33676 buf.push(bp[ po[i] ]);
33678 }else if(this.paramsAsHash){
33687 requestData : function(node, callback, scope){
33688 if(this.fireEvent("beforeload", this, node, callback) !== false){
33690 var args = this.getParams(node);
33691 args.push(this.processDirectResponse.createDelegate(this, [{callback: callback, node: node, scope: scope}], true));
33692 this.directFn.apply(window, args);
33694 this.transId = Ext.Ajax.request({
33695 method:this.requestMethod,
33696 url: this.dataUrl||this.url,
33697 success: this.handleResponse,
33698 failure: this.handleFailure,
33700 argument: {callback: callback, node: node, scope: scope},
33701 params: this.getParams(node)
33707 this.runCallback(callback, scope || node, []);
33711 processDirectResponse: function(result, response, args){
33712 if(response.status){
33713 this.handleResponse({
33714 responseData: Ext.isArray(result) ? result : null,
33715 responseText: result,
33719 this.handleFailure({
33726 runCallback: function(cb, scope, args){
33727 if(Ext.isFunction(cb)){
33728 cb.apply(scope, args);
33732 isLoading : function(){
33733 return !!this.transId;
33736 abort : function(){
33737 if(this.isLoading()){
33738 Ext.Ajax.abort(this.transId);
33743 createNode : function(attr){
33745 if(this.baseAttrs){
33746 Ext.applyIf(attr, this.baseAttrs);
33748 if(this.applyLoader !== false && !attr.loader){
33749 attr.loader = this;
33751 if(Ext.isString(attr.uiProvider)){
33752 attr.uiProvider = this.uiProviders[attr.uiProvider] || eval(attr.uiProvider);
33755 return new Ext.tree.TreePanel.nodeTypes[attr.nodeType](attr);
33758 new Ext.tree.TreeNode(attr) :
33759 new Ext.tree.AsyncTreeNode(attr);
33763 processResponse : function(response, node, callback, scope){
33764 var json = response.responseText;
33766 var o = response.responseData || Ext.decode(json);
33767 node.beginUpdate();
33768 for(var i = 0, len = o.length; i < len; i++){
33769 var n = this.createNode(o[i]);
33771 node.appendChild(n);
33775 this.runCallback(callback, scope || node, [node]);
33777 this.handleFailure(response);
33781 handleResponse : function(response){
33782 this.transId = false;
33783 var a = response.argument;
33784 this.processResponse(response, a.node, a.callback, a.scope);
33785 this.fireEvent("load", this, a.node, response);
33788 handleFailure : function(response){
33789 this.transId = false;
33790 var a = response.argument;
33791 this.fireEvent("loadexception", this, a.node, response);
33792 this.runCallback(a.callback, a.scope || a.node, [a.node]);
33795 destroy : function(){
33797 this.purgeListeners();
33800 Ext.tree.TreeFilter = function(tree, config){
33802 this.filtered = {};
33803 Ext.apply(this, config);
33806 Ext.tree.TreeFilter.prototype = {
33813 filter : function(value, attr, startNode){
33814 attr = attr || "text";
33816 if(typeof value == "string"){
33817 var vlen = value.length;
33819 if(vlen == 0 && this.clearBlank){
33823 value = value.toLowerCase();
33825 return n.attributes[attr].substr(0, vlen).toLowerCase() == value;
33827 }else if(value.exec){
33829 return value.test(n.attributes[attr]);
33832 throw 'Illegal filter type, must be string or regex';
33834 this.filterBy(f, null, startNode);
33838 filterBy : function(fn, scope, startNode){
33839 startNode = startNode || this.tree.root;
33840 if(this.autoClear){
33843 var af = this.filtered, rv = this.reverse;
33844 var f = function(n){
33845 if(n == startNode){
33851 var m = fn.call(scope || n, n);
33859 startNode.cascade(f);
33862 if(typeof id != "function"){
33864 if(n && n.parentNode){
33865 n.parentNode.removeChild(n);
33873 clear : function(){
33875 var af = this.filtered;
33877 if(typeof id != "function"){
33884 this.filtered = {};
33888 Ext.tree.TreeSorter = function(tree, config){
33896 Ext.apply(this, config);
33897 tree.on("beforechildrenrendered", this.doSort, this);
33898 tree.on("append", this.updateSort, this);
33899 tree.on("insert", this.updateSort, this);
33900 tree.on("textchange", this.updateSortParent, this);
33902 var dsc = this.dir && this.dir.toLowerCase() == "desc";
33903 var p = this.property || "text";
33904 var sortType = this.sortType;
33905 var fs = this.folderSort;
33906 var cs = this.caseSensitive === true;
33907 var leafAttr = this.leafAttr || 'leaf';
33909 this.sortFn = function(n1, n2){
33911 if(n1.attributes[leafAttr] && !n2.attributes[leafAttr]){
33914 if(!n1.attributes[leafAttr] && n2.attributes[leafAttr]){
33918 var v1 = sortType ? sortType(n1) : (cs ? n1.attributes[p] : n1.attributes[p].toUpperCase());
33919 var v2 = sortType ? sortType(n2) : (cs ? n2.attributes[p] : n2.attributes[p].toUpperCase());
33921 return dsc ? +1 : -1;
33923 return dsc ? -1 : +1;
33930 Ext.tree.TreeSorter.prototype = {
33931 doSort : function(node){
33932 node.sort(this.sortFn);
33935 compareNodes : function(n1, n2){
33936 return (n1.text.toUpperCase() > n2.text.toUpperCase() ? 1 : -1);
33939 updateSort : function(tree, node){
33940 if(node.childrenRendered){
33941 this.doSort.defer(1, this, [node]);
33945 updateSortParent : function(node){
33946 var p = node.parentNode;
33947 if(p && p.childrenRendered){
33948 this.doSort.defer(1, this, [p]);
33952 if(Ext.dd.DropZone){
33954 Ext.tree.TreeDropZone = function(tree, config){
33956 this.allowParentInsert = config.allowParentInsert || false;
33958 this.allowContainerDrop = config.allowContainerDrop || false;
33960 this.appendOnly = config.appendOnly || false;
33962 Ext.tree.TreeDropZone.superclass.constructor.call(this, tree.getTreeEl(), config);
33966 this.dragOverData = {};
33968 this.lastInsertClass = "x-tree-no-status";
33971 Ext.extend(Ext.tree.TreeDropZone, Ext.dd.DropZone, {
33973 ddGroup : "TreeDD",
33976 expandDelay : 1000,
33979 expandNode : function(node){
33980 if(node.hasChildNodes() && !node.isExpanded()){
33981 node.expand(false, null, this.triggerCacheRefresh.createDelegate(this));
33986 queueExpand : function(node){
33987 this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]);
33991 cancelExpand : function(){
33992 if(this.expandProcId){
33993 clearTimeout(this.expandProcId);
33994 this.expandProcId = false;
33999 isValidDropPoint : function(n, pt, dd, e, data){
34000 if(!n || !data){ return false; }
34001 var targetNode = n.node;
34002 var dropNode = data.node;
34004 if(!(targetNode && targetNode.isTarget && pt)){
34007 if(pt == "append" && targetNode.allowChildren === false){
34010 if((pt == "above" || pt == "below") && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){
34013 if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){
34017 var overEvent = this.dragOverData;
34018 overEvent.tree = this.tree;
34019 overEvent.target = targetNode;
34020 overEvent.data = data;
34021 overEvent.point = pt;
34022 overEvent.source = dd;
34023 overEvent.rawEvent = e;
34024 overEvent.dropNode = dropNode;
34025 overEvent.cancel = false;
34026 var result = this.tree.fireEvent("nodedragover", overEvent);
34027 return overEvent.cancel === false && result !== false;
34031 getDropPoint : function(e, n, dd){
34034 return tn.allowChildren !== false ? "append" : false;
34036 var dragEl = n.ddel;
34037 var t = Ext.lib.Dom.getY(dragEl), b = t + dragEl.offsetHeight;
34038 var y = Ext.lib.Event.getPageY(e);
34039 var noAppend = tn.allowChildren === false || tn.isLeaf();
34040 if(this.appendOnly || tn.parentNode.allowChildren === false){
34041 return noAppend ? false : "append";
34043 var noBelow = false;
34044 if(!this.allowParentInsert){
34045 noBelow = tn.hasChildNodes() && tn.isExpanded();
34047 var q = (b - t) / (noAppend ? 2 : 3);
34048 if(y >= t && y < (t + q)){
34050 }else if(!noBelow && (noAppend || y >= b-q && y <= b)){
34058 onNodeEnter : function(n, dd, e, data){
34059 this.cancelExpand();
34062 onContainerOver : function(dd, e, data) {
34063 if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) {
34064 return this.dropAllowed;
34066 return this.dropNotAllowed;
34070 onNodeOver : function(n, dd, e, data){
34071 var pt = this.getDropPoint(e, n, dd);
34075 if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){
34076 this.queueExpand(node);
34077 }else if(pt != "append"){
34078 this.cancelExpand();
34082 var returnCls = this.dropNotAllowed;
34083 if(this.isValidDropPoint(n, pt, dd, e, data)){
34088 returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between";
34089 cls = "x-tree-drag-insert-above";
34090 }else if(pt == "below"){
34091 returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between";
34092 cls = "x-tree-drag-insert-below";
34094 returnCls = "x-tree-drop-ok-append";
34095 cls = "x-tree-drag-append";
34097 if(this.lastInsertClass != cls){
34098 Ext.fly(el).replaceClass(this.lastInsertClass, cls);
34099 this.lastInsertClass = cls;
34107 onNodeOut : function(n, dd, e, data){
34108 this.cancelExpand();
34109 this.removeDropIndicators(n);
34113 onNodeDrop : function(n, dd, e, data){
34114 var point = this.getDropPoint(e, n, dd);
34115 var targetNode = n.node;
34116 targetNode.ui.startDrop();
34117 if(!this.isValidDropPoint(n, point, dd, e, data)){
34118 targetNode.ui.endDrop();
34122 var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
34123 return this.processDrop(targetNode, data, point, dd, e, dropNode);
34126 onContainerDrop : function(dd, e, data){
34127 if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) {
34128 var targetNode = this.tree.getRootNode();
34129 targetNode.ui.startDrop();
34130 var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, 'append', e) : null);
34131 return this.processDrop(targetNode, data, 'append', dd, e, dropNode);
34137 processDrop: function(target, data, point, dd, e, dropNode){
34145 dropNode: dropNode,
34149 var retval = this.tree.fireEvent("beforenodedrop", dropEvent);
34150 if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
34151 target.ui.endDrop();
34152 return dropEvent.dropStatus;
34155 target = dropEvent.target;
34156 if(point == 'append' && !target.isExpanded()){
34157 target.expand(false, null, function(){
34158 this.completeDrop(dropEvent);
34159 }.createDelegate(this));
34161 this.completeDrop(dropEvent);
34167 completeDrop : function(de){
34168 var ns = de.dropNode, p = de.point, t = de.target;
34169 if(!Ext.isArray(ns)){
34173 for(var i = 0, len = ns.length; i < len; i++){
34176 t.parentNode.insertBefore(n, t);
34177 }else if(p == "below"){
34178 t.parentNode.insertBefore(n, t.nextSibling);
34184 if(Ext.enableFx && this.tree.hlDrop){
34188 this.tree.fireEvent("nodedrop", de);
34192 afterNodeMoved : function(dd, data, e, targetNode, dropNode){
34193 if(Ext.enableFx && this.tree.hlDrop){
34194 dropNode.ui.focus();
34195 dropNode.ui.highlight();
34197 this.tree.fireEvent("nodedrop", this.tree, targetNode, data, dd, e);
34201 getTree : function(){
34206 removeDropIndicators : function(n){
34209 Ext.fly(el).removeClass([
34210 "x-tree-drag-insert-above",
34211 "x-tree-drag-insert-below",
34212 "x-tree-drag-append"]);
34213 this.lastInsertClass = "_noclass";
34218 beforeDragDrop : function(target, e, id){
34219 this.cancelExpand();
34224 afterRepair : function(data){
34225 if(data && Ext.enableFx){
34226 data.node.ui.highlight();
34233 if(Ext.dd.DragZone){
34234 Ext.tree.TreeDragZone = function(tree, config){
34235 Ext.tree.TreeDragZone.superclass.constructor.call(this, tree.innerCt, config);
34240 Ext.extend(Ext.tree.TreeDragZone, Ext.dd.DragZone, {
34242 ddGroup : "TreeDD",
34245 onBeforeDrag : function(data, e){
34247 return n && n.draggable && !n.disabled;
34251 onInitDrag : function(e){
34252 var data = this.dragData;
34253 this.tree.getSelectionModel().select(data.node);
34254 this.tree.eventModel.disable();
34255 this.proxy.update("");
34256 data.node.ui.appendDDGhost(this.proxy.ghost.dom);
34257 this.tree.fireEvent("startdrag", this.tree, data.node, e);
34261 getRepairXY : function(e, data){
34262 return data.node.ui.getDDRepairXY();
34266 onEndDrag : function(data, e){
34267 this.tree.eventModel.enable.defer(100, this.tree.eventModel);
34268 this.tree.fireEvent("enddrag", this.tree, data.node, e);
34272 onValidDrop : function(dd, e, id){
34273 this.tree.fireEvent("dragdrop", this.tree, this.dragData.node, dd, e);
34278 beforeInvalidDrop : function(e, id){
34280 var sm = this.tree.getSelectionModel();
34281 sm.clearSelections();
34282 sm.select(this.dragData.node);
34286 afterRepair : function(){
34287 if (Ext.enableFx && this.tree.hlDrop) {
34288 Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9");
34290 this.dragging = false;
34294 Ext.tree.TreeEditor = function(tree, fc, config){
34296 var field = fc.events ? fc : new Ext.form.TextField(fc);
34298 Ext.tree.TreeEditor.superclass.constructor.call(this, field, config);
34302 if(!tree.rendered){
34303 tree.on('render', this.initEditor, this);
34305 this.initEditor(tree);
34309 Ext.extend(Ext.tree.TreeEditor, Ext.Editor, {
34317 cls: "x-small-editor x-tree-editor",
34327 initEditor : function(tree){
34330 beforeclick: this.beforeNodeClick,
34331 dblclick : this.onNodeDblClick
34336 complete : this.updateNode,
34337 beforestartedit: this.fitToTree,
34338 specialkey : this.onSpecialKey
34341 this.on('startedit', this.bindScroll, this, {delay:10});
34345 fitToTree : function(ed, el){
34346 var td = this.tree.getTreeEl().dom, nd = el.dom;
34347 if(td.scrollLeft > nd.offsetLeft){
34348 td.scrollLeft = nd.offsetLeft;
34352 (td.clientWidth > 20 ? td.clientWidth : td.offsetWidth) - Math.max(0, nd.offsetLeft-td.scrollLeft) - 5);
34353 this.setSize(w, '');
34357 triggerEdit : function(node, defer){
34358 this.completeEdit();
34359 if(node.attributes.editable !== false){
34361 this.editNode = node;
34362 if(this.tree.autoScroll){
34363 Ext.fly(node.ui.getEl()).scrollIntoView(this.tree.body);
34365 var value = node.text || '';
34366 if (!Ext.isGecko && Ext.isEmpty(node.text)){
34367 node.setText(' ');
34369 this.autoEditTimer = this.startEdit.defer(this.editDelay, this, [node.ui.textNode, value]);
34375 bindScroll : function(){
34376 this.tree.getTreeEl().on('scroll', this.cancelEdit, this);
34380 beforeNodeClick : function(node, e){
34381 clearTimeout(this.autoEditTimer);
34382 if(this.tree.getSelectionModel().isSelected(node)){
34384 return this.triggerEdit(node);
34388 onNodeDblClick : function(node, e){
34389 clearTimeout(this.autoEditTimer);
34393 updateNode : function(ed, value){
34394 this.tree.getTreeEl().un('scroll', this.cancelEdit, this);
34395 this.editNode.setText(value);
34399 onHide : function(){
34400 Ext.tree.TreeEditor.superclass.onHide.call(this);
34402 this.editNode.ui.focus.defer(50, this.editNode.ui);
34407 onSpecialKey : function(field, e){
34408 var k = e.getKey();
34412 }else if(k == e.ENTER && !e.hasModifier()){
34414 this.completeEdit();
34418 onDestroy : function(){
34419 clearTimeout(this.autoEditTimer);
34420 Ext.tree.TreeEditor.superclass.onDestroy.call(this);
34421 var tree = this.tree;
34422 tree.un('beforeclick', this.beforeNodeClick, this);
34423 tree.un('dblclick', this.onNodeDblClick, this);
34427 var swfobject = function() {
34429 var UNDEF = "undefined",
34431 SHOCKWAVE_FLASH = "Shockwave Flash",
34432 SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash",
34433 FLASH_MIME_TYPE = "application/x-shockwave-flash",
34434 EXPRESS_INSTALL_ID = "SWFObjectExprInst",
34435 ON_READY_STATE_CHANGE = "onreadystatechange",
34442 domLoadFnArr = [main],
34447 storedAltContentId,
34450 isDomLoaded = false,
34451 isExpressInstallActive = false,
34453 dynamicStylesheetMedia,
34454 autoHideShow = true,
34458 var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF,
34459 u = nav.userAgent.toLowerCase(),
34460 p = nav.platform.toLowerCase(),
34461 windows = p ? /win/.test(p) : /win/.test(u),
34462 mac = p ? /mac/.test(p) : /mac/.test(u),
34463 webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false,
34465 playerVersion = [0,0,0],
34467 if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) {
34468 d = nav.plugins[SHOCKWAVE_FLASH].description;
34469 if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) {
34472 d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
34473 playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10);
34474 playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10);
34475 playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0;
34478 else if (typeof win.ActiveXObject != UNDEF) {
34480 var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);
34482 d = a.GetVariable("$version");
34485 d = d.split(" ")[1].split(",");
34486 playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
34492 return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac };
34496 onDomLoad = function() {
34497 if (!ua.w3) { return; }
34498 if ((typeof doc.readyState != UNDEF && doc.readyState == "complete") || (typeof doc.readyState == UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) {
34499 callDomLoadFunctions();
34501 if (!isDomLoaded) {
34502 if (typeof doc.addEventListener != UNDEF) {
34503 doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false);
34505 if (ua.ie && ua.win) {
34506 doc.attachEvent(ON_READY_STATE_CHANGE, function() {
34507 if (doc.readyState == "complete") {
34508 doc.detachEvent(ON_READY_STATE_CHANGE, arguments.callee);
34509 callDomLoadFunctions();
34514 if (isDomLoaded) { return; }
34516 doc.documentElement.doScroll("left");
34519 setTimeout(arguments.callee, 0);
34522 callDomLoadFunctions();
34528 if (isDomLoaded) { return; }
34529 if (!/loaded|complete/.test(doc.readyState)) {
34530 setTimeout(arguments.callee, 0);
34533 callDomLoadFunctions();
34536 addLoadEvent(callDomLoadFunctions);
34540 function callDomLoadFunctions() {
34541 if (isDomLoaded) { return; }
34543 var t = doc.getElementsByTagName("body")[0].appendChild(createElement("span"));
34544 t.parentNode.removeChild(t);
34546 catch (e) { return; }
34547 isDomLoaded = true;
34548 var dl = domLoadFnArr.length;
34549 for (var i = 0; i < dl; i++) {
34554 function addDomLoadEvent(fn) {
34559 domLoadFnArr[domLoadFnArr.length] = fn;
34564 function addLoadEvent(fn) {
34565 if (typeof win.addEventListener != UNDEF) {
34566 win.addEventListener("load", fn, false);
34568 else if (typeof doc.addEventListener != UNDEF) {
34569 doc.addEventListener("load", fn, false);
34571 else if (typeof win.attachEvent != UNDEF) {
34572 addListener(win, "onload", fn);
34574 else if (typeof win.onload == "function") {
34575 var fnOld = win.onload;
34576 win.onload = function() {
34589 testPlayerVersion();
34597 function testPlayerVersion() {
34598 var b = doc.getElementsByTagName("body")[0];
34599 var o = createElement(OBJECT);
34600 o.setAttribute("type", FLASH_MIME_TYPE);
34601 var t = b.appendChild(o);
34605 if (typeof t.GetVariable != UNDEF) {
34606 var d = t.GetVariable("$version");
34608 d = d.split(" ")[1].split(",");
34609 ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
34612 else if (counter < 10) {
34614 setTimeout(arguments.callee, 10);
34628 function matchVersions() {
34629 var rl = regObjArr.length;
34631 for (var i = 0; i < rl; i++) {
34632 var id = regObjArr[i].id;
34633 var cb = regObjArr[i].callbackFn;
34634 var cbObj = {success:false, id:id};
34635 if (ua.pv[0] > 0) {
34636 var obj = getElementById(id);
34638 if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) {
34639 setVisibility(id, true);
34641 cbObj.success = true;
34642 cbObj.ref = getObjectById(id);
34646 else if (regObjArr[i].expressInstall && canExpressInstall()) {
34648 att.data = regObjArr[i].expressInstall;
34649 att.width = obj.getAttribute("width") || "0";
34650 att.height = obj.getAttribute("height") || "0";
34651 if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); }
34652 if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); }
34655 var p = obj.getElementsByTagName("param");
34657 for (var j = 0; j < pl; j++) {
34658 if (p[j].getAttribute("name").toLowerCase() != "movie") {
34659 par[p[j].getAttribute("name")] = p[j].getAttribute("value");
34662 showExpressInstall(att, par, id, cb);
34665 displayAltContent(obj);
34666 if (cb) { cb(cbObj); }
34671 setVisibility(id, true);
34673 var o = getObjectById(id);
34674 if (o && typeof o.SetVariable != UNDEF) {
34675 cbObj.success = true;
34685 function getObjectById(objectIdStr) {
34687 var o = getElementById(objectIdStr);
34688 if (o && o.nodeName == "OBJECT") {
34689 if (typeof o.SetVariable != UNDEF) {
34693 var n = o.getElementsByTagName(OBJECT)[0];
34703 function canExpressInstall() {
34704 return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312);
34708 function showExpressInstall(att, par, replaceElemIdStr, callbackFn) {
34709 isExpressInstallActive = true;
34710 storedCallbackFn = callbackFn || null;
34711 storedCallbackObj = {success:false, id:replaceElemIdStr};
34712 var obj = getElementById(replaceElemIdStr);
34714 if (obj.nodeName == "OBJECT") {
34715 storedAltContent = abstractAltContent(obj);
34716 storedAltContentId = null;
34719 storedAltContent = obj;
34720 storedAltContentId = replaceElemIdStr;
34722 att.id = EXPRESS_INSTALL_ID;
34723 if (typeof att.width == UNDEF || (!/%$/.test(att.width) && parseInt(att.width, 10) < 310)) { att.width = "310"; }
34724 if (typeof att.height == UNDEF || (!/%$/.test(att.height) && parseInt(att.height, 10) < 137)) { att.height = "137"; }
34725 doc.title = doc.title.slice(0, 47) + " - Flash Player Installation";
34726 var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn",
34727 fv = "MMredirectURL=" + win.location.toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title;
34728 if (typeof par.flashvars != UNDEF) {
34729 par.flashvars += "&" + fv;
34732 par.flashvars = fv;
34736 if (ua.ie && ua.win && obj.readyState != 4) {
34737 var newObj = createElement("div");
34738 replaceElemIdStr += "SWFObjectNew";
34739 newObj.setAttribute("id", replaceElemIdStr);
34740 obj.parentNode.insertBefore(newObj, obj);
34741 obj.style.display = "none";
34743 if (obj.readyState == 4) {
34744 obj.parentNode.removeChild(obj);
34747 setTimeout(arguments.callee, 10);
34751 createSWF(att, par, replaceElemIdStr);
34756 function displayAltContent(obj) {
34757 if (ua.ie && ua.win && obj.readyState != 4) {
34760 var el = createElement("div");
34761 obj.parentNode.insertBefore(el, obj);
34762 el.parentNode.replaceChild(abstractAltContent(obj), el);
34763 obj.style.display = "none";
34765 if (obj.readyState == 4) {
34766 obj.parentNode.removeChild(obj);
34769 setTimeout(arguments.callee, 10);
34774 obj.parentNode.replaceChild(abstractAltContent(obj), obj);
34778 function abstractAltContent(obj) {
34779 var ac = createElement("div");
34780 if (ua.win && ua.ie) {
34781 ac.innerHTML = obj.innerHTML;
34784 var nestedObj = obj.getElementsByTagName(OBJECT)[0];
34786 var c = nestedObj.childNodes;
34789 for (var i = 0; i < cl; i++) {
34790 if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) {
34791 ac.appendChild(c[i].cloneNode(true));
34801 function createSWF(attObj, parObj, id) {
34802 var r, el = getElementById(id);
34803 if (ua.wk && ua.wk < 312) { return r; }
34805 if (typeof attObj.id == UNDEF) {
34808 if (ua.ie && ua.win) {
34810 for (var i in attObj) {
34811 if (attObj[i] != Object.prototype[i]) {
34812 if (i.toLowerCase() == "data") {
34813 parObj.movie = attObj[i];
34815 else if (i.toLowerCase() == "styleclass") {
34816 att += ' class="' + attObj[i] + '"';
34818 else if (i.toLowerCase() != "classid") {
34819 att += ' ' + i + '="' + attObj[i] + '"';
34824 for (var j in parObj) {
34825 if (parObj[j] != Object.prototype[j]) {
34826 par += '<param name="' + j + '" value="' + parObj[j] + '" />';
34829 el.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + '>' + par + '</object>';
34830 objIdArr[objIdArr.length] = attObj.id;
34831 r = getElementById(attObj.id);
34834 var o = createElement(OBJECT);
34835 o.setAttribute("type", FLASH_MIME_TYPE);
34836 for (var m in attObj) {
34837 if (attObj[m] != Object.prototype[m]) {
34838 if (m.toLowerCase() == "styleclass") {
34839 o.setAttribute("class", attObj[m]);
34841 else if (m.toLowerCase() != "classid") {
34842 o.setAttribute(m, attObj[m]);
34846 for (var n in parObj) {
34847 if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") {
34848 createObjParam(o, n, parObj[n]);
34851 el.parentNode.replaceChild(o, el);
34858 function createObjParam(el, pName, pValue) {
34859 var p = createElement("param");
34860 p.setAttribute("name", pName);
34861 p.setAttribute("value", pValue);
34866 function removeSWF(id) {
34867 var obj = getElementById(id);
34868 if (obj && obj.nodeName == "OBJECT") {
34869 if (ua.ie && ua.win) {
34870 obj.style.display = "none";
34872 if (obj.readyState == 4) {
34873 removeObjectInIE(id);
34876 setTimeout(arguments.callee, 10);
34881 obj.parentNode.removeChild(obj);
34886 function removeObjectInIE(id) {
34887 var obj = getElementById(id);
34889 for (var i in obj) {
34890 if (typeof obj[i] == "function") {
34894 obj.parentNode.removeChild(obj);
34899 function getElementById(id) {
34902 el = doc.getElementById(id);
34908 function createElement(el) {
34909 return doc.createElement(el);
34913 function addListener(target, eventType, fn) {
34914 target.attachEvent(eventType, fn);
34915 listenersArr[listenersArr.length] = [target, eventType, fn];
34919 function hasPlayerVersion(rv) {
34920 var pv = ua.pv, v = rv.split(".");
34921 v[0] = parseInt(v[0], 10);
34922 v[1] = parseInt(v[1], 10) || 0;
34923 v[2] = parseInt(v[2], 10) || 0;
34924 return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false;
34928 function createCSS(sel, decl, media, newStyle) {
34929 if (ua.ie && ua.mac) { return; }
34930 var h = doc.getElementsByTagName("head")[0];
34931 if (!h) { return; }
34932 var m = (media && typeof media == "string") ? media : "screen";
34934 dynamicStylesheet = null;
34935 dynamicStylesheetMedia = null;
34937 if (!dynamicStylesheet || dynamicStylesheetMedia != m) {
34939 var s = createElement("style");
34940 s.setAttribute("type", "text/css");
34941 s.setAttribute("media", m);
34942 dynamicStylesheet = h.appendChild(s);
34943 if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) {
34944 dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];
34946 dynamicStylesheetMedia = m;
34949 if (ua.ie && ua.win) {
34950 if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) {
34951 dynamicStylesheet.addRule(sel, decl);
34955 if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) {
34956 dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}"));
34961 function setVisibility(id, isVisible) {
34962 if (!autoHideShow) { return; }
34963 var v = isVisible ? "visible" : "hidden";
34964 if (isDomLoaded && getElementById(id)) {
34965 getElementById(id).style.visibility = v;
34968 createCSS("#" + id, "visibility:" + v);
34973 function urlEncodeIfNecessary(s) {
34974 var regex = /[\\\"<>\.;]/;
34975 var hasBadChars = regex.exec(s) != null;
34976 return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s;
34980 var cleanup = function() {
34981 if (ua.ie && ua.win) {
34982 window.attachEvent("onunload", function() {
34984 var ll = listenersArr.length;
34985 for (var i = 0; i < ll; i++) {
34986 listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);
34989 var il = objIdArr.length;
34990 for (var j = 0; j < il; j++) {
34991 removeSWF(objIdArr[j]);
34994 for (var k in ua) {
34998 for (var l in swfobject) {
34999 swfobject[l] = null;
35008 registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) {
35009 if (ua.w3 && objectIdStr && swfVersionStr) {
35011 regObj.id = objectIdStr;
35012 regObj.swfVersion = swfVersionStr;
35013 regObj.expressInstall = xiSwfUrlStr;
35014 regObj.callbackFn = callbackFn;
35015 regObjArr[regObjArr.length] = regObj;
35016 setVisibility(objectIdStr, false);
35018 else if (callbackFn) {
35019 callbackFn({success:false, id:objectIdStr});
35023 getObjectById: function(objectIdStr) {
35025 return getObjectById(objectIdStr);
35029 embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {
35030 var callbackObj = {success:false, id:replaceElemIdStr};
35031 if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) {
35032 setVisibility(replaceElemIdStr, false);
35033 addDomLoadEvent(function() {
35037 if (attObj && typeof attObj === OBJECT) {
35038 for (var i in attObj) {
35039 att[i] = attObj[i];
35042 att.data = swfUrlStr;
35043 att.width = widthStr;
35044 att.height = heightStr;
35046 if (parObj && typeof parObj === OBJECT) {
35047 for (var j in parObj) {
35048 par[j] = parObj[j];
35051 if (flashvarsObj && typeof flashvarsObj === OBJECT) {
35052 for (var k in flashvarsObj) {
35053 if (typeof par.flashvars != UNDEF) {
35054 par.flashvars += "&" + k + "=" + flashvarsObj[k];
35057 par.flashvars = k + "=" + flashvarsObj[k];
35061 if (hasPlayerVersion(swfVersionStr)) {
35062 var obj = createSWF(att, par, replaceElemIdStr);
35063 if (att.id == replaceElemIdStr) {
35064 setVisibility(replaceElemIdStr, true);
35066 callbackObj.success = true;
35067 callbackObj.ref = obj;
35069 else if (xiSwfUrlStr && canExpressInstall()) {
35070 att.data = xiSwfUrlStr;
35071 showExpressInstall(att, par, replaceElemIdStr, callbackFn);
35075 setVisibility(replaceElemIdStr, true);
35077 if (callbackFn) { callbackFn(callbackObj); }
35080 else if (callbackFn) { callbackFn(callbackObj); }
35083 switchOffAutoHideShow: function() {
35084 autoHideShow = false;
35089 getFlashPlayerVersion: function() {
35090 return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] };
35093 hasFlashPlayerVersion: hasPlayerVersion,
35095 createSWF: function(attObj, parObj, replaceElemIdStr) {
35097 return createSWF(attObj, parObj, replaceElemIdStr);
35104 showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) {
35105 if (ua.w3 && canExpressInstall()) {
35106 showExpressInstall(att, par, replaceElemIdStr, callbackFn);
35110 removeSWF: function(objElemIdStr) {
35112 removeSWF(objElemIdStr);
35116 createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) {
35118 createCSS(selStr, declStr, mediaStr, newStyleBoolean);
35122 addDomLoadEvent: addDomLoadEvent,
35124 addLoadEvent: addLoadEvent,
35126 getQueryParamValue: function(param) {
35127 var q = doc.location.search || doc.location.hash;
35129 if (/\?/.test(q)) { q = q.split("?")[1]; }
35130 if (param == null) {
35131 return urlEncodeIfNecessary(q);
35133 var pairs = q.split("&");
35134 for (var i = 0; i < pairs.length; i++) {
35135 if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
35136 return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1)));
35144 expressInstallCallback: function() {
35145 if (isExpressInstallActive) {
35146 var obj = getElementById(EXPRESS_INSTALL_ID);
35147 if (obj && storedAltContent) {
35148 obj.parentNode.replaceChild(storedAltContent, obj);
35149 if (storedAltContentId) {
35150 setVisibility(storedAltContentId, true);
35151 if (ua.ie && ua.win) { storedAltContent.style.display = "block"; }
35153 if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); }
35155 isExpressInstallActive = false;
35161 Ext.FlashComponent = Ext.extend(Ext.BoxComponent, {
35163 flashVersion : '9.0.115',
35166 backgroundColor: '#ffffff',
35172 flashVars: undefined,
35175 flashParams: undefined,
35184 expressInstall: false,
35186 initComponent : function(){
35187 Ext.FlashComponent.superclass.initComponent.call(this);
35195 onRender : function(){
35196 Ext.FlashComponent.superclass.onRender.apply(this, arguments);
35198 var params = Ext.apply({
35199 allowScriptAccess: 'always',
35200 bgcolor: this.backgroundColor,
35202 }, this.flashParams), vars = Ext.apply({
35203 allowedDomain: document.location.hostname,
35204 YUISwfId: this.getId(),
35205 YUIBridgeCallback: 'Ext.FlashEventProxy.onEvent'
35206 }, this.flashVars);
35208 new swfobject.embedSWF(this.url, this.id, this.swfWidth, this.swfHeight, this.flashVersion,
35209 this.expressInstall ? Ext.FlashComponent.EXPRESS_INSTALL_URL : undefined, vars, params);
35211 this.swf = Ext.getDom(this.id);
35212 this.el = Ext.get(this.swf);
35215 getSwfId : function(){
35216 return this.swfId || (this.swfId = "extswf" + (++Ext.Component.AUTO_ID));
35219 getId : function(){
35220 return this.id || (this.id = "extflashcmp" + (++Ext.Component.AUTO_ID));
35223 onFlashEvent : function(e){
35231 e.component = this;
35232 this.fireEvent(e.type.toLowerCase().replace(/event$/, ''), e);
35235 initSwf : function(){
35236 this.onSwfReady(!!this.isInitialized);
35237 this.isInitialized = true;
35238 this.fireEvent('initialize', this);
35241 beforeDestroy: function(){
35243 swfobject.removeSWF(this.swf.id);
35245 Ext.FlashComponent.superclass.beforeDestroy.call(this);
35248 onSwfReady : Ext.emptyFn
35252 Ext.FlashComponent.EXPRESS_INSTALL_URL = 'http:/' + '/swfobject.googlecode.com/svn/trunk/swfobject/expressInstall.swf';
35254 Ext.reg('flash', Ext.FlashComponent);
35255 Ext.FlashEventProxy = {
35256 onEvent : function(id, e){
35257 var fp = Ext.getCmp(id);
35259 fp.onFlashEvent(e);
35261 arguments.callee.defer(10, this, [id, e]);
35266 Ext.chart.Chart = Ext.extend(Ext.FlashComponent, {
35267 refreshBuffer: 100,
35274 animationEnabled: true,
35305 seriesStyles: null,
35308 disableCaching: Ext.isIE || Ext.isOpera,
35309 disableCacheParam: '_dc',
35311 initComponent : function(){
35312 Ext.chart.Chart.superclass.initComponent.call(this);
35314 this.url = Ext.chart.Chart.CHART_URL;
35316 if(this.disableCaching){
35317 this.url = Ext.urlAppend(this.url, String.format('{0}={1}', this.disableCacheParam, new Date().getTime()));
35332 this.store = Ext.StoreMgr.lookup(this.store);
35336 setStyle: function(name, value){
35337 this.swf.setStyle(name, Ext.encode(value));
35341 setStyles: function(styles){
35342 this.swf.setStyles(Ext.encode(styles));
35346 setSeriesStyles: function(styles){
35347 this.seriesStyles = styles;
35349 Ext.each(styles, function(style){
35350 s.push(Ext.encode(style));
35352 this.swf.setSeriesStyles(s);
35355 setCategoryNames : function(names){
35356 this.swf.setCategoryNames(names);
35359 setLegendRenderer : function(fn, scope){
35361 scope = scope || chart;
35362 chart.removeFnProxy(chart.legendFnName);
35363 chart.legendFnName = chart.createFnProxy(function(name){
35364 return fn.call(scope, name);
35366 chart.swf.setLegendLabelFunction(chart.legendFnName);
35369 setTipRenderer : function(fn, scope){
35371 scope = scope || chart;
35372 chart.removeFnProxy(chart.tipFnName);
35373 chart.tipFnName = chart.createFnProxy(function(item, index, series){
35374 var record = chart.store.getAt(index);
35375 return fn.call(scope, chart, record, index, series);
35377 chart.swf.setDataTipFunction(chart.tipFnName);
35380 setSeries : function(series){
35381 this.series = series;
35386 bindStore : function(store, initial){
35387 if(!initial && this.store){
35388 if(store !== this.store && this.store.autoDestroy){
35389 this.store.destroy();
35391 this.store.un("datachanged", this.refresh, this);
35392 this.store.un("add", this.delayRefresh, this);
35393 this.store.un("remove", this.delayRefresh, this);
35394 this.store.un("update", this.delayRefresh, this);
35395 this.store.un("clear", this.refresh, this);
35399 store = Ext.StoreMgr.lookup(store);
35402 datachanged: this.refresh,
35403 add: this.delayRefresh,
35404 remove: this.delayRefresh,
35405 update: this.delayRefresh,
35406 clear: this.refresh
35409 this.store = store;
35410 if(store && !initial){
35415 onSwfReady : function(isReset){
35416 Ext.chart.Chart.superclass.onSwfReady.call(this, isReset);
35418 this.swf.setType(this.type);
35420 if(this.chartStyle){
35421 this.setStyles(Ext.apply({}, this.extraStyle, this.chartStyle));
35424 if(this.categoryNames){
35425 this.setCategoryNames(this.categoryNames);
35428 if(this.tipRenderer){
35429 ref = this.getFunctionRef(this.tipRenderer);
35430 this.setTipRenderer(ref.fn, ref.scope);
35432 if(this.legendRenderer){
35433 ref = this.getFunctionRef(this.legendRenderer);
35434 this.setLegendRenderer(ref.fn, ref.scope);
35437 this.bindStore(this.store, true);
35439 this.refresh.defer(10, this);
35442 delayRefresh : function(){
35443 if(!this.refreshTask){
35444 this.refreshTask = new Ext.util.DelayedTask(this.refresh, this);
35446 this.refreshTask.delay(this.refreshBuffer);
35449 refresh : function(){
35450 if(this.fireEvent('beforerefresh', this) !== false){
35451 var styleChanged = false;
35453 var data = [], rs = this.store.data.items;
35454 for(var j = 0, len = rs.length; j < len; j++){
35455 data[j] = rs[j].data;
35459 var dataProvider = [];
35460 var seriesCount = 0;
35461 var currentSeries = null;
35464 seriesCount = this.series.length;
35465 for(i = 0; i < seriesCount; i++){
35466 currentSeries = this.series[i];
35467 var clonedSeries = {};
35468 for(var prop in currentSeries){
35469 if(prop == "style" && currentSeries.style !== null){
35470 clonedSeries.style = Ext.encode(currentSeries.style);
35471 styleChanged = true;
35477 clonedSeries[prop] = currentSeries[prop];
35480 dataProvider.push(clonedSeries);
35484 if(seriesCount > 0){
35485 for(i = 0; i < seriesCount; i++){
35486 currentSeries = dataProvider[i];
35487 if(!currentSeries.type){
35488 currentSeries.type = this.type;
35490 currentSeries.dataProvider = data;
35493 dataProvider.push({type: this.type, dataProvider: data});
35495 this.swf.setDataProvider(dataProvider);
35496 if(this.seriesStyles){
35497 this.setSeriesStyles(this.seriesStyles);
35499 this.fireEvent('refresh', this);
35504 createFnProxy : function(fn){
35505 var fnName = 'extFnProxy' + (++Ext.chart.Chart.PROXY_FN_ID);
35506 Ext.chart.Chart.proxyFunction[fnName] = fn;
35507 return 'Ext.chart.Chart.proxyFunction.' + fnName;
35511 removeFnProxy : function(fn){
35512 if(!Ext.isEmpty(fn)){
35513 fn = fn.replace('Ext.chart.Chart.proxyFunction.', '');
35514 delete Ext.chart.Chart.proxyFunction[fn];
35519 getFunctionRef : function(val){
35520 if(Ext.isFunction(val)){
35528 scope: val.scope || this
35534 onDestroy: function(){
35535 if (this.refreshTask && this.refreshTask.cancel){
35536 this.refreshTask.cancel();
35538 Ext.chart.Chart.superclass.onDestroy.call(this);
35539 this.bindStore(null);
35540 this.removeFnProxy(this.tipFnName);
35541 this.removeFnProxy(this.legendFnName);
35544 Ext.reg('chart', Ext.chart.Chart);
35545 Ext.chart.Chart.PROXY_FN_ID = 0;
35546 Ext.chart.Chart.proxyFunction = {};
35549 Ext.chart.Chart.CHART_URL = 'http:/' + '/yui.yahooapis.com/2.8.0/build/charts/assets/charts.swf';
35552 Ext.chart.PieChart = Ext.extend(Ext.chart.Chart, {
35555 onSwfReady : function(isReset){
35556 Ext.chart.PieChart.superclass.onSwfReady.call(this, isReset);
35558 this.setDataField(this.dataField);
35559 this.setCategoryField(this.categoryField);
35562 setDataField : function(field){
35563 this.dataField = field;
35564 this.swf.setDataField(field);
35567 setCategoryField : function(field){
35568 this.categoryField = field;
35569 this.swf.setCategoryField(field);
35572 Ext.reg('piechart', Ext.chart.PieChart);
35575 Ext.chart.CartesianChart = Ext.extend(Ext.chart.Chart, {
35576 onSwfReady : function(isReset){
35577 Ext.chart.CartesianChart.superclass.onSwfReady.call(this, isReset);
35580 this.setXField(this.xField);
35583 this.setYField(this.yField);
35586 this.setXAxis(this.xAxis);
35589 this.setXAxes(this.xAxes);
35592 this.setYAxis(this.yAxis);
35595 this.setYAxes(this.yAxes);
35597 if(Ext.isDefined(this.constrainViewport)){
35598 this.swf.setConstrainViewport(this.constrainViewport);
35602 setXField : function(value){
35603 this.xField = value;
35604 this.swf.setHorizontalField(value);
35607 setYField : function(value){
35608 this.yField = value;
35609 this.swf.setVerticalField(value);
35612 setXAxis : function(value){
35613 this.xAxis = this.createAxis('xAxis', value);
35614 this.swf.setHorizontalAxis(this.xAxis);
35617 setXAxes : function(value){
35619 for(var i = 0; i < value.length; i++) {
35620 axis = this.createAxis('xAxis' + i, value[i]);
35621 this.swf.setHorizontalAxis(axis);
35625 setYAxis : function(value){
35626 this.yAxis = this.createAxis('yAxis', value);
35627 this.swf.setVerticalAxis(this.yAxis);
35630 setYAxes : function(value){
35632 for(var i = 0; i < value.length; i++) {
35633 axis = this.createAxis('yAxis' + i, value[i]);
35634 this.swf.setVerticalAxis(axis);
35638 createAxis : function(axis, value){
35639 var o = Ext.apply({}, value),
35644 old = this[axis].labelFunction;
35645 this.removeFnProxy(old);
35646 this.labelFn.remove(old);
35648 if(o.labelRenderer){
35649 ref = this.getFunctionRef(o.labelRenderer);
35650 o.labelFunction = this.createFnProxy(function(v){
35651 return ref.fn.call(ref.scope, v);
35653 delete o.labelRenderer;
35654 this.labelFn.push(o.labelFunction);
35656 if(axis.indexOf('xAxis') > -1 && o.position == 'left'){
35657 o.position = 'bottom';
35662 onDestroy : function(){
35663 Ext.chart.CartesianChart.superclass.onDestroy.call(this);
35664 Ext.each(this.labelFn, function(fn){
35665 this.removeFnProxy(fn);
35669 Ext.reg('cartesianchart', Ext.chart.CartesianChart);
35672 Ext.chart.LineChart = Ext.extend(Ext.chart.CartesianChart, {
35675 Ext.reg('linechart', Ext.chart.LineChart);
35678 Ext.chart.ColumnChart = Ext.extend(Ext.chart.CartesianChart, {
35681 Ext.reg('columnchart', Ext.chart.ColumnChart);
35684 Ext.chart.StackedColumnChart = Ext.extend(Ext.chart.CartesianChart, {
35685 type: 'stackcolumn'
35687 Ext.reg('stackedcolumnchart', Ext.chart.StackedColumnChart);
35690 Ext.chart.BarChart = Ext.extend(Ext.chart.CartesianChart, {
35693 Ext.reg('barchart', Ext.chart.BarChart);
35696 Ext.chart.StackedBarChart = Ext.extend(Ext.chart.CartesianChart, {
35699 Ext.reg('stackedbarchart', Ext.chart.StackedBarChart);
35704 Ext.chart.Axis = function(config){
35705 Ext.apply(this, config);
35708 Ext.chart.Axis.prototype =
35714 orientation: "horizontal",
35720 labelFunction: null,
35723 hideOverlappingLabels: true,
35730 Ext.chart.NumericAxis = Ext.extend(Ext.chart.Axis, {
35749 alwaysShowZero: true,
35755 roundMajorUnit: true,
35758 calculateByLabelSize: true,
35764 adjustMaximumByMajorUnit: true,
35767 adjustMinimumByMajorUnit: true
35772 Ext.chart.TimeAxis = Ext.extend(Ext.chart.Axis, {
35785 majorTimeUnit: null,
35791 minorTimeUnit: null,
35797 stackingEnabled: false,
35800 calculateByLabelSize: true
35805 Ext.chart.CategoryAxis = Ext.extend(Ext.chart.Axis, {
35809 categoryNames: null,
35812 calculateCategoryCount: false
35817 Ext.chart.Series = function(config) { Ext.apply(this, config); };
35819 Ext.chart.Series.prototype =
35829 Ext.chart.CartesianSeries = Ext.extend(Ext.chart.Series, {
35837 showInLegend: true,
35844 Ext.chart.ColumnSeries = Ext.extend(Ext.chart.CartesianSeries, {
35849 Ext.chart.LineSeries = Ext.extend(Ext.chart.CartesianSeries, {
35854 Ext.chart.BarSeries = Ext.extend(Ext.chart.CartesianSeries, {
35860 Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, {
35863 categoryField: null
35865 Ext.menu.Menu = Ext.extend(Ext.Container, {
35873 subMenuAlign : 'tl-tr?',
35875 defaultAlign : 'tl-bl?',
35877 allowOtherMenus : false,
35879 ignoreParentClicks : false,
35881 enableScrolling : true,
35885 scrollIncrement : 24,
35887 showSeparator : true,
35889 defaultOffsets : [0, 0],
35906 hideMode : 'offsets',
35907 scrollerHeight : 8,
35909 defaultType : 'menuitem',
35910 bufferResize : false,
35912 initComponent : function(){
35913 if(Ext.isArray(this.initialConfig)){
35914 Ext.apply(this, {items:this.initialConfig});
35926 Ext.menu.MenuMgr.register(this);
35928 Ext.EventManager.onWindowResize(this.hide, this);
35930 if(this.initialConfig.hidden !== false){
35931 this.hidden = false;
35933 this.internalDefaults = {hideOnClick: false};
35935 Ext.menu.Menu.superclass.initComponent.call(this);
35936 if(this.autoLayout){
35937 var fn = this.doLayout.createDelegate(this, []);
35946 getLayoutTarget : function() {
35951 onRender : function(ct, position){
35953 ct = Ext.getBody();
35958 cls: 'x-menu ' + ((this.floating) ? 'x-menu-floating x-layer ' : '') + (this.cls || '') + (this.plain ? ' x-menu-plain' : '') + (this.showSeparator ? '' : ' x-menu-nosep'),
35961 {tag: 'a', cls: 'x-menu-focus', href: '#', onclick: 'return false;', tabIndex: '-1'},
35962 {tag: 'ul', cls: 'x-menu-list'}
35966 this.el = new Ext.Layer({
35967 shadow: this.shadow,
35971 zindex: this.zIndex
35974 this.el = ct.createChild(dh);
35976 Ext.menu.Menu.superclass.onRender.call(this, ct, position);
35979 this.keyNav = new Ext.menu.MenuNav(this);
35982 this.focusEl = this.el.child('a.x-menu-focus');
35983 this.ul = this.el.child('ul.x-menu-list');
35984 this.mon(this.ul, {
35986 click: this.onClick,
35987 mouseover: this.onMouseOver,
35988 mouseout: this.onMouseOut
35990 if(this.enableScrolling){
35991 this.mon(this.el, {
35993 delegate: '.x-menu-scroller',
35994 click: this.onScroll,
35995 mouseover: this.deactivateActive
36001 findTargetItem : function(e){
36002 var t = e.getTarget('.x-menu-list-item', this.ul, true);
36003 if(t && t.menuItemId){
36004 return this.items.get(t.menuItemId);
36009 onClick : function(e){
36010 var t = this.findTargetItem(e);
36013 this.setActiveItem(t);
36014 }else if(t instanceof Ext.menu.BaseItem){
36015 if(t.menu && this.ignoreParentClicks){
36017 e.preventDefault();
36018 }else if(t.onClick){
36020 this.fireEvent('click', this, t, e);
36027 setActiveItem : function(item, autoExpand){
36028 if(item != this.activeItem){
36029 this.deactivateActive();
36030 if((this.activeItem = item).isFormField){
36033 item.activate(autoExpand);
36035 }else if(autoExpand){
36040 deactivateActive : function(){
36041 var a = this.activeItem;
36051 delete this.activeItem;
36056 tryActivate : function(start, step){
36057 var items = this.items;
36058 for(var i = start, len = items.length; i >= 0 && i < len; i+= step){
36059 var item = items.get(i);
36060 if(!item.disabled && (item.canActivate || item.isFormField)){
36061 this.setActiveItem(item, false);
36069 onMouseOver : function(e){
36070 var t = this.findTargetItem(e);
36072 if(t.canActivate && !t.disabled){
36073 this.setActiveItem(t, true);
36077 this.fireEvent('mouseover', this, e, t);
36081 onMouseOut : function(e){
36082 var t = this.findTargetItem(e);
36084 if(t == this.activeItem && t.shouldDeactivate && t.shouldDeactivate(e)){
36085 this.activeItem.deactivate();
36086 delete this.activeItem;
36090 this.fireEvent('mouseout', this, e, t);
36094 onScroll : function(e, t){
36098 var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top');
36099 ul.scrollTop += this.scrollIncrement * (top ? -1 : 1);
36100 if(top ? ul.scrollTop <= 0 : ul.scrollTop + this.activeMax >= ul.scrollHeight){
36101 this.onScrollerOut(null, t);
36106 onScrollerIn : function(e, t){
36107 var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top');
36108 if(top ? ul.scrollTop > 0 : ul.scrollTop + this.activeMax < ul.scrollHeight){
36109 Ext.fly(t).addClass(['x-menu-item-active', 'x-menu-scroller-active']);
36114 onScrollerOut : function(e, t){
36115 Ext.fly(t).removeClass(['x-menu-item-active', 'x-menu-scroller-active']);
36119 show : function(el, pos, parentMenu){
36121 this.parentMenu = parentMenu;
36124 this.doLayout(false, true);
36126 this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign, this.defaultOffsets), parentMenu);
36128 Ext.menu.Menu.superclass.show.call(this);
36133 showAt : function(xy, parentMenu){
36134 if(this.fireEvent('beforeshow', this) !== false){
36135 this.parentMenu = parentMenu;
36139 if(this.enableScrolling){
36143 xy[1] = this.constrainScroll(xy[1]);
36144 xy = [this.el.adjustForConstraints(xy)[0], xy[1]];
36147 xy = this.el.adjustForConstraints(xy);
36151 Ext.menu.Menu.superclass.onShow.call(this);
36154 this.fireEvent('autosize', this);
36159 this.hidden = false;
36161 this.fireEvent('show', this);
36165 constrainScroll : function(y){
36166 var max, full = this.ul.setHeight('auto').getHeight(),
36167 returnY = y, normalY, parentEl, scrollTop, viewHeight;
36169 parentEl = Ext.fly(this.el.dom.parentNode);
36170 scrollTop = parentEl.getScroll().top;
36171 viewHeight = parentEl.getViewSize().height;
36174 normalY = y - scrollTop;
36175 max = this.maxHeight ? this.maxHeight : viewHeight - normalY;
36176 if(full > viewHeight) {
36179 returnY = y - normalY;
36180 } else if(max < full) {
36181 returnY = y - (full - max);
36185 max = this.getHeight();
36188 if (this.maxHeight){
36189 max = Math.min(this.maxHeight, max);
36191 if(full > max && max > 0){
36192 this.activeMax = max - this.scrollerHeight * 2 - this.el.getFrameWidth('tb') - Ext.num(this.el.shadowOffset, 0);
36193 this.ul.setHeight(this.activeMax);
36194 this.createScrollers();
36195 this.el.select('.x-menu-scroller').setDisplayed('');
36197 this.ul.setHeight(full);
36198 this.el.select('.x-menu-scroller').setDisplayed('none');
36200 this.ul.dom.scrollTop = 0;
36204 createScrollers : function(){
36205 if(!this.scroller){
36208 top: this.el.insertFirst({
36210 cls: 'x-menu-scroller x-menu-scroller-top',
36213 bottom: this.el.createChild({
36215 cls: 'x-menu-scroller x-menu-scroller-bottom',
36219 this.scroller.top.hover(this.onScrollerIn, this.onScrollerOut, this);
36220 this.scroller.topRepeater = new Ext.util.ClickRepeater(this.scroller.top, {
36222 click: this.onScroll.createDelegate(this, [null, this.scroller.top], false)
36225 this.scroller.bottom.hover(this.onScrollerIn, this.onScrollerOut, this);
36226 this.scroller.bottomRepeater = new Ext.util.ClickRepeater(this.scroller.bottom, {
36228 click: this.onScroll.createDelegate(this, [null, this.scroller.bottom], false)
36234 onLayout : function(){
36235 if(this.isVisible()){
36236 if(this.enableScrolling){
36237 this.constrainScroll(this.el.getTop());
36245 focus : function(){
36247 this.doFocus.defer(50, this);
36251 doFocus : function(){
36253 this.focusEl.focus();
36258 hide : function(deep){
36259 if (!this.isDestroyed) {
36260 this.deepHide = deep;
36261 Ext.menu.Menu.superclass.hide.call(this);
36262 delete this.deepHide;
36267 onHide : function(){
36268 Ext.menu.Menu.superclass.onHide.call(this);
36269 this.deactivateActive();
36270 if(this.el && this.floating){
36273 var pm = this.parentMenu;
36274 if(this.deepHide === true && pm){
36278 pm.deactivateActive();
36284 lookupComponent : function(c){
36285 if(Ext.isString(c)){
36286 c = (c == 'separator' || c == '-') ? new Ext.menu.Separator() : new Ext.menu.TextItem(c);
36287 this.applyDefaults(c);
36289 if(Ext.isObject(c)){
36290 c = this.getMenuItem(c);
36291 }else if(c.tagName || c.el){
36292 c = new Ext.BoxComponent({
36300 applyDefaults : function(c){
36301 if(!Ext.isString(c)){
36302 c = Ext.menu.Menu.superclass.applyDefaults.call(this, c);
36303 var d = this.internalDefaults;
36306 Ext.applyIf(c.initialConfig, d);
36317 getMenuItem : function(config){
36318 if(!config.isXType){
36319 if(!config.xtype && Ext.isBoolean(config.checked)){
36320 return new Ext.menu.CheckItem(config)
36322 return Ext.create(config, this.defaultType);
36328 addSeparator : function(){
36329 return this.add(new Ext.menu.Separator());
36333 addElement : function(el){
36334 return this.add(new Ext.menu.BaseItem({
36340 addItem : function(item){
36341 return this.add(item);
36345 addMenuItem : function(config){
36346 return this.add(this.getMenuItem(config));
36350 addText : function(text){
36351 return this.add(new Ext.menu.TextItem(text));
36355 onDestroy : function(){
36356 Ext.EventManager.removeResizeListener(this.hide, this);
36357 var pm = this.parentMenu;
36358 if(pm && pm.activeChild == this){
36359 delete pm.activeChild;
36361 delete this.parentMenu;
36362 Ext.menu.Menu.superclass.onDestroy.call(this);
36363 Ext.menu.MenuMgr.unregister(this);
36365 this.keyNav.disable();
36367 var s = this.scroller;
36369 Ext.destroy(s.topRepeater, s.bottomRepeater, s.top, s.bottom);
36379 Ext.reg('menu', Ext.menu.Menu);
36382 Ext.menu.MenuNav = Ext.extend(Ext.KeyNav, function(){
36384 if(!m.tryActivate(m.items.indexOf(m.activeItem)-1, -1)){
36385 m.tryActivate(m.items.length-1, -1);
36388 function down(e, m){
36389 if(!m.tryActivate(m.items.indexOf(m.activeItem)+1, 1)){
36390 m.tryActivate(0, 1);
36394 constructor : function(menu){
36395 Ext.menu.MenuNav.superclass.constructor.call(this, menu.el);
36396 this.scope = this.menu = menu;
36399 doRelay : function(e, h){
36400 var k = e.getKey();
36402 if (this.menu.activeItem && this.menu.activeItem.isFormField && k != e.TAB) {
36405 if(!this.menu.activeItem && e.isNavKeyPress() && k != e.SPACE && k != e.RETURN){
36406 this.menu.tryActivate(0, 1);
36409 return h.call(this.scope || this, e, this.menu);
36412 tab: function(e, m) {
36425 right : function(e, m){
36427 m.activeItem.expandMenu(true);
36431 left : function(e, m){
36433 if(m.parentMenu && m.parentMenu.activeItem){
36434 m.parentMenu.activeItem.activate();
36438 enter : function(e, m){
36440 e.stopPropagation();
36441 m.activeItem.onClick(e);
36442 m.fireEvent('click', this, m.activeItem);
36449 Ext.menu.MenuMgr = function(){
36450 var menus, active, groups = {}, attached = false, lastShow = new Date();
36455 active = new Ext.util.MixedCollection();
36456 Ext.getDoc().addKeyListener(27, function(){
36457 if(active.length > 0){
36464 function hideAll(){
36465 if(active && active.length > 0){
36466 var c = active.clone();
36467 c.each(function(m){
36476 function onHide(m){
36478 if(active.length < 1){
36479 Ext.getDoc().un("mousedown", onMouseDown);
36485 function onShow(m){
36486 var last = active.last();
36487 lastShow = new Date();
36490 Ext.getDoc().on("mousedown", onMouseDown);
36494 m.getEl().setZIndex(parseInt(m.parentMenu.getEl().getStyle("z-index"), 10) + 3);
36495 m.parentMenu.activeChild = m;
36496 }else if(last && !last.isDestroyed && last.isVisible()){
36497 m.getEl().setZIndex(parseInt(last.getEl().getStyle("z-index"), 10) + 3);
36502 function onBeforeHide(m){
36504 m.activeChild.hide();
36506 if(m.autoHideTimer){
36507 clearTimeout(m.autoHideTimer);
36508 delete m.autoHideTimer;
36513 function onBeforeShow(m){
36514 var pm = m.parentMenu;
36515 if(!pm && !m.allowOtherMenus){
36517 }else if(pm && pm.activeChild){
36518 pm.activeChild.hide();
36523 function onMouseDown(e){
36524 if(lastShow.getElapsed() > 50 && active.length > 0 && !e.getTarget(".x-menu")){
36530 function onBeforeCheck(mi, state){
36532 var g = groups[mi.group];
36533 for(var i = 0, l = g.length; i < l; i++){
36535 g[i].setChecked(false);
36544 hideAll : function(){
36549 register : function(menu){
36553 menus[menu.id] = menu;
36555 beforehide: onBeforeHide,
36557 beforeshow: onBeforeShow,
36563 get : function(menu){
36564 if(typeof menu == "string"){
36568 return menus[menu];
36569 }else if(menu.events){
36571 }else if(typeof menu.length == 'number'){
36572 return new Ext.menu.Menu({items:menu});
36574 return Ext.create(menu, 'menu');
36579 unregister : function(menu){
36580 delete menus[menu.id];
36581 menu.un("beforehide", onBeforeHide);
36582 menu.un("hide", onHide);
36583 menu.un("beforeshow", onBeforeShow);
36584 menu.un("show", onShow);
36588 registerCheckable : function(menuItem){
36589 var g = menuItem.group;
36594 groups[g].push(menuItem);
36595 menuItem.on("beforecheckchange", onBeforeCheck);
36600 unregisterCheckable : function(menuItem){
36601 var g = menuItem.group;
36603 groups[g].remove(menuItem);
36604 menuItem.un("beforecheckchange", onBeforeCheck);
36608 getCheckedItem : function(groupId){
36609 var g = groups[groupId];
36611 for(var i = 0, l = g.length; i < l; i++){
36620 setCheckedItem : function(groupId, itemId){
36621 var g = groups[groupId];
36623 for(var i = 0, l = g.length; i < l; i++){
36624 if(g[i].id == itemId){
36625 g[i].setChecked(true);
36634 Ext.menu.BaseItem = Ext.extend(Ext.Component, {
36639 canActivate : false,
36641 activeClass : "x-menu-item-active",
36643 hideOnClick : true,
36645 clickHideDelay : 1,
36648 ctype : "Ext.menu.BaseItem",
36651 actionMode : "container",
36653 initComponent : function(){
36654 Ext.menu.BaseItem.superclass.initComponent.call(this);
36664 this.on("click", this.handler, this.scope);
36669 onRender : function(container, position){
36670 Ext.menu.BaseItem.superclass.onRender.apply(this, arguments);
36671 if(this.ownerCt && this.ownerCt instanceof Ext.menu.Menu){
36672 this.parentMenu = this.ownerCt;
36674 this.container.addClass('x-menu-list-item');
36675 this.mon(this.el, {
36677 click: this.onClick,
36678 mouseenter: this.activate,
36679 mouseleave: this.deactivate
36685 setHandler : function(handler, scope){
36687 this.un("click", this.handler, this.scope);
36689 this.on("click", this.handler = handler, this.scope = scope);
36693 onClick : function(e){
36694 if(!this.disabled && this.fireEvent("click", this, e) !== false
36695 && (this.parentMenu && this.parentMenu.fireEvent("itemclick", this, e) !== false)){
36696 this.handleClick(e);
36703 activate : function(){
36707 var li = this.container;
36708 li.addClass(this.activeClass);
36709 this.region = li.getRegion().adjust(2, 2, -2, -2);
36710 this.fireEvent("activate", this);
36715 deactivate : function(){
36716 this.container.removeClass(this.activeClass);
36717 this.fireEvent("deactivate", this);
36721 shouldDeactivate : function(e){
36722 return !this.region || !this.region.contains(e.getPoint());
36726 handleClick : function(e){
36727 var pm = this.parentMenu;
36728 if(this.hideOnClick){
36730 pm.hide.defer(this.clickHideDelay, pm, [true]);
36732 pm.deactivateActive();
36738 expandMenu : Ext.emptyFn,
36741 hideMenu : Ext.emptyFn
36743 Ext.reg('menubaseitem', Ext.menu.BaseItem);
36744 Ext.menu.TextItem = Ext.extend(Ext.menu.BaseItem, {
36747 hideOnClick : false,
36749 itemCls : "x-menu-text",
36751 constructor : function(config){
36752 if(typeof config == 'string'){
36753 config = {text: config}
36755 Ext.menu.TextItem.superclass.constructor.call(this, config);
36759 onRender : function(){
36760 var s = document.createElement("span");
36761 s.className = this.itemCls;
36762 s.innerHTML = this.text;
36764 Ext.menu.TextItem.superclass.onRender.apply(this, arguments);
36767 Ext.reg('menutextitem', Ext.menu.TextItem);
36768 Ext.menu.Separator = Ext.extend(Ext.menu.BaseItem, {
36770 itemCls : "x-menu-sep",
36772 hideOnClick : false,
36778 onRender : function(li){
36779 var s = document.createElement("span");
36780 s.className = this.itemCls;
36781 s.innerHTML = " ";
36783 li.addClass("x-menu-sep-li");
36784 Ext.menu.Separator.superclass.onRender.apply(this, arguments);
36787 Ext.reg('menuseparator', Ext.menu.Separator);
36788 Ext.menu.Item = Ext.extend(Ext.menu.BaseItem, {
36797 itemCls : 'x-menu-item',
36799 canActivate : true,
36806 ctype: 'Ext.menu.Item',
36808 initComponent : function(){
36809 Ext.menu.Item.superclass.initComponent.call(this);
36811 this.menu = Ext.menu.MenuMgr.get(this.menu);
36812 this.menu.ownerCt = this;
36817 onRender : function(container, position){
36818 if (!this.itemTpl) {
36819 this.itemTpl = Ext.menu.Item.prototype.itemTpl = new Ext.XTemplate(
36820 '<a id="{id}" class="{cls}" hidefocus="true" unselectable="on" href="{href}"',
36821 '<tpl if="hrefTarget">',
36822 ' target="{hrefTarget}"',
36825 '<img src="{icon}" class="x-menu-item-icon {iconCls}"/>',
36826 '<span class="x-menu-item-text">{text}</span>',
36830 var a = this.getTemplateArgs();
36831 this.el = position ? this.itemTpl.insertBefore(position, a, true) : this.itemTpl.append(container, a, true);
36832 this.iconEl = this.el.child('img.x-menu-item-icon');
36833 this.textEl = this.el.child('.x-menu-item-text');
36835 this.mon(this.el, 'click', Ext.emptyFn, null, { preventDefault: true });
36837 Ext.menu.Item.superclass.onRender.call(this, container, position);
36840 getTemplateArgs: function() {
36843 cls: this.itemCls + (this.menu ? ' x-menu-item-arrow' : '') + (this.cls ? ' ' + this.cls : ''),
36844 href: this.href || '#',
36845 hrefTarget: this.hrefTarget,
36846 icon: this.icon || Ext.BLANK_IMAGE_URL,
36847 iconCls: this.iconCls || '',
36848 text: this.itemText||this.text||' '
36853 setText : function(text){
36854 this.text = text||' ';
36856 this.textEl.update(this.text);
36857 this.parentMenu.layout.doAutoSize();
36862 setIconClass : function(cls){
36863 var oldCls = this.iconCls;
36864 this.iconCls = cls;
36866 this.iconEl.replaceClass(oldCls, this.iconCls);
36871 beforeDestroy: function(){
36873 delete this.menu.ownerCt;
36874 this.menu.destroy();
36876 Ext.menu.Item.superclass.beforeDestroy.call(this);
36880 handleClick : function(e){
36884 Ext.menu.Item.superclass.handleClick.apply(this, arguments);
36888 activate : function(autoExpand){
36889 if(Ext.menu.Item.superclass.activate.apply(this, arguments)){
36899 shouldDeactivate : function(e){
36900 if(Ext.menu.Item.superclass.shouldDeactivate.call(this, e)){
36901 if(this.menu && this.menu.isVisible()){
36902 return !this.menu.getEl().getRegion().contains(e.getPoint());
36910 deactivate : function(){
36911 Ext.menu.Item.superclass.deactivate.apply(this, arguments);
36916 expandMenu : function(autoActivate){
36917 if(!this.disabled && this.menu){
36918 clearTimeout(this.hideTimer);
36919 delete this.hideTimer;
36920 if(!this.menu.isVisible() && !this.showTimer){
36921 this.showTimer = this.deferExpand.defer(this.showDelay, this, [autoActivate]);
36922 }else if (this.menu.isVisible() && autoActivate){
36923 this.menu.tryActivate(0, 1);
36929 deferExpand : function(autoActivate){
36930 delete this.showTimer;
36931 this.menu.show(this.container, this.parentMenu.subMenuAlign || 'tl-tr?', this.parentMenu);
36933 this.menu.tryActivate(0, 1);
36938 hideMenu : function(){
36939 clearTimeout(this.showTimer);
36940 delete this.showTimer;
36941 if(!this.hideTimer && this.menu && this.menu.isVisible()){
36942 this.hideTimer = this.deferHide.defer(this.hideDelay, this);
36947 deferHide : function(){
36948 delete this.hideTimer;
36949 if(this.menu.over){
36950 this.parentMenu.setActiveItem(this, false);
36956 Ext.reg('menuitem', Ext.menu.Item);
36957 Ext.menu.CheckItem = Ext.extend(Ext.menu.Item, {
36960 itemCls : "x-menu-item x-menu-check-item",
36962 groupClass : "x-menu-group-item",
36968 ctype: "Ext.menu.CheckItem",
36970 initComponent : function(){
36971 Ext.menu.CheckItem.superclass.initComponent.call(this);
36974 "beforecheckchange" ,
36979 if(this.checkHandler){
36980 this.on('checkchange', this.checkHandler, this.scope);
36982 Ext.menu.MenuMgr.registerCheckable(this);
36986 onRender : function(c){
36987 Ext.menu.CheckItem.superclass.onRender.apply(this, arguments);
36989 this.el.addClass(this.groupClass);
36992 this.checked = false;
36993 this.setChecked(true, true);
36998 destroy : function(){
36999 Ext.menu.MenuMgr.unregisterCheckable(this);
37000 Ext.menu.CheckItem.superclass.destroy.apply(this, arguments);
37004 setChecked : function(state, suppressEvent){
37005 var suppress = suppressEvent === true;
37006 if(this.checked != state && (suppress || this.fireEvent("beforecheckchange", this, state) !== false)){
37007 if(this.container){
37008 this.container[state ? "addClass" : "removeClass"]("x-menu-item-checked");
37010 this.checked = state;
37012 this.fireEvent("checkchange", this, state);
37018 handleClick : function(e){
37019 if(!this.disabled && !(this.checked && this.group)){
37020 this.setChecked(!this.checked);
37022 Ext.menu.CheckItem.superclass.handleClick.apply(this, arguments);
37025 Ext.reg('menucheckitem', Ext.menu.CheckItem);
37026 Ext.menu.DateMenu = Ext.extend(Ext.menu.Menu, {
37028 enableScrolling : false,
37032 hideOnClick : true,
37040 cls : 'x-date-menu',
37046 initComponent : function(){
37047 this.on('beforeshow', this.onBeforeShow, this);
37048 if(this.strict = (Ext.isIE7 && Ext.isStrict)){
37049 this.on('show', this.onShow, this, {single: true, delay: 20});
37053 showSeparator: false,
37054 items: this.picker = new Ext.DatePicker(Ext.applyIf({
37055 internalRender: this.strict || !Ext.isIE,
37056 ctCls: 'x-menu-date-item',
37058 }, this.initialConfig))
37060 this.picker.purgeListeners();
37061 Ext.menu.DateMenu.superclass.initComponent.call(this);
37063 this.relayEvents(this.picker, ['select']);
37064 this.on('show', this.picker.focus, this.picker);
37065 this.on('select', this.menuHide, this);
37067 this.on('select', this.handler, this.scope || this);
37071 menuHide : function() {
37072 if(this.hideOnClick){
37077 onBeforeShow : function(){
37079 this.picker.hideMonthPicker(true);
37083 onShow : function(){
37084 var el = this.picker.getEl();
37085 el.setWidth(el.getWidth());
37088 Ext.reg('datemenu', Ext.menu.DateMenu);
37090 Ext.menu.ColorMenu = Ext.extend(Ext.menu.Menu, {
37092 enableScrolling : false,
37097 hideOnClick : true,
37099 cls : 'x-color-menu',
37113 initComponent : function(){
37116 showSeparator: false,
37117 items: this.palette = new Ext.ColorPalette(Ext.applyIf({
37119 }, this.initialConfig))
37121 this.palette.purgeListeners();
37122 Ext.menu.ColorMenu.superclass.initComponent.call(this);
37124 this.relayEvents(this.palette, ['select']);
37125 this.on('select', this.menuHide, this);
37127 this.on('select', this.handler, this.scope || this);
37131 menuHide : function(){
37132 if(this.hideOnClick){
37137 Ext.reg('colormenu', Ext.menu.ColorMenu);
37139 Ext.form.Field = Ext.extend(Ext.BoxComponent, {
37148 invalidClass : 'x-form-invalid',
37150 invalidText : 'The value in this field is invalid',
37152 focusClass : 'x-form-focus',
37155 validationEvent : 'keyup',
37157 validateOnBlur : true,
37159 validationDelay : 250,
37161 defaultAutoCreate : {tag: 'input', type: 'text', size: '20', autocomplete: 'off'},
37163 fieldClass : 'x-form-field',
37165 msgTarget : 'qtip',
37176 isFormField : true,
37185 initComponent : function(){
37186 Ext.form.Field.superclass.initComponent.call(this);
37204 getName : function(){
37205 return this.rendered && this.el.dom.name ? this.el.dom.name : this.name || this.id || '';
37209 onRender : function(ct, position){
37211 var cfg = this.getAutoCreate();
37214 cfg.name = this.name || this.id;
37216 if(this.inputType){
37217 cfg.type = this.inputType;
37221 Ext.form.Field.superclass.onRender.call(this, ct, position);
37222 if(this.submitValue === false){
37223 this.el.dom.removeAttribute('name');
37225 var type = this.el.dom.type;
37227 if(type == 'password'){
37230 this.el.addClass('x-form-'+type);
37233 this.setReadOnly(true);
37235 if(this.tabIndex !== undefined){
37236 this.el.dom.setAttribute('tabIndex', this.tabIndex);
37239 this.el.addClass([this.fieldClass, this.cls]);
37243 getItemCt : function(){
37244 return this.itemCt;
37248 initValue : function(){
37249 if(this.value !== undefined){
37250 this.setValue(this.value);
37251 }else if(!Ext.isEmpty(this.el.dom.value) && this.el.dom.value != this.emptyText){
37252 this.setValue(this.el.dom.value);
37255 this.originalValue = this.getValue();
37259 isDirty : function() {
37260 if(this.disabled || !this.rendered) {
37263 return String(this.getValue()) !== String(this.originalValue);
37267 setReadOnly : function(readOnly){
37269 this.el.dom.readOnly = readOnly;
37271 this.readOnly = readOnly;
37275 afterRender : function(){
37276 Ext.form.Field.superclass.afterRender.call(this);
37282 fireKey : function(e){
37283 if(e.isSpecialKey()){
37284 this.fireEvent('specialkey', this, e);
37289 reset : function(){
37290 this.setValue(this.originalValue);
37291 this.clearInvalid();
37295 initEvents : function(){
37296 this.mon(this.el, Ext.EventManager.useKeydown ? 'keydown' : 'keypress', this.fireKey, this);
37297 this.mon(this.el, 'focus', this.onFocus, this);
37301 this.mon(this.el, 'blur', this.onBlur, this, this.inEditor ? {buffer:10} : null);
37305 preFocus: Ext.emptyFn,
37308 onFocus : function(){
37310 if(this.focusClass){
37311 this.el.addClass(this.focusClass);
37313 if(!this.hasFocus){
37314 this.hasFocus = true;
37316 this.startValue = this.getValue();
37317 this.fireEvent('focus', this);
37322 beforeBlur : Ext.emptyFn,
37325 onBlur : function(){
37327 if(this.focusClass){
37328 this.el.removeClass(this.focusClass);
37330 this.hasFocus = false;
37331 if(this.validationEvent !== false && (this.validateOnBlur || this.validationEvent == 'blur')){
37334 var v = this.getValue();
37335 if(String(v) !== String(this.startValue)){
37336 this.fireEvent('change', this, v, this.startValue);
37338 this.fireEvent('blur', this);
37343 postBlur : Ext.emptyFn,
37346 isValid : function(preventMark){
37350 var restore = this.preventMark;
37351 this.preventMark = preventMark === true;
37352 var v = this.validateValue(this.processValue(this.getRawValue()));
37353 this.preventMark = restore;
37358 validate : function(){
37359 if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
37360 this.clearInvalid();
37367 processValue : function(value){
37372 validateValue : function(value) {
37374 var error = this.getErrors(value)[0];
37376 if (error == undefined) {
37379 this.markInvalid(error);
37385 getErrors: function() {
37390 getActiveError : function(){
37391 return this.activeError || '';
37395 markInvalid : function(msg){
37397 if (this.rendered && !this.preventMark) {
37398 msg = msg || this.invalidText;
37400 var mt = this.getMessageHandler();
37402 mt.mark(this, msg);
37403 }else if(this.msgTarget){
37404 this.el.addClass(this.invalidClass);
37405 var t = Ext.getDom(this.msgTarget);
37408 t.style.display = this.msgDisplay;
37413 this.setActiveError(msg);
37417 clearInvalid : function(){
37419 if (this.rendered && !this.preventMark) {
37420 this.el.removeClass(this.invalidClass);
37421 var mt = this.getMessageHandler();
37424 }else if(this.msgTarget){
37425 this.el.removeClass(this.invalidClass);
37426 var t = Ext.getDom(this.msgTarget);
37429 t.style.display = 'none';
37434 this.unsetActiveError();
37438 setActiveError: function(msg, suppressEvent) {
37439 this.activeError = msg;
37440 if (suppressEvent !== true) this.fireEvent('invalid', this, msg);
37444 unsetActiveError: function(suppressEvent) {
37445 delete this.activeError;
37446 if (suppressEvent !== true) this.fireEvent('valid', this);
37450 getMessageHandler : function(){
37451 return Ext.form.MessageTargets[this.msgTarget];
37455 getErrorCt : function(){
37456 return this.el.findParent('.x-form-element', 5, true) ||
37457 this.el.findParent('.x-form-field-wrap', 5, true);
37461 alignErrorEl : function(){
37462 this.errorEl.setWidth(this.getErrorCt().getWidth(true) - 20);
37466 alignErrorIcon : function(){
37467 this.errorIcon.alignTo(this.el, 'tl-tr', [2, 0]);
37471 getRawValue : function(){
37472 var v = this.rendered ? this.el.getValue() : Ext.value(this.value, '');
37473 if(v === this.emptyText){
37480 getValue : function(){
37481 if(!this.rendered) {
37484 var v = this.el.getValue();
37485 if(v === this.emptyText || v === undefined){
37492 setRawValue : function(v){
37493 return this.rendered ? (this.el.dom.value = (Ext.isEmpty(v) ? '' : v)) : '';
37497 setValue : function(v){
37500 this.el.dom.value = (Ext.isEmpty(v) ? '' : v);
37507 append : function(v){
37508 this.setValue([this.getValue(), v].join(''));
37518 Ext.form.MessageTargets = {
37520 mark: function(field, msg){
37521 field.el.addClass(field.invalidClass);
37522 field.el.dom.qtip = msg;
37523 field.el.dom.qclass = 'x-form-invalid-tip';
37525 Ext.QuickTips.enable();
37528 clear: function(field){
37529 field.el.removeClass(field.invalidClass);
37530 field.el.dom.qtip = '';
37534 mark: function(field, msg){
37535 field.el.addClass(field.invalidClass);
37536 field.el.dom.title = msg;
37538 clear: function(field){
37539 field.el.dom.title = '';
37543 mark: function(field, msg){
37544 field.el.addClass(field.invalidClass);
37545 if(!field.errorEl){
37546 var elp = field.getErrorCt();
37548 field.el.dom.title = msg;
37551 field.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
37552 field.on('resize', field.alignErrorEl, field);
37553 field.on('destroy', function(){
37554 Ext.destroy(this.errorEl);
37557 field.alignErrorEl();
37558 field.errorEl.update(msg);
37559 Ext.form.Field.msgFx[field.msgFx].show(field.errorEl, field);
37561 clear: function(field){
37562 field.el.removeClass(field.invalidClass);
37564 Ext.form.Field.msgFx[field.msgFx].hide(field.errorEl, field);
37566 field.el.dom.title = '';
37571 mark: function(field, msg){
37572 field.el.addClass(field.invalidClass);
37573 if(!field.errorIcon){
37574 var elp = field.getErrorCt();
37577 field.el.dom.title = msg;
37580 field.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
37581 if (field.ownerCt) {
37582 field.ownerCt.on('afterlayout', field.alignErrorIcon, field);
37583 field.ownerCt.on('expand', field.alignErrorIcon, field);
37585 field.on('resize', field.alignErrorIcon, field);
37586 field.on('destroy', function(){
37587 Ext.destroy(this.errorIcon);
37590 field.alignErrorIcon();
37591 field.errorIcon.dom.qtip = msg;
37592 field.errorIcon.dom.qclass = 'x-form-invalid-tip';
37593 field.errorIcon.show();
37595 clear: function(field){
37596 field.el.removeClass(field.invalidClass);
37597 if(field.errorIcon){
37598 field.errorIcon.dom.qtip = '';
37599 field.errorIcon.hide();
37601 field.el.dom.title = '';
37608 Ext.form.Field.msgFx = {
37610 show: function(msgEl, f){
37611 msgEl.setDisplayed('block');
37614 hide : function(msgEl, f){
37615 msgEl.setDisplayed(false).update('');
37620 show: function(msgEl, f){
37621 msgEl.slideIn('t', {stopFx:true});
37624 hide : function(msgEl, f){
37625 msgEl.slideOut('t', {stopFx:true,useDisplay:true});
37630 show: function(msgEl, f){
37631 msgEl.fixDisplay();
37632 msgEl.alignTo(f.el, 'tl-tr');
37633 msgEl.slideIn('l', {stopFx:true});
37636 hide : function(msgEl, f){
37637 msgEl.slideOut('l', {stopFx:true,useDisplay:true});
37641 Ext.reg('field', Ext.form.Field);
37643 Ext.form.TextField = Ext.extend(Ext.form.Field, {
37657 disableKeyFilter : false,
37663 maxLength : Number.MAX_VALUE,
37665 minLengthText : 'The minimum length for this field is {0}',
37667 maxLengthText : 'The maximum length for this field is {0}',
37669 selectOnFocus : false,
37671 blankText : 'This field is required',
37681 emptyClass : 'x-form-empty-field',
37685 initComponent : function(){
37686 Ext.form.TextField.superclass.initComponent.call(this);
37701 initEvents : function(){
37702 Ext.form.TextField.superclass.initEvents.call(this);
37703 if(this.validationEvent == 'keyup'){
37704 this.validationTask = new Ext.util.DelayedTask(this.validate, this);
37705 this.mon(this.el, 'keyup', this.filterValidation, this);
37707 else if(this.validationEvent !== false && this.validationEvent != 'blur'){
37708 this.mon(this.el, this.validationEvent, this.validate, this, {buffer: this.validationDelay});
37710 if(this.selectOnFocus || this.emptyText){
37711 this.mon(this.el, 'mousedown', this.onMouseDown, this);
37713 if(this.emptyText){
37714 this.applyEmptyText();
37717 if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Ext.form.VTypes[this.vtype+'Mask']))){
37718 this.mon(this.el, 'keypress', this.filterKeys, this);
37721 this.mon(this.el, 'keyup', this.onKeyUpBuffered, this, {buffer: 50});
37722 this.mon(this.el, 'click', this.autoSize, this);
37724 if(this.enableKeyEvents){
37725 this.mon(this.el, {
37727 keyup: this.onKeyUp,
37728 keydown: this.onKeyDown,
37729 keypress: this.onKeyPress
37734 onMouseDown: function(e){
37735 if(!this.hasFocus){
37736 this.mon(this.el, 'mouseup', Ext.emptyFn, this, { single: true, preventDefault: true });
37740 processValue : function(value){
37741 if(this.stripCharsRe){
37742 var newValue = value.replace(this.stripCharsRe, '');
37743 if(newValue !== value){
37744 this.setRawValue(newValue);
37751 filterValidation : function(e){
37752 if(!e.isNavKeyPress()){
37753 this.validationTask.delay(this.validationDelay);
37758 onDisable: function(){
37759 Ext.form.TextField.superclass.onDisable.call(this);
37761 this.el.dom.unselectable = 'on';
37766 onEnable: function(){
37767 Ext.form.TextField.superclass.onEnable.call(this);
37769 this.el.dom.unselectable = '';
37774 onKeyUpBuffered : function(e){
37775 if(this.doAutoSize(e)){
37781 doAutoSize : function(e){
37782 return !e.isNavKeyPress();
37786 onKeyUp : function(e){
37787 this.fireEvent('keyup', this, e);
37791 onKeyDown : function(e){
37792 this.fireEvent('keydown', this, e);
37796 onKeyPress : function(e){
37797 this.fireEvent('keypress', this, e);
37801 reset : function(){
37802 Ext.form.TextField.superclass.reset.call(this);
37803 this.applyEmptyText();
37806 applyEmptyText : function(){
37807 if(this.rendered && this.emptyText && this.getRawValue().length < 1 && !this.hasFocus){
37808 this.setRawValue(this.emptyText);
37809 this.el.addClass(this.emptyClass);
37814 preFocus : function(){
37816 if(this.emptyText){
37817 if(el.dom.value == this.emptyText){
37818 this.setRawValue('');
37820 el.removeClass(this.emptyClass);
37822 if(this.selectOnFocus){
37828 postBlur : function(){
37829 this.applyEmptyText();
37833 filterKeys : function(e){
37837 var k = e.getKey();
37838 if(Ext.isGecko && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
37841 var cc = String.fromCharCode(e.getCharCode());
37842 if(!Ext.isGecko && e.isSpecialKey() && !cc){
37845 if(!this.maskRe.test(cc)){
37850 setValue : function(v){
37851 if(this.emptyText && this.el && !Ext.isEmpty(v)){
37852 this.el.removeClass(this.emptyClass);
37854 Ext.form.TextField.superclass.setValue.apply(this, arguments);
37855 this.applyEmptyText();
37861 getErrors: function(value) {
37862 var errors = Ext.form.TextField.superclass.getErrors.apply(this, arguments);
37864 value = value || this.processValue(this.getRawValue());
37866 if (Ext.isFunction(this.validator)) {
37867 var msg = this.validator(value);
37868 if (msg !== true) {
37873 if (value.length < 1 || value === this.emptyText) {
37874 if (this.allowBlank) {
37878 errors.push(this.blankText);
37882 if (!this.allowBlank && (value.length < 1 || value === this.emptyText)) {
37883 errors.push(this.blankText);
37886 if (value.length < this.minLength) {
37887 errors.push(String.format(this.minLengthText, this.minLength));
37890 if (value.length > this.maxLength) {
37891 errors.push(String.format(this.maxLengthText, this.maxLength));
37895 var vt = Ext.form.VTypes;
37896 if(!vt[this.vtype](value, this)){
37897 errors.push(this.vtypeText || vt[this.vtype +'Text']);
37901 if (this.regex && !this.regex.test(value)) {
37902 errors.push(this.regexText);
37909 selectText : function(start, end){
37910 var v = this.getRawValue();
37911 var doFocus = false;
37913 start = start === undefined ? 0 : start;
37914 end = end === undefined ? v.length : end;
37915 var d = this.el.dom;
37916 if(d.setSelectionRange){
37917 d.setSelectionRange(start, end);
37918 }else if(d.createTextRange){
37919 var range = d.createTextRange();
37920 range.moveStart('character', start);
37921 range.moveEnd('character', end-v.length);
37924 doFocus = Ext.isGecko || Ext.isOpera;
37934 autoSize : function(){
37935 if(!this.grow || !this.rendered){
37939 this.metrics = Ext.util.TextMetrics.createInstance(this.el);
37942 var v = el.dom.value;
37943 var d = document.createElement('div');
37944 d.appendChild(document.createTextNode(v));
37949 var w = Math.min(this.growMax, Math.max(this.metrics.getWidth(v) + 10, this.growMin));
37950 this.el.setWidth(w);
37951 this.fireEvent('autosize', this, w);
37954 onDestroy: function(){
37955 if(this.validationTask){
37956 this.validationTask.cancel();
37957 this.validationTask = null;
37959 Ext.form.TextField.superclass.onDestroy.call(this);
37962 Ext.reg('textfield', Ext.form.TextField);
37964 Ext.form.TriggerField = Ext.extend(Ext.form.TextField, {
37968 defaultAutoCreate : {tag: "input", type: "text", size: "16", autocomplete: "off"},
37976 wrapFocusClass: 'x-trigger-wrap-focus',
37978 autoSize: Ext.emptyFn,
37982 deferHeight : true,
37986 actionMode: 'wrap',
37988 defaultTriggerWidth: 17,
37991 onResize : function(w, h){
37992 Ext.form.TriggerField.superclass.onResize.call(this, w, h);
37993 var tw = this.getTriggerWidth();
37994 if(Ext.isNumber(w)){
37995 this.el.setWidth(w - tw);
37997 this.wrap.setWidth(this.el.getWidth() + tw);
38000 getTriggerWidth: function(){
38001 var tw = this.trigger.getWidth();
38002 if(!this.hideTrigger && !this.readOnly && tw === 0){
38003 tw = this.defaultTriggerWidth;
38009 alignErrorIcon : function(){
38011 this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
38016 onRender : function(ct, position){
38017 this.doc = Ext.isIE ? Ext.getBody() : Ext.getDoc();
38018 Ext.form.TriggerField.superclass.onRender.call(this, ct, position);
38020 this.wrap = this.el.wrap({cls: 'x-form-field-wrap x-form-field-trigger-wrap'});
38021 this.trigger = this.wrap.createChild(this.triggerConfig ||
38022 {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.triggerClass});
38023 this.initTrigger();
38025 this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
38027 this.resizeEl = this.positionEl = this.wrap;
38030 getWidth: function() {
38031 return(this.el.getWidth() + this.trigger.getWidth());
38034 updateEditState: function(){
38036 if (this.readOnly) {
38037 this.el.dom.readOnly = true;
38038 this.el.addClass('x-trigger-noedit');
38039 this.mun(this.el, 'click', this.onTriggerClick, this);
38040 this.trigger.setDisplayed(false);
38042 if (!this.editable) {
38043 this.el.dom.readOnly = true;
38044 this.el.addClass('x-trigger-noedit');
38045 this.mon(this.el, 'click', this.onTriggerClick, this);
38047 this.el.dom.readOnly = false;
38048 this.el.removeClass('x-trigger-noedit');
38049 this.mun(this.el, 'click', this.onTriggerClick, this);
38051 this.trigger.setDisplayed(!this.hideTrigger);
38053 this.onResize(this.width || this.wrap.getWidth());
38057 setHideTrigger: function(hideTrigger){
38058 if(hideTrigger != this.hideTrigger){
38059 this.hideTrigger = hideTrigger;
38060 this.updateEditState();
38065 setEditable: function(editable){
38066 if(editable != this.editable){
38067 this.editable = editable;
38068 this.updateEditState();
38073 setReadOnly: function(readOnly){
38074 if(readOnly != this.readOnly){
38075 this.readOnly = readOnly;
38076 this.updateEditState();
38080 afterRender : function(){
38081 Ext.form.TriggerField.superclass.afterRender.call(this);
38082 this.updateEditState();
38086 initTrigger : function(){
38087 this.mon(this.trigger, 'click', this.onTriggerClick, this, {preventDefault:true});
38088 this.trigger.addClassOnOver('x-form-trigger-over');
38089 this.trigger.addClassOnClick('x-form-trigger-click');
38093 onDestroy : function(){
38094 Ext.destroy(this.trigger, this.wrap);
38095 if (this.mimicing){
38096 this.doc.un('mousedown', this.mimicBlur, this);
38099 Ext.form.TriggerField.superclass.onDestroy.call(this);
38103 onFocus : function(){
38104 Ext.form.TriggerField.superclass.onFocus.call(this);
38105 if(!this.mimicing){
38106 this.wrap.addClass(this.wrapFocusClass);
38107 this.mimicing = true;
38108 this.doc.on('mousedown', this.mimicBlur, this, {delay: 10});
38109 if(this.monitorTab){
38110 this.on('specialkey', this.checkTab, this);
38116 checkTab : function(me, e){
38117 if(e.getKey() == e.TAB){
38118 this.triggerBlur();
38123 onBlur : Ext.emptyFn,
38126 mimicBlur : function(e){
38127 if(!this.isDestroyed && !this.wrap.contains(e.target) && this.validateBlur(e)){
38128 this.triggerBlur();
38133 triggerBlur : function(){
38134 this.mimicing = false;
38135 this.doc.un('mousedown', this.mimicBlur, this);
38136 if(this.monitorTab && this.el){
38137 this.un('specialkey', this.checkTab, this);
38139 Ext.form.TriggerField.superclass.onBlur.call(this);
38141 this.wrap.removeClass(this.wrapFocusClass);
38145 beforeBlur : Ext.emptyFn,
38149 validateBlur : function(e){
38154 onTriggerClick : Ext.emptyFn
38162 Ext.form.TwinTriggerField = Ext.extend(Ext.form.TriggerField, {
38167 initComponent : function(){
38168 Ext.form.TwinTriggerField.superclass.initComponent.call(this);
38170 this.triggerConfig = {
38171 tag:'span', cls:'x-form-twin-triggers', cn:[
38172 {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger1Class},
38173 {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger2Class}
38177 getTrigger : function(index){
38178 return this.triggers[index];
38181 afterRender: function(){
38182 Ext.form.TwinTriggerField.superclass.afterRender.call(this);
38183 var triggers = this.triggers,
38185 len = triggers.length;
38187 for(; i < len; ++i){
38188 if(this['hideTrigger' + (i + 1)]){
38189 triggers[i].hide();
38195 initTrigger : function(){
38196 var ts = this.trigger.select('.x-form-trigger', true),
38197 triggerField = this;
38199 ts.each(function(t, all, index){
38200 var triggerIndex = 'Trigger'+(index+1);
38201 t.hide = function(){
38202 var w = triggerField.wrap.getWidth();
38203 this.dom.style.display = 'none';
38204 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
38205 this['hidden' + triggerIndex] = true;
38207 t.show = function(){
38208 var w = triggerField.wrap.getWidth();
38209 this.dom.style.display = '';
38210 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
38211 this['hidden' + triggerIndex] = false;
38213 this.mon(t, 'click', this['on'+triggerIndex+'Click'], this, {preventDefault:true});
38214 t.addClassOnOver('x-form-trigger-over');
38215 t.addClassOnClick('x-form-trigger-click');
38217 this.triggers = ts.elements;
38220 getTriggerWidth: function(){
38222 Ext.each(this.triggers, function(t, index){
38223 var triggerIndex = 'Trigger' + (index + 1),
38225 if(w === 0 && !this['hidden' + triggerIndex]){
38226 tw += this.defaultTriggerWidth;
38235 onDestroy : function() {
38236 Ext.destroy(this.triggers);
38237 Ext.form.TwinTriggerField.superclass.onDestroy.call(this);
38241 onTrigger1Click : Ext.emptyFn,
38243 onTrigger2Click : Ext.emptyFn
38245 Ext.reg('trigger', Ext.form.TriggerField);
38247 Ext.form.TextArea = Ext.extend(Ext.form.TextField, {
38252 growAppend : ' \n ',
38254 enterIsSpecial : false,
38257 preventScrollbars: false,
38261 onRender : function(ct, position){
38263 this.defaultAutoCreate = {
38265 style:"width:100px;height:60px;",
38266 autocomplete: "off"
38269 Ext.form.TextArea.superclass.onRender.call(this, ct, position);
38271 this.textSizeEl = Ext.DomHelper.append(document.body, {
38272 tag: "pre", cls: "x-form-grow-sizer"
38274 if(this.preventScrollbars){
38275 this.el.setStyle("overflow", "hidden");
38277 this.el.setHeight(this.growMin);
38281 onDestroy : function(){
38282 Ext.removeNode(this.textSizeEl);
38283 Ext.form.TextArea.superclass.onDestroy.call(this);
38286 fireKey : function(e){
38287 if(e.isSpecialKey() && (this.enterIsSpecial || (e.getKey() != e.ENTER || e.hasModifier()))){
38288 this.fireEvent("specialkey", this, e);
38293 doAutoSize : function(e){
38294 return !e.isNavKeyPress() || e.getKey() == e.ENTER;
38298 autoSize: function(){
38299 if(!this.grow || !this.textSizeEl){
38303 v = Ext.util.Format.htmlEncode(el.dom.value),
38304 ts = this.textSizeEl,
38307 Ext.fly(ts).setWidth(this.el.getWidth());
38309 v = "  ";
38311 v += this.growAppend;
38313 v = v.replace(/\n/g, ' <br />');
38317 h = Math.min(this.growMax, Math.max(ts.offsetHeight, this.growMin));
38318 if(h != this.lastHeight){
38319 this.lastHeight = h;
38320 this.el.setHeight(h);
38321 this.fireEvent("autosize", this, h);
38325 Ext.reg('textarea', Ext.form.TextArea);
38326 Ext.form.NumberField = Ext.extend(Ext.form.TextField, {
38330 fieldClass: "x-form-field x-form-num-field",
38332 allowDecimals : true,
38334 decimalSeparator : ".",
38336 decimalPrecision : 2,
38338 allowNegative : true,
38340 minValue : Number.NEGATIVE_INFINITY,
38342 maxValue : Number.MAX_VALUE,
38344 minText : "The minimum value for this field is {0}",
38346 maxText : "The maximum value for this field is {0}",
38348 nanText : "{0} is not a valid number",
38350 baseChars : "0123456789",
38353 initEvents : function(){
38354 var allowed = this.baseChars + '';
38355 if (this.allowDecimals) {
38356 allowed += this.decimalSeparator;
38358 if (this.allowNegative) {
38361 this.maskRe = new RegExp('[' + Ext.escapeRe(allowed) + ']');
38362 Ext.form.NumberField.superclass.initEvents.call(this);
38366 getErrors: function(value) {
38367 var errors = Ext.form.NumberField.superclass.getErrors.apply(this, arguments);
38369 value = value || this.processValue(this.getRawValue());
38371 if (value.length < 1) {
38375 value = String(value).replace(this.decimalSeparator, ".");
38378 errors.push(String.format(this.nanText, value));
38381 var num = this.parseValue(value);
38383 if(num < this.minValue){
38384 errors.push(String.format(this.minText, this.minValue));
38387 if(num > this.maxValue){
38388 errors.push(String.format(this.maxText, this.maxValue));
38394 getValue : function(){
38395 return this.fixPrecision(this.parseValue(Ext.form.NumberField.superclass.getValue.call(this)));
38398 setValue : function(v){
38399 v = this.fixPrecision(v);
38400 v = Ext.isNumber(v) ? v : parseFloat(String(v).replace(this.decimalSeparator, "."));
38401 v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator);
38402 return Ext.form.NumberField.superclass.setValue.call(this, v);
38406 setMinValue : function(value){
38407 this.minValue = Ext.num(value, Number.NEGATIVE_INFINITY);
38411 setMaxValue : function(value){
38412 this.maxValue = Ext.num(value, Number.MAX_VALUE);
38416 parseValue : function(value){
38417 value = parseFloat(String(value).replace(this.decimalSeparator, "."));
38418 return isNaN(value) ? '' : value;
38422 fixPrecision : function(value){
38423 var nan = isNaN(value);
38424 if(!this.allowDecimals || this.decimalPrecision == -1 || nan || !value){
38425 return nan ? '' : value;
38427 return parseFloat(parseFloat(value).toFixed(this.decimalPrecision));
38430 beforeBlur : function(){
38431 var v = this.parseValue(this.getRawValue());
38432 if(!Ext.isEmpty(v)){
38437 Ext.reg('numberfield', Ext.form.NumberField);
38438 Ext.form.DateField = Ext.extend(Ext.form.TriggerField, {
38442 altFormats : "m/d/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d",
38444 disabledDaysText : "Disabled",
38446 disabledDatesText : "Disabled",
38448 minText : "The date in this field must be equal to or after {0}",
38450 maxText : "The date in this field must be equal to or before {0}",
38452 invalidText : "{0} is not a valid date - it must be in the format {1}",
38454 triggerClass : 'x-form-date-trigger',
38464 defaultAutoCreate : {tag: "input", type: "text", size: "10", autocomplete: "off"},
38470 initTimeFormat: 'H',
38473 safeParse : function(value, format) {
38474 if (/[gGhH]/.test(format.replace(/(\\.)/g, ''))) {
38476 return Date.parseDate(value, format);
38479 var parsedDate = Date.parseDate(value + ' ' + this.initTime, format + ' ' + this.initTimeFormat);
38481 if (parsedDate) return parsedDate.clearTime();
38485 initComponent : function(){
38486 Ext.form.DateField.superclass.initComponent.call(this);
38493 if(Ext.isString(this.minValue)){
38494 this.minValue = this.parseDate(this.minValue);
38496 if(Ext.isString(this.maxValue)){
38497 this.maxValue = this.parseDate(this.maxValue);
38499 this.disabledDatesRE = null;
38500 this.initDisabledDays();
38503 initEvents: function() {
38504 Ext.form.DateField.superclass.initEvents.call(this);
38505 this.keyNav = new Ext.KeyNav(this.el, {
38506 "down": function(e) {
38507 this.onTriggerClick();
38516 initDisabledDays : function(){
38517 if(this.disabledDates){
38518 var dd = this.disabledDates,
38519 len = dd.length - 1,
38522 Ext.each(dd, function(d, i){
38523 re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i];
38528 this.disabledDatesRE = new RegExp(re + ')');
38533 setDisabledDates : function(dd){
38534 this.disabledDates = dd;
38535 this.initDisabledDays();
38537 this.menu.picker.setDisabledDates(this.disabledDatesRE);
38542 setDisabledDays : function(dd){
38543 this.disabledDays = dd;
38545 this.menu.picker.setDisabledDays(dd);
38550 setMinValue : function(dt){
38551 this.minValue = (Ext.isString(dt) ? this.parseDate(dt) : dt);
38553 this.menu.picker.setMinDate(this.minValue);
38558 setMaxValue : function(dt){
38559 this.maxValue = (Ext.isString(dt) ? this.parseDate(dt) : dt);
38561 this.menu.picker.setMaxDate(this.maxValue);
38566 getErrors: function(value) {
38567 var errors = Ext.form.DateField.superclass.getErrors.apply(this, arguments);
38569 value = this.formatDate(value || this.processValue(this.getRawValue()));
38571 if (value.length < 1) {
38575 var svalue = value;
38576 value = this.parseDate(value);
38578 errors.push(String.format(this.invalidText, svalue, this.format));
38582 var time = value.getTime();
38583 if (this.minValue && time < this.minValue.clearTime().getTime()) {
38584 errors.push(String.format(this.minText, this.formatDate(this.minValue)));
38587 if (this.maxValue && time > this.maxValue.clearTime().getTime()) {
38588 errors.push(String.format(this.maxText, this.formatDate(this.maxValue)));
38591 if (this.disabledDays) {
38592 var day = value.getDay();
38594 for(var i = 0; i < this.disabledDays.length; i++) {
38595 if (day === this.disabledDays[i]) {
38596 errors.push(this.disabledDaysText);
38602 var fvalue = this.formatDate(value);
38603 if (this.disabledDatesRE && this.disabledDatesRE.test(fvalue)) {
38604 errors.push(String.format(this.disabledDatesText, fvalue));
38612 validateBlur : function(){
38613 return !this.menu || !this.menu.isVisible();
38617 getValue : function(){
38618 return this.parseDate(Ext.form.DateField.superclass.getValue.call(this)) || "";
38622 setValue : function(date){
38623 return Ext.form.DateField.superclass.setValue.call(this, this.formatDate(this.parseDate(date)));
38627 parseDate : function(value) {
38628 if(!value || Ext.isDate(value)){
38632 var v = this.safeParse(value, this.format),
38633 af = this.altFormats,
38634 afa = this.altFormatsArray;
38637 afa = afa || af.split("|");
38639 for (var i = 0, len = afa.length; i < len && !v; i++) {
38640 v = this.safeParse(value, afa[i]);
38647 onDestroy : function(){
38648 Ext.destroy(this.menu, this.keyNav);
38649 Ext.form.DateField.superclass.onDestroy.call(this);
38653 formatDate : function(date){
38654 return Ext.isDate(date) ? date.dateFormat(this.format) : date;
38660 onTriggerClick : function(){
38664 if(this.menu == null){
38665 this.menu = new Ext.menu.DateMenu({
38666 hideOnClick: false,
38667 focusOnSelect: false
38671 Ext.apply(this.menu.picker, {
38672 minDate : this.minValue,
38673 maxDate : this.maxValue,
38674 disabledDatesRE : this.disabledDatesRE,
38675 disabledDatesText : this.disabledDatesText,
38676 disabledDays : this.disabledDays,
38677 disabledDaysText : this.disabledDaysText,
38678 format : this.format,
38679 showToday : this.showToday,
38680 minText : String.format(this.minText, this.formatDate(this.minValue)),
38681 maxText : String.format(this.maxText, this.formatDate(this.maxValue))
38683 this.menu.picker.setValue(this.getValue() || new Date());
38684 this.menu.show(this.el, "tl-bl?");
38685 this.menuEvents('on');
38689 menuEvents: function(method){
38690 this.menu[method]('select', this.onSelect, this);
38691 this.menu[method]('hide', this.onMenuHide, this);
38692 this.menu[method]('show', this.onFocus, this);
38695 onSelect: function(m, d){
38697 this.fireEvent('select', this, d);
38701 onMenuHide: function(){
38702 this.focus(false, 60);
38703 this.menuEvents('un');
38707 beforeBlur : function(){
38708 var v = this.parseDate(this.getRawValue());
38719 Ext.reg('datefield', Ext.form.DateField);
38721 Ext.form.DisplayField = Ext.extend(Ext.form.Field, {
38722 validationEvent : false,
38723 validateOnBlur : false,
38724 defaultAutoCreate : {tag: "div"},
38726 fieldClass : "x-form-display-field",
38731 initEvents : Ext.emptyFn,
38733 isValid : function(){
38737 validate : function(){
38741 getRawValue : function(){
38742 var v = this.rendered ? this.el.dom.innerHTML : Ext.value(this.value, '');
38743 if(v === this.emptyText){
38746 if(this.htmlEncode){
38747 v = Ext.util.Format.htmlDecode(v);
38752 getValue : function(){
38753 return this.getRawValue();
38756 getName: function() {
38760 setRawValue : function(v){
38761 if(this.htmlEncode){
38762 v = Ext.util.Format.htmlEncode(v);
38764 return this.rendered ? (this.el.dom.innerHTML = (Ext.isEmpty(v) ? '' : v)) : (this.value = v);
38767 setValue : function(v){
38768 this.setRawValue(v);
38779 Ext.reg('displayfield', Ext.form.DisplayField);
38781 Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
38789 defaultAutoCreate : {tag: "input", type: "text", size: "24", autocomplete: "off"},
38799 selectedClass : 'x-combo-selected',
38803 triggerClass : 'x-form-arrow-trigger',
38807 listAlign : 'tl-bl?',
38813 triggerAction : 'query',
38825 selectOnFocus : false,
38827 queryParam : 'query',
38829 loadingText : 'Loading...',
38841 forceSelection : false,
38843 typeAheadDelay : 250,
38850 clearFilterOnReset : true,
38853 submitValue: undefined,
38858 initComponent : function(){
38859 Ext.form.ComboBox.superclass.initComponent.call(this);
38873 if(this.transform){
38874 var s = Ext.getDom(this.transform);
38875 if(!this.hiddenName){
38876 this.hiddenName = s.name;
38879 this.mode = 'local';
38880 var d = [], opts = s.options;
38881 for(var i = 0, len = opts.length;i < len; i++){
38883 value = (o.hasAttribute ? o.hasAttribute('value') : o.getAttributeNode('value').specified) ? o.value : o.text;
38884 if(o.selected && Ext.isEmpty(this.value, true)) {
38885 this.value = value;
38887 d.push([value, o.text]);
38889 this.store = new Ext.data.ArrayStore({
38891 fields: ['value', 'text'],
38895 this.valueField = 'value';
38896 this.displayField = 'text';
38899 if(!this.lazyRender){
38900 this.target = true;
38901 this.el = Ext.DomHelper.insertBefore(s, this.autoCreate || this.defaultAutoCreate);
38902 this.render(this.el.parentNode, s);
38907 else if(this.store){
38908 this.store = Ext.StoreMgr.lookup(this.store);
38909 if(this.store.autoCreated){
38910 this.displayField = this.valueField = 'field1';
38911 if(!this.store.expandData){
38912 this.displayField = 'field2';
38914 this.mode = 'local';
38918 this.selectedIndex = -1;
38919 if(this.mode == 'local'){
38920 if(!Ext.isDefined(this.initialConfig.queryDelay)){
38921 this.queryDelay = 10;
38923 if(!Ext.isDefined(this.initialConfig.minChars)){
38930 onRender : function(ct, position){
38931 if(this.hiddenName && !Ext.isDefined(this.submitValue)){
38932 this.submitValue = false;
38934 Ext.form.ComboBox.superclass.onRender.call(this, ct, position);
38935 if(this.hiddenName){
38936 this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName,
38937 id: (this.hiddenId||this.hiddenName)}, 'before', true);
38941 this.el.dom.setAttribute('autocomplete', 'off');
38944 if(!this.lazyInit){
38947 this.on('focus', this.initList, this, {single: true});
38952 initValue : function(){
38953 Ext.form.ComboBox.superclass.initValue.call(this);
38954 if(this.hiddenField){
38955 this.hiddenField.value =
38956 Ext.value(Ext.isDefined(this.hiddenValue) ? this.hiddenValue : this.value, '');
38960 getParentZIndex : function(){
38963 this.findParentBy(function(ct){
38964 zindex = parseInt(ct.getPositionEl().getStyle('z-index'), 10);
38971 getZIndex : function(listParent){
38972 listParent = listParent || Ext.getDom(this.getListParent() || Ext.getBody());
38973 var zindex = parseInt(Ext.fly(listParent).getStyle('z-index'), 10);
38975 zindex = this.getParentZIndex();
38977 return (zindex || 12000) + 5;
38981 initList : function(){
38983 var cls = 'x-combo-list',
38984 listParent = Ext.getDom(this.getListParent() || Ext.getBody());
38986 this.list = new Ext.Layer({
38987 parentEl: listParent,
38988 shadow: this.shadow,
38989 cls: [cls, this.listClass].join(' '),
38991 zindex: this.getZIndex(listParent)
38994 var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
38995 this.list.setSize(lw, 0);
38996 this.list.swallowEvent('mousewheel');
38997 this.assetHeight = 0;
38998 if(this.syncFont !== false){
38999 this.list.setStyle('font-size', this.el.getStyle('font-size'));
39002 this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
39003 this.assetHeight += this.header.getHeight();
39006 this.innerList = this.list.createChild({cls:cls+'-inner'});
39007 this.mon(this.innerList, 'mouseover', this.onViewOver, this);
39008 this.mon(this.innerList, 'mousemove', this.onViewMove, this);
39009 this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
39012 this.footer = this.list.createChild({cls:cls+'-ft'});
39013 this.pageTb = new Ext.PagingToolbar({
39015 pageSize: this.pageSize,
39016 renderTo:this.footer
39018 this.assetHeight += this.footer.getHeight();
39023 this.tpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';
39028 this.view = new Ext.DataView({
39029 applyTo: this.innerList,
39031 singleSelect: true,
39032 selectedClass: this.selectedClass,
39033 itemSelector: this.itemSelector || '.' + cls + '-item',
39034 emptyText: this.listEmptyText,
39035 deferEmptyText: false
39038 this.mon(this.view, {
39039 containerclick : this.onViewClick,
39040 click : this.onViewClick,
39044 this.bindStore(this.store, true);
39046 if(this.resizable){
39047 this.resizer = new Ext.Resizable(this.list, {
39048 pinned:true, handles:'se'
39050 this.mon(this.resizer, 'resize', function(r, w, h){
39051 this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
39052 this.listWidth = w;
39053 this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
39054 this.restrictHeight();
39057 this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
39063 getListParent : function() {
39064 return document.body;
39068 getStore : function(){
39073 bindStore : function(store, initial){
39074 if(this.store && !initial){
39075 if(this.store !== store && this.store.autoDestroy){
39076 this.store.destroy();
39078 this.store.un('beforeload', this.onBeforeLoad, this);
39079 this.store.un('load', this.onLoad, this);
39080 this.store.un('exception', this.collapse, this);
39085 this.view.bindStore(null);
39088 this.pageTb.bindStore(null);
39094 this.lastQuery = null;
39096 this.pageTb.bindStore(store);
39100 this.store = Ext.StoreMgr.lookup(store);
39103 beforeload: this.onBeforeLoad,
39105 exception: this.collapse
39109 this.view.bindStore(store);
39114 reset : function(){
39115 Ext.form.ComboBox.superclass.reset.call(this);
39116 if(this.clearFilterOnReset && this.mode == 'local'){
39117 this.store.clearFilter();
39122 initEvents : function(){
39123 Ext.form.ComboBox.superclass.initEvents.call(this);
39126 this.keyNav = new Ext.KeyNav(this.el, {
39127 "up" : function(e){
39128 this.inKeyMode = true;
39132 "down" : function(e){
39133 if(!this.isExpanded()){
39134 this.onTriggerClick();
39136 this.inKeyMode = true;
39141 "enter" : function(e){
39142 this.onViewClick();
39145 "esc" : function(e){
39149 "tab" : function(e){
39150 if (this.forceSelection === true) {
39153 this.onViewClick(false);
39160 doRelay : function(e, h, hname){
39161 if(hname == 'down' || this.scope.isExpanded()){
39163 var relay = Ext.KeyNav.prototype.doRelay.apply(this, arguments);
39164 if(!Ext.isIE && Ext.EventManager.useKeydown){
39166 this.scope.fireKey(e);
39173 forceKeyDown : true,
39174 defaultEventAction: 'stopEvent'
39176 this.queryDelay = Math.max(this.queryDelay || 10,
39177 this.mode == 'local' ? 10 : 250);
39178 this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);
39179 if(this.typeAhead){
39180 this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
39182 if(!this.enableKeyEvents){
39183 this.mon(this.el, 'keyup', this.onKeyUp, this);
39189 onDestroy : function(){
39191 this.dqTask.cancel();
39192 this.dqTask = null;
39194 this.bindStore(null);
39201 Ext.destroyMembers(this, 'hiddenField');
39202 Ext.form.ComboBox.superclass.onDestroy.call(this);
39206 fireKey : function(e){
39207 if (!this.isExpanded()) {
39208 Ext.form.ComboBox.superclass.fireKey.call(this, e);
39213 onResize : function(w, h){
39214 Ext.form.ComboBox.superclass.onResize.apply(this, arguments);
39215 if(!isNaN(w) && this.isVisible() && this.list){
39218 this.bufferSize = w;
39222 doResize: function(w){
39223 if(!Ext.isDefined(this.listWidth)){
39224 var lw = Math.max(w, this.minListWidth);
39225 this.list.setWidth(lw);
39226 this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
39231 onEnable : function(){
39232 Ext.form.ComboBox.superclass.onEnable.apply(this, arguments);
39233 if(this.hiddenField){
39234 this.hiddenField.disabled = false;
39239 onDisable : function(){
39240 Ext.form.ComboBox.superclass.onDisable.apply(this, arguments);
39241 if(this.hiddenField){
39242 this.hiddenField.disabled = true;
39247 onBeforeLoad : function(){
39248 if(!this.hasFocus){
39251 this.innerList.update(this.loadingText ?
39252 '<div class="loading-indicator">'+this.loadingText+'</div>' : '');
39253 this.restrictHeight();
39254 this.selectedIndex = -1;
39258 onLoad : function(){
39259 if(!this.hasFocus){
39262 if(this.store.getCount() > 0 || this.listEmptyText){
39264 this.restrictHeight();
39265 if(this.lastQuery == this.allQuery){
39267 this.el.dom.select();
39270 if(this.autoSelect !== false && !this.selectByValue(this.value, true)){
39271 this.select(0, true);
39274 if(this.autoSelect !== false){
39277 if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){
39278 this.taTask.delay(this.typeAheadDelay);
39288 onTypeAhead : function(){
39289 if(this.store.getCount() > 0){
39290 var r = this.store.getAt(0);
39291 var newValue = r.data[this.displayField];
39292 var len = newValue.length;
39293 var selStart = this.getRawValue().length;
39294 if(selStart != len){
39295 this.setRawValue(newValue);
39296 this.selectText(selStart, newValue.length);
39302 assertValue : function(){
39303 var val = this.getRawValue(),
39304 rec = this.findRecord(this.displayField, val);
39306 if(!rec && this.forceSelection){
39307 if(val.length > 0 && val != this.emptyText){
39308 this.el.dom.value = Ext.value(this.lastSelectionText, '');
39309 this.applyEmptyText();
39318 if (val == rec.get(this.displayField) && this.value == rec.get(this.valueField)){
39321 val = rec.get(this.valueField || this.displayField);
39323 this.setValue(val);
39328 onSelect : function(record, index){
39329 if(this.fireEvent('beforeselect', this, record, index) !== false){
39330 this.setValue(record.data[this.valueField || this.displayField]);
39332 this.fireEvent('select', this, record, index);
39337 getName: function(){
39338 var hf = this.hiddenField;
39339 return hf && hf.name ? hf.name : this.hiddenName || Ext.form.ComboBox.superclass.getName.call(this);
39343 getValue : function(){
39344 if(this.valueField){
39345 return Ext.isDefined(this.value) ? this.value : '';
39347 return Ext.form.ComboBox.superclass.getValue.call(this);
39352 clearValue : function(){
39353 if(this.hiddenField){
39354 this.hiddenField.value = '';
39356 this.setRawValue('');
39357 this.lastSelectionText = '';
39358 this.applyEmptyText();
39363 setValue : function(v){
39365 if(this.valueField){
39366 var r = this.findRecord(this.valueField, v);
39368 text = r.data[this.displayField];
39369 }else if(Ext.isDefined(this.valueNotFoundText)){
39370 text = this.valueNotFoundText;
39373 this.lastSelectionText = text;
39374 if(this.hiddenField){
39375 this.hiddenField.value = Ext.value(v, '');
39377 Ext.form.ComboBox.superclass.setValue.call(this, text);
39383 findRecord : function(prop, value){
39385 if(this.store.getCount() > 0){
39386 this.store.each(function(r){
39387 if(r.data[prop] == value){
39397 onViewMove : function(e, t){
39398 this.inKeyMode = false;
39402 onViewOver : function(e, t){
39403 if(this.inKeyMode){
39406 var item = this.view.findItemFromChild(t);
39408 var index = this.view.indexOf(item);
39409 this.select(index, false);
39414 onViewClick : function(doFocus){
39415 var index = this.view.getSelectedIndexes()[0],
39417 r = s.getAt(index);
39419 this.onSelect(r, index);
39423 if(doFocus !== false){
39430 restrictHeight : function(){
39431 this.innerList.dom.style.height = '';
39432 var inner = this.innerList.dom,
39433 pad = this.list.getFrameWidth('tb') + (this.resizable ? this.handleHeight : 0) + this.assetHeight,
39434 h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight),
39435 ha = this.getPosition()[1]-Ext.getBody().getScroll().top,
39436 hb = Ext.lib.Dom.getViewHeight()-ha-this.getSize().height,
39437 space = Math.max(ha, hb, this.minHeight || 0)-this.list.shadowOffset-pad-5;
39439 h = Math.min(h, space, this.maxHeight);
39441 this.innerList.setHeight(h);
39442 this.list.beginUpdate();
39443 this.list.setHeight(h+pad);
39444 this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
39445 this.list.endUpdate();
39449 isExpanded : function(){
39450 return this.list && this.list.isVisible();
39454 selectByValue : function(v, scrollIntoView){
39455 if(!Ext.isEmpty(v, true)){
39456 var r = this.findRecord(this.valueField || this.displayField, v);
39458 this.select(this.store.indexOf(r), scrollIntoView);
39466 select : function(index, scrollIntoView){
39467 this.selectedIndex = index;
39468 this.view.select(index);
39469 if(scrollIntoView !== false){
39470 var el = this.view.getNode(index);
39472 this.innerList.scrollChildIntoView(el, false);
39479 selectNext : function(){
39480 var ct = this.store.getCount();
39482 if(this.selectedIndex == -1){
39484 }else if(this.selectedIndex < ct-1){
39485 this.select(this.selectedIndex+1);
39491 selectPrev : function(){
39492 var ct = this.store.getCount();
39494 if(this.selectedIndex == -1){
39496 }else if(this.selectedIndex !== 0){
39497 this.select(this.selectedIndex-1);
39503 onKeyUp : function(e){
39504 var k = e.getKey();
39505 if(this.editable !== false && this.readOnly !== true && (k == e.BACKSPACE || !e.isSpecialKey())){
39508 this.dqTask.delay(this.queryDelay);
39510 Ext.form.ComboBox.superclass.onKeyUp.call(this, e);
39514 validateBlur : function(){
39515 return !this.list || !this.list.isVisible();
39519 initQuery : function(){
39520 this.doQuery(this.getRawValue());
39524 beforeBlur : function(){
39525 this.assertValue();
39529 postBlur : function(){
39530 Ext.form.ComboBox.superclass.postBlur.call(this);
39532 this.inKeyMode = false;
39536 doQuery : function(q, forceAll){
39537 q = Ext.isEmpty(q) ? '' : q;
39540 forceAll: forceAll,
39544 if(this.fireEvent('beforequery', qe)===false || qe.cancel){
39548 forceAll = qe.forceAll;
39549 if(forceAll === true || (q.length >= this.minChars)){
39550 if(this.lastQuery !== q){
39551 this.lastQuery = q;
39552 if(this.mode == 'local'){
39553 this.selectedIndex = -1;
39555 this.store.clearFilter();
39557 this.store.filter(this.displayField, q);
39561 this.store.baseParams[this.queryParam] = q;
39563 params: this.getParams(q)
39568 this.selectedIndex = -1;
39575 getParams : function(q){
39580 p.limit = this.pageSize;
39586 collapse : function(){
39587 if(!this.isExpanded()){
39591 Ext.getDoc().un('mousewheel', this.collapseIf, this);
39592 Ext.getDoc().un('mousedown', this.collapseIf, this);
39593 this.fireEvent('collapse', this);
39597 collapseIf : function(e){
39598 if(!this.isDestroyed && !e.within(this.wrap) && !e.within(this.list)){
39604 expand : function(){
39605 if(this.isExpanded() || !this.hasFocus){
39609 if(this.title || this.pageSize){
39610 this.assetHeight = 0;
39612 this.assetHeight += this.header.getHeight();
39615 this.assetHeight += this.footer.getHeight();
39619 if(this.bufferSize){
39620 this.doResize(this.bufferSize);
39621 delete this.bufferSize;
39623 this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
39626 this.list.setZIndex(this.getZIndex());
39629 this.innerList.setOverflow('auto');
39631 this.mon(Ext.getDoc(), {
39633 mousewheel: this.collapseIf,
39634 mousedown: this.collapseIf
39636 this.fireEvent('expand', this);
39642 onTriggerClick : function(){
39643 if(this.readOnly || this.disabled){
39646 if(this.isExpanded()){
39651 if(this.triggerAction == 'all') {
39652 this.doQuery(this.allQuery, true);
39654 this.doQuery(this.getRawValue());
39666 Ext.reg('combo', Ext.form.ComboBox);
39668 Ext.form.Checkbox = Ext.extend(Ext.form.Field, {
39670 focusClass : undefined,
39672 fieldClass : 'x-form-field',
39676 boxLabel: ' ',
39678 defaultAutoCreate : { tag: 'input', type: 'checkbox', autocomplete: 'off'},
39685 actionMode : 'wrap',
39688 initComponent : function(){
39689 Ext.form.Checkbox.superclass.initComponent.call(this);
39697 onResize : function(){
39698 Ext.form.Checkbox.superclass.onResize.apply(this, arguments);
39699 if(!this.boxLabel && !this.fieldLabel){
39700 this.el.alignTo(this.wrap, 'c-c');
39705 initEvents : function(){
39706 Ext.form.Checkbox.superclass.initEvents.call(this);
39707 this.mon(this.el, {
39709 click: this.onClick,
39710 change: this.onClick
39715 markInvalid : Ext.emptyFn,
39717 clearInvalid : Ext.emptyFn,
39720 onRender : function(ct, position){
39721 Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
39722 if(this.inputValue !== undefined){
39723 this.el.dom.value = this.inputValue;
39725 this.wrap = this.el.wrap({cls: 'x-form-check-wrap'});
39727 this.wrap.createChild({tag: 'label', htmlFor: this.el.id, cls: 'x-form-cb-label', html: this.boxLabel});
39730 this.setValue(true);
39732 this.checked = this.el.dom.checked;
39735 if (Ext.isIE && !Ext.isStrict) {
39736 this.wrap.repaint();
39738 this.resizeEl = this.positionEl = this.wrap;
39742 onDestroy : function(){
39743 Ext.destroy(this.wrap);
39744 Ext.form.Checkbox.superclass.onDestroy.call(this);
39748 initValue : function() {
39749 this.originalValue = this.getValue();
39753 getValue : function(){
39755 return this.el.dom.checked;
39757 return this.checked;
39761 onClick : function(){
39762 if(this.el.dom.checked != this.checked){
39763 this.setValue(this.el.dom.checked);
39768 setValue : function(v){
39769 var checked = this.checked ;
39770 this.checked = (v === true || v === 'true' || v == '1' || String(v).toLowerCase() == 'on');
39772 this.el.dom.checked = this.checked;
39773 this.el.dom.defaultChecked = this.checked;
39775 if(checked != this.checked){
39776 this.fireEvent('check', this, this.checked);
39778 this.handler.call(this.scope || this, this, this.checked);
39784 Ext.reg('checkbox', Ext.form.Checkbox);
39786 Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {
39795 blankText : "You must select at least one item in this group",
39798 defaultType : 'checkbox',
39801 groupCls : 'x-form-check-group',
39804 initComponent: function(){
39809 this.on('change', this.validate, this);
39810 Ext.form.CheckboxGroup.superclass.initComponent.call(this);
39814 onRender : function(ct, position){
39820 cls: this.groupCls,
39823 bufferResize: false
39826 xtype: 'container',
39827 defaultType: this.defaultType,
39835 if(this.items[0].items){
39839 Ext.apply(panelCfg, {
39840 layoutConfig: {columns: this.items.length},
39841 defaults: this.defaults,
39844 for(var i=0, len=this.items.length; i<len; i++){
39845 Ext.applyIf(this.items[i], colCfg);
39853 var numCols, cols = [];
39855 if(typeof this.columns == 'string'){
39856 this.columns = this.items.length;
39858 if(!Ext.isArray(this.columns)){
39860 for(var i=0; i<this.columns; i++){
39861 cs.push((100/this.columns)*.01);
39866 numCols = this.columns.length;
39869 for(var i=0; i<numCols; i++){
39870 var cc = Ext.apply({items:[]}, colCfg);
39871 cc[this.columns[i] <= 1 ? 'columnWidth' : 'width'] = this.columns[i];
39873 cc.defaults = Ext.apply(cc.defaults || {}, this.defaults);
39880 var rows = Math.ceil(this.items.length / numCols), ri = 0;
39881 for(var i=0, len=this.items.length; i<len; i++){
39882 if(i>0 && i%rows==0){
39885 if(this.items[i].fieldLabel){
39886 this.items[i].hideLabel = false;
39888 cols[ri].items.push(this.items[i]);
39891 for(var i=0, len=this.items.length; i<len; i++){
39892 var ci = i % numCols;
39893 if(this.items[i].fieldLabel){
39894 this.items[i].hideLabel = false;
39896 cols[ci].items.push(this.items[i]);
39900 Ext.apply(panelCfg, {
39901 layoutConfig: {columns: numCols},
39906 this.panel = new Ext.Container(panelCfg);
39907 this.panel.ownerCt = this;
39908 this.el = this.panel.getEl();
39910 if(this.forId && this.itemCls){
39911 var l = this.el.up(this.itemCls).child('label', true);
39913 l.setAttribute('htmlFor', this.forId);
39917 var fields = this.panel.findBy(function(c){
39918 return c.isFormField;
39921 this.items = new Ext.util.MixedCollection();
39922 this.items.addAll(fields);
39924 Ext.form.CheckboxGroup.superclass.onRender.call(this, ct, position);
39927 initValue : function(){
39929 this.setValue.apply(this, this.buffered ? this.value : [this.value]);
39930 delete this.buffered;
39935 afterRender : function(){
39936 Ext.form.CheckboxGroup.superclass.afterRender.call(this);
39937 this.eachItem(function(item){
39938 item.on('check', this.fireChecked, this);
39939 item.inGroup = true;
39944 doLayout: function(){
39947 this.panel.forceLayout = this.ownerCt.forceLayout;
39948 this.panel.doLayout();
39953 fireChecked: function(){
39955 this.eachItem(function(item){
39960 this.fireEvent('change', this, arr);
39964 getErrors: function() {
39965 var errors = Ext.form.CheckboxGroup.superclass.getErrors.apply(this, arguments);
39967 if (!this.allowBlank) {
39970 this.eachItem(function(f){
39972 return (blank = false);
39976 if (blank) errors.push(this.blankText);
39983 isDirty: function(){
39985 if (this.disabled || !this.rendered) {
39991 this.eachItem(function(item){
39992 if(item.isDirty()){
40002 setReadOnly : function(readOnly){
40004 this.eachItem(function(item){
40005 item.setReadOnly(readOnly);
40008 this.readOnly = readOnly;
40012 onDisable : function(){
40013 this.eachItem(function(item){
40019 onEnable : function(){
40020 this.eachItem(function(item){
40026 onResize : function(w, h){
40027 this.panel.setSize(w, h);
40028 this.panel.doLayout();
40032 reset : function(){
40033 if (this.originalValue) {
40035 this.eachItem(function(c){
40038 c.originalValue = c.getValue();
40043 this.resetOriginal = true;
40044 this.setValue(this.originalValue);
40045 delete this.resetOriginal;
40047 this.eachItem(function(c){
40056 this.clearInvalid();
40057 }).defer(50, this);
40061 setValue: function(){
40063 this.onSetValue.apply(this, arguments);
40065 this.buffered = true;
40066 this.value = arguments;
40072 onSetValue: function(id, value){
40073 if(arguments.length == 1){
40074 if(Ext.isArray(id)){
40075 Ext.each(id, function(val, idx){
40076 if (Ext.isObject(val) && val.setValue){
40077 val.setValue(true);
40078 if (this.resetOriginal === true) {
40079 val.originalValue = val.getValue();
40082 var item = this.items.itemAt(idx);
40084 item.setValue(val);
40088 }else if(Ext.isObject(id)){
40091 var f = this.getBox(i);
40097 this.setValueForItem(id);
40100 var f = this.getBox(id);
40108 beforeDestroy: function(){
40109 Ext.destroy(this.panel);
40110 Ext.form.CheckboxGroup.superclass.beforeDestroy.call(this);
40114 setValueForItem : function(val){
40115 val = String(val).split(',');
40116 this.eachItem(function(item){
40117 if(val.indexOf(item.inputValue)> -1){
40118 item.setValue(true);
40124 getBox : function(id){
40126 this.eachItem(function(f){
40127 if(id == f || f.dataIndex == id || f.id == id || f.getName() == id){
40136 getValue : function(){
40138 this.eachItem(function(item){
40147 eachItem: function(fn, scope) {
40148 if(this.items && this.items.each){
40149 this.items.each(fn, scope || this);
40156 getRawValue : Ext.emptyFn,
40159 setRawValue : Ext.emptyFn
40163 Ext.reg('checkboxgroup', Ext.form.CheckboxGroup);
40165 Ext.form.CompositeField = Ext.extend(Ext.form.Field, {
40168 defaultMargins: '0 5 0 0',
40171 skipLastItemMargin: true,
40177 combineErrors: true,
40180 labelConnector: ', ',
40184 initComponent: function() {
40186 items = this.items,
40189 for (var i=0, j = items.length; i < j; i++) {
40192 labels.push(item.fieldLabel);
40195 Ext.apply(item, this.defaults);
40198 if (!(i == j - 1 && this.skipLastItemMargin)) {
40199 Ext.applyIf(item, {margins: this.defaultMargins});
40203 this.fieldLabel = this.fieldLabel || this.buildLabel(labels);
40206 this.fieldErrors = new Ext.util.MixedCollection(true, function(item) {
40210 this.fieldErrors.on({
40212 add : this.updateInvalidMark,
40213 remove : this.updateInvalidMark,
40214 replace: this.updateInvalidMark
40217 Ext.form.CompositeField.superclass.initComponent.apply(this, arguments);
40221 onRender: function(ct, position) {
40224 var innerCt = this.innerCt = new Ext.Container({
40227 items : this.items,
40228 cls : 'x-form-composite',
40229 defaultMargins: '0 3 0 0'
40232 this.el = innerCt.getEl();
40234 var fields = innerCt.findBy(function(c) {
40235 return c.isFormField;
40239 this.items = new Ext.util.MixedCollection();
40240 this.items.addAll(fields);
40244 if (this.combineErrors) {
40245 this.eachItem(function(field) {
40247 markInvalid : this.onFieldMarkInvalid.createDelegate(this, [field], 0),
40248 clearInvalid: this.onFieldClearInvalid.createDelegate(this, [field], 0)
40254 var l = this.el.parent().parent().child('label', true);
40256 l.setAttribute('for', this.items.items[0].id);
40260 Ext.form.CompositeField.superclass.onRender.apply(this, arguments);
40264 onFieldMarkInvalid: function(field, message) {
40265 var name = field.getName(),
40266 error = {field: name, error: message};
40268 this.fieldErrors.replace(name, error);
40270 field.el.addClass(field.invalidClass);
40274 onFieldClearInvalid: function(field) {
40275 this.fieldErrors.removeKey(field.getName());
40277 field.el.removeClass(field.invalidClass);
40281 updateInvalidMark: function() {
40282 var ieStrict = Ext.isIE6 && Ext.isStrict;
40284 if (this.fieldErrors.length == 0) {
40285 this.clearInvalid();
40289 this.clearInvalid.defer(50, this);
40292 var message = this.buildCombinedErrorMessage(this.fieldErrors.items);
40295 this.markInvalid(message);
40299 this.markInvalid(message);
40305 validateValue: function() {
40308 this.eachItem(function(field) {
40309 if (!field.isValid()) valid = false;
40316 buildCombinedErrorMessage: function(errors) {
40320 for (var i = 0, j = errors.length; i < j; i++) {
40323 combined.push(String.format("{0}: {1}", error.field, error.error));
40326 return combined.join("<br />");
40330 sortErrors: function() {
40331 var fields = this.items;
40333 this.fieldErrors.sort("ASC", function(a, b) {
40334 var findByName = function(key) {
40335 return function(field) {
40336 return field.getName() == key;
40340 var aIndex = fields.findIndexBy(findByName(a.field)),
40341 bIndex = fields.findIndexBy(findByName(b.field));
40343 return aIndex < bIndex ? -1 : 1;
40348 reset: function() {
40349 this.eachItem(function(item) {
40356 this.clearInvalid();
40357 }).defer(50, this);
40361 clearInvalidChildren: function() {
40362 this.eachItem(function(item) {
40363 item.clearInvalid();
40368 buildLabel: function(segments) {
40369 return Ext.clean(segments).join(this.labelConnector);
40373 isDirty: function(){
40375 if (this.disabled || !this.rendered) {
40380 this.eachItem(function(item){
40381 if(item.isDirty()){
40390 eachItem: function(fn, scope) {
40391 if(this.items && this.items.each){
40392 this.items.each(fn, scope || this);
40397 onResize: function(adjWidth, adjHeight, rawWidth, rawHeight) {
40398 var innerCt = this.innerCt;
40400 if (this.rendered && innerCt.rendered) {
40401 innerCt.setSize(adjWidth, adjHeight);
40404 Ext.form.CompositeField.superclass.onResize.apply(this, arguments);
40408 doLayout: function(shallow, force) {
40409 if (this.rendered) {
40410 var innerCt = this.innerCt;
40412 innerCt.forceLayout = this.ownerCt.forceLayout;
40413 innerCt.doLayout(shallow, force);
40418 beforeDestroy: function(){
40419 Ext.destroy(this.innerCt);
40421 Ext.form.CompositeField.superclass.beforeDestroy.call(this);
40425 setReadOnly : function(readOnly) {
40426 readOnly = readOnly || true;
40429 this.eachItem(function(item){
40430 item.setReadOnly(readOnly);
40433 this.readOnly = readOnly;
40436 onShow : function() {
40437 Ext.form.CompositeField.superclass.onShow.call(this);
40442 onDisable : function(){
40443 this.eachItem(function(item){
40449 onEnable : function(){
40450 this.eachItem(function(item){
40456 Ext.reg('compositefield', Ext.form.CompositeField);
40458 Ext.form.Radio = Ext.extend(Ext.form.Checkbox, {
40459 inputType: 'radio',
40462 markInvalid : Ext.emptyFn,
40464 clearInvalid : Ext.emptyFn,
40467 getGroupValue : function(){
40468 var p = this.el.up('form') || Ext.getBody();
40469 var c = p.child('input[name='+this.el.dom.name+']:checked', true);
40470 return c ? c.value : null;
40474 onClick : function(){
40475 if(this.el.dom.checked != this.checked){
40476 var els = this.getCheckEl().select('input[name=' + this.el.dom.name + ']');
40477 els.each(function(el){
40478 if(el.dom.id == this.id){
40479 this.setValue(true);
40481 Ext.getCmp(el.dom.id).setValue(false);
40488 setValue : function(v){
40489 if (typeof v == 'boolean') {
40490 Ext.form.Radio.superclass.setValue.call(this, v);
40491 } else if (this.rendered) {
40492 var r = this.getCheckEl().child('input[name=' + this.el.dom.name + '][value=' + v + ']', true);
40494 Ext.getCmp(r.id).setValue(true);
40501 getCheckEl: function(){
40503 return this.el.up('.x-form-radio-group')
40505 return this.el.up('form') || Ext.getBody();
40508 Ext.reg('radio', Ext.form.Radio);
40510 Ext.form.RadioGroup = Ext.extend(Ext.form.CheckboxGroup, {
40515 blankText : 'You must select one item in this group',
40518 defaultType : 'radio',
40521 groupCls : 'x-form-radio-group',
40526 getValue : function(){
40528 this.eachItem(function(item){
40538 onSetValue : function(id, value){
40539 if(arguments.length > 1){
40540 var f = this.getBox(id);
40544 this.eachItem(function(item){
40546 item.setValue(false);
40552 this.setValueForItem(id);
40556 setValueForItem : function(val){
40557 val = String(val).split(',')[0];
40558 this.eachItem(function(item){
40559 item.setValue(val == item.inputValue);
40564 fireChecked : function(){
40565 if(!this.checkTask){
40566 this.checkTask = new Ext.util.DelayedTask(this.bufferChecked, this);
40568 this.checkTask.delay(10);
40572 bufferChecked : function(){
40574 this.eachItem(function(item){
40580 this.fireEvent('change', this, out);
40583 onDestroy : function(){
40584 if(this.checkTask){
40585 this.checkTask.cancel();
40586 this.checkTask = null;
40588 Ext.form.RadioGroup.superclass.onDestroy.call(this);
40593 Ext.reg('radiogroup', Ext.form.RadioGroup);
40595 Ext.form.Hidden = Ext.extend(Ext.form.Field, {
40597 inputType : 'hidden',
40600 onRender : function(){
40601 Ext.form.Hidden.superclass.onRender.apply(this, arguments);
40605 initEvents : function(){
40606 this.originalValue = this.getValue();
40610 setSize : Ext.emptyFn,
40611 setWidth : Ext.emptyFn,
40612 setHeight : Ext.emptyFn,
40613 setPosition : Ext.emptyFn,
40614 setPagePosition : Ext.emptyFn,
40615 markInvalid : Ext.emptyFn,
40616 clearInvalid : Ext.emptyFn
40618 Ext.reg('hidden', Ext.form.Hidden);
40619 Ext.form.BasicForm = Ext.extend(Ext.util.Observable, {
40621 constructor: function(el, config){
40622 Ext.apply(this, config);
40623 if(Ext.isString(this.paramOrder)){
40624 this.paramOrder = this.paramOrder.split(/[\s,|]/);
40627 this.items = new Ext.util.MixedCollection(false, function(o){
40628 return o.getItemId();
40642 Ext.form.BasicForm.superclass.constructor.call(this);
40657 paramOrder: undefined,
40660 paramsAsHash: false,
40663 waitTitle: 'Please Wait...',
40666 activeAction : null,
40669 trackResetOnLoad : false,
40675 initEl : function(el){
40676 this.el = Ext.get(el);
40677 this.id = this.el.id || Ext.id();
40678 if(!this.standardSubmit){
40679 this.el.on('submit', this.onSubmit, this);
40681 this.el.addClass('x-form');
40690 onSubmit : function(e){
40695 destroy: function(bound){
40696 if(bound !== true){
40697 this.items.each(function(f){
40700 Ext.destroy(this.el);
40702 this.items.clear();
40703 this.purgeListeners();
40707 isValid : function(){
40709 this.items.each(function(f){
40718 isDirty : function(){
40720 this.items.each(function(f){
40730 doAction : function(action, options){
40731 if(Ext.isString(action)){
40732 action = new Ext.form.Action.ACTION_TYPES[action](this, options);
40734 if(this.fireEvent('beforeaction', this, action) !== false){
40735 this.beforeAction(action);
40736 action.run.defer(100, action);
40742 submit : function(options){
40743 options = options || {};
40744 if(this.standardSubmit){
40745 var v = options.clientValidation === false || this.isValid();
40747 var el = this.el.dom;
40748 if(this.url && Ext.isEmpty(el.action)){
40749 el.action = this.url;
40755 var submitAction = String.format('{0}submit', this.api ? 'direct' : '');
40756 this.doAction(submitAction, options);
40761 load : function(options){
40762 var loadAction = String.format('{0}load', this.api ? 'direct' : '');
40763 this.doAction(loadAction, options);
40768 updateRecord : function(record){
40769 record.beginEdit();
40770 var fs = record.fields;
40771 fs.each(function(f){
40772 var field = this.findField(f.name);
40774 record.set(f.name, field.getValue());
40782 loadRecord : function(record){
40783 this.setValues(record.data);
40788 beforeAction : function(action){
40790 this.items.each(function(f){
40791 if(f.isFormField && f.syncValue){
40795 var o = action.options;
40797 if(this.waitMsgTarget === true){
40798 this.el.mask(o.waitMsg, 'x-mask-loading');
40799 }else if(this.waitMsgTarget){
40800 this.waitMsgTarget = Ext.get(this.waitMsgTarget);
40801 this.waitMsgTarget.mask(o.waitMsg, 'x-mask-loading');
40803 Ext.MessageBox.wait(o.waitMsg, o.waitTitle || this.waitTitle);
40809 afterAction : function(action, success){
40810 this.activeAction = null;
40811 var o = action.options;
40813 if(this.waitMsgTarget === true){
40815 }else if(this.waitMsgTarget){
40816 this.waitMsgTarget.unmask();
40818 Ext.MessageBox.updateProgress(1);
40819 Ext.MessageBox.hide();
40826 Ext.callback(o.success, o.scope, [this, action]);
40827 this.fireEvent('actioncomplete', this, action);
40829 Ext.callback(o.failure, o.scope, [this, action]);
40830 this.fireEvent('actionfailed', this, action);
40835 findField : function(id) {
40836 var field = this.items.get(id);
40838 if (!Ext.isObject(field)) {
40840 var findMatchingField = function(f) {
40841 if (f.isFormField) {
40842 if (f.dataIndex == id || f.id == id || f.getName() == id) {
40845 } else if (f.isComposite && f.rendered) {
40846 return f.items.each(findMatchingField);
40851 this.items.each(findMatchingField);
40853 return field || null;
40858 markInvalid : function(errors){
40859 if (Ext.isArray(errors)) {
40860 for(var i = 0, len = errors.length; i < len; i++){
40861 var fieldError = errors[i];
40862 var f = this.findField(fieldError.id);
40864 f.markInvalid(fieldError.msg);
40870 if(!Ext.isFunction(errors[id]) && (field = this.findField(id))){
40871 field.markInvalid(errors[id]);
40880 setValues : function(values){
40881 if(Ext.isArray(values)){
40882 for(var i = 0, len = values.length; i < len; i++){
40884 var f = this.findField(v.id);
40886 f.setValue(v.value);
40887 if(this.trackResetOnLoad){
40888 f.originalValue = f.getValue();
40895 if(!Ext.isFunction(values[id]) && (field = this.findField(id))){
40896 field.setValue(values[id]);
40897 if(this.trackResetOnLoad){
40898 field.originalValue = field.getValue();
40907 getValues : function(asString){
40908 var fs = Ext.lib.Ajax.serializeForm(this.el.dom);
40909 if(asString === true){
40912 return Ext.urlDecode(fs);
40916 getFieldValues : function(dirtyOnly){
40921 this.items.each(function(f) {
40922 if (dirtyOnly !== true || f.isDirty()) {
40925 val = f.getValue();
40927 if(Ext.isDefined(key)){
40928 if(Ext.isArray(key)){
40942 clearInvalid : function(){
40943 this.items.each(function(f){
40950 reset : function(){
40951 this.items.each(function(f){
40959 this.items.addAll(Array.prototype.slice.call(arguments, 0));
40964 remove : function(field){
40965 this.items.remove(field);
40970 cleanDestroyed : function() {
40971 this.items.filterBy(function(o) { return !!o.isDestroyed; }).each(this.remove, this);
40975 render : function(){
40976 this.items.each(function(f){
40977 if(f.isFormField && !f.rendered && document.getElementById(f.id)){
40978 f.applyToMarkup(f.id);
40985 applyToFields : function(o){
40986 this.items.each(function(f){
40993 applyIfToFields : function(o){
40994 this.items.each(function(f){
41000 callFieldMethod : function(fnName, args){
41002 this.items.each(function(f){
41003 if(Ext.isFunction(f[fnName])){
41004 f[fnName].apply(f, args);
41012 Ext.BasicForm = Ext.form.BasicForm;
41014 Ext.FormPanel = Ext.extend(Ext.Panel, {
41025 minButtonWidth : 75,
41028 labelAlign : 'left',
41031 monitorValid : false,
41040 initComponent : function(){
41041 this.form = this.createForm();
41042 Ext.FormPanel.superclass.initComponent.call(this);
41046 cls: this.baseCls + '-body',
41047 method : this.method || 'POST',
41048 id : this.formId || Ext.id()
41050 if(this.fileUpload) {
41051 this.bodyCfg.enctype = 'multipart/form-data';
41060 this.relayEvents(this.form, ['beforeaction', 'actionfailed', 'actioncomplete']);
41064 createForm : function(){
41065 var config = Ext.applyIf({listeners: {}}, this.initialConfig);
41066 return new Ext.form.BasicForm(null, config);
41070 initFields : function(){
41072 var formPanel = this;
41073 var fn = function(c){
41074 if(formPanel.isField(c)){
41076 }else if(c.findBy && c != formPanel){
41077 formPanel.applySettings(c);
41079 if(c.items && c.items.each){
41080 c.items.each(fn, this);
41084 this.items.each(fn, this);
41088 applySettings: function(c){
41089 var ct = c.ownerCt;
41091 labelAlign: ct.labelAlign,
41092 labelWidth: ct.labelWidth,
41093 itemCls: ct.itemCls
41098 getLayoutTarget : function(){
41099 return this.form.el;
41103 getForm : function(){
41108 onRender : function(ct, position){
41110 Ext.FormPanel.superclass.onRender.call(this, ct, position);
41111 this.form.initEl(this.body);
41115 beforeDestroy : function(){
41116 this.stopMonitoring();
41117 this.form.destroy(true);
41118 Ext.FormPanel.superclass.beforeDestroy.call(this);
41122 isField : function(c) {
41123 return !!c.setValue && !!c.getValue && !!c.markInvalid && !!c.clearInvalid;
41127 initEvents : function(){
41128 Ext.FormPanel.superclass.initEvents.call(this);
41132 add: this.onAddEvent,
41133 remove: this.onRemoveEvent
41135 if(this.monitorValid){
41136 this.startMonitoring();
41141 onAdd: function(c){
41142 Ext.FormPanel.superclass.onAdd.call(this, c);
41143 this.processAdd(c);
41147 onAddEvent: function(ct, c){
41149 this.processAdd(c);
41154 processAdd : function(c){
41156 if(this.isField(c)){
41159 }else if(c.findBy){
41160 this.applySettings(c);
41161 this.form.add.apply(this.form, c.findBy(this.isField));
41166 onRemove: function(c){
41167 Ext.FormPanel.superclass.onRemove.call(this, c);
41168 this.processRemove(c);
41171 onRemoveEvent: function(ct, c){
41173 this.processRemove(c);
41178 processRemove: function(c){
41179 if(!this.destroying){
41181 if(this.isField(c)){
41182 this.form.remove(c);
41184 }else if (c.findBy){
41185 Ext.each(c.findBy(this.isField), this.form.remove, this.form);
41186 if (c.isDestroyed) {
41187 this.form.cleanDestroyed();
41194 startMonitoring : function(){
41195 if(!this.validTask){
41196 this.validTask = new Ext.util.TaskRunner();
41197 this.validTask.start({
41198 run : this.bindHandler,
41199 interval : this.monitorPoll || 200,
41206 stopMonitoring : function(){
41207 if(this.validTask){
41208 this.validTask.stopAll();
41209 this.validTask = null;
41215 this.form.load.apply(this.form, arguments);
41219 onDisable : function(){
41220 Ext.FormPanel.superclass.onDisable.call(this);
41222 this.form.items.each(function(){
41229 onEnable : function(){
41230 Ext.FormPanel.superclass.onEnable.call(this);
41232 this.form.items.each(function(){
41239 bindHandler : function(){
41241 this.form.items.each(function(f){
41242 if(!f.isValid(true)){
41248 var fitems = this.fbar.items.items;
41249 for(var i = 0, len = fitems.length; i < len; i++){
41250 var btn = fitems[i];
41251 if(btn.formBind === true && btn.disabled === valid){
41252 btn.setDisabled(!valid);
41256 this.fireEvent('clientvalidation', this, valid);
41259 Ext.reg('form', Ext.FormPanel);
41261 Ext.form.FormPanel = Ext.FormPanel;
41263 Ext.form.FieldSet = Ext.extend(Ext.Panel, {
41270 baseCls : 'x-fieldset',
41274 animCollapse : false,
41277 onRender : function(ct, position){
41279 this.el = document.createElement('fieldset');
41280 this.el.id = this.id;
41281 if (this.title || this.header || this.checkboxToggle) {
41282 this.el.appendChild(document.createElement('legend')).className = this.baseCls + '-header';
41286 Ext.form.FieldSet.superclass.onRender.call(this, ct, position);
41288 if(this.checkboxToggle){
41289 var o = typeof this.checkboxToggle == 'object' ?
41290 this.checkboxToggle :
41291 {tag: 'input', type: 'checkbox', name: this.checkboxName || this.id+'-checkbox'};
41292 this.checkbox = this.header.insertFirst(o);
41293 this.checkbox.dom.checked = !this.collapsed;
41294 this.mon(this.checkbox, 'click', this.onCheckClick, this);
41299 onCollapse : function(doAnim, animArg){
41301 this.checkbox.dom.checked = false;
41303 Ext.form.FieldSet.superclass.onCollapse.call(this, doAnim, animArg);
41308 onExpand : function(doAnim, animArg){
41310 this.checkbox.dom.checked = true;
41312 Ext.form.FieldSet.superclass.onExpand.call(this, doAnim, animArg);
41316 onCheckClick : function(){
41317 this[this.checkbox.dom.checked ? 'expand' : 'collapse']();
41355 Ext.reg('fieldset', Ext.form.FieldSet);
41357 Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
41359 enableFormat : true,
41361 enableFontSize : true,
41363 enableColors : true,
41365 enableAlignments : true,
41367 enableLists : true,
41369 enableSourceEdit : true,
41371 enableLinks : true,
41375 createLinkText : 'Please enter the URL for the link:',
41377 defaultLinkValue : 'http:/'+'/',
41386 defaultFont: 'tahoma',
41388 defaultValue: (Ext.isOpera || Ext.isIE6) ? ' ' : '​',
41391 actionMode: 'wrap',
41392 validationEvent : false,
41394 initialized : false,
41396 sourceEditMode : false,
41397 onFocus : Ext.emptyFn,
41399 hideMode:'offsets',
41400 defaultAutoCreate : {
41402 style:"width:500px;height:300px;",
41403 autocomplete: "off"
41407 initComponent : function(){
41427 createFontOptions : function(){
41428 var buf = [], fs = this.fontFamilies, ff, lc;
41429 for(var i = 0, len = fs.length; i< len; i++){
41431 lc = ff.toLowerCase();
41433 '<option value="',lc,'" style="font-family:',ff,';"',
41434 (this.defaultFont == lc ? ' selected="true">' : '>'),
41439 return buf.join('');
41443 createToolbar : function(editor){
41445 var tipsEnabled = Ext.QuickTips && Ext.QuickTips.isEnabled();
41448 function btn(id, toggle, handler){
41451 cls : 'x-btn-icon',
41452 iconCls: 'x-edit-'+id,
41453 enableToggle:toggle !== false,
41455 handler:handler||editor.relayBtnCmd,
41456 clickEvent:'mousedown',
41457 tooltip: tipsEnabled ? editor.buttonTips[id] || undefined : undefined,
41458 overflowText: editor.buttonTips[id].title || undefined,
41464 if(this.enableFont && !Ext.isSafari2){
41465 var fontSelectItem = new Ext.Toolbar.Item({
41468 cls:'x-font-select',
41469 html: this.createFontOptions()
41479 if(this.enableFormat){
41487 if(this.enableFontSize){
41490 btn('increasefontsize', false, this.adjustFont),
41491 btn('decreasefontsize', false, this.adjustFont)
41495 if(this.enableColors){
41498 itemId:'forecolor',
41500 iconCls: 'x-edit-forecolor',
41501 clickEvent:'mousedown',
41502 tooltip: tipsEnabled ? editor.buttonTips.forecolor || undefined : undefined,
41504 menu : new Ext.menu.ColorMenu({
41505 allowReselect: true,
41506 focus: Ext.emptyFn,
41511 select: function(cp, color){
41512 this.execCmd('forecolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
41516 clickEvent:'mousedown'
41519 itemId:'backcolor',
41521 iconCls: 'x-edit-backcolor',
41522 clickEvent:'mousedown',
41523 tooltip: tipsEnabled ? editor.buttonTips.backcolor || undefined : undefined,
41525 menu : new Ext.menu.ColorMenu({
41526 focus: Ext.emptyFn,
41529 allowReselect: true,
41532 select: function(cp, color){
41534 this.execCmd('useCSS', false);
41535 this.execCmd('hilitecolor', color);
41536 this.execCmd('useCSS', true);
41539 this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
41544 clickEvent:'mousedown'
41550 if(this.enableAlignments){
41553 btn('justifyleft'),
41554 btn('justifycenter'),
41555 btn('justifyright')
41559 if(!Ext.isSafari2){
41560 if(this.enableLinks){
41563 btn('createlink', false, this.createLink)
41567 if(this.enableLists){
41570 btn('insertorderedlist'),
41571 btn('insertunorderedlist')
41574 if(this.enableSourceEdit){
41577 btn('sourceedit', true, function(btn){
41578 this.toggleSourceEdit(!this.sourceEditMode);
41585 var tb = new Ext.Toolbar({
41586 renderTo: this.wrap.dom.firstChild,
41590 if (fontSelectItem) {
41591 this.fontSelect = fontSelectItem.el;
41593 this.mon(this.fontSelect, 'change', function(){
41594 var font = this.fontSelect.dom.value;
41595 this.relayCmd('fontname', font);
41601 this.mon(tb.el, 'click', function(e){
41602 e.preventDefault();
41606 this.tb.doLayout();
41609 onDisable: function(){
41611 Ext.form.HtmlEditor.superclass.onDisable.call(this);
41614 onEnable: function(){
41615 this.wrap.unmask();
41616 Ext.form.HtmlEditor.superclass.onEnable.call(this);
41619 setReadOnly: function(readOnly){
41621 Ext.form.HtmlEditor.superclass.setReadOnly.call(this, readOnly);
41622 if(this.initialized){
41624 this.getEditorBody().contentEditable = !readOnly;
41626 this.setDesignMode(!readOnly);
41628 var bd = this.getEditorBody();
41630 bd.style.cursor = this.readOnly ? 'default' : 'text';
41632 this.disableItems(readOnly);
41637 getDocMarkup : function(){
41638 var h = Ext.fly(this.iframe).getHeight() - this.iframePad * 2;
41639 return String.format('<html><head><style type="text/css">body{border: 0; margin: 0; padding: {0}px; height: {1}px; cursor: text}</style></head><body></body></html>', this.iframePad, h);
41643 getEditorBody : function(){
41644 var doc = this.getDoc();
41645 return doc.body || doc.documentElement;
41649 getDoc : function(){
41650 return Ext.isIE ? this.getWin().document : (this.iframe.contentDocument || this.getWin().document);
41654 getWin : function(){
41655 return Ext.isIE ? this.iframe.contentWindow : window.frames[this.iframe.name];
41659 onRender : function(ct, position){
41660 Ext.form.HtmlEditor.superclass.onRender.call(this, ct, position);
41661 this.el.dom.style.border = '0 none';
41662 this.el.dom.setAttribute('tabIndex', -1);
41663 this.el.addClass('x-hidden');
41665 this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;');
41667 this.wrap = this.el.wrap({
41668 cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
41671 this.createToolbar(this);
41673 this.disableItems(true);
41675 this.tb.doLayout();
41677 this.createIFrame();
41680 var sz = this.el.getSize();
41681 this.setSize(sz.width, this.height || sz.height);
41683 this.resizeEl = this.positionEl = this.wrap;
41686 createIFrame: function(){
41687 var iframe = document.createElement('iframe');
41688 iframe.name = Ext.id();
41689 iframe.frameBorder = '0';
41690 iframe.style.overflow = 'auto';
41692 this.wrap.dom.appendChild(iframe);
41693 this.iframe = iframe;
41695 this.monitorTask = Ext.TaskMgr.start({
41696 run: this.checkDesignMode,
41702 initFrame : function(){
41703 Ext.TaskMgr.stop(this.monitorTask);
41704 var doc = this.getDoc();
41705 this.win = this.getWin();
41708 doc.write(this.getDocMarkup());
41713 var doc = this.getDoc();
41714 if(doc.body || doc.readyState == 'complete'){
41715 Ext.TaskMgr.stop(task);
41716 this.setDesignMode(true);
41717 this.initEditor.defer(10, this);
41724 Ext.TaskMgr.start(task);
41728 checkDesignMode : function(){
41729 if(this.wrap && this.wrap.dom.offsetWidth){
41730 var doc = this.getDoc();
41734 if(!doc.editorInitialized || this.getDesignMode() != 'on'){
41741 setDesignMode : function(mode){
41743 if(doc = this.getDoc()){
41747 doc.designMode = (/on|true/i).test(String(mode).toLowerCase()) ?'on':'off';
41753 getDesignMode : function(){
41754 var doc = this.getDoc();
41755 if(!doc){ return ''; }
41756 return String(doc.designMode).toLowerCase();
41760 disableItems: function(disabled){
41761 if(this.fontSelect){
41762 this.fontSelect.dom.disabled = disabled;
41764 this.tb.items.each(function(item){
41765 if(item.getItemId() != 'sourceedit'){
41766 item.setDisabled(disabled);
41772 onResize : function(w, h){
41773 Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments);
41774 if(this.el && this.iframe){
41775 if(Ext.isNumber(w)){
41776 var aw = w - this.wrap.getFrameWidth('lr');
41777 this.el.setWidth(aw);
41778 this.tb.setWidth(aw);
41779 this.iframe.style.width = Math.max(aw, 0) + 'px';
41781 if(Ext.isNumber(h)){
41782 var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight();
41783 this.el.setHeight(ah);
41784 this.iframe.style.height = Math.max(ah, 0) + 'px';
41785 var bd = this.getEditorBody();
41787 bd.style.height = Math.max((ah - (this.iframePad*2)), 0) + 'px';
41794 toggleSourceEdit : function(sourceEditMode){
41798 if (sourceEditMode === undefined) {
41799 sourceEditMode = !this.sourceEditMode;
41801 this.sourceEditMode = sourceEditMode === true;
41802 var btn = this.tb.getComponent('sourceedit');
41804 if (btn.pressed !== this.sourceEditMode) {
41805 btn.toggle(this.sourceEditMode);
41806 if (!btn.xtbHidden) {
41810 if (this.sourceEditMode) {
41812 this.previousSize = this.getSize();
41814 iframeHeight = Ext.get(this.iframe).getHeight();
41816 this.disableItems(true);
41818 this.iframe.className = 'x-hidden';
41819 this.el.removeClass('x-hidden');
41820 this.el.dom.removeAttribute('tabIndex');
41822 this.el.dom.style.height = iframeHeight + 'px';
41825 elHeight = parseInt(this.el.dom.style.height, 10);
41826 if (this.initialized) {
41827 this.disableItems(this.readOnly);
41830 this.iframe.className = '';
41831 this.el.addClass('x-hidden');
41832 this.el.dom.setAttribute('tabIndex', -1);
41835 this.setSize(this.previousSize);
41836 delete this.previousSize;
41837 this.iframe.style.height = elHeight + 'px';
41839 this.fireEvent('editmodechange', this, this.sourceEditMode);
41843 createLink : function() {
41844 var url = prompt(this.createLinkText, this.defaultLinkValue);
41845 if(url && url != 'http:/'+'/'){
41846 this.relayCmd('createlink', url);
41851 initEvents : function(){
41852 this.originalValue = this.getValue();
41856 markInvalid : Ext.emptyFn,
41859 clearInvalid : Ext.emptyFn,
41862 setValue : function(v){
41863 Ext.form.HtmlEditor.superclass.setValue.call(this, v);
41869 cleanHtml: function(html) {
41870 html = String(html);
41872 html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');
41876 if(html.charCodeAt(0) == this.defaultValue.replace(/\D/g, '')){
41877 html = html.substring(1);
41883 syncValue : function(){
41884 if(this.initialized){
41885 var bd = this.getEditorBody();
41886 var html = bd.innerHTML;
41888 var bs = bd.getAttribute('style');
41889 var m = bs.match(/text-align:(.*?);/i);
41891 html = '<div style="'+m[0]+'">' + html + '</div>';
41894 html = this.cleanHtml(html);
41895 if(this.fireEvent('beforesync', this, html) !== false){
41896 this.el.dom.value = html;
41897 this.fireEvent('sync', this, html);
41903 getValue : function() {
41904 this[this.sourceEditMode ? 'pushValue' : 'syncValue']();
41905 return Ext.form.HtmlEditor.superclass.getValue.call(this);
41909 pushValue : function(){
41910 if(this.initialized){
41911 var v = this.el.dom.value;
41912 if(!this.activated && v.length < 1){
41913 v = this.defaultValue;
41915 if(this.fireEvent('beforepush', this, v) !== false){
41916 this.getEditorBody().innerHTML = v;
41919 this.setDesignMode(false);
41920 this.setDesignMode(true);
41922 this.fireEvent('push', this, v);
41929 deferFocus : function(){
41930 this.focus.defer(10, this);
41934 focus : function(){
41935 if(this.win && !this.sourceEditMode){
41943 initEditor : function(){
41946 var dbody = this.getEditorBody(),
41947 ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat', 'background-color', 'color'),
41951 ss['background-attachment'] = 'fixed';
41952 dbody.bgProperties = 'fixed';
41954 Ext.DomHelper.applyStyles(dbody, ss);
41956 doc = this.getDoc();
41960 Ext.EventManager.removeAll(doc);
41965 fn = this.onEditorEvent.createDelegate(this);
41966 Ext.EventManager.on(doc, {
41975 Ext.EventManager.on(doc, 'keypress', this.applyCommand, this);
41977 if(Ext.isIE || Ext.isWebKit || Ext.isOpera){
41978 Ext.EventManager.on(doc, 'keydown', this.fixKeys, this);
41980 doc.editorInitialized = true;
41981 this.initialized = true;
41983 this.setReadOnly(this.readOnly);
41984 this.fireEvent('initialize', this);
41989 onDestroy : function(){
41990 if(this.monitorTask){
41991 Ext.TaskMgr.stop(this.monitorTask);
41994 Ext.destroy(this.tb);
41995 var doc = this.getDoc();
41998 Ext.EventManager.removeAll(doc);
41999 for (var prop in doc){
42005 this.wrap.dom.innerHTML = '';
42006 this.wrap.remove();
42011 this.el.removeAllListeners();
42014 this.purgeListeners();
42018 onFirstFocus : function(){
42019 this.activated = true;
42020 this.disableItems(this.readOnly);
42023 var s = this.win.getSelection();
42024 if(!s.focusNode || s.focusNode.nodeType != 3){
42025 var r = s.getRangeAt(0);
42026 r.selectNodeContents(this.getEditorBody());
42031 this.execCmd('useCSS', true);
42032 this.execCmd('styleWithCSS', false);
42035 this.fireEvent('activate', this);
42039 adjustFont: function(btn){
42040 var adjust = btn.getItemId() == 'increasefontsize' ? 1 : -1,
42041 doc = this.getDoc(),
42042 v = parseInt(doc.queryCommandValue('FontSize') || 2, 10);
42043 if((Ext.isSafari && !Ext.isSafari2) || Ext.isChrome || Ext.isAir){
42059 v = v.constrain(1, 6);
42064 v = Math.max(1, v+adjust) + (Ext.isSafari ? 'px' : 0);
42066 this.execCmd('FontSize', v);
42070 onEditorEvent : function(e){
42071 this.updateToolbar();
42076 updateToolbar: function(){
42082 if(!this.activated){
42083 this.onFirstFocus();
42087 var btns = this.tb.items.map,
42088 doc = this.getDoc();
42090 if(this.enableFont && !Ext.isSafari2){
42091 var name = (doc.queryCommandValue('FontName')||this.defaultFont).toLowerCase();
42092 if(name != this.fontSelect.dom.value){
42093 this.fontSelect.dom.value = name;
42096 if(this.enableFormat){
42097 btns.bold.toggle(doc.queryCommandState('bold'));
42098 btns.italic.toggle(doc.queryCommandState('italic'));
42099 btns.underline.toggle(doc.queryCommandState('underline'));
42101 if(this.enableAlignments){
42102 btns.justifyleft.toggle(doc.queryCommandState('justifyleft'));
42103 btns.justifycenter.toggle(doc.queryCommandState('justifycenter'));
42104 btns.justifyright.toggle(doc.queryCommandState('justifyright'));
42106 if(!Ext.isSafari2 && this.enableLists){
42107 btns.insertorderedlist.toggle(doc.queryCommandState('insertorderedlist'));
42108 btns.insertunorderedlist.toggle(doc.queryCommandState('insertunorderedlist'));
42111 Ext.menu.MenuMgr.hideAll();
42117 relayBtnCmd : function(btn){
42118 this.relayCmd(btn.getItemId());
42122 relayCmd : function(cmd, value){
42125 this.execCmd(cmd, value);
42126 this.updateToolbar();
42127 }).defer(10, this);
42131 execCmd : function(cmd, value){
42132 var doc = this.getDoc();
42133 doc.execCommand(cmd, false, value === undefined ? null : value);
42138 applyCommand : function(e){
42140 var c = e.getCharCode(), cmd;
42142 c = String.fromCharCode(c);
42158 e.preventDefault();
42165 insertAtCursor : function(text){
42166 if(!this.activated){
42171 var doc = this.getDoc(),
42172 r = doc.selection.createRange();
42180 this.execCmd('InsertHTML', text);
42186 fixKeys : function(){
42188 return function(e){
42189 var k = e.getKey(),
42190 doc = this.getDoc(),
42194 r = doc.selection.createRange();
42197 r.pasteHTML(' ');
42200 }else if(k == e.ENTER){
42201 r = doc.selection.createRange();
42203 var target = r.parentElement();
42204 if(!target || target.tagName.toLowerCase() != 'li'){
42206 r.pasteHTML('<br />');
42213 }else if(Ext.isOpera){
42214 return function(e){
42215 var k = e.getKey();
42219 this.execCmd('InsertHTML',' ');
42223 }else if(Ext.isWebKit){
42224 return function(e){
42225 var k = e.getKey();
42228 this.execCmd('InsertText','\t');
42230 }else if(k == e.ENTER){
42232 this.execCmd('InsertHtml','<br /><br />');
42240 getToolbar : function(){
42247 title: 'Bold (Ctrl+B)',
42248 text: 'Make the selected text bold.',
42249 cls: 'x-html-editor-tip'
42252 title: 'Italic (Ctrl+I)',
42253 text: 'Make the selected text italic.',
42254 cls: 'x-html-editor-tip'
42257 title: 'Underline (Ctrl+U)',
42258 text: 'Underline the selected text.',
42259 cls: 'x-html-editor-tip'
42261 increasefontsize : {
42262 title: 'Grow Text',
42263 text: 'Increase the font size.',
42264 cls: 'x-html-editor-tip'
42266 decreasefontsize : {
42267 title: 'Shrink Text',
42268 text: 'Decrease the font size.',
42269 cls: 'x-html-editor-tip'
42272 title: 'Text Highlight Color',
42273 text: 'Change the background color of the selected text.',
42274 cls: 'x-html-editor-tip'
42277 title: 'Font Color',
42278 text: 'Change the color of the selected text.',
42279 cls: 'x-html-editor-tip'
42282 title: 'Align Text Left',
42283 text: 'Align text to the left.',
42284 cls: 'x-html-editor-tip'
42287 title: 'Center Text',
42288 text: 'Center text in the editor.',
42289 cls: 'x-html-editor-tip'
42292 title: 'Align Text Right',
42293 text: 'Align text to the right.',
42294 cls: 'x-html-editor-tip'
42296 insertunorderedlist : {
42297 title: 'Bullet List',
42298 text: 'Start a bulleted list.',
42299 cls: 'x-html-editor-tip'
42301 insertorderedlist : {
42302 title: 'Numbered List',
42303 text: 'Start a numbered list.',
42304 cls: 'x-html-editor-tip'
42307 title: 'Hyperlink',
42308 text: 'Make the selected text a hyperlink.',
42309 cls: 'x-html-editor-tip'
42312 title: 'Source Edit',
42313 text: 'Switch to source editing mode.',
42314 cls: 'x-html-editor-tip'
42353 Ext.reg('htmleditor', Ext.form.HtmlEditor);
42355 Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {
42357 minValue : undefined,
42359 maxValue : undefined,
42361 minText : "The time in this field must be equal to or after {0}",
42363 maxText : "The time in this field must be equal to or before {0}",
42365 invalidText : "{0} is not a valid time",
42369 altFormats : "g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H|gi a|hi a|giA|hiA|gi A|hi A",
42376 triggerAction: 'all',
42383 initDate: '1/1/2008',
42385 initDateFormat: 'j/n/Y',
42388 initComponent : function(){
42389 if(Ext.isDefined(this.minValue)){
42390 this.setMinValue(this.minValue, true);
42392 if(Ext.isDefined(this.maxValue)){
42393 this.setMaxValue(this.maxValue, true);
42396 this.generateStore(true);
42398 Ext.form.TimeField.superclass.initComponent.call(this);
42402 setMinValue: function(value, initial){
42403 this.setLimit(value, true, initial);
42408 setMaxValue: function(value, initial){
42409 this.setLimit(value, false, initial);
42414 generateStore: function(initial){
42415 var min = this.minValue || new Date(this.initDate).clearTime(),
42416 max = this.maxValue || new Date(this.initDate).clearTime().add('mi', (24 * 60) - 1),
42420 times.push(min.dateFormat(this.format));
42421 min = min.add('mi', this.increment);
42423 this.bindStore(times, initial);
42427 setLimit: function(value, isMin, initial){
42429 if(Ext.isString(value)){
42430 d = this.parseDate(value);
42431 }else if(Ext.isDate(value)){
42435 var val = new Date(this.initDate).clearTime();
42436 val.setHours(d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
42437 this[isMin ? 'minValue' : 'maxValue'] = val;
42439 this.generateStore();
42445 getValue : function(){
42446 var v = Ext.form.TimeField.superclass.getValue.call(this);
42447 return this.formatDate(this.parseDate(v)) || '';
42451 setValue : function(value){
42452 return Ext.form.TimeField.superclass.setValue.call(this, this.formatDate(this.parseDate(value)));
42456 validateValue : Ext.form.DateField.prototype.validateValue,
42458 formatDate : Ext.form.DateField.prototype.formatDate,
42460 parseDate: function(value) {
42461 if (!value || Ext.isDate(value)) {
42465 var id = this.initDate + ' ',
42466 idf = this.initDateFormat + ' ',
42467 v = Date.parseDate(id + value, idf + this.format),
42468 af = this.altFormats;
42471 if (!this.altFormatsArray) {
42472 this.altFormatsArray = af.split("|");
42474 for (var i = 0, afa = this.altFormatsArray, len = afa.length; i < len && !v; i++) {
42475 v = Date.parseDate(id + value, idf + afa[i]);
42482 Ext.reg('timefield', Ext.form.TimeField);
42483 Ext.form.SliderField = Ext.extend(Ext.form.Field, {
42492 actionMode: 'wrap',
42495 initComponent : function() {
42496 var cfg = Ext.copyTo({
42497 id: this.id + '-slider'
42498 }, this.initialConfig, ['vertical', 'minValue', 'maxValue', 'decimalPrecision', 'keyIncrement', 'increment', 'clickToChange', 'animate']);
42501 if (this.useTips) {
42502 var plug = this.tipText ? {getText: this.tipText} : {};
42503 cfg.plugins = [new Ext.slider.Tip(plug)];
42505 this.slider = new Ext.Slider(cfg);
42506 Ext.form.SliderField.superclass.initComponent.call(this);
42510 onRender : function(ct, position){
42511 this.autoCreate = {
42517 Ext.form.SliderField.superclass.onRender.call(this, ct, position);
42518 this.wrap = this.el.wrap({cls: 'x-form-field-wrap'});
42519 this.resizeEl = this.positionEl = this.wrap;
42520 this.slider.render(this.wrap);
42524 onResize : function(w, h, aw, ah){
42525 Ext.form.SliderField.superclass.onResize.call(this, w, h, aw, ah);
42526 this.slider.setSize(w, h);
42530 initEvents : function(){
42531 Ext.form.SliderField.superclass.initEvents.call(this);
42532 this.slider.on('change', this.onChange, this);
42536 onChange : function(slider, v){
42537 this.setValue(v, undefined, true);
42541 onEnable : function(){
42542 Ext.form.SliderField.superclass.onEnable.call(this);
42543 this.slider.enable();
42547 onDisable : function(){
42548 Ext.form.SliderField.superclass.onDisable.call(this);
42549 this.slider.disable();
42553 beforeDestroy : function(){
42554 Ext.destroy(this.slider);
42555 Ext.form.SliderField.superclass.beforeDestroy.call(this);
42559 alignErrorIcon : function(){
42560 this.errorIcon.alignTo(this.slider.el, 'tl-tr', [2, 0]);
42564 setMinValue : function(v){
42565 this.slider.setMinValue(v);
42570 setMaxValue : function(v){
42571 this.slider.setMaxValue(v);
42576 setValue : function(v, animate, silent){
42580 this.slider.setValue(v, animate);
42582 return Ext.form.SliderField.superclass.setValue.call(this, this.slider.getValue());
42586 getValue : function(){
42587 return this.slider.getValue();
42591 Ext.reg('sliderfield', Ext.form.SliderField);
42592 Ext.form.Label = Ext.extend(Ext.BoxComponent, {
42598 onRender : function(ct, position){
42600 this.el = document.createElement('label');
42601 this.el.id = this.getId();
42602 this.el.innerHTML = this.text ? Ext.util.Format.htmlEncode(this.text) : (this.html || '');
42604 this.el.setAttribute('for', this.forId);
42607 Ext.form.Label.superclass.onRender.call(this, ct, position);
42611 setText : function(t, encode){
42612 var e = encode === false;
42613 this[!e ? 'text' : 'html'] = t;
42614 delete this[e ? 'text' : 'html'];
42616 this.el.dom.innerHTML = encode !== false ? Ext.util.Format.htmlEncode(t) : t;
42622 Ext.reg('label', Ext.form.Label);
42623 Ext.form.Action = function(form, options){
42625 this.options = options || {};
42629 Ext.form.Action.CLIENT_INVALID = 'client';
42631 Ext.form.Action.SERVER_INVALID = 'server';
42633 Ext.form.Action.CONNECT_FAILURE = 'connect';
42635 Ext.form.Action.LOAD_FAILURE = 'load';
42637 Ext.form.Action.prototype = {
42658 run : function(options){
42663 success : function(response){
42668 handleResponse : function(response){
42673 failure : function(response){
42674 this.response = response;
42675 this.failureType = Ext.form.Action.CONNECT_FAILURE;
42676 this.form.afterAction(this, false);
42682 processResponse : function(response){
42683 this.response = response;
42684 if(!response.responseText && !response.responseXML){
42687 this.result = this.handleResponse(response);
42688 return this.result;
42692 getUrl : function(appendParams){
42693 var url = this.options.url || this.form.url || this.form.el.dom.action;
42695 var p = this.getParams();
42697 url = Ext.urlAppend(url, p);
42704 getMethod : function(){
42705 return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();
42709 getParams : function(){
42710 var bp = this.form.baseParams;
42711 var p = this.options.params;
42713 if(typeof p == "object"){
42714 p = Ext.urlEncode(Ext.applyIf(p, bp));
42715 }else if(typeof p == 'string' && bp){
42716 p += '&' + Ext.urlEncode(bp);
42719 p = Ext.urlEncode(bp);
42725 createCallback : function(opts){
42726 var opts = opts || {};
42728 success: this.success,
42729 failure: this.failure,
42731 timeout: (opts.timeout*1000) || (this.form.timeout*1000),
42732 upload: this.form.fileUpload ? this.success : undefined
42738 Ext.form.Action.Submit = function(form, options){
42739 Ext.form.Action.Submit.superclass.constructor.call(this, form, options);
42742 Ext.extend(Ext.form.Action.Submit, Ext.form.Action, {
42749 var o = this.options,
42750 method = this.getMethod(),
42751 isGet = method == 'GET';
42752 if(o.clientValidation === false || this.form.isValid()){
42753 if (o.submitEmptyText === false) {
42754 var fields = this.form.items,
42756 fields.each(function(f) {
42757 if (f.el.getValue() == f.emptyText) {
42758 emptyFields.push(f);
42759 f.el.dom.value = "";
42763 Ext.Ajax.request(Ext.apply(this.createCallback(o), {
42764 form:this.form.el.dom,
42765 url:this.getUrl(isGet),
42767 headers: o.headers,
42768 params:!isGet ? this.getParams() : null,
42769 isUpload: this.form.fileUpload
42771 if (o.submitEmptyText === false) {
42772 Ext.each(emptyFields, function(f) {
42773 if (f.applyEmptyText) {
42774 f.applyEmptyText();
42778 }else if (o.clientValidation !== false){
42779 this.failureType = Ext.form.Action.CLIENT_INVALID;
42780 this.form.afterAction(this, false);
42785 success : function(response){
42786 var result = this.processResponse(response);
42787 if(result === true || result.success){
42788 this.form.afterAction(this, true);
42792 this.form.markInvalid(result.errors);
42794 this.failureType = Ext.form.Action.SERVER_INVALID;
42795 this.form.afterAction(this, false);
42799 handleResponse : function(response){
42800 if(this.form.errorReader){
42801 var rs = this.form.errorReader.read(response);
42804 for(var i = 0, len = rs.records.length; i < len; i++) {
42805 var r = rs.records[i];
42806 errors[i] = r.data;
42809 if(errors.length < 1){
42813 success : rs.success,
42817 return Ext.decode(response.responseText);
42823 Ext.form.Action.Load = function(form, options){
42824 Ext.form.Action.Load.superclass.constructor.call(this, form, options);
42825 this.reader = this.form.reader;
42828 Ext.extend(Ext.form.Action.Load, Ext.form.Action, {
42834 Ext.Ajax.request(Ext.apply(
42835 this.createCallback(this.options), {
42836 method:this.getMethod(),
42837 url:this.getUrl(false),
42838 headers: this.options.headers,
42839 params:this.getParams()
42844 success : function(response){
42845 var result = this.processResponse(response);
42846 if(result === true || !result.success || !result.data){
42847 this.failureType = Ext.form.Action.LOAD_FAILURE;
42848 this.form.afterAction(this, false);
42851 this.form.clearInvalid();
42852 this.form.setValues(result.data);
42853 this.form.afterAction(this, true);
42857 handleResponse : function(response){
42858 if(this.form.reader){
42859 var rs = this.form.reader.read(response);
42860 var data = rs.records && rs.records[0] ? rs.records[0].data : null;
42862 success : rs.success,
42866 return Ext.decode(response.responseText);
42873 Ext.form.Action.DirectLoad = Ext.extend(Ext.form.Action.Load, {
42874 constructor: function(form, opts) {
42875 Ext.form.Action.DirectLoad.superclass.constructor.call(this, form, opts);
42877 type : 'directload',
42880 var args = this.getParams();
42881 args.push(this.success, this);
42882 this.form.api.load.apply(window, args);
42885 getParams : function() {
42886 var buf = [], o = {};
42887 var bp = this.form.baseParams;
42888 var p = this.options.params;
42889 Ext.apply(o, p, bp);
42890 var paramOrder = this.form.paramOrder;
42892 for(var i = 0, len = paramOrder.length; i < len; i++){
42893 buf.push(o[paramOrder[i]]);
42895 }else if(this.form.paramsAsHash){
42903 processResponse : function(result) {
42904 this.result = result;
42908 success : function(response, trans){
42909 if(trans.type == Ext.Direct.exceptions.SERVER){
42912 Ext.form.Action.DirectLoad.superclass.success.call(this, response);
42917 Ext.form.Action.DirectSubmit = Ext.extend(Ext.form.Action.Submit, {
42918 constructor : function(form, opts) {
42919 Ext.form.Action.DirectSubmit.superclass.constructor.call(this, form, opts);
42921 type : 'directsubmit',
42924 var o = this.options;
42925 if(o.clientValidation === false || this.form.isValid()){
42928 this.success.params = this.getParams();
42929 this.form.api.submit(this.form.el.dom, this.success, this);
42930 }else if (o.clientValidation !== false){
42931 this.failureType = Ext.form.Action.CLIENT_INVALID;
42932 this.form.afterAction(this, false);
42936 getParams : function() {
42938 var bp = this.form.baseParams;
42939 var p = this.options.params;
42940 Ext.apply(o, p, bp);
42946 processResponse : function(result) {
42947 this.result = result;
42951 success : function(response, trans){
42952 if(trans.type == Ext.Direct.exceptions.SERVER){
42955 Ext.form.Action.DirectSubmit.superclass.success.call(this, response);
42959 Ext.form.Action.ACTION_TYPES = {
42960 'load' : Ext.form.Action.Load,
42961 'submit' : Ext.form.Action.Submit,
42962 'directload' : Ext.form.Action.DirectLoad,
42963 'directsubmit' : Ext.form.Action.DirectSubmit
42966 Ext.form.VTypes = function(){
42968 var alpha = /^[a-zA-Z_]+$/,
42969 alphanum = /^[a-zA-Z0-9_]+$/,
42970 email = /^(\w+)([\-+.][\w]+)*@(\w[\-\w]*\.){1,5}([A-Za-z]){2,6}$/,
42971 url = /(((^https?)|(^ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
42976 'email' : function(v){
42977 return email.test(v);
42980 'emailText' : 'This field should be an e-mail address in the format "user@example.com"',
42982 'emailMask' : /[a-z0-9_\.\-@\+]/i,
42985 'url' : function(v){
42986 return url.test(v);
42989 'urlText' : 'This field should be a URL in the format "http:/'+'/www.example.com"',
42992 'alpha' : function(v){
42993 return alpha.test(v);
42996 'alphaText' : 'This field should only contain letters and _',
42998 'alphaMask' : /[a-z_]/i,
43001 'alphanum' : function(v){
43002 return alphanum.test(v);
43005 'alphanumText' : 'This field should only contain letters, numbers and _',
43007 'alphanumMask' : /[a-z0-9_]/i
43011 Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
43013 autoExpandColumn : false,
43015 autoExpandMax : 1000,
43017 autoExpandMin : 50,
43019 columnLines : false,
43025 ddText : '{0} selected row{1}',
43027 deferRowRender : true,
43031 enableColumnHide : true,
43033 enableColumnMove : true,
43035 enableDragDrop : false,
43037 enableHdMenu : true,
43043 minColumnWidth : 25,
43048 stripeRows : false,
43050 trackMouseOver : true,
43052 stateEvents : ['columnmove', 'columnresize', 'sortchange', 'groupchange'],
43067 initComponent : function(){
43068 Ext.grid.GridPanel.superclass.initComponent.call(this);
43070 if(this.columnLines){
43071 this.cls = (this.cls || '') + ' x-grid-with-col-lines';
43075 this.autoScroll = false;
43076 this.autoWidth = false;
43078 if(Ext.isArray(this.columns)){
43079 this.colModel = new Ext.grid.ColumnModel(this.columns);
43080 delete this.columns;
43085 this.store = this.ds;
43089 this.colModel = this.cm;
43093 this.selModel = this.sm;
43096 this.store = Ext.StoreMgr.lookup(this.store);
43131 'rowbodymousedown',
43134 'containermousedown',
43155 'containerdblclick',
43167 'headercontextmenu',
43169 'groupcontextmenu',
43171 'containercontextmenu',
43173 'rowbodycontextmenu',
43192 onRender : function(ct, position){
43193 Ext.grid.GridPanel.superclass.onRender.apply(this, arguments);
43195 var c = this.getGridEl();
43197 this.el.addClass('x-grid-panel');
43201 mousedown: this.onMouseDown,
43202 click: this.onClick,
43203 dblclick: this.onDblClick,
43204 contextmenu: this.onContextMenu
43207 this.relayEvents(c, ['mousedown','mouseup','mouseover','mouseout','keypress', 'keydown']);
43209 var view = this.getView();
43212 this.getSelectionModel().init(this);
43216 initEvents : function(){
43217 Ext.grid.GridPanel.superclass.initEvents.call(this);
43220 this.loadMask = new Ext.LoadMask(this.bwrap,
43221 Ext.apply({store:this.store}, this.loadMask));
43225 initStateEvents : function(){
43226 Ext.grid.GridPanel.superclass.initStateEvents.call(this);
43227 this.mon(this.colModel, 'hiddenchange', this.saveState, this, {delay: 100});
43230 applyState : function(state){
43231 var cm = this.colModel,
43232 cs = state.columns,
43233 store = this.store,
43239 for(var i = 0, len = cs.length; i < len; i++){
43241 c = cm.getColumnById(s.id);
43247 oldIndex = cm.getIndexById(s.id);
43249 cm.moveColumn(oldIndex, i);
43257 store[store.remoteSort ? 'setDefaultSort' : 'sort'](s.field, s.direction);
43264 store.clearGrouping();
43269 var o = Ext.apply({}, state);
43272 Ext.grid.GridPanel.superclass.applyState.call(this, o);
43275 getState : function(){
43276 var o = {columns: []},
43277 store = this.store,
43281 for(var i = 0, c; (c = this.colModel.config[i]); i++){
43287 o.columns[i].hidden = true;
43291 ss = store.getSortState();
43295 if(store.getGroupState){
43296 gs = store.getGroupState();
43306 afterRender : function(){
43307 Ext.grid.GridPanel.superclass.afterRender.call(this);
43309 this.on('bodyresize', v.layout, v);
43311 if(this.deferRowRender){
43312 if (!this.deferRowRenderTask){
43313 this.deferRowRenderTask = new Ext.util.DelayedTask(v.afterRender, this.view);
43315 this.deferRowRenderTask.delay(10);
43319 this.viewReady = true;
43323 reconfigure : function(store, colModel){
43324 var rendered = this.rendered;
43327 this.loadMask.destroy();
43328 this.loadMask = new Ext.LoadMask(this.bwrap,
43329 Ext.apply({}, {store:store}, this.initialConfig.loadMask));
43333 this.view.initData(store, colModel);
43335 this.store = store;
43336 this.colModel = colModel;
43338 this.view.refresh(true);
43340 this.fireEvent('reconfigure', this, store, colModel);
43344 onDestroy : function(){
43345 if (this.deferRowRenderTask && this.deferRowRenderTask.cancel){
43346 this.deferRowRenderTask.cancel();
43349 Ext.destroy(this.view, this.loadMask);
43350 }else if(this.store && this.store.autoDestroy){
43351 this.store.destroy();
43353 Ext.destroy(this.colModel, this.selModel);
43354 this.store = this.selModel = this.colModel = this.view = this.loadMask = null;
43355 Ext.grid.GridPanel.superclass.onDestroy.call(this);
43359 processEvent : function(name, e){
43360 this.view.processEvent(name, e);
43364 onClick : function(e){
43365 this.processEvent('click', e);
43369 onMouseDown : function(e){
43370 this.processEvent('mousedown', e);
43374 onContextMenu : function(e, t){
43375 this.processEvent('contextmenu', e);
43379 onDblClick : function(e){
43380 this.processEvent('dblclick', e);
43384 walkCells : function(row, col, step, fn, scope){
43385 var cm = this.colModel,
43386 clen = cm.getColumnCount(),
43388 rlen = ds.getCount(),
43402 if(fn.call(scope || this, row, col, cm) === true){
43420 if(fn.call(scope || this, row, col, cm) === true){
43432 getGridEl : function(){
43437 stopEditing : Ext.emptyFn,
43440 getSelectionModel : function(){
43441 if(!this.selModel){
43442 this.selModel = new Ext.grid.RowSelectionModel(
43443 this.disableSelection ? {selectRow: Ext.emptyFn} : null);
43445 return this.selModel;
43449 getStore : function(){
43454 getColumnModel : function(){
43455 return this.colModel;
43459 getView : function(){
43461 this.view = new Ext.grid.GridView(this.viewConfig);
43466 getDragDropText : function(){
43467 var count = this.selModel.getCount();
43468 return String.format(this.ddText, count, count == 1 ? '' : 's');
43522 Ext.reg('grid', Ext.grid.GridPanel);
43523 Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
43535 deferEmptyText : true,
43538 scrollOffset : undefined,
43547 sortClasses : ['sort-asc', 'sort-desc'],
43550 sortAscText : 'Sort Ascending',
43553 sortDescText : 'Sort Descending',
43556 columnsText : 'Columns',
43559 selectedRowClass : 'x-grid3-row-selected',
43563 tdClass : 'x-grid3-cell',
43564 hdCls : 'x-grid3-hd',
43568 cellSelectorDepth : 4,
43570 rowSelectorDepth : 10,
43573 rowBodySelectorDepth : 10,
43576 cellSelector : 'td.x-grid3-cell',
43578 rowSelector : 'div.x-grid3-row',
43581 rowBodySelector : 'div.x-grid3-row-body',
43584 firstRowCls: 'x-grid3-row-first',
43585 lastRowCls: 'x-grid3-row-last',
43586 rowClsRe: /(?:^|\s+)x-grid3-row-(first|last|alt)(?:\s+|$)/g,
43588 constructor : function(config){
43589 Ext.apply(this, config);
43593 'beforerowremoved',
43595 'beforerowsinserted',
43607 Ext.grid.GridView.superclass.constructor.call(this);
43613 initTemplates : function(){
43614 var ts = this.templates || {};
43616 ts.master = new Ext.Template(
43617 '<div class="x-grid3" hidefocus="true">',
43618 '<div class="x-grid3-viewport">',
43619 '<div class="x-grid3-header"><div class="x-grid3-header-inner"><div class="x-grid3-header-offset" style="{ostyle}">{header}</div></div><div class="x-clear"></div></div>',
43620 '<div class="x-grid3-scroller"><div class="x-grid3-body" style="{bstyle}">{body}</div><a href="#" class="x-grid3-focus" tabIndex="-1"></a></div>',
43622 '<div class="x-grid3-resize-marker"> </div>',
43623 '<div class="x-grid3-resize-proxy"> </div>',
43629 ts.header = new Ext.Template(
43630 '<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
43631 '<thead><tr class="x-grid3-hd-row">{cells}</tr></thead>',
43637 ts.hcell = new Ext.Template(
43638 '<td class="x-grid3-hd x-grid3-cell x-grid3-td-{id} {css}" style="{style}"><div {tooltip} {attr} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">', this.grid.enableHdMenu ? '<a class="x-grid3-hd-btn" href="#"></a>' : '',
43639 '{value}<img class="x-grid3-sort-icon" src="', Ext.BLANK_IMAGE_URL, '" />',
43645 ts.body = new Ext.Template('{rows}');
43649 ts.row = new Ext.Template(
43650 '<div class="x-grid3-row {alt}" style="{tstyle}"><table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
43651 '<tbody><tr>{cells}</tr>',
43652 (this.enableRowBody ? '<tr class="x-grid3-row-body-tr" style="{bodyStyle}"><td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on"><div class="x-grid3-row-body">{body}</div></td></tr>' : ''),
43653 '</tbody></table></div>'
43658 ts.cell = new Ext.Template(
43659 '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}" tabIndex="0" {cellAttr}>',
43660 '<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr}>{value}</div>',
43667 if(t && Ext.isFunction(t.compile) && !t.compiled){
43668 t.disableFormats = true;
43673 this.templates = ts;
43674 this.colRe = new RegExp('x-grid3-td-([^\\s]+)', '');
43678 fly : function(el){
43679 if(!this._flyweight){
43680 this._flyweight = new Ext.Element.Flyweight(document.body);
43682 this._flyweight.dom = el;
43683 return this._flyweight;
43687 getEditorParent : function(){
43688 return this.scroller.dom;
43692 initElements : function(){
43693 var E = Ext.Element;
43695 var el = this.grid.getGridEl().dom.firstChild;
43696 var cs = el.childNodes;
43698 this.el = new E(el);
43700 this.mainWrap = new E(cs[0]);
43701 this.mainHd = new E(this.mainWrap.dom.firstChild);
43703 if(this.grid.hideHeaders){
43704 this.mainHd.setDisplayed(false);
43707 this.innerHd = this.mainHd.dom.firstChild;
43708 this.scroller = new E(this.mainWrap.dom.childNodes[1]);
43710 this.scroller.setStyle('overflow-x', 'hidden');
43713 this.mainBody = new E(this.scroller.dom.firstChild);
43715 this.focusEl = new E(this.scroller.dom.childNodes[1]);
43716 this.focusEl.swallowEvent('click', true);
43718 this.resizeMarker = new E(cs[1]);
43719 this.resizeProxy = new E(cs[2]);
43723 getRows : function(){
43724 return this.hasRows() ? this.mainBody.dom.childNodes : [];
43730 findCell : function(el){
43734 return this.fly(el).findParent(this.cellSelector, this.cellSelectorDepth);
43738 findCellIndex : function(el, requiredCls){
43739 var cell = this.findCell(el);
43740 if(cell && (!requiredCls || this.fly(cell).hasClass(requiredCls))){
43741 return this.getCellIndex(cell);
43747 getCellIndex : function(el){
43749 var m = el.className.match(this.colRe);
43751 return this.cm.getIndexById(m[1]);
43758 findHeaderCell : function(el){
43759 var cell = this.findCell(el);
43760 return cell && this.fly(cell).hasClass(this.hdCls) ? cell : null;
43764 findHeaderIndex : function(el){
43765 return this.findCellIndex(el, this.hdCls);
43769 findRow : function(el){
43773 return this.fly(el).findParent(this.rowSelector, this.rowSelectorDepth);
43777 findRowIndex : function(el){
43778 var r = this.findRow(el);
43779 return r ? r.rowIndex : false;
43783 findRowBody : function(el){
43787 return this.fly(el).findParent(this.rowBodySelector, this.rowBodySelectorDepth);
43793 getRow : function(row){
43794 return this.getRows()[row];
43798 getCell : function(row, col){
43799 return this.getRow(row).getElementsByTagName('td')[col];
43803 getHeaderCell : function(index){
43804 return this.mainHd.dom.getElementsByTagName('td')[index];
43810 addRowClass : function(row, cls){
43811 var r = this.getRow(row);
43813 this.fly(r).addClass(cls);
43818 removeRowClass : function(row, cls){
43819 var r = this.getRow(row);
43821 this.fly(r).removeClass(cls);
43826 removeRow : function(row){
43827 Ext.removeNode(this.getRow(row));
43828 this.syncFocusEl(row);
43832 removeRows : function(firstRow, lastRow){
43833 var bd = this.mainBody.dom;
43834 for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
43835 Ext.removeNode(bd.childNodes[firstRow]);
43837 this.syncFocusEl(firstRow);
43843 getScrollState : function(){
43844 var sb = this.scroller.dom;
43845 return {left: sb.scrollLeft, top: sb.scrollTop};
43849 restoreScroll : function(state){
43850 var sb = this.scroller.dom;
43851 sb.scrollLeft = state.left;
43852 sb.scrollTop = state.top;
43856 scrollToTop : function(){
43857 this.scroller.dom.scrollTop = 0;
43858 this.scroller.dom.scrollLeft = 0;
43862 syncScroll : function(){
43863 this.syncHeaderScroll();
43864 var mb = this.scroller.dom;
43865 this.grid.fireEvent('bodyscroll', mb.scrollLeft, mb.scrollTop);
43869 syncHeaderScroll : function(){
43870 var mb = this.scroller.dom;
43871 this.innerHd.scrollLeft = mb.scrollLeft;
43872 this.innerHd.scrollLeft = mb.scrollLeft;
43876 updateSortIcon : function(col, dir){
43877 var sc = this.sortClasses;
43878 var hds = this.mainHd.select('td').removeClass(sc);
43879 hds.item(col).addClass(sc[dir == 'DESC' ? 1 : 0]);
43883 updateAllColumnWidths : function(){
43884 var tw = this.getTotalWidth(),
43885 clen = this.cm.getColumnCount(),
43890 for(i = 0; i < clen; i++){
43891 ws[i] = this.getColumnWidth(i);
43894 this.innerHd.firstChild.style.width = this.getOffsetWidth();
43895 this.innerHd.firstChild.firstChild.style.width = tw;
43896 this.mainBody.dom.style.width = tw;
43898 for(i = 0; i < clen; i++){
43899 var hd = this.getHeaderCell(i);
43900 hd.style.width = ws[i];
43903 var ns = this.getRows(), row, trow;
43904 for(i = 0, len = ns.length; i < len; i++){
43906 row.style.width = tw;
43907 if(row.firstChild){
43908 row.firstChild.style.width = tw;
43909 trow = row.firstChild.rows[0];
43910 for (var j = 0; j < clen; j++) {
43911 trow.childNodes[j].style.width = ws[j];
43916 this.onAllColumnWidthsUpdated(ws, tw);
43920 updateColumnWidth : function(col, width){
43921 var w = this.getColumnWidth(col);
43922 var tw = this.getTotalWidth();
43923 this.innerHd.firstChild.style.width = this.getOffsetWidth();
43924 this.innerHd.firstChild.firstChild.style.width = tw;
43925 this.mainBody.dom.style.width = tw;
43926 var hd = this.getHeaderCell(col);
43927 hd.style.width = w;
43929 var ns = this.getRows(), row;
43930 for(var i = 0, len = ns.length; i < len; i++){
43932 row.style.width = tw;
43933 if(row.firstChild){
43934 row.firstChild.style.width = tw;
43935 row.firstChild.rows[0].childNodes[col].style.width = w;
43939 this.onColumnWidthUpdated(col, w, tw);
43943 updateColumnHidden : function(col, hidden){
43944 var tw = this.getTotalWidth();
43945 this.innerHd.firstChild.style.width = this.getOffsetWidth();
43946 this.innerHd.firstChild.firstChild.style.width = tw;
43947 this.mainBody.dom.style.width = tw;
43948 var display = hidden ? 'none' : '';
43950 var hd = this.getHeaderCell(col);
43951 hd.style.display = display;
43953 var ns = this.getRows(), row;
43954 for(var i = 0, len = ns.length; i < len; i++){
43956 row.style.width = tw;
43957 if(row.firstChild){
43958 row.firstChild.style.width = tw;
43959 row.firstChild.rows[0].childNodes[col].style.display = display;
43963 this.onColumnHiddenUpdated(col, hidden, tw);
43964 delete this.lastViewWidth;
43969 doRender : function(columns, records, store, startRow, colCount, stripe) {
43970 var templates = this.templates,
43971 cellTemplate = templates.cell,
43972 rowTemplate = templates.row,
43973 last = colCount - 1;
43975 var tstyle = 'width:' + this.getTotalWidth() + ';';
43978 var rowBuffer = [],
43980 rowParams = {tstyle: tstyle},
43986 for (var j = 0, len = records.length; j < len; j++) {
43987 record = records[j];
43990 var rowIndex = j + startRow;
43993 for (var i = 0; i < colCount; i++) {
43994 column = columns[i];
43996 meta.id = column.id;
43997 meta.css = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
43998 meta.attr = meta.cellAttr = '';
43999 meta.style = column.style;
44000 meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store);
44002 if (Ext.isEmpty(meta.value)) {
44003 meta.value = ' ';
44006 if (this.markDirty && record.dirty && Ext.isDefined(record.modified[column.name])) {
44007 meta.css += ' x-grid3-dirty-cell';
44010 colBuffer[colBuffer.length] = cellTemplate.apply(meta);
44016 if (stripe && ((rowIndex + 1) % 2 === 0)) {
44017 alt[0] = 'x-grid3-row-alt';
44020 if (record.dirty) {
44021 alt[1] = ' x-grid3-dirty-row';
44024 rowParams.cols = colCount;
44026 if (this.getRowClass) {
44027 alt[2] = this.getRowClass(record, rowIndex, rowParams, store);
44030 rowParams.alt = alt.join(' ');
44031 rowParams.cells = colBuffer.join('');
44033 rowBuffer[rowBuffer.length] = rowTemplate.apply(rowParams);
44036 return rowBuffer.join('');
44040 processRows : function(startRow, skipStripe) {
44041 if (!this.ds || this.ds.getCount() < 1) {
44045 var rows = this.getRows(),
44049 skipStripe = skipStripe || !this.grid.stripeRows;
44050 startRow = startRow || 0;
44052 for (i = 0; i<len; i++) {
44057 r.className = r.className.replace(this.rowClsRe, ' ');
44058 if ((i + 1) % 2 === 0){
44059 r.className += ' x-grid3-row-alt';
44066 if (startRow === 0) {
44067 Ext.fly(rows[0]).addClass(this.firstRowCls);
44070 Ext.fly(rows[rows.length - 1]).addClass(this.lastRowCls);
44073 afterRender : function(){
44074 if(!this.ds || !this.cm){
44077 this.mainBody.dom.innerHTML = this.renderRows() || ' ';
44078 this.processRows(0, true);
44080 if(this.deferEmptyText !== true){
44081 this.applyEmptyText();
44083 this.grid.fireEvent('viewready', this.grid);
44087 renderUI : function() {
44088 var templates = this.templates,
44089 header = this.renderHeaders(),
44090 body = templates.body.apply({rows:' '});
44092 var html = templates.master.apply({
44095 ostyle: 'width:' + this.getOffsetWidth() + ';',
44096 bstyle: 'width:' + this.getTotalWidth() + ';'
44101 g.getGridEl().dom.innerHTML = html;
44103 this.initElements();
44106 Ext.fly(this.innerHd).on('click', this.handleHdDown, this);
44110 mouseover: this.handleHdOver,
44111 mouseout : this.handleHdOut,
44112 mousemove: this.handleHdMove
44115 this.scroller.on('scroll', this.syncScroll, this);
44116 if (g.enableColumnResize !== false) {
44117 this.splitZone = new Ext.grid.GridView.SplitDragZone(g, this.mainHd.dom);
44120 if (g.enableColumnMove) {
44121 this.columnDrag = new Ext.grid.GridView.ColumnDragZone(g, this.innerHd);
44122 this.columnDrop = new Ext.grid.HeaderDropZone(g, this.mainHd.dom);
44125 if (g.enableHdMenu !== false) {
44126 this.hmenu = new Ext.menu.Menu({id: g.id + '-hctx'});
44128 {itemId:'asc', text: this.sortAscText, cls: 'xg-hmenu-sort-asc'},
44129 {itemId:'desc', text: this.sortDescText, cls: 'xg-hmenu-sort-desc'}
44132 if (g.enableColumnHide !== false) {
44133 this.colMenu = new Ext.menu.Menu({id:g.id + '-hcols-menu'});
44136 beforeshow: this.beforeColMenuShow,
44137 itemclick : this.handleHdMenuClick
44139 this.hmenu.add('-', {
44141 hideOnClick: false,
44142 text: this.columnsText,
44143 menu: this.colMenu,
44144 iconCls: 'x-cols-icon'
44148 this.hmenu.on('itemclick', this.handleHdMenuClick, this);
44151 if (g.trackMouseOver) {
44154 mouseover: this.onRowOver,
44155 mouseout : this.onRowOut
44159 if (g.enableDragDrop || g.enableDrag) {
44160 this.dragZone = new Ext.grid.GridDragZone(g, {
44161 ddGroup : g.ddGroup || 'GridDD'
44165 this.updateHeaderSortState();
44169 processEvent : function(name, e) {
44170 var t = e.getTarget(),
44172 header = this.findHeaderIndex(t);
44173 g.fireEvent(name, e);
44174 if (header !== false) {
44175 g.fireEvent('header' + name, g, header, e);
44177 var row = this.findRowIndex(t),
44180 if (row !== false) {
44181 g.fireEvent('row' + name, g, row, e);
44182 cell = this.findCellIndex(t);
44183 if (cell !== false) {
44184 g.fireEvent('cell' + name, g, row, cell, e);
44186 body = this.findRowBody(t);
44188 g.fireEvent('rowbody' + name, g, row, e);
44192 g.fireEvent('container' + name, g, e);
44198 layout : function() {
44199 if(!this.mainBody){
44203 var c = g.getGridEl();
44204 var csize = c.getSize(true);
44205 var vw = csize.width;
44207 if(!g.hideHeaders && (vw < 20 || csize.height < 20)){
44212 this.scroller.dom.style.overflow = 'visible';
44214 this.scroller.dom.style.position = 'static';
44217 this.el.setSize(csize.width, csize.height);
44219 var hdHeight = this.mainHd.getHeight();
44220 var vh = csize.height - (hdHeight);
44222 this.scroller.setSize(vw, vh);
44224 this.innerHd.style.width = (vw)+'px';
44228 if(this.lastViewWidth != vw){
44229 this.fitColumns(false, false);
44230 this.lastViewWidth = vw;
44234 this.syncHeaderScroll();
44236 this.onLayout(vw, vh);
44241 onLayout : function(vw, vh){
44245 onColumnWidthUpdated : function(col, w, tw){
44249 onAllColumnWidthsUpdated : function(ws, tw){
44253 onColumnHiddenUpdated : function(col, hidden, tw){
44257 updateColumnText : function(col, text){
44261 afterMove : function(colIndex){
44267 init : function(grid){
44270 this.initTemplates();
44271 this.initData(grid.store, grid.colModel);
44276 getColumnId : function(index){
44277 return this.cm.getColumnId(index);
44281 getOffsetWidth : function() {
44282 return (this.cm.getTotalWidth() + this.getScrollOffset()) + 'px';
44285 getScrollOffset: function(){
44286 return Ext.num(this.scrollOffset, Ext.getScrollBarWidth());
44290 renderHeaders : function() {
44292 ts = this.templates,
44296 len = cm.getColumnCount(),
44299 for (var i = 0; i < len; i++) {
44300 p.id = cm.getColumnId(i);
44301 p.value = cm.getColumnHeader(i) || '';
44302 p.style = this.getColumnStyle(i, true);
44303 p.tooltip = this.getColumnTooltip(i);
44304 p.css = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
44306 if (cm.config[i].align == 'right') {
44307 p.istyle = 'padding-right:16px';
44311 cb[cb.length] = ct.apply(p);
44313 return ts.header.apply({cells: cb.join(''), tstyle:'width:'+this.getTotalWidth()+';'});
44317 getColumnTooltip : function(i){
44318 var tt = this.cm.getColumnTooltip(i);
44320 if(Ext.QuickTips.isEnabled()){
44321 return 'ext:qtip="'+tt+'"';
44323 return 'title="'+tt+'"';
44330 beforeUpdate : function(){
44331 this.grid.stopEditing(true);
44335 updateHeaders : function(){
44336 this.innerHd.firstChild.innerHTML = this.renderHeaders();
44337 this.innerHd.firstChild.style.width = this.getOffsetWidth();
44338 this.innerHd.firstChild.firstChild.style.width = this.getTotalWidth();
44342 focusRow : function(row){
44343 this.focusCell(row, 0, false);
44347 focusCell : function(row, col, hscroll){
44348 this.syncFocusEl(this.ensureVisible(row, col, hscroll));
44350 this.focusEl.focus();
44352 this.focusEl.focus.defer(1, this.focusEl);
44356 resolveCell : function(row, col, hscroll){
44357 if(!Ext.isNumber(row)){
44358 row = row.rowIndex;
44363 if(row < 0 || row >= this.ds.getCount()){
44366 col = (col !== undefined ? col : 0);
44368 var rowEl = this.getRow(row),
44370 colCount = cm.getColumnCount(),
44372 if(!(hscroll === false && col === 0)){
44373 while(col < colCount && cm.isHidden(col)){
44376 cellEl = this.getCell(row, col);
44379 return {row: rowEl, cell: cellEl};
44382 getResolvedXY : function(resolved){
44386 var s = this.scroller.dom, c = resolved.cell, r = resolved.row;
44387 return c ? Ext.fly(c).getXY() : [this.el.getX(), Ext.fly(r).getY()];
44390 syncFocusEl : function(row, col, hscroll){
44392 if(!Ext.isArray(xy)){
44393 row = Math.min(row, Math.max(0, this.getRows().length-1));
44397 xy = this.getResolvedXY(this.resolveCell(row, col, hscroll));
44399 this.focusEl.setXY(xy||this.scroller.getXY());
44402 ensureVisible : function(row, col, hscroll){
44403 var resolved = this.resolveCell(row, col, hscroll);
44404 if(!resolved || !resolved.row){
44408 var rowEl = resolved.row,
44409 cellEl = resolved.cell,
44410 c = this.scroller.dom,
44413 stop = this.el.dom;
44415 while(p && p != stop){
44416 ctop += p.offsetTop;
44417 p = p.offsetParent;
44420 ctop -= this.mainHd.dom.offsetHeight;
44421 stop = parseInt(c.scrollTop, 10);
44423 var cbot = ctop + rowEl.offsetHeight,
44424 ch = c.clientHeight,
44429 c.scrollTop = ctop;
44430 }else if(cbot > sbot){
44431 c.scrollTop = cbot-ch;
44434 if(hscroll !== false){
44435 var cleft = parseInt(cellEl.offsetLeft, 10);
44436 var cright = cleft + cellEl.offsetWidth;
44438 var sleft = parseInt(c.scrollLeft, 10);
44439 var sright = sleft + c.clientWidth;
44441 c.scrollLeft = cleft;
44442 }else if(cright > sright){
44443 c.scrollLeft = cright-c.clientWidth;
44446 return this.getResolvedXY(resolved);
44450 insertRows : function(dm, firstRow, lastRow, isUpdate) {
44451 var last = dm.getCount() - 1;
44452 if( !isUpdate && firstRow === 0 && lastRow >= last) {
44453 this.fireEvent('beforerowsinserted', this, firstRow, lastRow);
44455 this.fireEvent('rowsinserted', this, firstRow, lastRow);
44458 this.fireEvent('beforerowsinserted', this, firstRow, lastRow);
44460 var html = this.renderRows(firstRow, lastRow),
44461 before = this.getRow(firstRow);
44463 if(firstRow === 0){
44464 Ext.fly(this.getRow(0)).removeClass(this.firstRowCls);
44466 Ext.DomHelper.insertHtml('beforeBegin', before, html);
44468 var r = this.getRow(last - 1);
44470 Ext.fly(r).removeClass(this.lastRowCls);
44472 Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html);
44475 this.fireEvent('rowsinserted', this, firstRow, lastRow);
44476 this.processRows(firstRow);
44477 } else if (firstRow === 0 || firstRow >= last) {
44479 Ext.fly(this.getRow(firstRow)).addClass(firstRow === 0 ? this.firstRowCls : this.lastRowCls);
44482 this.syncFocusEl(firstRow);
44486 deleteRows : function(dm, firstRow, lastRow){
44487 if(dm.getRowCount()<1){
44490 this.fireEvent('beforerowsdeleted', this, firstRow, lastRow);
44492 this.removeRows(firstRow, lastRow);
44494 this.processRows(firstRow);
44495 this.fireEvent('rowsdeleted', this, firstRow, lastRow);
44500 getColumnStyle : function(col, isHeader){
44501 var style = !isHeader ? (this.cm.config[col].css || '') : '';
44502 style += 'width:'+this.getColumnWidth(col)+';';
44503 if(this.cm.isHidden(col)){
44504 style += 'display:none;';
44506 var align = this.cm.config[col].align;
44508 style += 'text-align:'+align+';';
44514 getColumnWidth : function(col){
44515 var w = this.cm.getColumnWidth(col);
44516 if(Ext.isNumber(w)){
44517 return (Ext.isBorderBox || (Ext.isWebKit && !Ext.isSafari2) ? w : (w - this.borderWidth > 0 ? w - this.borderWidth : 0)) + 'px';
44523 getTotalWidth : function(){
44524 return this.cm.getTotalWidth()+'px';
44528 fitColumns : function(preventRefresh, onlyExpand, omitColumn){
44529 var cm = this.cm, i;
44530 var tw = cm.getTotalWidth(false);
44531 var aw = this.grid.getGridEl().getWidth(true)-this.getScrollOffset();
44536 var extra = aw - tw;
44542 var vc = cm.getColumnCount(true);
44543 var ac = vc-(Ext.isNumber(omitColumn) ? 1 : 0);
44546 omitColumn = undefined;
44548 var colCount = cm.getColumnCount();
44553 for (i = 0; i < colCount; i++){
44554 if(!cm.isFixed(i) && i !== omitColumn){
44555 w = cm.getColumnWidth(i);
44557 if(!cm.isHidden(i)){
44563 var frac = (aw - cm.getTotalWidth())/width;
44564 while (cols.length){
44567 cm.setColumnWidth(i, Math.max(this.grid.minColumnWidth, Math.floor(w + w*frac)), true);
44570 if((tw = cm.getTotalWidth(false)) > aw){
44571 var adjustCol = ac != vc ? omitColumn : extraCol;
44572 cm.setColumnWidth(adjustCol, Math.max(1,
44573 cm.getColumnWidth(adjustCol)- (tw-aw)), true);
44576 if(preventRefresh !== true){
44577 this.updateAllColumnWidths();
44585 autoExpand : function(preventUpdate){
44586 var g = this.grid, cm = this.cm;
44587 if(!this.userResized && g.autoExpandColumn){
44588 var tw = cm.getTotalWidth(false);
44589 var aw = this.grid.getGridEl().getWidth(true)-this.getScrollOffset();
44591 var ci = cm.getIndexById(g.autoExpandColumn);
44592 var currentWidth = cm.getColumnWidth(ci);
44593 var cw = Math.min(Math.max(((aw-tw)+currentWidth), g.autoExpandMin), g.autoExpandMax);
44594 if(cw != currentWidth){
44595 cm.setColumnWidth(ci, cw, true);
44596 if(preventUpdate !== true){
44597 this.updateColumnWidth(ci, cw);
44605 getColumnData : function(){
44609 colCount = cm.getColumnCount();
44611 for (var i = 0; i < colCount; i++) {
44612 var name = cm.getDataIndex(i);
44615 name : (!Ext.isDefined(name) ? this.ds.fields.get(i).name : name),
44616 renderer: cm.getRenderer(i),
44617 scope : cm.getRendererScope(i),
44618 id : cm.getColumnId(i),
44619 style : this.getColumnStyle(i)
44627 renderRows : function(startRow, endRow){
44629 var g = this.grid, cm = g.colModel, ds = g.store, stripe = g.stripeRows;
44630 var colCount = cm.getColumnCount();
44632 if(ds.getCount() < 1){
44636 var cs = this.getColumnData();
44638 startRow = startRow || 0;
44639 endRow = !Ext.isDefined(endRow) ? ds.getCount()-1 : endRow;
44642 var rs = ds.getRange(startRow, endRow);
44644 return this.doRender(cs, rs, ds, startRow, colCount, stripe);
44648 renderBody : function(){
44649 var markup = this.renderRows() || ' ';
44650 return this.templates.body.apply({rows: markup});
44654 refreshRow : function(record){
44655 var ds = this.ds, index;
44656 if(Ext.isNumber(record)){
44658 record = ds.getAt(index);
44663 index = ds.indexOf(record);
44668 this.insertRows(ds, index, index, true);
44669 this.getRow(index).rowIndex = index;
44670 this.onRemove(ds, record, index+1, true);
44671 this.fireEvent('rowupdated', this, index, record);
44675 refresh : function(headersToo){
44676 this.fireEvent('beforerefresh', this);
44677 this.grid.stopEditing(true);
44679 var result = this.renderBody();
44680 this.mainBody.update(result).setWidth(this.getTotalWidth());
44681 if(headersToo === true){
44682 this.updateHeaders();
44683 this.updateHeaderSortState();
44685 this.processRows(0, true);
44687 this.applyEmptyText();
44688 this.fireEvent('refresh', this);
44692 applyEmptyText : function(){
44693 if(this.emptyText && !this.hasRows()){
44694 this.mainBody.update('<div class="x-grid-empty">' + this.emptyText + '</div>');
44699 updateHeaderSortState : function(){
44700 var state = this.ds.getSortState();
44705 if (!this.sortState || (this.sortState.field != state.field || this.sortState.direction != state.direction)) {
44706 this.grid.fireEvent('sortchange', this.grid, state);
44709 this.sortState = state;
44711 var sortColumn = this.cm.findColumnIndex(state.field);
44712 if (sortColumn != -1){
44713 var sortDir = state.direction;
44714 this.updateSortIcon(sortColumn, sortDir);
44719 clearHeaderSortState : function(){
44720 if (!this.sortState) {
44723 this.grid.fireEvent('sortchange', this.grid, null);
44724 this.mainHd.select('td').removeClass(this.sortClasses);
44725 delete this.sortState;
44729 destroy : function(){
44730 if (this.scrollToTopTask && this.scrollToTopTask.cancel){
44731 this.scrollToTopTask.cancel();
44734 Ext.menu.MenuMgr.unregister(this.colMenu);
44735 this.colMenu.destroy();
44736 delete this.colMenu;
44739 Ext.menu.MenuMgr.unregister(this.hmenu);
44740 this.hmenu.destroy();
44744 this.initData(null, null);
44745 this.purgeListeners();
44746 Ext.fly(this.innerHd).un("click", this.handleHdDown, this);
44748 if(this.grid.enableColumnMove){
44750 this.columnDrag.el,
44751 this.columnDrag.proxy.ghost,
44752 this.columnDrag.proxy.el,
44753 this.columnDrop.el,
44754 this.columnDrop.proxyTop,
44755 this.columnDrop.proxyBottom,
44756 this.columnDrag.dragData.ddel,
44757 this.columnDrag.dragData.header
44759 if (this.columnDrag.proxy.anim) {
44760 Ext.destroy(this.columnDrag.proxy.anim);
44762 delete this.columnDrag.proxy.ghost;
44763 delete this.columnDrag.dragData.ddel;
44764 delete this.columnDrag.dragData.header;
44765 this.columnDrag.destroy();
44766 delete Ext.dd.DDM.locationCache[this.columnDrag.id];
44767 delete this.columnDrag._domRef;
44769 delete this.columnDrop.proxyTop;
44770 delete this.columnDrop.proxyBottom;
44771 this.columnDrop.destroy();
44772 delete Ext.dd.DDM.locationCache["gridHeader" + this.grid.getGridEl().id];
44773 delete this.columnDrop._domRef;
44774 delete Ext.dd.DDM.ids[this.columnDrop.ddGroup];
44777 if (this.splitZone){
44778 this.splitZone.destroy();
44779 delete this.splitZone._domRef;
44780 delete Ext.dd.DDM.ids["gridSplitters" + this.grid.getGridEl().id];
44783 Ext.fly(this.innerHd).removeAllListeners();
44784 Ext.removeNode(this.innerHd);
44785 delete this.innerHd;
44802 delete this.grid.container;
44805 this.dragZone.destroy();
44808 Ext.dd.DDM.currentTarget = null;
44809 delete Ext.dd.DDM.locationCache[this.grid.getGridEl().id];
44811 Ext.EventManager.removeResizeListener(this.onWindowResize, this);
44815 onDenyColumnHide : function(){
44820 render : function(){
44822 var ct = this.grid.ownerCt;
44823 if (ct && ct.getLayout()){
44824 ct.on('afterlayout', function(){
44825 this.fitColumns(true, true);
44826 this.updateHeaders();
44827 }, this, {single: true});
44829 this.fitColumns(true, true);
44831 }else if(this.forceFit){
44832 this.fitColumns(true, false);
44833 }else if(this.grid.autoExpandColumn){
44834 this.autoExpand(true);
44842 initData : function(ds, cm){
44844 this.ds.un('load', this.onLoad, this);
44845 this.ds.un('datachanged', this.onDataChange, this);
44846 this.ds.un('add', this.onAdd, this);
44847 this.ds.un('remove', this.onRemove, this);
44848 this.ds.un('update', this.onUpdate, this);
44849 this.ds.un('clear', this.onClear, this);
44850 if(this.ds !== ds && this.ds.autoDestroy){
44858 datachanged: this.onDataChange,
44860 remove: this.onRemove,
44861 update: this.onUpdate,
44862 clear: this.onClear
44868 this.cm.un('configchange', this.onColConfigChange, this);
44869 this.cm.un('widthchange', this.onColWidthChange, this);
44870 this.cm.un('headerchange', this.onHeaderChange, this);
44871 this.cm.un('hiddenchange', this.onHiddenChange, this);
44872 this.cm.un('columnmoved', this.onColumnMove, this);
44875 delete this.lastViewWidth;
44878 configchange: this.onColConfigChange,
44879 widthchange: this.onColWidthChange,
44880 headerchange: this.onHeaderChange,
44881 hiddenchange: this.onHiddenChange,
44882 columnmoved: this.onColumnMove
44889 onDataChange : function(){
44891 this.updateHeaderSortState();
44892 this.syncFocusEl(0);
44896 onClear : function(){
44898 this.syncFocusEl(0);
44902 onUpdate : function(ds, record){
44903 this.refreshRow(record);
44907 onAdd : function(ds, records, index){
44908 this.insertRows(ds, index, index + (records.length-1));
44912 onRemove : function(ds, record, index, isUpdate){
44913 if(isUpdate !== true){
44914 this.fireEvent('beforerowremoved', this, index, record);
44916 this.removeRow(index);
44917 if(isUpdate !== true){
44918 this.processRows(index);
44919 this.applyEmptyText();
44920 this.fireEvent('rowremoved', this, index, record);
44925 onLoad : function(){
44927 if (!this.scrollToTopTask) {
44928 this.scrollToTopTask = new Ext.util.DelayedTask(this.scrollToTop, this);
44930 this.scrollToTopTask.delay(1);
44932 this.scrollToTop();
44937 onColWidthChange : function(cm, col, width){
44938 this.updateColumnWidth(col, width);
44942 onHeaderChange : function(cm, col, text){
44943 this.updateHeaders();
44947 onHiddenChange : function(cm, col, hidden){
44948 this.updateColumnHidden(col, hidden);
44952 onColumnMove : function(cm, oldIndex, newIndex){
44953 this.indexMap = null;
44954 var s = this.getScrollState();
44955 this.refresh(true);
44956 this.restoreScroll(s);
44957 this.afterMove(newIndex);
44958 this.grid.fireEvent('columnmove', oldIndex, newIndex);
44962 onColConfigChange : function(){
44963 delete this.lastViewWidth;
44964 this.indexMap = null;
44965 this.refresh(true);
44970 initUI : function(grid){
44971 grid.on('headerclick', this.onHeaderClick, this);
44975 initEvents : function(){
44979 onHeaderClick : function(g, index){
44980 if(this.headersDisabled || !this.cm.isSortable(index)){
44983 g.stopEditing(true);
44984 g.store.sort(this.cm.getDataIndex(index));
44988 onRowOver : function(e, t){
44990 if((row = this.findRowIndex(t)) !== false){
44991 this.addRowClass(row, 'x-grid3-row-over');
44996 onRowOut : function(e, t){
44998 if((row = this.findRowIndex(t)) !== false && !e.within(this.getRow(row), true)){
44999 this.removeRowClass(row, 'x-grid3-row-over');
45004 handleWheel : function(e){
45005 e.stopPropagation();
45009 onRowSelect : function(row){
45010 this.addRowClass(row, this.selectedRowClass);
45014 onRowDeselect : function(row){
45015 this.removeRowClass(row, this.selectedRowClass);
45019 onCellSelect : function(row, col){
45020 var cell = this.getCell(row, col);
45022 this.fly(cell).addClass('x-grid3-cell-selected');
45027 onCellDeselect : function(row, col){
45028 var cell = this.getCell(row, col);
45030 this.fly(cell).removeClass('x-grid3-cell-selected');
45035 onColumnSplitterMoved : function(i, w){
45036 this.userResized = true;
45037 var cm = this.grid.colModel;
45038 cm.setColumnWidth(i, w, true);
45041 this.fitColumns(true, false, i);
45042 this.updateAllColumnWidths();
45044 this.updateColumnWidth(i, w);
45045 this.syncHeaderScroll();
45048 this.grid.fireEvent('columnresize', i, w);
45052 handleHdMenuClick : function(item){
45053 var index = this.hdCtxIndex,
45056 id = item.getItemId();
45059 ds.sort(cm.getDataIndex(index), 'ASC');
45062 ds.sort(cm.getDataIndex(index), 'DESC');
45065 index = cm.getIndexById(id.substr(4));
45067 if(item.checked && cm.getColumnsBy(this.isHideableColumn, this).length <= 1){
45068 this.onDenyColumnHide();
45071 cm.setHidden(index, item.checked);
45078 isHideableColumn : function(c){
45083 beforeColMenuShow : function(){
45084 var cm = this.cm, colCount = cm.getColumnCount();
45085 this.colMenu.removeAll();
45086 for(var i = 0; i < colCount; i++){
45087 if(cm.config[i].hideable !== false){
45088 this.colMenu.add(new Ext.menu.CheckItem({
45089 itemId: 'col-'+cm.getColumnId(i),
45090 text: cm.getColumnHeader(i),
45091 checked: !cm.isHidden(i),
45093 disabled: cm.config[i].hideable === false
45100 handleHdDown : function(e, t){
45101 if(Ext.fly(t).hasClass('x-grid3-hd-btn')){
45103 var hd = this.findHeaderCell(t);
45104 Ext.fly(hd).addClass('x-grid3-hd-menu-open');
45105 var index = this.getCellIndex(hd);
45106 this.hdCtxIndex = index;
45107 var ms = this.hmenu.items, cm = this.cm;
45108 ms.get('asc').setDisabled(!cm.isSortable(index));
45109 ms.get('desc').setDisabled(!cm.isSortable(index));
45110 this.hmenu.on('hide', function(){
45111 Ext.fly(hd).removeClass('x-grid3-hd-menu-open');
45112 }, this, {single:true});
45113 this.hmenu.show(t, 'tl-bl?');
45118 handleHdOver : function(e, t){
45119 var hd = this.findHeaderCell(t);
45120 if(hd && !this.headersDisabled){
45121 this.activeHdRef = t;
45122 this.activeHdIndex = this.getCellIndex(hd);
45123 var fly = this.fly(hd);
45124 this.activeHdRegion = fly.getRegion();
45125 if(!this.cm.isMenuDisabled(this.activeHdIndex)){
45126 fly.addClass('x-grid3-hd-over');
45127 this.activeHdBtn = fly.child('.x-grid3-hd-btn');
45128 if(this.activeHdBtn){
45129 this.activeHdBtn.dom.style.height = (hd.firstChild.offsetHeight-1)+'px';
45136 handleHdMove : function(e, t){
45137 var hd = this.findHeaderCell(this.activeHdRef);
45138 if(hd && !this.headersDisabled){
45139 var hw = this.splitHandleWidth || 5,
45140 r = this.activeHdRegion,
45144 if(this.grid.enableColumnResize !== false){
45145 if(x - r.left <= hw && this.cm.isResizable(this.activeHdIndex-1)){
45146 cur = Ext.isAir ? 'move' : Ext.isWebKit ? 'e-resize' : 'col-resize';
45147 }else if(r.right - x <= (!this.activeHdBtn ? hw : 2) && this.cm.isResizable(this.activeHdIndex)){
45148 cur = Ext.isAir ? 'move' : Ext.isWebKit ? 'w-resize' : 'col-resize';
45156 handleHdOut : function(e, t){
45157 var hd = this.findHeaderCell(t);
45158 if(hd && (!Ext.isIE || !e.within(hd, true))){
45159 this.activeHdRef = null;
45160 this.fly(hd).removeClass('x-grid3-hd-over');
45161 hd.style.cursor = '';
45166 hasRows : function(){
45167 var fc = this.mainBody.dom.firstChild;
45168 return fc && fc.nodeType == 1 && fc.className != 'x-grid-empty';
45172 bind : function(d, c){
45173 this.initData(d, c);
45180 Ext.grid.GridView.SplitDragZone = Ext.extend(Ext.dd.DDProxy, {
45182 constructor: function(grid, hd){
45184 this.view = grid.getView();
45185 this.marker = this.view.resizeMarker;
45186 this.proxy = this.view.resizeProxy;
45187 Ext.grid.GridView.SplitDragZone.superclass.constructor.call(this, hd,
45188 'gridSplitters' + this.grid.getGridEl().id, {
45189 dragElId : Ext.id(this.proxy.dom), resizeFrame:false
45191 this.scroll = false;
45192 this.hw = this.view.splitHandleWidth || 5;
45195 b4StartDrag : function(x, y){
45196 this.dragHeadersDisabled = this.view.headersDisabled;
45197 this.view.headersDisabled = true;
45198 var h = this.view.mainWrap.getHeight();
45199 this.marker.setHeight(h);
45200 this.marker.show();
45201 this.marker.alignTo(this.view.getHeaderCell(this.cellIndex), 'tl-tl', [-2, 0]);
45202 this.proxy.setHeight(h);
45203 var w = this.cm.getColumnWidth(this.cellIndex),
45204 minw = Math.max(w-this.grid.minColumnWidth, 0);
45205 this.resetConstraints();
45206 this.setXConstraint(minw, 1000);
45207 this.setYConstraint(0, 0);
45208 this.minX = x - minw;
45209 this.maxX = x + 1000;
45211 Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
45214 allowHeaderDrag : function(e){
45218 handleMouseDown : function(e){
45219 var t = this.view.findHeaderCell(e.getTarget());
45220 if(t && this.allowHeaderDrag(e)){
45221 var xy = this.view.fly(t).getXY(),
45224 exy = e.getXY(), ex = exy[0],
45225 w = t.offsetWidth, adjust = false;
45227 if((ex - x) <= this.hw){
45229 }else if((x+w) - ex <= this.hw){
45232 if(adjust !== false){
45233 this.cm = this.grid.colModel;
45234 var ci = this.view.getCellIndex(t);
45236 if (ci + adjust < 0) {
45239 while(this.cm.isHidden(ci+adjust)){
45246 this.cellIndex = ci+adjust;
45247 this.split = t.dom;
45248 if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
45249 Ext.grid.GridView.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
45251 }else if(this.view.columnDrag){
45252 this.view.columnDrag.callHandleMouseDown(e);
45257 endDrag : function(e){
45258 this.marker.hide();
45260 endX = Math.max(this.minX, e.getPageX()),
45261 diff = endX - this.startPos,
45262 disabled = this.dragHeadersDisabled;
45264 v.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
45265 setTimeout(function(){
45266 v.headersDisabled = disabled;
45270 autoOffset : function(){
45271 this.setDelta(0,0);
45276 Ext.grid.HeaderDragZone = Ext.extend(Ext.dd.DragZone, {
45279 constructor : function(grid, hd, hd2){
45281 this.view = grid.getView();
45282 this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
45283 Ext.grid.HeaderDragZone.superclass.constructor.call(this, hd);
45285 this.setHandleElId(Ext.id(hd));
45286 this.setOuterHandleElId(Ext.id(hd2));
45288 this.scroll = false;
45291 getDragData : function(e){
45292 var t = Ext.lib.Event.getTarget(e),
45293 h = this.view.findHeaderCell(t);
45295 return {ddel: h.firstChild, header:h};
45300 onInitDrag : function(e){
45302 this.dragHeadersDisabled = this.view.headersDisabled;
45303 this.view.headersDisabled = true;
45304 var clone = this.dragData.ddel.cloneNode(true);
45305 clone.id = Ext.id();
45306 clone.style.width = Math.min(this.dragData.header.offsetWidth,this.maxDragWidth) + "px";
45307 this.proxy.update(clone);
45311 afterValidDrop : function(){
45312 this.completeDrop();
45315 afterInvalidDrop : function(){
45316 this.completeDrop();
45319 completeDrop: function(){
45321 disabled = this.dragHeadersDisabled;
45322 setTimeout(function(){
45323 v.headersDisabled = disabled;
45330 Ext.grid.HeaderDropZone = Ext.extend(Ext.dd.DropZone, {
45331 proxyOffsets : [-4, -9],
45332 fly: Ext.Element.fly,
45334 constructor : function(grid, hd, hd2){
45336 this.view = grid.getView();
45338 this.proxyTop = Ext.DomHelper.append(document.body, {
45339 cls:"col-move-top", html:" "
45341 this.proxyBottom = Ext.DomHelper.append(document.body, {
45342 cls:"col-move-bottom", html:" "
45344 this.proxyTop.hide = this.proxyBottom.hide = function(){
45345 this.setLeftTop(-100,-100);
45346 this.setStyle("visibility", "hidden");
45348 this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
45351 Ext.grid.HeaderDropZone.superclass.constructor.call(this, grid.getGridEl().dom);
45354 getTargetFromEvent : function(e){
45355 var t = Ext.lib.Event.getTarget(e),
45356 cindex = this.view.findCellIndex(t);
45357 if(cindex !== false){
45358 return this.view.getHeaderCell(cindex);
45362 nextVisible : function(h){
45363 var v = this.view, cm = this.grid.colModel;
45366 if(!cm.isHidden(v.getCellIndex(h))){
45374 prevVisible : function(h){
45375 var v = this.view, cm = this.grid.colModel;
45378 if(!cm.isHidden(v.getCellIndex(h))){
45386 positionIndicator : function(h, n, e){
45387 var x = Ext.lib.Event.getPageX(e),
45388 r = Ext.lib.Dom.getRegion(n.firstChild),
45391 py = r.top + this.proxyOffsets[1];
45392 if((r.right - x) <= (r.right-r.left)/2){
45393 px = r.right+this.view.borderWidth;
45400 if(this.grid.colModel.isFixed(this.view.getCellIndex(n))){
45404 px += this.proxyOffsets[0];
45405 this.proxyTop.setLeftTop(px, py);
45406 this.proxyTop.show();
45407 if(!this.bottomOffset){
45408 this.bottomOffset = this.view.mainHd.getHeight();
45410 this.proxyBottom.setLeftTop(px, py+this.proxyTop.dom.offsetHeight+this.bottomOffset);
45411 this.proxyBottom.show();
45415 onNodeEnter : function(n, dd, e, data){
45416 if(data.header != n){
45417 this.positionIndicator(data.header, n, e);
45421 onNodeOver : function(n, dd, e, data){
45422 var result = false;
45423 if(data.header != n){
45424 result = this.positionIndicator(data.header, n, e);
45427 this.proxyTop.hide();
45428 this.proxyBottom.hide();
45430 return result ? this.dropAllowed : this.dropNotAllowed;
45433 onNodeOut : function(n, dd, e, data){
45434 this.proxyTop.hide();
45435 this.proxyBottom.hide();
45438 onNodeDrop : function(n, dd, e, data){
45439 var h = data.header;
45441 var cm = this.grid.colModel,
45442 x = Ext.lib.Event.getPageX(e),
45443 r = Ext.lib.Dom.getRegion(n.firstChild),
45444 pt = (r.right - x) <= ((r.right-r.left)/2) ? "after" : "before",
45445 oldIndex = this.view.getCellIndex(h),
45446 newIndex = this.view.getCellIndex(n);
45450 if(oldIndex < newIndex){
45453 cm.moveColumn(oldIndex, newIndex);
45460 Ext.grid.GridView.ColumnDragZone = Ext.extend(Ext.grid.HeaderDragZone, {
45462 constructor : function(grid, hd){
45463 Ext.grid.GridView.ColumnDragZone.superclass.constructor.call(this, grid, hd, null);
45464 this.proxy.el.addClass('x-grid3-col-dd');
45467 handleMouseDown : function(e){
45470 callHandleMouseDown : function(e){
45471 Ext.grid.GridView.ColumnDragZone.superclass.handleMouseDown.call(this, e);
45475 Ext.grid.SplitDragZone = Ext.extend(Ext.dd.DDProxy, {
45476 fly: Ext.Element.fly,
45478 constructor : function(grid, hd, hd2){
45480 this.view = grid.getView();
45481 this.proxy = this.view.resizeProxy;
45482 Ext.grid.SplitDragZone.superclass.constructor.call(this, hd,
45483 "gridSplitters" + this.grid.getGridEl().id, {
45484 dragElId : Ext.id(this.proxy.dom), resizeFrame:false
45486 this.setHandleElId(Ext.id(hd));
45487 this.setOuterHandleElId(Ext.id(hd2));
45488 this.scroll = false;
45491 b4StartDrag : function(x, y){
45492 this.view.headersDisabled = true;
45493 this.proxy.setHeight(this.view.mainWrap.getHeight());
45494 var w = this.cm.getColumnWidth(this.cellIndex);
45495 var minw = Math.max(w-this.grid.minColumnWidth, 0);
45496 this.resetConstraints();
45497 this.setXConstraint(minw, 1000);
45498 this.setYConstraint(0, 0);
45499 this.minX = x - minw;
45500 this.maxX = x + 1000;
45502 Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
45506 handleMouseDown : function(e){
45507 var ev = Ext.EventObject.setEvent(e);
45508 var t = this.fly(ev.getTarget());
45509 if(t.hasClass("x-grid-split")){
45510 this.cellIndex = this.view.getCellIndex(t.dom);
45511 this.split = t.dom;
45512 this.cm = this.grid.colModel;
45513 if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
45514 Ext.grid.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
45519 endDrag : function(e){
45520 this.view.headersDisabled = false;
45521 var endX = Math.max(this.minX, Ext.lib.Event.getPageX(e));
45522 var diff = endX - this.startPos;
45523 this.view.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
45526 autoOffset : function(){
45527 this.setDelta(0,0);
45530 Ext.grid.GridDragZone = function(grid, config){
45531 this.view = grid.getView();
45532 Ext.grid.GridDragZone.superclass.constructor.call(this, this.view.mainBody.dom, config);
45533 this.scroll = false;
45535 this.ddel = document.createElement('div');
45536 this.ddel.className = 'x-grid-dd-wrap';
45539 Ext.extend(Ext.grid.GridDragZone, Ext.dd.DragZone, {
45540 ddGroup : "GridDD",
45543 getDragData : function(e){
45544 var t = Ext.lib.Event.getTarget(e);
45545 var rowIndex = this.view.findRowIndex(t);
45546 if(rowIndex !== false){
45547 var sm = this.grid.selModel;
45548 if(!sm.isSelected(rowIndex) || e.hasModifier()){
45549 sm.handleMouseDown(this.grid, rowIndex, e);
45551 return {grid: this.grid, ddel: this.ddel, rowIndex: rowIndex, selections:sm.getSelections()};
45557 onInitDrag : function(e){
45558 var data = this.dragData;
45559 this.ddel.innerHTML = this.grid.getDragDropText();
45560 this.proxy.update(this.ddel);
45565 afterRepair : function(){
45566 this.dragging = false;
45570 getRepairXY : function(e, data){
45574 onEndDrag : function(data, e){
45578 onValidDrop : function(dd, e, id){
45583 beforeInvalidDrop : function(e, id){
45588 Ext.grid.ColumnModel = Ext.extend(Ext.util.Observable, {
45592 defaultSortable: false,
45596 constructor : function(config){
45598 if(config.columns){
45599 Ext.apply(this, config);
45600 this.setConfig(config.columns, true);
45602 this.setConfig(config, true);
45616 Ext.grid.ColumnModel.superclass.constructor.call(this);
45620 getColumnId : function(index){
45621 return this.config[index].id;
45624 getColumnAt : function(index){
45625 return this.config[index];
45629 setConfig : function(config, initial){
45632 delete this.totalWidth;
45633 for(i = 0, len = this.config.length; i < len; i++){
45634 c = this.config[i];
45643 this.defaults = Ext.apply({
45644 width: this.defaultWidth,
45645 sortable: this.defaultSortable
45648 this.config = config;
45651 for(i = 0, len = config.length; i < len; i++){
45652 c = Ext.applyIf(config[i], this.defaults);
45654 if(Ext.isEmpty(c.id)){
45658 var Cls = Ext.grid.Column.types[c.xtype || 'gridcolumn'];
45662 this.lookup[c.id] = c;
45665 this.fireEvent('configchange', this);
45670 getColumnById : function(id){
45671 return this.lookup[id];
45675 getIndexById : function(id){
45676 for(var i = 0, len = this.config.length; i < len; i++){
45677 if(this.config[i].id == id){
45685 moveColumn : function(oldIndex, newIndex){
45686 var c = this.config[oldIndex];
45687 this.config.splice(oldIndex, 1);
45688 this.config.splice(newIndex, 0, c);
45689 this.dataMap = null;
45690 this.fireEvent("columnmoved", this, oldIndex, newIndex);
45694 getColumnCount : function(visibleOnly){
45695 if(visibleOnly === true){
45697 for(var i = 0, len = this.config.length; i < len; i++){
45698 if(!this.isHidden(i)){
45704 return this.config.length;
45708 getColumnsBy : function(fn, scope){
45710 for(var i = 0, len = this.config.length; i < len; i++){
45711 var c = this.config[i];
45712 if(fn.call(scope||this, c, i) === true){
45720 isSortable : function(col){
45721 return !!this.config[col].sortable;
45725 isMenuDisabled : function(col){
45726 return !!this.config[col].menuDisabled;
45730 getRenderer : function(col){
45731 if(!this.config[col].renderer){
45732 return Ext.grid.ColumnModel.defaultRenderer;
45734 return this.config[col].renderer;
45737 getRendererScope : function(col){
45738 return this.config[col].scope;
45742 setRenderer : function(col, fn){
45743 this.config[col].renderer = fn;
45747 getColumnWidth : function(col){
45748 return this.config[col].width;
45752 setColumnWidth : function(col, width, suppressEvent){
45753 this.config[col].width = width;
45754 this.totalWidth = null;
45755 if(!suppressEvent){
45756 this.fireEvent("widthchange", this, col, width);
45761 getTotalWidth : function(includeHidden){
45762 if(!this.totalWidth){
45763 this.totalWidth = 0;
45764 for(var i = 0, len = this.config.length; i < len; i++){
45765 if(includeHidden || !this.isHidden(i)){
45766 this.totalWidth += this.getColumnWidth(i);
45770 return this.totalWidth;
45774 getColumnHeader : function(col){
45775 return this.config[col].header;
45779 setColumnHeader : function(col, header){
45780 this.config[col].header = header;
45781 this.fireEvent("headerchange", this, col, header);
45785 getColumnTooltip : function(col){
45786 return this.config[col].tooltip;
45789 setColumnTooltip : function(col, tooltip){
45790 this.config[col].tooltip = tooltip;
45794 getDataIndex : function(col){
45795 return this.config[col].dataIndex;
45799 setDataIndex : function(col, dataIndex){
45800 this.config[col].dataIndex = dataIndex;
45804 findColumnIndex : function(dataIndex){
45805 var c = this.config;
45806 for(var i = 0, len = c.length; i < len; i++){
45807 if(c[i].dataIndex == dataIndex){
45815 isCellEditable : function(colIndex, rowIndex){
45816 var c = this.config[colIndex],
45820 return !!(ed || (!Ext.isDefined(ed) && c.editor));
45824 getCellEditor : function(colIndex, rowIndex){
45825 return this.config[colIndex].getCellEditor(rowIndex);
45829 setEditable : function(col, editable){
45830 this.config[col].editable = editable;
45834 isHidden : function(colIndex){
45835 return !!this.config[colIndex].hidden;
45839 isFixed : function(colIndex){
45840 return !!this.config[colIndex].fixed;
45844 isResizable : function(colIndex){
45845 return colIndex >= 0 && this.config[colIndex].resizable !== false && this.config[colIndex].fixed !== true;
45848 setHidden : function(colIndex, hidden){
45849 var c = this.config[colIndex];
45850 if(c.hidden !== hidden){
45852 this.totalWidth = null;
45853 this.fireEvent("hiddenchange", this, colIndex, hidden);
45858 setEditor : function(col, editor){
45859 this.config[col].setEditor(editor);
45863 destroy : function(){
45865 for(var i = 0, len = this.config.length; i < len; i++){
45866 c = this.config[i];
45871 this.purgeListeners();
45875 setState : function(col, state){
45876 Ext.applyIf(this.config[col], state);
45881 Ext.grid.ColumnModel.defaultRenderer = function(value){
45882 if(typeof value == "string" && value.length < 1){
45887 Ext.grid.AbstractSelectionModel = Ext.extend(Ext.util.Observable, {
45890 constructor : function(){
45891 this.locked = false;
45892 Ext.grid.AbstractSelectionModel.superclass.constructor.call(this);
45896 init : function(grid){
45898 if(this.lockOnInit){
45899 delete this.lockOnInit;
45900 this.locked = false;
45909 this.locked = true;
45915 beforerefresh: this.sortUnLock,
45916 refresh: this.sortLock
45919 this.lockOnInit = true;
45925 sortLock : function() {
45926 this.locked = true;
45930 sortUnLock : function() {
45931 this.locked = false;
45935 unlock : function(){
45937 this.locked = false;
45944 gv.un('beforerefresh', this.sortUnLock, this);
45945 gv.un('refresh', this.sortLock, this);
45947 delete this.lockOnInit;
45953 isLocked : function(){
45954 return this.locked;
45957 destroy: function(){
45959 this.purgeListeners();
45962 Ext.grid.RowSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel, {
45964 singleSelect : false,
45966 constructor : function(config){
45967 Ext.apply(this, config);
45968 this.selections = new Ext.util.MixedCollection(false, function(o){
45973 this.lastActive = false;
45985 Ext.grid.RowSelectionModel.superclass.constructor.call(this);
45990 initEvents : function(){
45992 if(!this.grid.enableDragDrop && !this.grid.enableDrag){
45993 this.grid.on('rowmousedown', this.handleMouseDown, this);
45996 this.rowNav = new Ext.KeyNav(this.grid.getGridEl(), {
45997 'up' : function(e){
45998 if(!e.shiftKey || this.singleSelect){
45999 this.selectPrevious(false);
46000 }else if(this.last !== false && this.lastActive !== false){
46001 var last = this.last;
46002 this.selectRange(this.last, this.lastActive-1);
46003 this.grid.getView().focusRow(this.lastActive);
46004 if(last !== false){
46008 this.selectFirstRow();
46011 'down' : function(e){
46012 if(!e.shiftKey || this.singleSelect){
46013 this.selectNext(false);
46014 }else if(this.last !== false && this.lastActive !== false){
46015 var last = this.last;
46016 this.selectRange(this.last, this.lastActive+1);
46017 this.grid.getView().focusRow(this.lastActive);
46018 if(last !== false){
46022 this.selectFirstRow();
46028 this.grid.getView().on({
46030 refresh: this.onRefresh,
46031 rowupdated: this.onRowUpdated,
46032 rowremoved: this.onRemove
46037 onRefresh : function(){
46038 var ds = this.grid.store, index;
46039 var s = this.getSelections();
46040 this.clearSelections(true);
46041 for(var i = 0, len = s.length; i < len; i++){
46043 if((index = ds.indexOfId(r.id)) != -1){
46044 this.selectRow(index, true);
46047 if(s.length != this.selections.getCount()){
46048 this.fireEvent('selectionchange', this);
46053 onRemove : function(v, index, r){
46054 if(this.selections.remove(r) !== false){
46055 this.fireEvent('selectionchange', this);
46060 onRowUpdated : function(v, index, r){
46061 if(this.isSelected(r)){
46062 v.onRowSelect(index);
46067 selectRecords : function(records, keepExisting){
46069 this.clearSelections();
46071 var ds = this.grid.store;
46072 for(var i = 0, len = records.length; i < len; i++){
46073 this.selectRow(ds.indexOf(records[i]), true);
46078 getCount : function(){
46079 return this.selections.length;
46083 selectFirstRow : function(){
46088 selectLastRow : function(keepExisting){
46089 this.selectRow(this.grid.store.getCount() - 1, keepExisting);
46093 selectNext : function(keepExisting){
46094 if(this.hasNext()){
46095 this.selectRow(this.last+1, keepExisting);
46096 this.grid.getView().focusRow(this.last);
46103 selectPrevious : function(keepExisting){
46104 if(this.hasPrevious()){
46105 this.selectRow(this.last-1, keepExisting);
46106 this.grid.getView().focusRow(this.last);
46113 hasNext : function(){
46114 return this.last !== false && (this.last+1) < this.grid.store.getCount();
46118 hasPrevious : function(){
46119 return !!this.last;
46124 getSelections : function(){
46125 return [].concat(this.selections.items);
46129 getSelected : function(){
46130 return this.selections.itemAt(0);
46134 each : function(fn, scope){
46135 var s = this.getSelections();
46136 for(var i = 0, len = s.length; i < len; i++){
46137 if(fn.call(scope || this, s[i], i) === false){
46145 clearSelections : function(fast){
46146 if(this.isLocked()){
46150 var ds = this.grid.store;
46151 var s = this.selections;
46152 s.each(function(r){
46153 this.deselectRow(ds.indexOfId(r.id));
46157 this.selections.clear();
46164 selectAll : function(){
46165 if(this.isLocked()){
46168 this.selections.clear();
46169 for(var i = 0, len = this.grid.store.getCount(); i < len; i++){
46170 this.selectRow(i, true);
46175 hasSelection : function(){
46176 return this.selections.length > 0;
46180 isSelected : function(index){
46181 var r = Ext.isNumber(index) ? this.grid.store.getAt(index) : index;
46182 return (r && this.selections.key(r.id) ? true : false);
46186 isIdSelected : function(id){
46187 return (this.selections.key(id) ? true : false);
46191 handleMouseDown : function(g, rowIndex, e){
46192 if(e.button !== 0 || this.isLocked()){
46195 var view = this.grid.getView();
46196 if(e.shiftKey && !this.singleSelect && this.last !== false){
46197 var last = this.last;
46198 this.selectRange(last, rowIndex, e.ctrlKey);
46200 view.focusRow(rowIndex);
46202 var isSelected = this.isSelected(rowIndex);
46203 if(e.ctrlKey && isSelected){
46204 this.deselectRow(rowIndex);
46205 }else if(!isSelected || this.getCount() > 1){
46206 this.selectRow(rowIndex, e.ctrlKey || e.shiftKey);
46207 view.focusRow(rowIndex);
46213 selectRows : function(rows, keepExisting){
46215 this.clearSelections();
46217 for(var i = 0, len = rows.length; i < len; i++){
46218 this.selectRow(rows[i], true);
46223 selectRange : function(startRow, endRow, keepExisting){
46225 if(this.isLocked()){
46229 this.clearSelections();
46231 if(startRow <= endRow){
46232 for(i = startRow; i <= endRow; i++){
46233 this.selectRow(i, true);
46236 for(i = startRow; i >= endRow; i--){
46237 this.selectRow(i, true);
46243 deselectRange : function(startRow, endRow, preventViewNotify){
46244 if(this.isLocked()){
46247 for(var i = startRow; i <= endRow; i++){
46248 this.deselectRow(i, preventViewNotify);
46253 selectRow : function(index, keepExisting, preventViewNotify){
46254 if(this.isLocked() || (index < 0 || index >= this.grid.store.getCount()) || (keepExisting && this.isSelected(index))){
46257 var r = this.grid.store.getAt(index);
46258 if(r && this.fireEvent('beforerowselect', this, index, keepExisting, r) !== false){
46259 if(!keepExisting || this.singleSelect){
46260 this.clearSelections();
46262 this.selections.add(r);
46263 this.last = this.lastActive = index;
46264 if(!preventViewNotify){
46265 this.grid.getView().onRowSelect(index);
46267 this.fireEvent('rowselect', this, index, r);
46268 this.fireEvent('selectionchange', this);
46273 deselectRow : function(index, preventViewNotify){
46274 if(this.isLocked()){
46277 if(this.last == index){
46280 if(this.lastActive == index){
46281 this.lastActive = false;
46283 var r = this.grid.store.getAt(index);
46285 this.selections.remove(r);
46286 if(!preventViewNotify){
46287 this.grid.getView().onRowDeselect(index);
46289 this.fireEvent('rowdeselect', this, index, r);
46290 this.fireEvent('selectionchange', this);
46295 restoreLast : function(){
46297 this.last = this._last;
46302 acceptsNav : function(row, col, cm){
46303 return !cm.isHidden(col) && cm.isCellEditable(col, row);
46307 onEditorKey : function(field, e){
46308 var k = e.getKey(),
46312 ed = g.activeEditor,
46314 var shift = e.shiftKey;
46319 newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
46321 newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
46323 }else if(k == e.ENTER){
46324 if(this.moveEditorOnEnter !== false){
46326 newCell = g.walkCells(last.row - 1, last.col, -1, this.acceptsNav, this);
46328 newCell = g.walkCells(last.row + 1, last.col, 1, this.acceptsNav, this);
46340 if(g.isEditor && g.editing){
46341 ae = g.activeEditor;
46342 if(ae && ae.field.triggerBlur){
46344 ae.field.triggerBlur();
46347 g.startEditing(r, c);
46351 destroy : function(){
46353 this.rowNav.disable();
46354 this.rowNav = null;
46356 Ext.grid.RowSelectionModel.superclass.destroy.call(this);
46359 Ext.grid.Column = Ext.extend(Object, {
46386 constructor : function(config){
46387 Ext.apply(this, config);
46389 if(Ext.isString(this.renderer)){
46390 this.renderer = Ext.util.Format[this.renderer];
46391 }else if(Ext.isObject(this.renderer)){
46392 this.scope = this.renderer.scope;
46393 this.renderer = this.renderer.fn;
46399 var ed = this.editor;
46400 delete this.editor;
46401 this.setEditor(ed);
46405 renderer : function(value){
46406 if(Ext.isString(value) && value.length < 1){
46413 getEditor: function(rowIndex){
46414 return this.editable !== false ? this.editor : null;
46418 setEditor : function(editor){
46419 var ed = this.editor;
46422 ed.gridEditor.destroy();
46423 delete ed.gridEditor;
46428 this.editor = null;
46431 if(!editor.isXType){
46432 editor = Ext.create(editor, 'textfield');
46434 this.editor = editor;
46439 getCellEditor: function(rowIndex){
46440 var ed = this.getEditor(rowIndex);
46443 if(!ed.gridEditor){
46444 ed.gridEditor = new Ext.grid.GridEditor(ed);
46446 ed = ed.gridEditor;
46454 Ext.grid.BooleanColumn = Ext.extend(Ext.grid.Column, {
46458 falseText: 'false',
46460 undefinedText: ' ',
46462 constructor: function(cfg){
46463 Ext.grid.BooleanColumn.superclass.constructor.call(this, cfg);
46464 var t = this.trueText, f = this.falseText, u = this.undefinedText;
46465 this.renderer = function(v){
46466 if(v === undefined){
46469 if(!v || v === 'false'){
46478 Ext.grid.NumberColumn = Ext.extend(Ext.grid.Column, {
46480 format : '0,000.00',
46481 constructor: function(cfg){
46482 Ext.grid.NumberColumn.superclass.constructor.call(this, cfg);
46483 this.renderer = Ext.util.Format.numberRenderer(this.format);
46488 Ext.grid.DateColumn = Ext.extend(Ext.grid.Column, {
46491 constructor: function(cfg){
46492 Ext.grid.DateColumn.superclass.constructor.call(this, cfg);
46493 this.renderer = Ext.util.Format.dateRenderer(this.format);
46498 Ext.grid.TemplateColumn = Ext.extend(Ext.grid.Column, {
46500 constructor: function(cfg){
46501 Ext.grid.TemplateColumn.superclass.constructor.call(this, cfg);
46502 var tpl = (!Ext.isPrimitive(this.tpl) && this.tpl.compile) ? this.tpl : new Ext.XTemplate(this.tpl);
46503 this.renderer = function(value, p, r){
46504 return tpl.apply(r.data);
46511 Ext.grid.Column.types = {
46512 gridcolumn : Ext.grid.Column,
46513 booleancolumn: Ext.grid.BooleanColumn,
46514 numbercolumn: Ext.grid.NumberColumn,
46515 datecolumn: Ext.grid.DateColumn,
46516 templatecolumn: Ext.grid.TemplateColumn
46518 Ext.grid.RowNumberer = Ext.extend(Object, {
46526 constructor : function(config){
46527 Ext.apply(this, config);
46529 this.renderer = this.renderer.createDelegate(this);
46539 rowspan: undefined,
46542 renderer : function(v, p, record, rowIndex){
46544 p.cellAttr = 'rowspan="'+this.rowspan+'"';
46549 Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, {
46553 header : '<div class="x-grid3-hd-checker"> </div>',
46560 menuDisabled : true,
46566 constructor : function(){
46567 Ext.grid.CheckboxSelectionModel.superclass.constructor.apply(this, arguments);
46569 if(this.checkOnly){
46570 this.handleMouseDown = Ext.emptyFn;
46575 initEvents : function(){
46576 Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this);
46577 this.grid.on('render', function(){
46578 var view = this.grid.getView();
46579 view.mainBody.on('mousedown', this.onMouseDown, this);
46580 Ext.fly(view.innerHd).on('mousedown', this.onHdMouseDown, this);
46587 handleMouseDown : function() {
46588 Ext.grid.CheckboxSelectionModel.superclass.handleMouseDown.apply(this, arguments);
46589 this.mouseHandled = true;
46593 onMouseDown : function(e, t){
46594 if(e.button === 0 && t.className == 'x-grid3-row-checker'){
46596 var row = e.getTarget('.x-grid3-row');
46599 if(!this.mouseHandled && row){
46600 var index = row.rowIndex;
46601 if(this.isSelected(index)){
46602 this.deselectRow(index);
46604 this.selectRow(index, true);
46605 this.grid.getView().focusRow(index);
46609 this.mouseHandled = false;
46613 onHdMouseDown : function(e, t){
46614 if(t.className == 'x-grid3-hd-checker'){
46616 var hd = Ext.fly(t.parentNode);
46617 var isChecked = hd.hasClass('x-grid3-hd-checker-on');
46619 hd.removeClass('x-grid3-hd-checker-on');
46620 this.clearSelections();
46622 hd.addClass('x-grid3-hd-checker-on');
46629 renderer : function(v, p, record){
46630 return '<div class="x-grid3-row-checker"> </div>';
46633 Ext.grid.CellSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel, {
46635 constructor : function(config){
46636 Ext.apply(this, config);
46638 this.selection = null;
46642 "beforecellselect",
46649 Ext.grid.CellSelectionModel.superclass.constructor.call(this);
46653 initEvents : function(){
46654 this.grid.on('cellmousedown', this.handleMouseDown, this);
46655 this.grid.on(Ext.EventManager.useKeydown ? 'keydown' : 'keypress', this.handleKeyDown, this);
46656 this.grid.getView().on({
46658 refresh: this.onViewChange,
46659 rowupdated: this.onRowUpdated,
46660 beforerowremoved: this.clearSelections,
46661 beforerowsinserted: this.clearSelections
46663 if(this.grid.isEditor){
46664 this.grid.on('beforeedit', this.beforeEdit, this);
46669 beforeEdit : function(e){
46670 this.select(e.row, e.column, false, true, e.record);
46674 onRowUpdated : function(v, index, r){
46675 if(this.selection && this.selection.record == r){
46676 v.onCellSelect(index, this.selection.cell[1]);
46681 onViewChange : function(){
46682 this.clearSelections(true);
46686 getSelectedCell : function(){
46687 return this.selection ? this.selection.cell : null;
46691 clearSelections : function(preventNotify){
46692 var s = this.selection;
46694 if(preventNotify !== true){
46695 this.grid.view.onCellDeselect(s.cell[0], s.cell[1]);
46697 this.selection = null;
46698 this.fireEvent("selectionchange", this, null);
46703 hasSelection : function(){
46704 return this.selection ? true : false;
46708 handleMouseDown : function(g, row, cell, e){
46709 if(e.button !== 0 || this.isLocked()){
46712 this.select(row, cell);
46716 select : function(rowIndex, colIndex, preventViewNotify, preventFocus, r){
46717 if(this.fireEvent("beforecellselect", this, rowIndex, colIndex) !== false){
46718 this.clearSelections();
46719 r = r || this.grid.store.getAt(rowIndex);
46722 cell : [rowIndex, colIndex]
46724 if(!preventViewNotify){
46725 var v = this.grid.getView();
46726 v.onCellSelect(rowIndex, colIndex);
46727 if(preventFocus !== true){
46728 v.focusCell(rowIndex, colIndex);
46731 this.fireEvent("cellselect", this, rowIndex, colIndex);
46732 this.fireEvent("selectionchange", this, this.selection);
46737 isSelectable : function(rowIndex, colIndex, cm){
46738 return !cm.isHidden(colIndex);
46742 onEditorKey: function(field, e){
46743 if(e.getKey() == e.TAB){
46744 this.handleKeyDown(e);
46749 handleKeyDown : function(e){
46750 if(!e.isNavKeyPress()){
46754 var k = e.getKey(),
46756 s = this.selection,
46758 walk = function(row, col, step){
46759 return g.walkCells(
46763 g.isEditor && g.editing ? sm.acceptsNav : sm.isSelectable,
46767 cell, newCell, r, c, ae;
46782 cell = walk(0, 0, 1);
46784 this.select(cell[0], cell[1]);
46796 newCell = walk(r, c - 1, -1);
46798 newCell = walk(r, c + 1, 1);
46802 newCell = walk(r + 1, c, 1);
46805 newCell = walk(r - 1, c, -1);
46808 newCell = walk(r, c + 1, 1);
46811 newCell = walk(r, c - 1, -1);
46814 if (g.isEditor && !g.editing) {
46815 g.startEditing(r, c);
46828 if(g.isEditor && g.editing){
46829 ae = g.activeEditor;
46830 if(ae && ae.field.triggerBlur){
46832 ae.field.triggerBlur();
46834 g.startEditing(r, c);
46839 acceptsNav : function(row, col, cm){
46840 return !cm.isHidden(col) && cm.isCellEditable(col, row);
46843 Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, {
46848 forceValidation: false,
46856 autoEncode : false,
46860 trackMouseOver: false,
46863 initComponent : function(){
46864 Ext.grid.EditorGridPanel.superclass.initComponent.call(this);
46866 if(!this.selModel){
46868 this.selModel = new Ext.grid.CellSelectionModel();
46871 this.activeEditor = null;
46884 initEvents : function(){
46885 Ext.grid.EditorGridPanel.superclass.initEvents.call(this);
46887 this.getGridEl().on('mousewheel', this.stopEditing.createDelegate(this, [true]), this);
46888 this.on('columnresize', this.stopEditing, this, [true]);
46890 if(this.clicksToEdit == 1){
46891 this.on("cellclick", this.onCellDblClick, this);
46893 var view = this.getView();
46894 if(this.clicksToEdit == 'auto' && view.mainBody){
46895 view.mainBody.on('mousedown', this.onAutoEditClick, this);
46897 this.on('celldblclick', this.onCellDblClick, this);
46901 onResize : function(){
46902 Ext.grid.EditorGridPanel.superclass.onResize.apply(this, arguments);
46903 var ae = this.activeEditor;
46904 if(this.editing && ae){
46910 onCellDblClick : function(g, row, col){
46911 this.startEditing(row, col);
46915 onAutoEditClick : function(e, t){
46916 if(e.button !== 0){
46919 var row = this.view.findRowIndex(t),
46920 col = this.view.findCellIndex(t);
46921 if(row !== false && col !== false){
46922 this.stopEditing();
46923 if(this.selModel.getSelectedCell){
46924 var sc = this.selModel.getSelectedCell();
46925 if(sc && sc[0] === row && sc[1] === col){
46926 this.startEditing(row, col);
46929 if(this.selModel.isSelected(row)){
46930 this.startEditing(row, col);
46937 onEditComplete : function(ed, value, startValue){
46938 this.editing = false;
46939 this.lastActiveEditor = this.activeEditor;
46940 this.activeEditor = null;
46943 field = this.colModel.getDataIndex(ed.col);
46944 value = this.postEditValue(value, startValue, r, field);
46945 if(this.forceValidation === true || String(value) !== String(startValue)){
46950 originalValue: startValue,
46956 if(this.fireEvent("validateedit", e) !== false && !e.cancel && String(value) !== String(startValue)){
46957 r.set(field, e.value);
46959 this.fireEvent("afteredit", e);
46962 this.view.focusCell(ed.row, ed.col);
46966 startEditing : function(row, col){
46967 this.stopEditing();
46968 if(this.colModel.isCellEditable(col, row)){
46969 this.view.ensureVisible(row, col, true);
46970 var r = this.store.getAt(row),
46971 field = this.colModel.getDataIndex(col),
46976 value: r.data[field],
46981 if(this.fireEvent("beforeedit", e) !== false && !e.cancel){
46982 this.editing = true;
46983 var ed = this.colModel.getCellEditor(col, row);
46988 ed.parentEl = this.view.getEditorParent(ed);
46993 c.field.focus(false, true);
46998 specialkey: function(field, e){
46999 this.getSelectionModel().onEditorKey(field, e);
47001 complete: this.onEditComplete,
47002 canceledit: this.stopEditing.createDelegate(this, [true])
47014 this.activeEditor = ed;
47017 ed.selectSameEditor = (this.activeEditor == this.lastActiveEditor);
47018 var v = this.preEditValue(r, field);
47019 ed.startEdit(this.view.getCell(row, col).firstChild, Ext.isDefined(v) ? v : '');
47023 delete ed.selectSameEditor;
47030 preEditValue : function(r, field){
47031 var value = r.data[field];
47032 return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlDecode(value) : value;
47036 postEditValue : function(value, originalValue, r, field){
47037 return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlEncode(value) : value;
47041 stopEditing : function(cancel){
47044 var ae = this.lastActiveEditor = this.activeEditor;
47046 ae[cancel === true ? 'cancelEdit' : 'completeEdit']();
47047 this.view.focusCell(ae.row, ae.col);
47049 this.activeEditor = null;
47051 this.editing = false;
47054 Ext.reg('editorgrid', Ext.grid.EditorGridPanel);
47056 Ext.grid.GridEditor = function(field, config){
47057 Ext.grid.GridEditor.superclass.constructor.call(this, field, config);
47058 field.monitorTab = false;
47061 Ext.extend(Ext.grid.GridEditor, Ext.Editor, {
47062 alignment: "tl-tl",
47065 cls: "x-small-editor x-grid-editor",
47069 Ext.grid.PropertyRecord = Ext.data.Record.create([
47070 {name:'name',type:'string'}, 'value'
47074 Ext.grid.PropertyStore = Ext.extend(Ext.util.Observable, {
47076 constructor : function(grid, source){
47078 this.store = new Ext.data.Store({
47079 recordType : Ext.grid.PropertyRecord
47081 this.store.on('update', this.onUpdate, this);
47083 this.setSource(source);
47085 Ext.grid.PropertyStore.superclass.constructor.call(this);
47089 setSource : function(o){
47091 this.store.removeAll();
47094 if(this.isEditableValue(o[k])){
47095 data.push(new Ext.grid.PropertyRecord({name: k, value: o[k]}, k));
47098 this.store.loadRecords({records: data}, {}, true);
47102 onUpdate : function(ds, record, type){
47103 if(type == Ext.data.Record.EDIT){
47104 var v = record.data.value;
47105 var oldValue = record.modified.value;
47106 if(this.grid.fireEvent('beforepropertychange', this.source, record.id, v, oldValue) !== false){
47107 this.source[record.id] = v;
47109 this.grid.fireEvent('propertychange', this.source, record.id, v, oldValue);
47117 getProperty : function(row){
47118 return this.store.getAt(row);
47122 isEditableValue: function(val){
47123 return Ext.isPrimitive(val) || Ext.isDate(val);
47127 setValue : function(prop, value, create){
47128 var r = this.getRec(prop);
47130 r.set('value', value);
47131 this.source[prop] = value;
47134 this.source[prop] = value;
47135 r = new Ext.grid.PropertyRecord({name: prop, value: value}, prop);
47142 remove : function(prop){
47143 var r = this.getRec(prop);
47145 this.store.remove(r);
47146 delete this.source[prop];
47151 getRec : function(prop){
47152 return this.store.getById(prop);
47156 getSource : function(){
47157 return this.source;
47162 Ext.grid.PropertyColumnModel = Ext.extend(Ext.grid.ColumnModel, {
47165 valueText : 'Value',
47166 dateFormat : 'm/j/Y',
47168 falseText: 'false',
47170 constructor : function(grid, store){
47175 g.PropertyColumnModel.superclass.constructor.call(this, [
47176 {header: this.nameText, width:50, sortable: true, dataIndex:'name', id: 'name', menuDisabled:true},
47177 {header: this.valueText, width:50, resizable:false, dataIndex: 'value', id: 'value', menuDisabled:true}
47179 this.store = store;
47181 var bfield = new f.Field({
47182 autoCreate: {tag: 'select', children: [
47183 {tag: 'option', value: 'true', html: this.trueText},
47184 {tag: 'option', value: 'false', html: this.falseText}
47186 getValue : function(){
47187 return this.el.dom.value == 'true';
47191 'date' : new g.GridEditor(new f.DateField({selectOnFocus:true})),
47192 'string' : new g.GridEditor(new f.TextField({selectOnFocus:true})),
47193 'number' : new g.GridEditor(new f.NumberField({selectOnFocus:true, style:'text-align:left;'})),
47194 'boolean' : new g.GridEditor(bfield, {
47198 this.renderCellDelegate = this.renderCell.createDelegate(this);
47199 this.renderPropDelegate = this.renderProp.createDelegate(this);
47203 renderDate : function(dateVal){
47204 return dateVal.dateFormat(this.dateFormat);
47208 renderBool : function(bVal){
47209 return this[bVal ? 'trueText' : 'falseText'];
47213 isCellEditable : function(colIndex, rowIndex){
47214 return colIndex == 1;
47218 getRenderer : function(col){
47220 this.renderCellDelegate : this.renderPropDelegate;
47224 renderProp : function(v){
47225 return this.getPropertyName(v);
47229 renderCell : function(val, meta, rec){
47230 var renderer = this.grid.customRenderers[rec.get('name')];
47232 return renderer.apply(this, arguments);
47235 if(Ext.isDate(val)){
47236 rv = this.renderDate(val);
47237 }else if(typeof val == 'boolean'){
47238 rv = this.renderBool(val);
47240 return Ext.util.Format.htmlEncode(rv);
47244 getPropertyName : function(name){
47245 var pn = this.grid.propertyNames;
47246 return pn && pn[name] ? pn[name] : name;
47250 getCellEditor : function(colIndex, rowIndex){
47251 var p = this.store.getProperty(rowIndex),
47253 val = p.data.value;
47254 if(this.grid.customEditors[n]){
47255 return this.grid.customEditors[n];
47257 if(Ext.isDate(val)){
47258 return this.editors.date;
47259 }else if(typeof val == 'number'){
47260 return this.editors.number;
47261 }else if(typeof val == 'boolean'){
47262 return this.editors['boolean'];
47264 return this.editors.string;
47269 destroy : function(){
47270 Ext.grid.PropertyColumnModel.superclass.destroy.call(this);
47271 for(var ed in this.editors){
47272 Ext.destroy(this.editors[ed]);
47278 Ext.grid.PropertyGrid = Ext.extend(Ext.grid.EditorGridPanel, {
47286 enableColumnMove:false,
47288 trackMouseOver: false,
47290 enableHdMenu : false,
47296 initComponent : function(){
47297 this.customRenderers = this.customRenderers || {};
47298 this.customEditors = this.customEditors || {};
47299 this.lastEditRow = null;
47300 var store = new Ext.grid.PropertyStore(this);
47301 this.propStore = store;
47302 var cm = new Ext.grid.PropertyColumnModel(this, store);
47303 store.store.sort('name', 'ASC');
47306 'beforepropertychange',
47311 this.ds = store.store;
47312 Ext.grid.PropertyGrid.superclass.initComponent.call(this);
47314 this.mon(this.selModel, 'beforecellselect', function(sm, rowIndex, colIndex){
47315 if(colIndex === 0){
47316 this.startEditing.defer(200, this, [rowIndex, 1]);
47323 onRender : function(){
47324 Ext.grid.PropertyGrid.superclass.onRender.apply(this, arguments);
47326 this.getGridEl().addClass('x-props-grid');
47330 afterRender: function(){
47331 Ext.grid.PropertyGrid.superclass.afterRender.apply(this, arguments);
47333 this.setSource(this.source);
47338 setSource : function(source){
47339 this.propStore.setSource(source);
47343 getSource : function(){
47344 return this.propStore.getSource();
47348 setProperty : function(prop, value, create){
47349 this.propStore.setValue(prop, value, create);
47353 removeProperty : function(prop){
47354 this.propStore.remove(prop);
47362 Ext.reg("propertygrid", Ext.grid.PropertyGrid);
47364 Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
47367 groupByText : 'Group By This Field',
47369 showGroupsText : 'Show in Groups',
47371 hideGroupedColumn : false,
47373 showGroupName : true,
47375 startCollapsed : false,
47377 enableGrouping : true,
47379 enableGroupingMenu : true,
47381 enableNoGroups : true,
47383 emptyGroupText : '(None)',
47387 groupTextTpl : '{text}',
47390 groupMode: 'value',
47395 initTemplates : function(){
47396 Ext.grid.GroupingView.superclass.initTemplates.call(this);
47399 var sm = this.grid.getSelectionModel();
47400 sm.on(sm.selectRow ? 'beforerowselect' : 'beforecellselect',
47401 this.onBeforeRowSelect, this);
47403 if(!this.startGroup){
47404 this.startGroup = new Ext.XTemplate(
47405 '<div id="{groupId}" class="x-grid-group {cls}">',
47406 '<div id="{groupId}-hd" class="x-grid-group-hd" style="{style}"><div class="x-grid-group-title">', this.groupTextTpl ,'</div></div>',
47407 '<div id="{groupId}-bd" class="x-grid-group-body">'
47410 this.startGroup.compile();
47412 if (!this.endGroup) {
47413 this.endGroup = '</div></div>';
47418 findGroup : function(el){
47419 return Ext.fly(el).up('.x-grid-group', this.mainBody.dom);
47423 getGroups : function(){
47424 return this.hasRows() ? this.mainBody.dom.childNodes : [];
47428 onAdd : function(ds, records, index) {
47429 if (this.canGroup() && !this.ignoreAdd) {
47430 var ss = this.getScrollState();
47431 this.fireEvent('beforerowsinserted', ds, index, index + (records.length-1));
47433 this.restoreScroll(ss);
47434 this.fireEvent('rowsinserted', ds, index, index + (records.length-1));
47435 } else if (!this.canGroup()) {
47436 Ext.grid.GroupingView.superclass.onAdd.apply(this, arguments);
47441 onRemove : function(ds, record, index, isUpdate){
47442 Ext.grid.GroupingView.superclass.onRemove.apply(this, arguments);
47443 var g = document.getElementById(record._groupId);
47444 if(g && g.childNodes[1].childNodes.length < 1){
47447 this.applyEmptyText();
47451 refreshRow : function(record){
47452 if(this.ds.getCount()==1){
47455 this.isUpdating = true;
47456 Ext.grid.GroupingView.superclass.refreshRow.apply(this, arguments);
47457 this.isUpdating = false;
47462 beforeMenuShow : function(){
47463 var item, items = this.hmenu.items, disabled = this.cm.config[this.hdCtxIndex].groupable === false;
47464 if((item = items.get('groupBy'))){
47465 item.setDisabled(disabled);
47467 if((item = items.get('showGroups'))){
47468 item.setDisabled(disabled);
47469 item.setChecked(this.canGroup(), true);
47474 renderUI : function(){
47475 Ext.grid.GroupingView.superclass.renderUI.call(this);
47476 this.mainBody.on('mousedown', this.interceptMouse, this);
47478 if(this.enableGroupingMenu && this.hmenu){
47479 this.hmenu.add('-',{
47481 text: this.groupByText,
47482 handler: this.onGroupByClick,
47484 iconCls:'x-group-by-icon'
47486 if(this.enableNoGroups){
47488 itemId:'showGroups',
47489 text: this.showGroupsText,
47491 checkHandler: this.onShowGroupsClick,
47495 this.hmenu.on('beforeshow', this.beforeMenuShow, this);
47499 processEvent: function(name, e){
47500 Ext.grid.GroupingView.superclass.processEvent.call(this, name, e);
47501 var hd = e.getTarget('.x-grid-group-hd', this.mainBody);
47504 var field = this.getGroupField(),
47505 prefix = this.getPrefix(field),
47506 groupValue = hd.id.substring(prefix.length),
47507 emptyRe = new RegExp('gp-' + Ext.escapeRe(field) + '--hd');
47510 groupValue = groupValue.substr(0, groupValue.length - 3);
47513 if(groupValue || emptyRe.test(hd.id)){
47514 this.grid.fireEvent('group' + name, this.grid, field, groupValue, e);
47516 if(name == 'mousedown' && e.button == 0){
47517 this.toggleGroup(hd.parentNode);
47524 onGroupByClick : function(){
47525 this.enableGrouping = true;
47526 this.grid.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex));
47527 this.grid.fireEvent('groupchange', this, this.grid.store.getGroupState());
47528 this.beforeMenuShow();
47533 onShowGroupsClick : function(mi, checked){
47534 this.enableGrouping = checked;
47536 this.onGroupByClick();
47538 this.grid.store.clearGrouping();
47539 this.grid.fireEvent('groupchange', this, null);
47544 toggleRowIndex : function(rowIndex, expanded){
47545 if(!this.canGroup()){
47548 var row = this.getRow(rowIndex);
47550 this.toggleGroup(this.findGroup(row), expanded);
47555 toggleGroup : function(group, expanded){
47556 var gel = Ext.get(group);
47557 expanded = Ext.isDefined(expanded) ? expanded : gel.hasClass('x-grid-group-collapsed');
47558 if(this.state[gel.id] !== expanded){
47559 this.grid.stopEditing(true);
47560 this.state[gel.id] = expanded;
47561 gel[expanded ? 'removeClass' : 'addClass']('x-grid-group-collapsed');
47566 toggleAllGroups : function(expanded){
47567 var groups = this.getGroups();
47568 for(var i = 0, len = groups.length; i < len; i++){
47569 this.toggleGroup(groups[i], expanded);
47574 expandAllGroups : function(){
47575 this.toggleAllGroups(true);
47579 collapseAllGroups : function(){
47580 this.toggleAllGroups(false);
47584 interceptMouse : function(e){
47585 var hd = e.getTarget('.x-grid-group-hd', this.mainBody);
47588 this.toggleGroup(hd.parentNode);
47593 getGroup : function(v, r, groupRenderer, rowIndex, colIndex, ds){
47594 var g = groupRenderer ? groupRenderer(v, {}, r, rowIndex, colIndex, ds) : String(v);
47595 if(g === '' || g === ' '){
47596 g = this.cm.config[colIndex].emptyGroupText || this.emptyGroupText;
47602 getGroupField : function(){
47603 return this.grid.store.getGroupState();
47607 afterRender : function(){
47608 if(!this.ds || !this.cm){
47611 Ext.grid.GroupingView.superclass.afterRender.call(this);
47612 if(this.grid.deferRowRender){
47613 this.updateGroupWidths();
47618 renderRows : function(){
47619 var groupField = this.getGroupField();
47620 var eg = !!groupField;
47622 if(this.hideGroupedColumn) {
47623 var colIndex = this.cm.findColumnIndex(groupField),
47624 hasLastGroupField = Ext.isDefined(this.lastGroupField);
47625 if(!eg && hasLastGroupField){
47626 this.mainBody.update('');
47627 this.cm.setHidden(this.cm.findColumnIndex(this.lastGroupField), false);
47628 delete this.lastGroupField;
47629 }else if (eg && !hasLastGroupField){
47630 this.lastGroupField = groupField;
47631 this.cm.setHidden(colIndex, true);
47632 }else if (eg && hasLastGroupField && groupField !== this.lastGroupField) {
47633 this.mainBody.update('');
47634 var oldIndex = this.cm.findColumnIndex(this.lastGroupField);
47635 this.cm.setHidden(oldIndex, false);
47636 this.lastGroupField = groupField;
47637 this.cm.setHidden(colIndex, true);
47640 return Ext.grid.GroupingView.superclass.renderRows.apply(
47645 doRender : function(cs, rs, ds, startRow, colCount, stripe){
47650 if(!this.canGroup() || this.isUpdating){
47651 return Ext.grid.GroupingView.superclass.doRender.apply(this, arguments);
47654 var groupField = this.getGroupField(),
47655 colIndex = this.cm.findColumnIndex(groupField),
47657 gstyle = 'width:' + this.getTotalWidth() + ';',
47658 cfg = this.cm.config[colIndex],
47659 groupRenderer = cfg.groupRenderer || cfg.renderer,
47660 prefix = this.showGroupName ? (cfg.groupName || cfg.header)+': ' : '',
47662 curGroup, i, len, gid;
47664 for(i = 0, len = rs.length; i < len; i++){
47665 var rowIndex = startRow + i,
47667 gvalue = r.data[groupField];
47669 g = this.getGroup(gvalue, r, groupRenderer, rowIndex, colIndex, ds);
47670 if(!curGroup || curGroup.group != g){
47671 gid = this.constructId(gvalue, groupField, colIndex);
47674 this.state[gid] = !(Ext.isDefined(this.state[gid]) ? !this.state[gid] : this.startCollapsed);
47680 startRow: rowIndex,
47682 cls: this.state[gid] ? '' : 'x-grid-group-collapsed',
47685 groups.push(curGroup);
47687 curGroup.rs.push(r);
47693 for(i = 0, len = groups.length; i < len; i++){
47695 this.doGroupStart(buf, g, cs, ds, colCount);
47696 buf[buf.length] = Ext.grid.GroupingView.superclass.doRender.call(
47697 this, cs, g.rs, ds, g.startRow, colCount, stripe);
47699 this.doGroupEnd(buf, g, cs, ds, colCount);
47701 return buf.join('');
47705 getGroupId : function(value){
47706 var field = this.getGroupField();
47707 return this.constructId(value, field, this.cm.findColumnIndex(field));
47711 constructId : function(value, field, idx){
47712 var cfg = this.cm.config[idx],
47713 groupRenderer = cfg.groupRenderer || cfg.renderer,
47714 val = (this.groupMode == 'value') ? value : this.getGroup(value, {data:{}}, groupRenderer, 0, idx, this.ds);
47716 return this.getPrefix(field) + Ext.util.Format.htmlEncode(val);
47720 canGroup : function(){
47721 return this.enableGrouping && !!this.getGroupField();
47725 getPrefix: function(field){
47726 return this.grid.getGridEl().id + '-gp-' + field + '-';
47730 doGroupStart : function(buf, g, cs, ds, colCount){
47731 buf[buf.length] = this.startGroup.apply(g);
47735 doGroupEnd : function(buf, g, cs, ds, colCount){
47736 buf[buf.length] = this.endGroup;
47740 getRows : function(){
47741 if(!this.canGroup()){
47742 return Ext.grid.GroupingView.superclass.getRows.call(this);
47745 gs = this.getGroups(),
47751 for(; i < len; ++i){
47752 g = gs[i].childNodes[1];
47755 for(j = 0, jlen = g.length; j < jlen; ++j){
47756 r[r.length] = g[j];
47764 updateGroupWidths : function(){
47765 if(!this.canGroup() || !this.hasRows()){
47768 var tw = Math.max(this.cm.getTotalWidth(), this.el.dom.offsetWidth-this.getScrollOffset()) +'px';
47769 var gs = this.getGroups();
47770 for(var i = 0, len = gs.length; i < len; i++){
47771 gs[i].firstChild.style.width = tw;
47776 onColumnWidthUpdated : function(col, w, tw){
47777 Ext.grid.GroupingView.superclass.onColumnWidthUpdated.call(this, col, w, tw);
47778 this.updateGroupWidths();
47782 onAllColumnWidthsUpdated : function(ws, tw){
47783 Ext.grid.GroupingView.superclass.onAllColumnWidthsUpdated.call(this, ws, tw);
47784 this.updateGroupWidths();
47788 onColumnHiddenUpdated : function(col, hidden, tw){
47789 Ext.grid.GroupingView.superclass.onColumnHiddenUpdated.call(this, col, hidden, tw);
47790 this.updateGroupWidths();
47794 onLayout : function(){
47795 this.updateGroupWidths();
47799 onBeforeRowSelect : function(sm, rowIndex){
47800 this.toggleRowIndex(rowIndex, true);
47804 Ext.grid.GroupingView.GROUP_ID = 1000;