3 <title>The source code</title>
\r
4 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
\r
5 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
\r
7 <body onload="prettyPrint();">
\r
8 <pre class="prettyprint lang-js">/*
10 * Copyright(c) 2006-2008, Ext JS, LLC.
13 * http://extjs.com/license
17 Ext.DomHelper = function(){
18 var tempTableEl = null;
19 var emptyTags = /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i;
20 var tableRe = /^table|tbody|tr|td$/i;
23 var createHtml = function(o){
24 if(typeof o == 'string'){
29 for (var i = 0, l = o.length; i < l; i++) {
30 b += createHtml(o[i]);
39 if(attr == "tag" || attr == "children" || attr == "cn" || attr == "html" || typeof o[attr] == "function") continue;
42 if(typeof s == "function"){
45 if(typeof s == "string"){
46 b += ' style="' + s + '"';
47 }else if(typeof s == "object"){
50 if(typeof s[key] != "function"){
51 b += key + ":" + s[key] + ";";
58 b += ' class="' + o["cls"] + '"';
59 }else if(attr == "htmlFor"){
60 b += ' for="' + o["htmlFor"] + '"';
62 b += " " + attr + '="' + o[attr] + '"';
66 if(emptyTags.test(o.tag)){
70 var cn = o.children || o.cn;
76 b += "</" + o.tag + ">";
83 var createDom = function(o, parentNode){
86 el = document.createDocumentFragment();
87 for(var i = 0, l = o.length; i < l; i++) {
90 } else if (typeof o == "string)") {
91 el = document.createTextNode(o);
93 el = document.createElement(o.tag||'div');
94 var useSet = !!el.setAttribute;
96 if(attr == "tag" || attr == "children" || attr == "cn" || attr == "html" || attr == "style" || typeof o[attr] == "function") continue;
98 el.className = o["cls"];
100 if(useSet) el.setAttribute(attr, o[attr]);
101 else el[attr] = o[attr];
104 Ext.DomHelper.applyStyles(el, o.style);
105 var cn = o.children || o.cn;
109 el.innerHTML = o.html;
113 parentNode.appendChild(el);
118 var ieTable = function(depth, s, h, e){
119 tempTableEl.innerHTML = [s, h, e].join('');
120 var i = -1, el = tempTableEl;
136 var insertIntoTable = function(tag, where, el, html){
138 tempTableEl = document.createElement('div');
143 if(where == 'afterbegin' || where == 'beforeend'){
146 if(where == 'beforebegin'){
150 before = el.nextSibling;
153 node = ieTable(4, trs, html, tre);
155 else if(tag == 'tr'){
156 if(where == 'beforebegin'){
159 node = ieTable(3, tbs, html, tbe);
160 } else if(where == 'afterend'){
161 before = el.nextSibling;
163 node = ieTable(3, tbs, html, tbe);
165 if(where == 'afterbegin'){
166 before = el.firstChild;
168 node = ieTable(4, trs, html, tre);
170 } else if(tag == 'tbody'){
171 if(where == 'beforebegin'){
174 node = ieTable(2, ts, html, te);
175 } else if(where == 'afterend'){
176 before = el.nextSibling;
178 node = ieTable(2, ts, html, te);
180 if(where == 'afterbegin'){
181 before = el.firstChild;
183 node = ieTable(3, tbs, html, tbe);
186 if(where == 'beforebegin' || where == 'afterend'){
189 if(where == 'afterbegin'){
190 before = el.firstChild;
192 node = ieTable(2, ts, html, te);
194 el.insertBefore(node, before);
204 markup : function(o){
205 return createHtml(o);
209 applyStyles : function(el, styles){
212 if(typeof styles == "string"){
213 var re = /\s?([a-z\-]*)\:\s?([^;]*);?/gi;
215 while ((matches = re.exec(styles)) != null){
216 el.setStyle(matches[1], matches[2]);
218 }else if (typeof styles == "object"){
219 for (var style in styles){
220 el.setStyle(style, styles[style]);
222 }else if (typeof styles == "function"){
223 Ext.DomHelper.applyStyles(el, styles.call());
229 insertHtml : function(where, el, html){
230 where = where.toLowerCase();
231 if(el.insertAdjacentHTML){
232 if(tableRe.test(el.tagName)){
234 if(rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html)){
240 el.insertAdjacentHTML('BeforeBegin', html);
241 return el.previousSibling;
243 el.insertAdjacentHTML('AfterBegin', html);
244 return el.firstChild;
246 el.insertAdjacentHTML('BeforeEnd', html);
249 el.insertAdjacentHTML('AfterEnd', html);
250 return el.nextSibling;
252 throw 'Illegal insertion point -> "' + where + '"';
254 var range = el.ownerDocument.createRange();
258 range.setStartBefore(el);
259 frag = range.createContextualFragment(html);
260 el.parentNode.insertBefore(frag, el);
261 return el.previousSibling;
264 range.setStartBefore(el.firstChild);
265 frag = range.createContextualFragment(html);
266 el.insertBefore(frag, el.firstChild);
267 return el.firstChild;
270 return el.firstChild;
274 range.setStartAfter(el.lastChild);
275 frag = range.createContextualFragment(html);
276 el.appendChild(frag);
283 range.setStartAfter(el);
284 frag = range.createContextualFragment(html);
285 el.parentNode.insertBefore(frag, el.nextSibling);
286 return el.nextSibling;
288 throw 'Illegal insertion point -> "' + where + '"';
292 insertBefore : function(el, o, returnElement){
293 return this.doInsert(el, o, returnElement, "beforeBegin");
297 insertAfter : function(el, o, returnElement){
298 return this.doInsert(el, o, returnElement, "afterEnd", "nextSibling");
302 insertFirst : function(el, o, returnElement){
303 return this.doInsert(el, o, returnElement, "afterBegin", "firstChild");
307 doInsert : function(el, o, returnElement, pos, sibling){
311 newNode = createDom(o, null);
312 (sibling === "firstChild" ? el : el.parentNode).insertBefore(newNode, sibling ? el[sibling] : el);
314 var html = createHtml(o);
315 newNode = this.insertHtml(pos, el, html);
317 return returnElement ? Ext.get(newNode, true) : newNode;
321 append : function(el, o, returnElement){
325 newNode = createDom(o, null);
326 el.appendChild(newNode);
328 var html = createHtml(o);
329 newNode = this.insertHtml("beforeEnd", el, html);
331 return returnElement ? Ext.get(newNode, true) : newNode;
335 overwrite : function(el, o, returnElement){
337 el.innerHTML = createHtml(o);
338 return returnElement ? Ext.get(el.firstChild, true) : el.firstChild;
342 createTemplate : function(o){
343 var html = createHtml(o);
344 return new Ext.Template(html);
350 Ext.Template = function(html){
352 if(Ext.isArray(html)){
353 html = html.join("");
354 }else if(a.length > 1){
356 for(var i = 0, len = a.length; i < len; i++){
357 if(typeof a[i] == 'object'){
358 Ext.apply(this, a[i]);
360 buf[buf.length] = a[i];
371 Ext.Template.prototype = {
373 applyTemplate : function(values){
375 return this.compiled(values);
377 var useF = this.disableFormats !== true;
378 var fm = Ext.util.Format, tpl = this;
379 var fn = function(m, name, format, args){
381 if(format.substr(0, 5) == "this."){
382 return tpl.call(format.substr(5), values[name], values);
388 var re = /^\s*['"](.*)["']\s*$/;
389 args = args.split(',');
390 for(var i = 0, len = args.length; i < len; i++){
391 args[i] = args[i].replace(re, "$1");
393 args = [values[name]].concat(args);
395 args = [values[name]];
397 return fm[format].apply(fm, args);
400 return values[name] !== undefined ? values[name] : "";
403 return this.html.replace(this.re, fn);
407 set : function(html, compile){
409 this.compiled = null;
417 disableFormats : false,
420 re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
423 compile : function(){
424 var fm = Ext.util.Format;
425 var useF = this.disableFormats !== true;
426 var sep = Ext.isGecko ? "+" : ",";
427 var fn = function(m, name, format, args){
429 args = args ? ',' + args : "";
430 if(format.substr(0, 5) != "this."){
431 format = "fm." + format + '(';
433 format = 'this.call("'+ format.substr(5) + '", ';
437 args= ''; format = "(values['" + name + "'] == undefined ? '' : ";
439 return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'";
444 body = "this.compiled = function(values){ return '" +
445 this.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) +
448 body = ["this.compiled = function(values){ return ['"];
449 body.push(this.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn));
450 body.push("'].join('');};");
451 body = body.join('');
458 call : function(fnName, value, allValues){
459 return this[fnName](value, allValues);
463 insertFirst: function(el, values, returnElement){
464 return this.doInsert('afterBegin', el, values, returnElement);
468 insertBefore: function(el, values, returnElement){
469 return this.doInsert('beforeBegin', el, values, returnElement);
473 insertAfter : function(el, values, returnElement){
474 return this.doInsert('afterEnd', el, values, returnElement);
478 append : function(el, values, returnElement){
479 return this.doInsert('beforeEnd', el, values, returnElement);
482 doInsert : function(where, el, values, returnEl){
484 var newNode = Ext.DomHelper.insertHtml(where, el, this.applyTemplate(values));
485 return returnEl ? Ext.get(newNode, true) : newNode;
489 overwrite : function(el, values, returnElement){
491 el.innerHTML = this.applyTemplate(values);
492 return returnElement ? Ext.get(el.firstChild, true) : el.firstChild;
496 Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;
499 Ext.DomHelper.Template = Ext.Template;
502 Ext.Template.from = function(el, config){
504 return new Ext.Template(el.value || el.innerHTML, config || '');
508 Ext.DomQuery = function(){
509 var cache = {}, simpleCache = {}, valueCache = {};
511 var trimRe = /^\s+|\s+$/g;
512 var tplRe = /\{(\d+)\}/g;
513 var modeRe = /^(\s?[\/>+~]\s?|\s|$)/;
514 var tagTokenRe = /^(#)?([\w-\*]+)/;
515 var nthRe = /(\d*)n\+?(\d*)/, nthRe2 = /\D/;
517 function child(p, index){
519 var n = p.firstChild;
532 while((n = n.nextSibling) && n.nodeType != 1);
537 while((n = n.previousSibling) && n.nodeType != 1);
541 function children(d){
542 var n = d.firstChild, ni = -1;
544 var nx = n.nextSibling;
545 if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){
555 function byClassName(c, a, v){
559 var r = [], ri = -1, cn;
560 for(var i = 0, ci; ci = c[i]; i++){
561 if((' '+ci.className+' ').indexOf(v) != -1){
568 function attrValue(n, attr){
569 if(!n.tagName && typeof n.length != "undefined"){
578 if(attr == "class" || attr == "className"){
581 return n.getAttribute(attr) || n[attr];
585 function getNodes(ns, mode, tagName){
586 var result = [], ri = -1, cs;
590 tagName = tagName || "*";
591 if(typeof ns.getElementsByTagName != "undefined"){
595 for(var i = 0, ni; ni = ns[i]; i++){
596 cs = ni.getElementsByTagName(tagName);
597 for(var j = 0, ci; ci = cs[j]; j++){
601 }else if(mode == "/" || mode == ">"){
602 var utag = tagName.toUpperCase();
603 for(var i = 0, ni, cn; ni = ns[i]; i++){
604 cn = ni.children || ni.childNodes;
605 for(var j = 0, cj; cj = cn[j]; j++){
606 if(cj.nodeName == utag || cj.nodeName == tagName || tagName == '*'){
611 }else if(mode == "+"){
612 var utag = tagName.toUpperCase();
613 for(var i = 0, n; n = ns[i]; i++){
614 while((n = n.nextSibling) && n.nodeType != 1);
615 if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){
619 }else if(mode == "~"){
620 for(var i = 0, n; n = ns[i]; i++){
621 while((n = n.nextSibling) && (n.nodeType != 1 || (tagName == '*' || n.tagName.toLowerCase()!=tagName)));
630 function concat(a, b){
634 for(var i = 0, l = b.length; i < l; i++){
640 function byTag(cs, tagName){
641 if(cs.tagName || cs == document){
648 tagName = tagName.toLowerCase();
649 for(var i = 0, ci; ci = cs[i]; i++){
650 if(ci.nodeType == 1 && ci.tagName.toLowerCase()==tagName){
657 function byId(cs, attr, id){
658 if(cs.tagName || cs == document){
665 for(var i = 0,ci; ci = cs[i]; i++){
666 if(ci && ci.id == id){
674 function byAttribute(cs, attr, value, op, custom){
675 var r = [], ri = -1, st = custom=="{";
676 var f = Ext.DomQuery.operators[op];
677 for(var i = 0, ci; ci = cs[i]; i++){
680 a = Ext.DomQuery.getStyle(ci, attr);
682 else if(attr == "class" || attr == "className"){
684 }else if(attr == "for"){
686 }else if(attr == "href"){
687 a = ci.getAttribute("href", 2);
689 a = ci.getAttribute(attr);
691 if((f && f(a, value)) || (!f && a)){
698 function byPseudo(cs, name, value){
699 return Ext.DomQuery.pseudos[name](cs, value);
705 var isIE = window.ActiveXObject ? true : false;
709 eval("var batch = 30803;");
713 function nodupIEXml(cs){
715 cs[0].setAttribute("_nodup", d);
717 for(var i = 1, len = cs.length; i < len; i++){
719 if(!c.getAttribute("_nodup") != d){
720 c.setAttribute("_nodup", d);
724 for(var i = 0, len = cs.length; i < len; i++){
725 cs[i].removeAttribute("_nodup");
734 var len = cs.length, c, i, r = cs, cj, ri = -1;
735 if(!len || typeof cs.nodeType != "undefined" || len == 1){
738 if(isIE && typeof cs[0].selectSingleNode != "undefined"){
739 return nodupIEXml(cs);
743 for(i = 1; c = cs[i]; i++){
748 for(var j = 0; j < i; j++){
751 for(j = i+1; cj = cs[j]; j++){
763 function quickDiffIEXml(c1, c2){
765 for(var i = 0, len = c1.length; i < len; i++){
766 c1[i].setAttribute("_qdiff", d);
769 for(var i = 0, len = c2.length; i < len; i++){
770 if(c2[i].getAttribute("_qdiff") != d){
774 for(var i = 0, len = c1.length; i < len; i++){
775 c1[i].removeAttribute("_qdiff");
780 function quickDiff(c1, c2){
781 var len1 = c1.length;
785 if(isIE && c1[0].selectSingleNode){
786 return quickDiffIEXml(c1, c2);
789 for(var i = 0; i < len1; i++){
793 for(var i = 0, len = c2.length; i < len; i++){
794 if(c2[i]._qdiff != d){
801 function quickId(ns, mode, root, id){
803 var d = root.ownerDocument || root;
804 return d.getElementById(id);
806 ns = getNodes(ns, mode, "*");
807 return byId(ns, null, id);
811 getStyle : function(el, name){
812 return Ext.fly(el).getStyle(name);
815 compile : function(path, type){
816 type = type || "select";
818 var fn = ["var f = function(root){\n var mode; ++batch; var n = root || document;\n"];
819 var q = path, mode, lq;
820 var tk = Ext.DomQuery.matchers;
821 var tklen = tk.length;
825 var lmode = q.match(modeRe);
826 if(lmode && lmode[1]){
827 fn[fn.length] = 'mode="'+lmode[1].replace(trimRe, "")+'";';
828 q = q.replace(lmode[1], "");
831 while(path.substr(0, 1)=="/"){
832 path = path.substr(1);
837 var tm = q.match(tagTokenRe);
838 if(type == "select"){
841 fn[fn.length] = 'n = quickId(n, mode, root, "'+tm[2]+'");';
843 fn[fn.length] = 'n = getNodes(n, mode, "'+tm[2]+'");';
845 q = q.replace(tm[0], "");
846 }else if(q.substr(0, 1) != '@'){
847 fn[fn.length] = 'n = getNodes(n, mode, "*");';
852 fn[fn.length] = 'n = byId(n, null, "'+tm[2]+'");';
854 fn[fn.length] = 'n = byTag(n, "'+tm[2]+'");';
856 q = q.replace(tm[0], "");
859 while(!(mm = q.match(modeRe))){
861 for(var j = 0; j < tklen; j++){
863 var m = q.match(t.re);
865 fn[fn.length] = t.select.replace(tplRe, function(x, i){
868 q = q.replace(m[0], "");
875 throw 'Error parsing selector, parsing failed at "' + q + '"';
879 fn[fn.length] = 'mode="'+mm[1].replace(trimRe, "")+'";';
880 q = q.replace(mm[1], "");
883 fn[fn.length] = "return nodup(n);\n}";
889 select : function(path, root, type){
890 if(!root || root == document){
893 if(typeof root == "string"){
894 root = document.getElementById(root);
896 var paths = path.split(",");
898 for(var i = 0, len = paths.length; i < len; i++){
899 var p = paths[i].replace(trimRe, "");
901 cache[p] = Ext.DomQuery.compile(p);
903 throw p + " is not a valid selector";
906 var result = cache[p](root);
907 if(result && result != document){
908 results = results.concat(result);
911 if(paths.length > 1){
912 return nodup(results);
918 selectNode : function(path, root){
919 return Ext.DomQuery.select(path, root)[0];
923 selectValue : function(path, root, defaultValue){
924 path = path.replace(trimRe, "");
925 if(!valueCache[path]){
926 valueCache[path] = Ext.DomQuery.compile(path, "select");
928 var n = valueCache[path](root);
930 var v = (n && n.firstChild ? n.firstChild.nodeValue : null);
931 return ((v === null||v === undefined||v==='') ? defaultValue : v);
935 selectNumber : function(path, root, defaultValue){
936 var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0);
937 return parseFloat(v);
941 is : function(el, ss){
942 if(typeof el == "string"){
943 el = document.getElementById(el);
945 var isArray = Ext.isArray(el);
946 var result = Ext.DomQuery.filter(isArray ? el : [el], ss);
947 return isArray ? (result.length == el.length) : (result.length > 0);
951 filter : function(els, ss, nonMatches){
952 ss = ss.replace(trimRe, "");
953 if(!simpleCache[ss]){
954 simpleCache[ss] = Ext.DomQuery.compile(ss, "simple");
956 var result = simpleCache[ss](els);
957 return nonMatches ? quickDiff(result, els) : result;
963 select: 'n = byClassName(n, null, " {1} ");'
965 re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,
966 select: 'n = byPseudo(n, "{1}", "{2}");'
968 re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,
969 select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'
972 select: 'n = byId(n, null, "{1}");'
975 select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
981 "=" : function(a, v){
984 "!=" : function(a, v){
987 "^=" : function(a, v){
988 return a && a.substr(0, v.length) == v;
990 "$=" : function(a, v){
991 return a && a.substr(a.length-v.length) == v;
993 "*=" : function(a, v){
994 return a && a.indexOf(v) !== -1;
996 "%=" : function(a, v){
999 "|=" : function(a, v){
1000 return a && (a == v || a.substr(0, v.length+1) == v+'-');
1002 "~=" : function(a, v){
1003 return a && (' '+a+' ').indexOf(' '+v+' ') != -1;
1009 "first-child" : function(c){
1010 var r = [], ri = -1, n;
1011 for(var i = 0, ci; ci = n = c[i]; i++){
1012 while((n = n.previousSibling) && n.nodeType != 1);
1020 "last-child" : function(c){
1021 var r = [], ri = -1, n;
1022 for(var i = 0, ci; ci = n = c[i]; i++){
1023 while((n = n.nextSibling) && n.nodeType != 1);
1031 "nth-child" : function(c, a) {
1032 var r = [], ri = -1;
1033 var m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a);
1034 var f = (m[1] || 1) - 0, l = m[2] - 0;
1035 for(var i = 0, n; n = c[i]; i++){
1036 var pn = n.parentNode;
1037 if (batch != pn._batch) {
1039 for(var cn = pn.firstChild; cn; cn = cn.nextSibling){
1040 if(cn.nodeType == 1){
1047 if (l == 0 || n.nodeIndex == l){
1050 } else if ((n.nodeIndex + l) % f == 0){
1058 "only-child" : function(c){
1059 var r = [], ri = -1;;
1060 for(var i = 0, ci; ci = c[i]; i++){
1061 if(!prev(ci) && !next(ci)){
1068 "empty" : function(c){
1069 var r = [], ri = -1;
1070 for(var i = 0, ci; ci = c[i]; i++){
1071 var cns = ci.childNodes, j = 0, cn, empty = true;
1074 if(cn.nodeType == 1 || cn.nodeType == 3){
1086 "contains" : function(c, v){
1087 var r = [], ri = -1;
1088 for(var i = 0, ci; ci = c[i]; i++){
1089 if((ci.textContent||ci.innerText||'').indexOf(v) != -1){
1096 "nodeValue" : function(c, v){
1097 var r = [], ri = -1;
1098 for(var i = 0, ci; ci = c[i]; i++){
1099 if(ci.firstChild && ci.firstChild.nodeValue == v){
1106 "checked" : function(c){
1107 var r = [], ri = -1;
1108 for(var i = 0, ci; ci = c[i]; i++){
1109 if(ci.checked == true){
1116 "not" : function(c, ss){
1117 return Ext.DomQuery.filter(c, ss, true);
1120 "any" : function(c, selectors){
1121 var ss = selectors.split('|');
1122 var r = [], ri = -1, s;
1123 for(var i = 0, ci; ci = c[i]; i++){
1124 for(var j = 0; s = ss[j]; j++){
1125 if(Ext.DomQuery.is(ci, s)){
1134 "odd" : function(c){
1135 return this["nth-child"](c, "odd");
1138 "even" : function(c){
1139 return this["nth-child"](c, "even");
1142 "nth" : function(c, a){
1143 return c[a-1] || [];
1146 "first" : function(c){
1150 "last" : function(c){
1151 return c[c.length-1] || [];
1154 "has" : function(c, ss){
1155 var s = Ext.DomQuery.select;
1156 var r = [], ri = -1;
1157 for(var i = 0, ci; ci = c[i]; i++){
1158 if(s(ss, ci).length > 0){
1165 "next" : function(c, ss){
1166 var is = Ext.DomQuery.is;
1167 var r = [], ri = -1;
1168 for(var i = 0, ci; ci = c[i]; i++){
1177 "prev" : function(c, ss){
1178 var is = Ext.DomQuery.is;
1179 var r = [], ri = -1;
1180 for(var i = 0, ci; ci = c[i]; i++){
1193 Ext.query = Ext.DomQuery.select;
1196 Ext.util.Observable = function(){
1199 this.on(this.listeners);
1200 delete this.listeners;
1203 Ext.util.Observable.prototype = {
1205 fireEvent : function(){
1206 if(this.eventsSuspended !== true){
1207 var ce = this.events[arguments[0].toLowerCase()];
1208 if(typeof ce == "object"){
1209 return ce.fire.apply(ce, Array.prototype.slice.call(arguments, 1));
1215 filterOptRe : /^(?:scope|delay|buffer|single)$/,
1218 addListener : function(eventName, fn, scope, o){
1219 if(typeof eventName == "object"){
1222 if(this.filterOptRe.test(e)){
1225 if(typeof o[e] == "function"){
1226 this.addListener(e, o[e], o.scope, o);
1228 this.addListener(e, o[e].fn, o[e].scope, o[e]);
1233 o = (!o || typeof o == "boolean") ? {} : o;
1234 eventName = eventName.toLowerCase();
1235 var ce = this.events[eventName] || true;
1236 if(typeof ce == "boolean"){
1237 ce = new Ext.util.Event(this, eventName);
1238 this.events[eventName] = ce;
1240 ce.addListener(fn, scope, o);
1244 removeListener : function(eventName, fn, scope){
1245 var ce = this.events[eventName.toLowerCase()];
1246 if(typeof ce == "object"){
1247 ce.removeListener(fn, scope);
1252 purgeListeners : function(){
1253 for(var evt in this.events){
1254 if(typeof this.events[evt] == "object"){
1255 this.events[evt].clearListeners();
1260 relayEvents : function(o, events){
1261 var createHandler = function(ename){
1263 return this.fireEvent.apply(this, Ext.combine(ename, Array.prototype.slice.call(arguments, 0)));
1266 for(var i = 0, len = events.length; i < len; i++){
1267 var ename = events[i];
1268 if(!this.events[ename]){ this.events[ename] = true; };
1269 o.on(ename, createHandler(ename), this);
1274 addEvents : function(o){
1278 if(typeof o == 'string'){
1279 for(var i = 0, a = arguments, v; v = a[i]; i++){
1280 if(!this.events[a[i]]){
1285 Ext.applyIf(this.events, o);
1290 hasListener : function(eventName){
1291 var e = this.events[eventName];
1292 return typeof e == "object" && e.listeners.length > 0;
1296 suspendEvents : function(){
1297 this.eventsSuspended = true;
1301 resumeEvents : function(){
1302 this.eventsSuspended = false;
1305 getMethodEvent : function(method){
1306 if(!this.methodEvents){
1307 this.methodEvents = {};
1309 var e = this.methodEvents[method];
1312 this.methodEvents[method] = e;
1314 e.originalFn = this[method];
1315 e.methodName = method;
1320 var returnValue, v, cancel;
1323 var makeCall = function(fn, scope, args){
1324 if((v = fn.apply(scope || obj, args)) !== undefined){
1325 if(typeof v === 'object'){
1326 if(v.returnValue !== undefined){
1327 returnValue = v.returnValue;
1331 if(v.cancel === true){
1334 }else if(v === false){
1342 this[method] = function(){
1343 returnValue = v = undefined; cancel = false;
1344 var args = Array.prototype.slice.call(arguments, 0);
1345 for(var i = 0, len = e.before.length; i < len; i++){
1346 makeCall(e.before[i].fn, e.before[i].scope, args);
1352 if((v = e.originalFn.apply(obj, args)) !== undefined){
1356 for(var i = 0, len = e.after.length; i < len; i++){
1357 makeCall(e.after[i].fn, e.after[i].scope, args);
1368 beforeMethod : function(method, fn, scope){
1369 var e = this.getMethodEvent(method);
1370 e.before.push({fn: fn, scope: scope});
1373 afterMethod : function(method, fn, scope){
1374 var e = this.getMethodEvent(method);
1375 e.after.push({fn: fn, scope: scope});
1378 removeMethodListener : function(method, fn, scope){
1379 var e = this.getMethodEvent(method);
1380 for(var i = 0, len = e.before.length; i < len; i++){
1381 if(e.before[i].fn == fn && e.before[i].scope == scope){
1382 e.before.splice(i, 1);
1386 for(var i = 0, len = e.after.length; i < len; i++){
1387 if(e.after[i].fn == fn && e.after[i].scope == scope){
1388 e.after.splice(i, 1);
1395 Ext.util.Observable.prototype.on = Ext.util.Observable.prototype.addListener;
1397 Ext.util.Observable.prototype.un = Ext.util.Observable.prototype.removeListener;
1400 Ext.util.Observable.capture = function(o, fn, scope){
1401 o.fireEvent = o.fireEvent.createInterceptor(fn, scope);
1405 Ext.util.Observable.releaseCapture = function(o){
1406 o.fireEvent = Ext.util.Observable.prototype.fireEvent;
1411 var createBuffered = function(h, o, scope){
1412 var task = new Ext.util.DelayedTask();
1414 task.delay(o.buffer, h, scope, Array.prototype.slice.call(arguments, 0));
1418 var createSingle = function(h, e, fn, scope){
1420 e.removeListener(fn, scope);
1421 return h.apply(scope, arguments);
1425 var createDelayed = function(h, o, scope){
1427 var args = Array.prototype.slice.call(arguments, 0);
1428 setTimeout(function(){
1429 h.apply(scope, args);
1434 Ext.util.Event = function(obj, name){
1437 this.listeners = [];
1440 Ext.util.Event.prototype = {
1441 addListener : function(fn, scope, options){
1442 scope = scope || this.obj;
1443 if(!this.isListening(fn, scope)){
1444 var l = this.createListener(fn, scope, options);
1446 this.listeners.push(l);
1447 }else{ this.listeners = this.listeners.slice(0);
1448 this.listeners.push(l);
1453 createListener : function(fn, scope, o){
1455 scope = scope || this.obj;
1456 var l = {fn: fn, scope: scope, options: o};
1459 h = createDelayed(h, o, scope);
1462 h = createSingle(h, this, fn, scope);
1465 h = createBuffered(h, o, scope);
1471 findListener : function(fn, scope){
1472 scope = scope || this.obj;
1473 var ls = this.listeners;
1474 for(var i = 0, len = ls.length; i < len; i++){
1476 if(l.fn == fn && l.scope == scope){
1483 isListening : function(fn, scope){
1484 return this.findListener(fn, scope) != -1;
1487 removeListener : function(fn, scope){
1489 if((index = this.findListener(fn, scope)) != -1){
1491 this.listeners.splice(index, 1);
1493 this.listeners = this.listeners.slice(0);
1494 this.listeners.splice(index, 1);
1501 clearListeners : function(){
1502 this.listeners = [];
1506 var ls = this.listeners, scope, len = ls.length;
1509 var args = Array.prototype.slice.call(arguments, 0);
1510 for(var i = 0; i < len; i++){
1512 if(l.fireFn.apply(l.scope||this.obj||window, arguments) === false){
1513 this.firing = false;
1517 this.firing = false;
1524 Ext.EventManager = function(){
1525 var docReadyEvent, docReadyProcId, docReadyState = false;
1526 var resizeEvent, resizeTask, textEvent, textSize;
1527 var E = Ext.lib.Event;
1528 var D = Ext.lib.Dom;
1531 var fireDocReady = function(){
1533 docReadyState = true;
1536 clearInterval(docReadyProcId);
1538 if(Ext.isGecko || Ext.isOpera) {
1539 document.removeEventListener("DOMContentLoaded", fireDocReady, false);
1542 var defer = document.getElementById("ie-deferred-loader");
1544 defer.onreadystatechange = null;
1545 defer.parentNode.removeChild(defer);
1549 docReadyEvent.fire();
1550 docReadyEvent.clearListeners();
1555 var initDocReady = function(){
1556 docReadyEvent = new Ext.util.Event();
1557 if(Ext.isGecko || Ext.isOpera) {
1558 document.addEventListener("DOMContentLoaded", fireDocReady, false);
1560 document.write("<s"+'cript id="ie-deferred-loader" defer="defer" src="/'+'/:"></s'+"cript>");
1561 var defer = document.getElementById("ie-deferred-loader");
1562 defer.onreadystatechange = function(){
1563 if(this.readyState == "complete"){
1567 }else if(Ext.isSafari){
1568 docReadyProcId = setInterval(function(){
1569 var rs = document.readyState;
1570 if(rs == "complete") {
1576 E.on(window, "load", fireDocReady);
1579 var createBuffered = function(h, o){
1580 var task = new Ext.util.DelayedTask(h);
1583 e = new Ext.EventObjectImpl(e);
1584 task.delay(o.buffer, h, null, [e]);
1588 var createSingle = function(h, el, ename, fn){
1590 Ext.EventManager.removeListener(el, ename, fn);
1595 var createDelayed = function(h, o){
1598 e = new Ext.EventObjectImpl(e);
1599 setTimeout(function(){
1605 var listen = function(element, ename, opt, fn, scope){
1606 var o = (!opt || typeof opt == "boolean") ? {} : opt;
1607 fn = fn || o.fn; scope = scope || o.scope;
1608 var el = Ext.getDom(element);
1610 throw "Error listening for \"" + ename + '\". Element "' + element + '" doesn\'t exist.';
1612 var h = function(e){
1613 e = Ext.EventObject.setEvent(e);
1616 t = e.getTarget(o.delegate, el);
1623 if(o.stopEvent === true){
1626 if(o.preventDefault === true){
1629 if(o.stopPropagation === true){
1630 e.stopPropagation();
1633 if(o.normalized === false){
1637 fn.call(scope || el, e, t, o);
1640 h = createDelayed(h, o);
1643 h = createSingle(h, el, ename, fn);
1646 h = createBuffered(h, o);
1648 fn._handlers = fn._handlers || [];
1649 fn._handlers.push([Ext.id(el), ename, h]);
1652 if(ename == "mousewheel" && el.addEventListener){
1653 el.addEventListener("DOMMouseScroll", h, false);
1654 E.on(window, 'unload', function(){
1655 el.removeEventListener("DOMMouseScroll", h, false);
1658 if(ename == "mousedown" && el == document){
1659 Ext.EventManager.stoppedMouseDownEvent.addListener(h);
1664 var stopListening = function(el, ename, fn){
1665 var id = Ext.id(el), hds = fn._handlers, hd = fn;
1667 for(var i = 0, len = hds.length; i < len; i++){
1669 if(h[0] == id && h[1] == ename){
1676 E.un(el, ename, hd);
1677 el = Ext.getDom(el);
1678 if(ename == "mousewheel" && el.addEventListener){
1679 el.removeEventListener("DOMMouseScroll", hd, false);
1681 if(ename == "mousedown" && el == document){
1682 Ext.EventManager.stoppedMouseDownEvent.removeListener(hd);
1686 var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
1690 addListener : function(element, eventName, fn, scope, options){
1691 if(typeof eventName == "object"){
1697 if(typeof o[e] == "function"){
1699 listen(element, e, o, o[e], o.scope);
1702 listen(element, e, o[e]);
1707 return listen(element, eventName, options, fn, scope);
1711 removeListener : function(element, eventName, fn){
1712 return stopListening(element, eventName, fn);
1716 onDocumentReady : function(fn, scope, options){
1718 docReadyEvent.addListener(fn, scope, options);
1719 docReadyEvent.fire();
1720 docReadyEvent.clearListeners();
1726 docReadyEvent.addListener(fn, scope, options);
1730 onWindowResize : function(fn, scope, options){
1732 resizeEvent = new Ext.util.Event();
1733 resizeTask = new Ext.util.DelayedTask(function(){
1734 resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
1736 E.on(window, "resize", this.fireWindowResize, this);
1738 resizeEvent.addListener(fn, scope, options);
1742 fireWindowResize : function(){
1744 if((Ext.isIE||Ext.isAir) && resizeTask){
1745 resizeTask.delay(50);
1747 resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
1753 onTextResize : function(fn, scope, options){
1755 textEvent = new Ext.util.Event();
1756 var textEl = new Ext.Element(document.createElement('div'));
1757 textEl.dom.className = 'x-text-resize';
1758 textEl.dom.innerHTML = 'X';
1759 textEl.appendTo(document.body);
1760 textSize = textEl.dom.offsetHeight;
1761 setInterval(function(){
1762 if(textEl.dom.offsetHeight != textSize){
1763 textEvent.fire(textSize, textSize = textEl.dom.offsetHeight);
1765 }, this.textResizeInterval);
1767 textEvent.addListener(fn, scope, options);
1771 removeResizeListener : function(fn, scope){
1773 resizeEvent.removeListener(fn, scope);
1778 fireResize : function(){
1780 resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
1786 textResizeInterval : 50
1789 pub.on = pub.addListener;
1791 pub.un = pub.removeListener;
1793 pub.stoppedMouseDownEvent = new Ext.util.Event();
1797 Ext.onReady = Ext.EventManager.onDocumentReady;
1799 Ext.onReady(function(){
1800 var bd = Ext.getBody();
1804 Ext.isIE ? "ext-ie " + (Ext.isIE6 ? 'ext-ie6' : 'ext-ie7')
1805 : Ext.isGecko ? "ext-gecko"
1806 : Ext.isOpera ? "ext-opera"
1807 : Ext.isSafari ? "ext-safari" : ""];
1810 cls.push("ext-mac");
1813 cls.push("ext-linux");
1815 if(Ext.isBorderBox){
1816 cls.push('ext-border-box');
1819 var p = bd.dom.parentNode;
1821 p.className += ' ext-strict';
1824 bd.addClass(cls.join(' '));
1828 Ext.EventObject = function(){
1830 var E = Ext.lib.Event;
1846 var btnMap = Ext.isIE ? {1:0,4:1,2:2} :
1847 (Ext.isSafari ? {1:0,2:1,3:2} : {0:0,1:1,2:2});
1849 Ext.EventObjectImpl = function(e){
1851 this.setEvent(e.browserEvent || e);
1854 Ext.EventObjectImpl.prototype = {
1856 browserEvent : null,
1904 setEvent : function(e){
1905 if(e == this || (e && e.browserEvent)){
1908 this.browserEvent = e;
1911 this.button = e.button ? btnMap[e.button] : (e.which ? e.which-1 : -1);
1912 if(e.type == 'click' && this.button == -1){
1916 this.shiftKey = e.shiftKey;
1918 this.ctrlKey = e.ctrlKey || e.metaKey;
1919 this.altKey = e.altKey;
1921 this.keyCode = e.keyCode;
1922 this.charCode = e.charCode;
1924 this.target = E.getTarget(e);
1926 this.xy = E.getXY(e);
1929 this.shiftKey = false;
1930 this.ctrlKey = false;
1931 this.altKey = false;
1941 stopEvent : function(){
1942 if(this.browserEvent){
1943 if(this.browserEvent.type == 'mousedown'){
1944 Ext.EventManager.stoppedMouseDownEvent.fire(this);
1946 E.stopEvent(this.browserEvent);
1951 preventDefault : function(){
1952 if(this.browserEvent){
1953 E.preventDefault(this.browserEvent);
1958 isNavKeyPress : function(){
1959 var k = this.keyCode;
1960 k = Ext.isSafari ? (safariKeys[k] || k) : k;
1961 return (k >= 33 && k <= 40) || k == this.RETURN || k == this.TAB || k == this.ESC;
1964 isSpecialKey : function(){
1965 var k = this.keyCode;
1966 return (this.type == 'keypress' && this.ctrlKey) || k == 9 || k == 13 || k == 40 || k == 27 ||
1967 (k == 16) || (k == 17) ||
1968 (k >= 18 && k <= 20) ||
1969 (k >= 33 && k <= 35) ||
1970 (k >= 36 && k <= 39) ||
1971 (k >= 44 && k <= 45);
1974 stopPropagation : function(){
1975 if(this.browserEvent){
1976 if(this.browserEvent.type == 'mousedown'){
1977 Ext.EventManager.stoppedMouseDownEvent.fire(this);
1979 E.stopPropagation(this.browserEvent);
1984 getCharCode : function(){
1985 return this.charCode || this.keyCode;
1989 getKey : function(){
1990 var k = this.keyCode || this.charCode;
1991 return Ext.isSafari ? (safariKeys[k] || k) : k;
1995 getPageX : function(){
2000 getPageY : function(){
2005 getTime : function(){
2006 if(this.browserEvent){
2007 return E.getTime(this.browserEvent);
2018 getTarget : function(selector, maxDepth, returnEl){
2019 var t = Ext.get(this.target);
2020 return selector ? t.findParent(selector, maxDepth, returnEl) : (returnEl ? t : this.target);
2024 getRelatedTarget : function(){
2025 if(this.browserEvent){
2026 return E.getRelatedTarget(this.browserEvent);
2032 getWheelDelta : function(){
2033 var e = this.browserEvent;
2036 delta = e.wheelDelta/120;
2038 delta = -e.detail/3;
2044 hasModifier : function(){
2045 return ((this.ctrlKey || this.altKey) || this.shiftKey) ? true : false;
2049 within : function(el, related){
2050 var t = this[related ? "getRelatedTarget" : "getTarget"]();
2051 return t && Ext.fly(el).contains(t);
2054 getPoint : function(){
2055 return new Ext.lib.Point(this.xy[0], this.xy[1]);
2059 return new Ext.EventObjectImpl();
2063 var D = Ext.lib.Dom;
2064 var E = Ext.lib.Event;
2065 var A = Ext.lib.Anim;
2068 var camelRe = /(-[a-z])/gi;
2069 var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };
2070 var view = document.defaultView;
2072 Ext.Element = function(element, forceNew){
2073 var dom = typeof element == "string" ?
2074 document.getElementById(element) : element;
2075 if(!dom){ return null;
2078 if(forceNew !== true && id && Ext.Element.cache[id]){ return Ext.Element.cache[id];
2085 this.id = id || Ext.id(dom);
2088 var El = Ext.Element;
2092 originalDisplay : "",
2098 setVisibilityMode : function(visMode){
2099 this.visibilityMode = visMode;
2103 enableDisplayMode : function(display){
2104 this.setVisibilityMode(El.DISPLAY);
2105 if(typeof display != "undefined") this.originalDisplay = display;
2110 findParent : function(simpleSelector, maxDepth, returnEl){
2111 var p = this.dom, b = document.body, depth = 0, dq = Ext.DomQuery, stopEl;
2112 maxDepth = maxDepth || 50;
2113 if(typeof maxDepth != "number"){
2114 stopEl = Ext.getDom(maxDepth);
2117 while(p && p.nodeType == 1 && depth < maxDepth && p != b && p != stopEl){
2118 if(dq.is(p, simpleSelector)){
2119 return returnEl ? Ext.get(p) : p;
2129 findParentNode : function(simpleSelector, maxDepth, returnEl){
2130 var p = Ext.fly(this.dom.parentNode, '_internal');
2131 return p ? p.findParent(simpleSelector, maxDepth, returnEl) : null;
2135 up : function(simpleSelector, maxDepth){
2136 return this.findParentNode(simpleSelector, maxDepth, true);
2142 is : function(simpleSelector){
2143 return Ext.DomQuery.is(this.dom, simpleSelector);
2147 animate : function(args, duration, onComplete, easing, animType){
2148 this.anim(args, {duration: duration, callback: onComplete, easing: easing}, animType);
2153 anim : function(args, opt, animType, defaultDur, defaultEase, cb){
2154 animType = animType || 'run';
2156 var anim = Ext.lib.Anim[animType](
2158 (opt.duration || defaultDur) || .35,
2159 (opt.easing || defaultEase) || 'easeOut',
2161 Ext.callback(cb, this);
2162 Ext.callback(opt.callback, opt.scope || this, [this, opt]);
2170 preanim : function(a, i){
2171 return !a[i] ? false : (typeof a[i] == "object" ? a[i]: {duration: a[i+1], callback: a[i+2], easing: a[i+3]});
2175 clean : function(forceReclean){
2176 if(this.isCleaned && forceReclean !== true){
2180 var d = this.dom, n = d.firstChild, ni = -1;
2182 var nx = n.nextSibling;
2183 if(n.nodeType == 3 && !ns.test(n.nodeValue)){
2190 this.isCleaned = true;
2195 scrollIntoView : function(container, hscroll){
2196 var c = Ext.getDom(container) || Ext.getBody().dom;
2199 var o = this.getOffsetsTo(c),
2200 l = o[0] + c.scrollLeft,
2201 t = o[1] + c.scrollTop,
2202 b = t+el.offsetHeight,
2203 r = l+el.offsetWidth;
2205 var ch = c.clientHeight;
2206 var ct = parseInt(c.scrollTop, 10);
2207 var cl = parseInt(c.scrollLeft, 10);
2209 var cr = cl + c.clientWidth;
2211 if(el.offsetHeight > ch || t < ct){
2216 c.scrollTop = c.scrollTop;
2217 if(hscroll !== false){
2218 if(el.offsetWidth > c.clientWidth || l < cl){
2221 c.scrollLeft = r-c.clientWidth;
2223 c.scrollLeft = c.scrollLeft;
2228 scrollChildIntoView : function(child, hscroll){
2229 Ext.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll);
2233 autoHeight : function(animate, duration, onComplete, easing){
2234 var oldHeight = this.getHeight();
2236 this.setHeight(1); setTimeout(function(){
2237 var height = parseInt(this.dom.scrollHeight, 10); if(!animate){
2238 this.setHeight(height);
2240 if(typeof onComplete == "function"){
2244 this.setHeight(oldHeight); this.setHeight(height, animate, duration, function(){
2246 if(typeof onComplete == "function") onComplete();
2247 }.createDelegate(this), easing);
2249 }.createDelegate(this), 0);
2254 contains : function(el){
2255 if(!el){return false;}
2256 return D.isAncestor(this.dom, el.dom ? el.dom : el);
2260 isVisible : function(deep) {
2261 var vis = !(this.getStyle("visibility") == "hidden" || this.getStyle("display") == "none");
2262 if(deep !== true || !vis){
2265 var p = this.dom.parentNode;
2266 while(p && p.tagName.toLowerCase() != "body"){
2267 if(!Ext.fly(p, '_isVisible').isVisible()){
2276 select : function(selector, unique){
2277 return El.select(selector, unique, this.dom);
2281 query : function(selector, unique){
2282 return Ext.DomQuery.select(selector, this.dom);
2286 child : function(selector, returnDom){
2287 var n = Ext.DomQuery.selectNode(selector, this.dom);
2288 return returnDom ? n : Ext.get(n);
2292 down : function(selector, returnDom){
2293 var n = Ext.DomQuery.selectNode(" > " + selector, this.dom);
2294 return returnDom ? n : Ext.get(n);
2298 initDD : function(group, config, overrides){
2299 var dd = new Ext.dd.DD(Ext.id(this.dom), group, config);
2300 return Ext.apply(dd, overrides);
2304 initDDProxy : function(group, config, overrides){
2305 var dd = new Ext.dd.DDProxy(Ext.id(this.dom), group, config);
2306 return Ext.apply(dd, overrides);
2310 initDDTarget : function(group, config, overrides){
2311 var dd = new Ext.dd.DDTarget(Ext.id(this.dom), group, config);
2312 return Ext.apply(dd, overrides);
2316 setVisible : function(visible, animate){
2318 if(this.visibilityMode == El.DISPLAY){
2319 this.setDisplayed(visible);
2322 this.dom.style.visibility = visible ? "visible" : "hidden";
2326 var visMode = this.visibilityMode;
2328 this.setOpacity(.01);
2329 this.setVisible(true);
2331 this.anim({opacity: { to: (visible?1:0) }},
2332 this.preanim(arguments, 1),
2333 null, .35, 'easeIn', function(){
2335 if(visMode == El.DISPLAY){
2336 dom.style.display = "none";
2338 dom.style.visibility = "hidden";
2340 Ext.get(dom).setOpacity(1);
2348 isDisplayed : function() {
2349 return this.getStyle("display") != "none";
2353 toggle : function(animate){
2354 this.setVisible(!this.isVisible(), this.preanim(arguments, 0));
2359 setDisplayed : function(value) {
2360 if(typeof value == "boolean"){
2361 value = value ? this.originalDisplay : "none";
2363 this.setStyle("display", value);
2368 focus : function() {
2384 addClass : function(className){
2385 if(Ext.isArray(className)){
2386 for(var i = 0, len = className.length; i < len; i++) {
2387 this.addClass(className[i]);
2390 if(className && !this.hasClass(className)){
2391 this.dom.className = this.dom.className + " " + className;
2398 radioClass : function(className){
2399 var siblings = this.dom.parentNode.childNodes;
2400 for(var i = 0; i < siblings.length; i++) {
2401 var s = siblings[i];
2402 if(s.nodeType == 1){
2403 Ext.get(s).removeClass(className);
2406 this.addClass(className);
2411 removeClass : function(className){
2412 if(!className || !this.dom.className){
2415 if(Ext.isArray(className)){
2416 for(var i = 0, len = className.length; i < len; i++) {
2417 this.removeClass(className[i]);
2420 if(this.hasClass(className)){
2421 var re = this.classReCache[className];
2423 re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)', "g");
2424 this.classReCache[className] = re;
2426 this.dom.className =
2427 this.dom.className.replace(re, " ");
2436 toggleClass : function(className){
2437 if(this.hasClass(className)){
2438 this.removeClass(className);
2440 this.addClass(className);
2446 hasClass : function(className){
2447 return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1;
2451 replaceClass : function(oldClassName, newClassName){
2452 this.removeClass(oldClassName);
2453 this.addClass(newClassName);
2458 getStyles : function(){
2459 var a = arguments, len = a.length, r = {};
2460 for(var i = 0; i < len; i++){
2461 r[a[i]] = this.getStyle(a[i]);
2467 getStyle : function(){
2468 return view && view.getComputedStyle ?
2470 var el = this.dom, v, cs, camel;
2471 if(prop == 'float'){
2474 if(v = el.style[prop]){
2477 if(cs = view.getComputedStyle(el, "")){
2478 if(!(camel = propCache[prop])){
2479 camel = propCache[prop] = prop.replace(camelRe, camelFn);
2486 var el = this.dom, v, cs, camel;
2487 if(prop == 'opacity'){
2488 if(typeof el.style.filter == 'string'){
2489 var m = el.style.filter.match(/alpha\(opacity=(.*)\)/i);
2491 var fv = parseFloat(m[1]);
2493 return fv ? fv / 100 : 0;
2498 }else if(prop == 'float'){
2499 prop = "styleFloat";
2501 if(!(camel = propCache[prop])){
2502 camel = propCache[prop] = prop.replace(camelRe, camelFn);
2504 if(v = el.style[camel]){
2507 if(cs = el.currentStyle){
2515 setStyle : function(prop, value){
2516 if(typeof prop == "string"){
2518 if(!(camel = propCache[prop])){
2519 camel = propCache[prop] = prop.replace(camelRe, camelFn);
2521 if(camel == 'opacity') {
2522 this.setOpacity(value);
2524 this.dom.style[camel] = value;
2527 for(var style in prop){
2528 if(typeof prop[style] != "function"){
2529 this.setStyle(style, prop[style]);
2537 applyStyles : function(style){
2538 Ext.DomHelper.applyStyles(this.dom, style);
2544 return D.getX(this.dom);
2549 return D.getY(this.dom);
2554 return D.getXY(this.dom);
2558 getOffsetsTo : function(el){
2559 var o = this.getXY();
2560 var e = Ext.fly(el, '_internal').getXY();
2561 return [o[0]-e[0],o[1]-e[1]];
2565 setX : function(x, animate){
2567 D.setX(this.dom, x);
2569 this.setXY([x, this.getY()], this.preanim(arguments, 1));
2575 setY : function(y, animate){
2577 D.setY(this.dom, y);
2579 this.setXY([this.getX(), y], this.preanim(arguments, 1));
2585 setLeft : function(left){
2586 this.setStyle("left", this.addUnits(left));
2591 setTop : function(top){
2592 this.setStyle("top", this.addUnits(top));
2597 setRight : function(right){
2598 this.setStyle("right", this.addUnits(right));
2603 setBottom : function(bottom){
2604 this.setStyle("bottom", this.addUnits(bottom));
2609 setXY : function(pos, animate){
2611 D.setXY(this.dom, pos);
2613 this.anim({points: {to: pos}}, this.preanim(arguments, 1), 'motion');
2619 setLocation : function(x, y, animate){
2620 this.setXY([x, y], this.preanim(arguments, 2));
2625 moveTo : function(x, y, animate){
2626 this.setXY([x, y], this.preanim(arguments, 2));
2631 getRegion : function(){
2632 return D.getRegion(this.dom);
2636 getHeight : function(contentHeight){
2637 var h = this.dom.offsetHeight || 0;
2638 h = contentHeight !== true ? h : h-this.getBorderWidth("tb")-this.getPadding("tb");
2639 return h < 0 ? 0 : h;
2643 getWidth : function(contentWidth){
2644 var w = this.dom.offsetWidth || 0;
2645 w = contentWidth !== true ? w : w-this.getBorderWidth("lr")-this.getPadding("lr");
2646 return w < 0 ? 0 : w;
2650 getComputedHeight : function(){
2651 var h = Math.max(this.dom.offsetHeight, this.dom.clientHeight);
2653 h = parseInt(this.getStyle('height'), 10) || 0;
2654 if(!this.isBorderBox()){
2655 h += this.getFrameWidth('tb');
2662 getComputedWidth : function(){
2663 var w = Math.max(this.dom.offsetWidth, this.dom.clientWidth);
2665 w = parseInt(this.getStyle('width'), 10) || 0;
2666 if(!this.isBorderBox()){
2667 w += this.getFrameWidth('lr');
2674 getSize : function(contentSize){
2675 return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)};
2678 getStyleSize : function(){
2679 var w, h, d = this.dom, s = d.style;
2680 if(s.width && s.width != 'auto'){
2681 w = parseInt(s.width, 10);
2682 if(Ext.isBorderBox){
2683 w -= this.getFrameWidth('lr');
2686 if(s.height && s.height != 'auto'){
2687 h = parseInt(s.height, 10);
2688 if(Ext.isBorderBox){
2689 h -= this.getFrameWidth('tb');
2692 return {width: w || this.getWidth(true), height: h || this.getHeight(true)};
2697 getViewSize : function(){
2698 var d = this.dom, doc = document, aw = 0, ah = 0;
2699 if(d == doc || d == doc.body){
2700 return {width : D.getViewWidth(), height: D.getViewHeight()};
2703 width : d.clientWidth,
2704 height: d.clientHeight
2710 getValue : function(asNumber){
2711 return asNumber ? parseInt(this.dom.value, 10) : this.dom.value;
2714 adjustWidth : function(width){
2715 if(typeof width == "number"){
2716 if(this.autoBoxAdjust && !this.isBorderBox()){
2717 width -= (this.getBorderWidth("lr") + this.getPadding("lr"));
2726 adjustHeight : function(height){
2727 if(typeof height == "number"){
2728 if(this.autoBoxAdjust && !this.isBorderBox()){
2729 height -= (this.getBorderWidth("tb") + this.getPadding("tb"));
2739 setWidth : function(width, animate){
2740 width = this.adjustWidth(width);
2742 this.dom.style.width = this.addUnits(width);
2744 this.anim({width: {to: width}}, this.preanim(arguments, 1));
2750 setHeight : function(height, animate){
2751 height = this.adjustHeight(height);
2753 this.dom.style.height = this.addUnits(height);
2755 this.anim({height: {to: height}}, this.preanim(arguments, 1));
2761 setSize : function(width, height, animate){
2762 if(typeof width == "object"){ height = width.height; width = width.width;
2764 width = this.adjustWidth(width); height = this.adjustHeight(height);
2766 this.dom.style.width = this.addUnits(width);
2767 this.dom.style.height = this.addUnits(height);
2769 this.anim({width: {to: width}, height: {to: height}}, this.preanim(arguments, 2));
2775 setBounds : function(x, y, width, height, animate){
2777 this.setSize(width, height);
2778 this.setLocation(x, y);
2780 width = this.adjustWidth(width); height = this.adjustHeight(height);
2781 this.anim({points: {to: [x, y]}, width: {to: width}, height: {to: height}},
2782 this.preanim(arguments, 4), 'motion');
2788 setRegion : function(region, animate){
2789 this.setBounds(region.left, region.top, region.right-region.left, region.bottom-region.top, this.preanim(arguments, 1));
2794 addListener : function(eventName, fn, scope, options){
2795 Ext.EventManager.on(this.dom, eventName, fn, scope || this, options);
2799 removeListener : function(eventName, fn){
2800 Ext.EventManager.removeListener(this.dom, eventName, fn);
2805 removeAllListeners : function(){
2806 E.purgeElement(this.dom);
2811 relayEvent : function(eventName, observable){
2812 this.on(eventName, function(e){
2813 observable.fireEvent(eventName, e);
2818 setOpacity : function(opacity, animate){
2820 var s = this.dom.style;
2823 s.filter = (s.filter || '').replace(/alpha\([^\)]*\)/gi,"") +
2824 (opacity == 1 ? "" : " alpha(opacity=" + opacity * 100 + ")");
2826 s.opacity = opacity;
2829 this.anim({opacity: {to: opacity}}, this.preanim(arguments, 1), null, .35, 'easeIn');
2835 getLeft : function(local){
2839 return parseInt(this.getStyle("left"), 10) || 0;
2844 getRight : function(local){
2846 return this.getX() + this.getWidth();
2848 return (this.getLeft(true) + this.getWidth()) || 0;
2853 getTop : function(local) {
2857 return parseInt(this.getStyle("top"), 10) || 0;
2862 getBottom : function(local){
2864 return this.getY() + this.getHeight();
2866 return (this.getTop(true) + this.getHeight()) || 0;
2871 position : function(pos, zIndex, x, y){
2873 if(this.getStyle('position') == 'static'){
2874 this.setStyle('position', 'relative');
2877 this.setStyle("position", pos);
2880 this.setStyle("z-index", zIndex);
2882 if(x !== undefined && y !== undefined){
2884 }else if(x !== undefined){
2886 }else if(y !== undefined){
2892 clearPositioning : function(value){
2900 "position" : "static"
2906 getPositioning : function(){
2907 var l = this.getStyle("left");
2908 var t = this.getStyle("top");
2910 "position" : this.getStyle("position"),
2912 "right" : l ? "" : this.getStyle("right"),
2914 "bottom" : t ? "" : this.getStyle("bottom"),
2915 "z-index" : this.getStyle("z-index")
2920 getBorderWidth : function(side){
2921 return this.addStyles(side, El.borders);
2925 getPadding : function(side){
2926 return this.addStyles(side, El.paddings);
2930 setPositioning : function(pc){
2931 this.applyStyles(pc);
2932 if(pc.right == "auto"){
2933 this.dom.style.right = "";
2935 if(pc.bottom == "auto"){
2936 this.dom.style.bottom = "";
2941 fixDisplay : function(){
2942 if(this.getStyle("display") == "none"){
2943 this.setStyle("visibility", "hidden");
2944 this.setStyle("display", this.originalDisplay); if(this.getStyle("display") == "none"){ this.setStyle("display", "block");
2949 setOverflow : function(v){
2950 if(v=='auto' && Ext.isMac && Ext.isGecko){ this.dom.style.overflow = 'hidden';
2951 (function(){this.dom.style.overflow = 'auto';}).defer(1, this);
2953 this.dom.style.overflow = v;
2958 setLeftTop : function(left, top){
2959 this.dom.style.left = this.addUnits(left);
2960 this.dom.style.top = this.addUnits(top);
2965 move : function(direction, distance, animate){
2966 var xy = this.getXY();
2967 direction = direction.toLowerCase();
2971 this.moveTo(xy[0]-distance, xy[1], this.preanim(arguments, 2));
2975 this.moveTo(xy[0]+distance, xy[1], this.preanim(arguments, 2));
2980 this.moveTo(xy[0], xy[1]-distance, this.preanim(arguments, 2));
2985 this.moveTo(xy[0], xy[1]+distance, this.preanim(arguments, 2));
2993 if(!this.isClipped){
2994 this.isClipped = true;
2995 this.originalClip = {
2996 "o": this.getStyle("overflow"),
2997 "x": this.getStyle("overflow-x"),
2998 "y": this.getStyle("overflow-y")
3000 this.setStyle("overflow", "hidden");
3001 this.setStyle("overflow-x", "hidden");
3002 this.setStyle("overflow-y", "hidden");
3008 unclip : function(){
3010 this.isClipped = false;
3011 var o = this.originalClip;
3012 if(o.o){this.setStyle("overflow", o.o);}
3013 if(o.x){this.setStyle("overflow-x", o.x);}
3014 if(o.y){this.setStyle("overflow-y", o.y);}
3021 getAnchorXY : function(anchor, local, s){
3023 var w, h, vp = false;
3026 if(d == document.body || d == document){
3028 w = D.getViewWidth(); h = D.getViewHeight();
3030 w = this.getWidth(); h = this.getHeight();
3033 w = s.width; h = s.height;
3035 var x = 0, y = 0, r = Math.round;
3036 switch((anchor || "tl").toLowerCase()){
3078 var sc = this.getScroll();
3079 return [x + sc.left, y + sc.top];
3081 var o = this.getXY();
3082 return [x+o[0], y+o[1]];
3086 getAlignToXY : function(el, p, o){
3089 throw "Element.alignToXY with an element that doesn't exist";
3092 var c = false; var p1 = "", p2 = "";
3099 }else if(p.indexOf("-") == -1){
3102 p = p.toLowerCase();
3103 var m = p.match(/^([a-z]+)-([a-z]+)(\?)?$/);
3105 throw "Element.alignTo with an invalid alignment " + p;
3107 p1 = m[1]; p2 = m[2]; c = !!m[3];
3109 var a1 = this.getAnchorXY(p1, true);
3110 var a2 = el.getAnchorXY(p2, false);
3112 var x = a2[0] - a1[0] + o[0];
3113 var y = a2[1] - a1[1] + o[1];
3116 var w = this.getWidth(), h = this.getHeight(), r = el.getRegion();
3117 var dw = D.getViewWidth()-5, dh = D.getViewHeight()-5;
3119 var p1y = p1.charAt(0), p1x = p1.charAt(p1.length-1);
3120 var p2y = p2.charAt(0), p2x = p2.charAt(p2.length-1);
3121 var swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t"));
3122 var swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r"));
3125 var scrollX = (doc.documentElement.scrollLeft || doc.body.scrollLeft || 0)+5;
3126 var scrollY = (doc.documentElement.scrollTop || doc.body.scrollTop || 0)+5;
3128 if((x+w) > dw + scrollX){
3129 x = swapX ? r.left-w : dw+scrollX-w;
3132 x = swapX ? r.right : scrollX;
3134 if((y+h) > dh + scrollY){
3135 y = swapY ? r.top-h : dh+scrollY-h;
3138 y = swapY ? r.bottom : scrollY;
3144 getConstrainToXY : function(){
3145 var os = {top:0, left:0, bottom:0, right: 0};
3147 return function(el, local, offsets, proposedXY){
3149 offsets = offsets ? Ext.applyIf(offsets, os) : os;
3151 var vw, vh, vx = 0, vy = 0;
3152 if(el.dom == document.body || el.dom == document){
3153 vw = Ext.lib.Dom.getViewWidth();
3154 vh = Ext.lib.Dom.getViewHeight();
3156 vw = el.dom.clientWidth;
3157 vh = el.dom.clientHeight;
3159 var vxy = el.getXY();
3165 var s = el.getScroll();
3167 vx += offsets.left + s.left;
3168 vy += offsets.top + s.top;
3170 vw -= offsets.right;
3171 vh -= offsets.bottom;
3176 var xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]);
3177 var x = xy[0], y = xy[1];
3178 var w = this.dom.offsetWidth, h = this.dom.offsetHeight;
3198 return moved ? [x, y] : false;
3202 adjustForConstraints : function(xy, parent, offsets){
3203 return this.getConstrainToXY(parent || document, false, offsets, xy) || xy;
3207 alignTo : function(element, position, offsets, animate){
3208 var xy = this.getAlignToXY(element, position, offsets);
3209 this.setXY(xy, this.preanim(arguments, 3));
3214 anchorTo : function(el, alignment, offsets, animate, monitorScroll, callback){
3215 var action = function(){
3216 this.alignTo(el, alignment, offsets, animate);
3217 Ext.callback(callback, this);
3219 Ext.EventManager.onWindowResize(action, this);
3220 var tm = typeof monitorScroll;
3221 if(tm != 'undefined'){
3222 Ext.EventManager.on(window, 'scroll', action, this,
3223 {buffer: tm == 'number' ? monitorScroll : 50});
3225 action.call(this); return this;
3228 clearOpacity : function(){
3229 if (window.ActiveXObject) {
3230 if(typeof this.dom.style.filter == 'string' && (/alpha/i).test(this.dom.style.filter)){
3231 this.dom.style.filter = "";
3234 this.dom.style.opacity = "";
3235 this.dom.style["-moz-opacity"] = "";
3236 this.dom.style["-khtml-opacity"] = "";
3242 hide : function(animate){
3243 this.setVisible(false, this.preanim(arguments, 0));
3248 show : function(animate){
3249 this.setVisible(true, this.preanim(arguments, 0));
3254 addUnits : function(size){
3255 return Ext.Element.addUnits(size, this.defaultUnit);
3259 update : function(html, loadScripts, callback){
3260 if(typeof html == "undefined"){
3263 if(loadScripts !== true){
3264 this.dom.innerHTML = html;
3265 if(typeof callback == "function"){
3273 html += '<span id="' + id + '"></span>';
3275 E.onAvailable(id, function(){
3276 var hd = document.getElementsByTagName("head")[0];
3277 var re = /(?:<script([^>]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig;
3278 var srcRe = /\ssrc=([\'\"])(.*?)\1/i;
3279 var typeRe = /\stype=([\'\"])(.*?)\1/i;
3282 while(match = re.exec(html)){
3283 var attrs = match[1];
3284 var srcMatch = attrs ? attrs.match(srcRe) : false;
3285 if(srcMatch && srcMatch[2]){
3286 var s = document.createElement("script");
3287 s.src = srcMatch[2];
3288 var typeMatch = attrs.match(typeRe);
3289 if(typeMatch && typeMatch[2]){
3290 s.type = typeMatch[2];
3293 }else if(match[2] && match[2].length > 0){
3294 if(window.execScript) {
3295 window.execScript(match[2]);
3297 window.eval(match[2]);
3301 var el = document.getElementById(id);
3302 if(el){Ext.removeNode(el);}
3303 if(typeof callback == "function"){
3307 dom.innerHTML = html.replace(/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig, "");
3313 var um = this.getUpdater();
3314 um.update.apply(um, arguments);
3319 getUpdater : function(){
3320 if(!this.updateManager){
3321 this.updateManager = new Ext.Updater(this);
3323 return this.updateManager;
3327 unselectable : function(){
3328 this.dom.unselectable = "on";
3329 this.swallowEvent("selectstart", true);
3330 this.applyStyles("-moz-user-select:none;-khtml-user-select:none;");
3331 this.addClass("x-unselectable");
3336 getCenterXY : function(){
3337 return this.getAlignToXY(document, 'c-c');
3341 center : function(centerIn){
3342 this.alignTo(centerIn || document, 'c-c');
3347 isBorderBox : function(){
3348 return noBoxAdjust[this.dom.tagName.toLowerCase()] || Ext.isBorderBox;
3352 getBox : function(contentBox, local){
3357 var left = parseInt(this.getStyle("left"), 10) || 0;
3358 var top = parseInt(this.getStyle("top"), 10) || 0;
3361 var el = this.dom, w = el.offsetWidth, h = el.offsetHeight, bx;
3363 bx = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: w, height: h};
3365 var l = this.getBorderWidth("l")+this.getPadding("l");
3366 var r = this.getBorderWidth("r")+this.getPadding("r");
3367 var t = this.getBorderWidth("t")+this.getPadding("t");
3368 var b = this.getBorderWidth("b")+this.getPadding("b");
3369 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)};
3371 bx.right = bx.x + bx.width;
3372 bx.bottom = bx.y + bx.height;
3377 getFrameWidth : function(sides, onlyContentBox){
3378 return onlyContentBox && Ext.isBorderBox ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides));
3382 setBox : function(box, adjust, animate){
3383 var w = box.width, h = box.height;
3384 if((adjust && !this.autoBoxAdjust) && !this.isBorderBox()){
3385 w -= (this.getBorderWidth("lr") + this.getPadding("lr"));
3386 h -= (this.getBorderWidth("tb") + this.getPadding("tb"));
3388 this.setBounds(box.x, box.y, w, h, this.preanim(arguments, 2));
3393 repaint : function(){
3395 this.addClass("x-repaint");
3396 setTimeout(function(){
3397 Ext.get(dom).removeClass("x-repaint");
3403 getMargins : function(side){
3406 top: parseInt(this.getStyle("margin-top"), 10) || 0,
3407 left: parseInt(this.getStyle("margin-left"), 10) || 0,
3408 bottom: parseInt(this.getStyle("margin-bottom"), 10) || 0,
3409 right: parseInt(this.getStyle("margin-right"), 10) || 0
3412 return this.addStyles(side, El.margins);
3416 addStyles : function(sides, styles){
3418 for(var i = 0, len = sides.length; i < len; i++){
3419 v = this.getStyle(styles[sides.charAt(i)]);
3421 w = parseInt(v, 10);
3422 if(w){ val += (w >= 0 ? w : -1 * w); }
3429 createProxy : function(config, renderTo, matchBox){
3430 config = typeof config == "object" ?
3431 config : {tag : "div", cls: config};
3435 proxy = Ext.DomHelper.append(renderTo, config, true);
3437 proxy = Ext.DomHelper.insertBefore(this.dom, config, true);
3440 proxy.setBox(this.getBox());
3446 mask : function(msg, msgCls){
3447 if(this.getStyle("position") == "static"){
3448 this.setStyle("position", "relative");
3451 this._maskMsg.remove();
3454 this._mask.remove();
3457 this._mask = Ext.DomHelper.append(this.dom, {cls:"ext-el-mask"}, true);
3459 this.addClass("x-masked");
3460 this._mask.setDisplayed(true);
3461 if(typeof msg == 'string'){
3462 this._maskMsg = Ext.DomHelper.append(this.dom, {cls:"ext-el-mask-msg", cn:{tag:'div'}}, true);
3463 var mm = this._maskMsg;
3464 mm.dom.className = msgCls ? "ext-el-mask-msg " + msgCls : "ext-el-mask-msg";
3465 mm.dom.firstChild.innerHTML = msg;
3466 mm.setDisplayed(true);
3469 if(Ext.isIE && !(Ext.isIE7 && Ext.isStrict) && this.getStyle('height') == 'auto'){ this._mask.setSize(this.dom.clientWidth, this.getHeight());
3475 unmask : function(){
3478 this._maskMsg.remove();
3479 delete this._maskMsg;
3481 this._mask.remove();
3484 this.removeClass("x-masked");
3488 isMasked : function(){
3489 return this._mask && this._mask.isVisible();
3493 createShim : function(){
3494 var el = document.createElement('iframe');
3495 el.frameBorder = 'no';
3496 el.className = 'ext-shim';
3497 if(Ext.isIE && Ext.isSecure){
3498 el.src = Ext.SSL_SECURE_URL;
3500 var shim = Ext.get(this.dom.parentNode.insertBefore(el, this.dom));
3501 shim.autoBoxAdjust = false;
3506 remove : function(){
3507 Ext.removeNode(this.dom);
3508 delete El.cache[this.dom.id];
3512 hover : function(overFn, outFn, scope){
3513 var preOverFn = function(e){
3514 if(!e.within(this, true)){
3515 overFn.apply(scope || this, arguments);
3518 var preOutFn = function(e){
3519 if(!e.within(this, true)){
3520 outFn.apply(scope || this, arguments);
3523 this.on("mouseover", preOverFn, this.dom);
3524 this.on("mouseout", preOutFn, this.dom);
3529 addClassOnOver : function(className, preventFlicker){
3532 Ext.fly(this, '_internal').addClass(className);
3535 Ext.fly(this, '_internal').removeClass(className);
3542 addClassOnFocus : function(className){
3543 this.on("focus", function(){
3544 Ext.fly(this, '_internal').addClass(className);
3546 this.on("blur", function(){
3547 Ext.fly(this, '_internal').removeClass(className);
3552 addClassOnClick : function(className){
3554 this.on("mousedown", function(){
3555 Ext.fly(dom, '_internal').addClass(className);
3556 var d = Ext.getDoc();
3557 var fn = function(){
3558 Ext.fly(dom, '_internal').removeClass(className);
3559 d.removeListener("mouseup", fn);
3561 d.on("mouseup", fn);
3567 swallowEvent : function(eventName, preventDefault){
3568 var fn = function(e){
3569 e.stopPropagation();
3574 if(Ext.isArray(eventName)){
3575 for(var i = 0, len = eventName.length; i < len; i++){
3576 this.on(eventName[i], fn);
3580 this.on(eventName, fn);
3585 parent : function(selector, returnDom){
3586 return this.matchNode('parentNode', 'parentNode', selector, returnDom);
3590 next : function(selector, returnDom){
3591 return this.matchNode('nextSibling', 'nextSibling', selector, returnDom);
3595 prev : function(selector, returnDom){
3596 return this.matchNode('previousSibling', 'previousSibling', selector, returnDom);
3601 first : function(selector, returnDom){
3602 return this.matchNode('nextSibling', 'firstChild', selector, returnDom);
3606 last : function(selector, returnDom){
3607 return this.matchNode('previousSibling', 'lastChild', selector, returnDom);
3610 matchNode : function(dir, start, selector, returnDom){
3611 var n = this.dom[start];
3613 if(n.nodeType == 1 && (!selector || Ext.DomQuery.is(n, selector))){
3614 return !returnDom ? Ext.get(n) : n;
3622 appendChild: function(el){
3629 createChild: function(config, insertBefore, returnDom){
3630 config = config || {tag:'div'};
3632 return Ext.DomHelper.insertBefore(insertBefore, config, returnDom !== true);
3634 return Ext.DomHelper[!this.dom.firstChild ? 'overwrite' : 'append'](this.dom, config, returnDom !== true);
3638 appendTo: function(el){
3639 el = Ext.getDom(el);
3640 el.appendChild(this.dom);
3645 insertBefore: function(el){
3646 el = Ext.getDom(el);
3647 el.parentNode.insertBefore(this.dom, el);
3652 insertAfter: function(el){
3653 el = Ext.getDom(el);
3654 el.parentNode.insertBefore(this.dom, el.nextSibling);
3659 insertFirst: function(el, returnDom){
3661 if(typeof el == 'object' && !el.nodeType && !el.dom){ return this.createChild(el, this.dom.firstChild, returnDom);
3663 el = Ext.getDom(el);
3664 this.dom.insertBefore(el, this.dom.firstChild);
3665 return !returnDom ? Ext.get(el) : el;
3670 insertSibling: function(el, where, returnDom){
3672 if(Ext.isArray(el)){
3673 for(var i = 0, len = el.length; i < len; i++){
3674 rt = this.insertSibling(el[i], where, returnDom);
3678 where = where ? where.toLowerCase() : 'before';
3680 var refNode = where == 'before' ? this.dom : this.dom.nextSibling;
3682 if(typeof el == 'object' && !el.nodeType && !el.dom){ if(where == 'after' && !this.dom.nextSibling){
3683 rt = Ext.DomHelper.append(this.dom.parentNode, el, !returnDom);
3685 rt = Ext.DomHelper[where == 'after' ? 'insertAfter' : 'insertBefore'](this.dom, el, !returnDom);
3689 rt = this.dom.parentNode.insertBefore(Ext.getDom(el), refNode);
3698 wrap: function(config, returnDom){
3700 config = {tag: "div"};
3702 var newEl = Ext.DomHelper.insertBefore(this.dom, config, !returnDom);
3703 newEl.dom ? newEl.dom.appendChild(this.dom) : newEl.appendChild(this.dom);
3708 replace: function(el){
3710 this.insertBefore(el);
3716 replaceWith: function(el){
3717 if(typeof el == 'object' && !el.nodeType && !el.dom){ el = this.insertSibling(el, 'before');
3719 el = Ext.getDom(el);
3720 this.dom.parentNode.insertBefore(el, this.dom);
3722 El.uncache(this.id);
3723 this.dom.parentNode.removeChild(this.dom);
3725 this.id = Ext.id(el);
3726 El.cache[this.id] = this;
3731 insertHtml : function(where, html, returnEl){
3732 var el = Ext.DomHelper.insertHtml(where, this.dom, html);
3733 return returnEl ? Ext.get(el) : el;
3737 set : function(o, useSet){
3739 useSet = typeof useSet == 'undefined' ? (el.setAttribute ? true : false) : useSet;
3741 if(attr == "style" || typeof o[attr] == "function") continue;
3743 el.className = o["cls"];
3744 }else if(o.hasOwnProperty(attr)){
3745 if(useSet) el.setAttribute(attr, o[attr]);
3746 else el[attr] = o[attr];
3750 Ext.DomHelper.applyStyles(el, o.style);
3756 addKeyListener : function(key, fn, scope){
3758 if(typeof key != "object" || Ext.isArray(key)){
3774 return new Ext.KeyMap(this, config);
3778 addKeyMap : function(config){
3779 return new Ext.KeyMap(this, config);
3783 isScrollable : function(){
3785 return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth;
3789 scrollTo : function(side, value, animate){
3790 var prop = side.toLowerCase() == "left" ? "scrollLeft" : "scrollTop";
3792 this.dom[prop] = value;
3794 var to = prop == "scrollLeft" ? [value, this.dom.scrollTop] : [this.dom.scrollLeft, value];
3795 this.anim({scroll: {"to": to}}, this.preanim(arguments, 2), 'scroll');
3801 scroll : function(direction, distance, animate){
3802 if(!this.isScrollable()){
3806 var l = el.scrollLeft, t = el.scrollTop;
3807 var w = el.scrollWidth, h = el.scrollHeight;
3808 var cw = el.clientWidth, ch = el.clientHeight;
3809 direction = direction.toLowerCase();
3810 var scrolled = false;
3811 var a = this.preanim(arguments, 2);
3816 var v = Math.min(l + distance, w-cw);
3817 this.scrollTo("left", v, a);
3824 var v = Math.max(l - distance, 0);
3825 this.scrollTo("left", v, a);
3833 var v = Math.max(t - distance, 0);
3834 this.scrollTo("top", v, a);
3842 var v = Math.min(t + distance, h-ch);
3843 this.scrollTo("top", v, a);
3852 translatePoints : function(x, y){
3853 if(typeof x == 'object' || Ext.isArray(x)){
3856 var p = this.getStyle('position');
3857 var o = this.getXY();
3859 var l = parseInt(this.getStyle('left'), 10);
3860 var t = parseInt(this.getStyle('top'), 10);
3863 l = (p == "relative") ? 0 : this.dom.offsetLeft;
3866 t = (p == "relative") ? 0 : this.dom.offsetTop;
3869 return {left: (x - o[0] + l), top: (y - o[1] + t)};
3873 getScroll : function(){
3874 var d = this.dom, doc = document;
3875 if(d == doc || d == doc.body){
3877 if(Ext.isIE && Ext.isStrict){
3878 l = doc.documentElement.scrollLeft || (doc.body.scrollLeft || 0);
3879 t = doc.documentElement.scrollTop || (doc.body.scrollTop || 0);
3881 l = window.pageXOffset || (doc.body.scrollLeft || 0);
3882 t = window.pageYOffset || (doc.body.scrollTop || 0);
3884 return {left: l, top: t};
3886 return {left: d.scrollLeft, top: d.scrollTop};
3891 getColor : function(attr, defaultValue, prefix){
3892 var v = this.getStyle(attr);
3893 if(!v || v == "transparent" || v == "inherit") {
3894 return defaultValue;
3896 var color = typeof prefix == "undefined" ? "#" : prefix;
3897 if(v.substr(0, 4) == "rgb("){
3898 var rvs = v.slice(4, v.length -1).split(",");
3899 for(var i = 0; i < 3; i++){
3900 var h = parseInt(rvs[i]);
3901 var s = h.toString(16);
3908 if(v.substr(0, 1) == "#"){
3910 for(var i = 1; i < 4; i++){
3911 var c = v.charAt(i);
3914 }else if(v.length == 7){
3915 color += v.substr(1);
3919 return(color.length > 5 ? color.toLowerCase() : defaultValue);
3923 boxWrap : function(cls){
3924 cls = cls || 'x-box';
3925 var el = Ext.get(this.insertHtml('beforeBegin', String.format('<div class="{0}">'+El.boxMarkup+'</div>', cls)));
3926 el.child('.'+cls+'-mc').dom.appendChild(this.dom);
3931 getAttributeNS : Ext.isIE ? function(ns, name){
3933 var type = typeof d[ns+":"+name];
3934 if(type != 'undefined' && type != 'unknown'){
3935 return d[ns+":"+name];
3938 } : function(ns, name){
3940 return d.getAttributeNS(ns, name) || d.getAttribute(ns+":"+name) || d.getAttribute(name) || d[name];
3943 getTextWidth : function(text, min, max){
3944 return (Ext.util.TextMetrics.measure(this.dom, Ext.value(text, this.dom.innerHTML, true)).width).constrain(min || 0, max || 1000000);
3948 var ep = El.prototype;
3951 ep.on = ep.addListener;
3952 ep.mon = ep.addListener;
3954 ep.getUpdateManager = ep.getUpdater;
3957 ep.un = ep.removeListener;
3960 ep.autoBoxAdjust = true;
3962 El.unitPattern = /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i;
3964 El.addUnits = function(v, defaultUnit){
3965 if(v === "" || v == "auto"){
3968 if(v === undefined){
3971 if(typeof v == "number" || !El.unitPattern.test(v)){
3972 return v + (defaultUnit || 'px');
3977 El.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>';
3983 El.borders = {l: "border-left-width", r: "border-right-width", t: "border-top-width", b: "border-bottom-width"};
3984 El.paddings = {l: "padding-left", r: "padding-right", t: "padding-top", b: "padding-bottom"};
3985 El.margins = {l: "margin-left", r: "margin-right", t: "margin-top", b: "margin-bottom"};
3995 El.get = function(el){
3997 if(!el){ return null; }
3998 if(typeof el == "string"){ if(!(elm = document.getElementById(el))){
4001 if(ex = El.cache[el]){
4004 ex = El.cache[el] = new El(elm);
4007 }else if(el.tagName){ if(!(id = el.id)){
4010 if(ex = El.cache[id]){
4013 ex = El.cache[id] = new El(el);
4016 }else if(el instanceof El){
4018 el.dom = document.getElementById(el.id) || el.dom; El.cache[el.id] = el; }
4020 }else if(el.isComposite){
4022 }else if(Ext.isArray(el)){
4023 return El.select(el);
4024 }else if(el == document){
4026 var f = function(){};
4027 f.prototype = El.prototype;
4029 docEl.dom = document;
4036 El.uncache = function(el){
4037 for(var i = 0, a = arguments, len = a.length; i < len; i++) {
4039 delete El.cache[a[i].id || a[i]];
4044 El.garbageCollect = function(){
4045 if(!Ext.enableGarbageCollector){
4046 clearInterval(El.collectorThread);
4049 for(var eid in El.cache){
4050 var el = El.cache[eid], d = el.dom;
4051 if(!d || !d.parentNode || (!d.offsetParent && !document.getElementById(eid))){
4052 delete El.cache[eid];
4053 if(d && Ext.enableListenerCollection){
4059 El.collectorThreadId = setInterval(El.garbageCollect, 30000);
4061 var flyFn = function(){};
4062 flyFn.prototype = El.prototype;
4063 var _cls = new flyFn();
4065 El.Flyweight = function(dom){
4069 El.Flyweight.prototype = _cls;
4070 El.Flyweight.prototype.isFlyweight = true;
4072 El._flyweights = {};
4074 El.fly = function(el, named){
4075 named = named || '_global';
4076 el = Ext.getDom(el);
4080 if(!El._flyweights[named]){
4081 El._flyweights[named] = new El.Flyweight();
4083 El._flyweights[named].dom = el;
4084 return El._flyweights[named];
4092 var noBoxAdjust = Ext.isStrict ? {
4095 input:1, select:1, textarea:1
4097 if(Ext.isIE || Ext.isGecko){
4098 noBoxAdjust['button'] = 1;
4102 Ext.EventManager.on(window, 'unload', function(){
4104 delete El._flyweights;
4108 Ext.enableFx = true;
4113 slideIn : function(anchor, o){
4114 var el = this.getFxEl();
4117 el.queueFx(o, function(){
4119 anchor = anchor || "t";
4123 var r = this.getFxRestore();
4124 var b = this.getBox();
4127 var wrap = this.fxWrap(r.pos, o, "hidden");
4129 var st = this.dom.style;
4130 st.visibility = "visible";
4131 st.position = "absolute";
4133 var after = function(){
4134 el.fxUnwrap(wrap, r.pos, o);
4136 st.height = r.height;
4139 var a, pt = {to: [b.x, b.y]}, bw = {to: b.width}, bh = {to: b.height};
4141 switch(anchor.toLowerCase()){
4143 wrap.setSize(b.width, 0);
4144 st.left = st.bottom = "0";
4148 wrap.setSize(0, b.height);
4149 st.right = st.top = "0";
4153 wrap.setSize(0, b.height);
4155 st.left = st.top = "0";
4156 a = {width: bw, points: pt};
4159 wrap.setSize(b.width, 0);
4160 wrap.setY(b.bottom);
4161 st.left = st.top = "0";
4162 a = {height: bh, points: pt};
4166 st.right = st.bottom = "0";
4167 a = {width: bw, height: bh};
4171 wrap.setY(b.y+b.height);
4172 st.right = st.top = "0";
4173 a = {width: bw, height: bh, points: pt};
4177 wrap.setXY([b.right, b.bottom]);
4178 st.left = st.top = "0";
4179 a = {width: bw, height: bh, points: pt};
4183 wrap.setX(b.x+b.width);
4184 st.left = st.bottom = "0";
4185 a = {width: bw, height: bh, points: pt};
4188 this.dom.style.visibility = "visible";
4191 arguments.callee.anim = wrap.fxanim(a,
4201 slideOut : function(anchor, o){
4202 var el = this.getFxEl();
4205 el.queueFx(o, function(){
4207 anchor = anchor || "t";
4209 var r = this.getFxRestore();
4211 var b = this.getBox();
4214 var wrap = this.fxWrap(r.pos, o, "visible");
4216 var st = this.dom.style;
4217 st.visibility = "visible";
4218 st.position = "absolute";
4222 var after = function(){
4224 el.setDisplayed(false);
4229 el.fxUnwrap(wrap, r.pos, o);
4232 st.height = r.height;
4237 var a, zero = {to: 0};
4238 switch(anchor.toLowerCase()){
4240 st.left = st.bottom = "0";
4244 st.right = st.top = "0";
4248 st.left = st.top = "0";
4249 a = {width: zero, points: {to:[b.right, b.y]}};
4252 st.left = st.top = "0";
4253 a = {height: zero, points: {to:[b.x, b.bottom]}};
4256 st.right = st.bottom = "0";
4257 a = {width: zero, height: zero};
4260 st.right = st.top = "0";
4261 a = {width: zero, height: zero, points: {to:[b.x, b.bottom]}};
4264 st.left = st.top = "0";
4265 a = {width: zero, height: zero, points: {to:[b.x+b.width, b.bottom]}};
4268 st.left = st.bottom = "0";
4269 a = {width: zero, height: zero, points: {to:[b.right, b.y]}};
4273 arguments.callee.anim = wrap.fxanim(a,
4284 var el = this.getFxEl();
4287 el.queueFx(o, function(){
4288 this.clearOpacity();
4291 var r = this.getFxRestore();
4292 var st = this.dom.style;
4294 var after = function(){
4296 el.setDisplayed(false);
4303 el.setPositioning(r.pos);
4305 st.height = r.height;
4310 var width = this.getWidth();
4311 var height = this.getHeight();
4313 arguments.callee.anim = this.fxanim({
4314 width : {to: this.adjustWidth(width * 2)},
4315 height : {to: this.adjustHeight(height * 2)},
4316 points : {by: [-(width * .5), -(height * .5)]},
4318 fontSize: {to:200, unit: "%"}
4329 switchOff : function(o){
4330 var el = this.getFxEl();
4333 el.queueFx(o, function(){
4334 this.clearOpacity();
4337 var r = this.getFxRestore();
4338 var st = this.dom.style;
4340 var after = function(){
4342 el.setDisplayed(false);
4348 el.setPositioning(r.pos);
4350 st.height = r.height;
4355 this.fxanim({opacity:{to:0.3}}, null, null, .1, null, function(){
4356 this.clearOpacity();
4360 points:{by:[0, this.getHeight() * .5]}
4361 }, o, 'motion', 0.3, 'easeIn', after);
4362 }).defer(100, this);
4369 highlight : function(color, o){
4370 var el = this.getFxEl();
4373 el.queueFx(o, function(){
4374 color = color || "ffff9c";
4375 var attr = o.attr || "backgroundColor";
4377 this.clearOpacity();
4380 var origColor = this.getColor(attr);
4381 var restoreColor = this.dom.style[attr];
4382 var endColor = (o.endColor || origColor) || "ffffff";
4384 var after = function(){
4385 el.dom.style[attr] = restoreColor;
4390 a[attr] = {from: color, to: endColor};
4391 arguments.callee.anim = this.fxanim(a,
4401 frame : function(color, count, o){
4402 var el = this.getFxEl();
4405 el.queueFx(o, function(){
4406 color = color || "#C3DAF9";
4407 if(color.length == 6){
4408 color = "#" + color;
4411 var duration = o.duration || 1;
4414 var b = this.getBox();
4415 var animFn = function(){
4416 var proxy = Ext.getBody().createChild({
4419 position:"absolute",
4420 "z-index":"35000", border:"0px solid " + color
4423 var scale = Ext.isBorderBox ? 2 : 1;
4425 top:{from:b.y, to:b.y - 20},
4426 left:{from:b.x, to:b.x - 20},
4427 borderWidth:{from:0, to:10},
4428 opacity:{from:1, to:0},
4429 height:{from:b.height, to:(b.height + (20*scale))},
4430 width:{from:b.width, to:(b.width + (20*scale))}
4431 }, duration, function(){
4446 pause : function(seconds){
4447 var el = this.getFxEl();
4450 el.queueFx(o, function(){
4451 setTimeout(function(){
4459 fadeIn : function(o){
4460 var el = this.getFxEl();
4462 el.queueFx(o, function(){
4465 this.dom.style.visibility = 'visible';
4466 var to = o.endOpacity || 1;
4467 arguments.callee.anim = this.fxanim({opacity:{to:to}},
4468 o, null, .5, "easeOut", function(){
4470 this.clearOpacity();
4479 fadeOut : function(o){
4480 var el = this.getFxEl();
4482 el.queueFx(o, function(){
4483 arguments.callee.anim = this.fxanim({opacity:{to:o.endOpacity || 0}},
4484 o, null, .5, "easeOut", function(){
4485 if(this.visibilityMode == Ext.Element.DISPLAY || o.useDisplay){
4486 this.dom.style.display = "none";
4488 this.dom.style.visibility = "hidden";
4490 this.clearOpacity();
4498 scale : function(w, h, o){
4499 this.shift(Ext.apply({}, o, {
4507 shift : function(o){
4508 var el = this.getFxEl();
4510 el.queueFx(o, function(){
4511 var a = {}, w = o.width, h = o.height, x = o.x, y = o.y, op = o.opacity;
4512 if(w !== undefined){
4513 a.width = {to: this.adjustWidth(w)};
4515 if(h !== undefined){
4516 a.height = {to: this.adjustHeight(h)};
4518 if(x !== undefined || y !== undefined){
4520 x !== undefined ? x : this.getX(),
4521 y !== undefined ? y : this.getY()
4524 if(op !== undefined){
4525 a.opacity = {to: op};
4527 if(o.xy !== undefined){
4528 a.points = {to: o.xy};
4530 arguments.callee.anim = this.fxanim(a,
4531 o, 'motion', .35, "easeOut", function(){
4539 ghost : function(anchor, o){
4540 var el = this.getFxEl();
4543 el.queueFx(o, function(){
4544 anchor = anchor || "b";
4546 var r = this.getFxRestore();
4547 var w = this.getWidth(),
4548 h = this.getHeight();
4550 var st = this.dom.style;
4552 var after = function(){
4554 el.setDisplayed(false);
4560 el.setPositioning(r.pos);
4562 st.height = r.height;
4567 var a = {opacity: {to: 0}, points: {}}, pt = a.points;
4568 switch(anchor.toLowerCase()){
4595 arguments.callee.anim = this.fxanim(a,
4605 syncFx : function(){
4606 this.fxDefaults = Ext.apply(this.fxDefaults || {}, {
4615 sequenceFx : function(){
4616 this.fxDefaults = Ext.apply(this.fxDefaults || {}, {
4625 nextFx : function(){
4626 var ef = this.fxQueue[0];
4633 hasActiveFx : function(){
4634 return this.fxQueue && this.fxQueue[0];
4638 stopFx : function(){
4639 if(this.hasActiveFx()){
4640 var cur = this.fxQueue[0];
4641 if(cur && cur.anim && cur.anim.isAnimated()){
4642 this.fxQueue = [cur]; cur.anim.stop(true);
4649 beforeFx : function(o){
4650 if(this.hasActiveFx() && !o.concurrent){
4661 hasFxBlock : function(){
4662 var q = this.fxQueue;
4663 return q && q[0] && q[0].block;
4667 queueFx : function(o, fn){
4671 if(!this.hasFxBlock()){
4672 Ext.applyIf(o, this.fxDefaults);
4674 var run = this.beforeFx(o);
4676 this.fxQueue.push(fn);
4688 fxWrap : function(pos, o, vis){
4690 if(!o.wrap || !(wrap = Ext.get(o.wrap))){
4693 wrapXY = this.getXY();
4695 var div = document.createElement("div");
4696 div.style.visibility = vis;
4697 wrap = Ext.get(this.dom.parentNode.insertBefore(div, this.dom));
4698 wrap.setPositioning(pos);
4699 if(wrap.getStyle("position") == "static"){
4700 wrap.position("relative");
4702 this.clearPositioning('auto');
4704 wrap.dom.appendChild(this.dom);
4713 fxUnwrap : function(wrap, pos, o){
4714 this.clearPositioning();
4715 this.setPositioning(pos);
4717 wrap.dom.parentNode.insertBefore(this.dom, wrap.dom);
4723 getFxRestore : function(){
4724 var st = this.dom.style;
4725 return {pos: this.getPositioning(), width: st.width, height : st.height};
4729 afterFx : function(o){
4731 this.applyStyles(o.afterStyle);
4734 this.addClass(o.afterCls);
4736 if(o.remove === true){
4739 Ext.callback(o.callback, o.scope, [this]);
4741 this.fxQueue.shift();
4747 getFxEl : function(){ return Ext.get(this.dom);
4751 fxanim : function(args, opt, animType, defaultDur, defaultEase, cb){
4752 animType = animType || 'run';
4754 var anim = Ext.lib.Anim[animType](
4756 (opt.duration || defaultDur) || .35,
4757 (opt.easing || defaultEase) || 'easeOut',
4759 Ext.callback(cb, this);
4768 Ext.Fx.resize = Ext.Fx.scale;
4770 Ext.apply(Ext.Element.prototype, Ext.Fx);
4773 Ext.CompositeElement = function(els){
4775 this.addElements(els);
4777 Ext.CompositeElement.prototype = {
4779 addElements : function(els){
4780 if(!els) return this;
4781 if(typeof els == "string"){
4782 els = Ext.Element.selectorFunction(els);
4784 var yels = this.elements;
4785 var index = yels.length-1;
4786 for(var i = 0, len = els.length; i < len; i++) {
4787 yels[++index] = Ext.get(els[i]);
4793 fill : function(els){
4800 filter : function(selector){
4802 this.each(function(el){
4803 if(el.is(selector)){
4804 els[els.length] = el.dom;
4811 invoke : function(fn, args){
4812 var els = this.elements;
4813 for(var i = 0, len = els.length; i < len; i++) {
4814 Ext.Element.prototype[fn].apply(els[i], args);
4819 add : function(els){
4820 if(typeof els == "string"){
4821 this.addElements(Ext.Element.selectorFunction(els));
4822 }else if(els.length !== undefined){
4823 this.addElements(els);
4825 this.addElements([els]);
4830 each : function(fn, scope){
4831 var els = this.elements;
4832 for(var i = 0, len = els.length; i < len; i++){
4833 if(fn.call(scope || els[i], els[i], this, i) === false) {
4841 item : function(index){
4842 return this.elements[index] || null;
4847 return this.item(0);
4852 return this.item(this.elements.length-1);
4856 getCount : function(){
4857 return this.elements.length;
4861 contains : function(el){
4862 return this.indexOf(el) !== -1;
4866 indexOf : function(el){
4867 return this.elements.indexOf(Ext.get(el));
4872 removeElement : function(el, removeDom){
4873 if(Ext.isArray(el)){
4874 for(var i = 0, len = el.length; i < len; i++){
4875 this.removeElement(el[i]);
4879 var index = typeof el == 'number' ? el : this.indexOf(el);
4880 if(index !== -1 && this.elements[index]){
4882 var d = this.elements[index];
4889 this.elements.splice(index, 1);
4895 replaceElement : function(el, replacement, domReplace){
4896 var index = typeof el == 'number' ? el : this.indexOf(el);
4899 this.elements[index].replaceWith(replacement);
4901 this.elements.splice(index, 1, Ext.get(replacement))
4913 Ext.CompositeElement.createCall = function(proto, fnName){
4915 proto[fnName] = function(){
4916 return this.invoke(fnName, arguments);
4920 for(var fnName in Ext.Element.prototype){
4921 if(typeof Ext.Element.prototype[fnName] == "function"){
4922 Ext.CompositeElement.createCall(Ext.CompositeElement.prototype, fnName);
4928 Ext.CompositeElementLite = function(els){
4929 Ext.CompositeElementLite.superclass.constructor.call(this, els);
4930 this.el = new Ext.Element.Flyweight();
4932 Ext.extend(Ext.CompositeElementLite, Ext.CompositeElement, {
4933 addElements : function(els){
4935 if(Ext.isArray(els)){
4936 this.elements = this.elements.concat(els);
4938 var yels = this.elements;
4939 var index = yels.length-1;
4940 for(var i = 0, len = els.length; i < len; i++) {
4941 yels[++index] = els[i];
4947 invoke : function(fn, args){
4948 var els = this.elements;
4950 for(var i = 0, len = els.length; i < len; i++) {
4952 Ext.Element.prototype[fn].apply(el, args);
4957 item : function(index){
4958 if(!this.elements[index]){
4961 this.el.dom = this.elements[index];
4966 addListener : function(eventName, handler, scope, opt){
4967 var els = this.elements;
4968 for(var i = 0, len = els.length; i < len; i++) {
4969 Ext.EventManager.on(els[i], eventName, handler, scope || els[i], opt);
4975 each : function(fn, scope){
4976 var els = this.elements;
4978 for(var i = 0, len = els.length; i < len; i++){
4980 if(fn.call(scope || el, el, this, i) === false){
4987 indexOf : function(el){
4988 return this.elements.indexOf(Ext.getDom(el));
4991 replaceElement : function(el, replacement, domReplace){
4992 var index = typeof el == 'number' ? el : this.indexOf(el);
4994 replacement = Ext.getDom(replacement);
4996 var d = this.elements[index];
4997 d.parentNode.insertBefore(replacement, d);
5000 this.elements.splice(index, 1, replacement);
5005 Ext.CompositeElementLite.prototype.on = Ext.CompositeElementLite.prototype.addListener;
5007 Ext.Element.selectorFunction = Ext.DomQuery.select;
5010 Ext.Element.select = function(selector, unique, root){
5012 if(typeof selector == "string"){
5013 els = Ext.Element.selectorFunction(selector, root);
5014 }else if(selector.length !== undefined){
5017 throw "Invalid selector";
5019 if(unique === true){
5020 return new Ext.CompositeElement(els);
5022 return new Ext.CompositeElementLite(els);
5026 Ext.select = Ext.Element.select;
5028 Ext.data.Connection = function(config){
5029 Ext.apply(this, config);
5038 Ext.data.Connection.superclass.constructor.call(this);
5041 Ext.extend(Ext.data.Connection, Ext.util.Observable, {
5052 disableCaching: true,
5055 request : function(o){
5056 if(this.fireEvent("beforerequest", this, o) !== false){
5059 if(typeof p == "function"){
5060 p = p.call(o.scope||window, o);
5062 if(typeof p == "object"){
5063 p = Ext.urlEncode(p);
5065 if(this.extraParams){
5066 var extras = Ext.urlEncode(this.extraParams);
5067 p = p ? (p + '&' + extras) : extras;
5070 var url = o.url || this.url;
5071 if(typeof url == 'function'){
5072 url = url.call(o.scope||window, o);
5076 var form = Ext.getDom(o.form);
5077 url = url || form.action;
5079 var enctype = form.getAttribute("enctype");
5080 if(o.isUpload || (enctype && enctype.toLowerCase() == 'multipart/form-data')){
5081 return this.doFormUpload(o, p, url);
5083 var f = Ext.lib.Ajax.serializeForm(form);
5084 p = p ? (p + '&' + f) : f;
5088 if(this.defaultHeaders){
5089 hs = Ext.apply(hs || {}, this.defaultHeaders);
5096 success: this.handleResponse,
5097 failure: this.handleFailure,
5099 argument: {options: o},
5100 timeout : o.timeout || this.timeout
5103 var method = o.method||this.method||(p ? "POST" : "GET");
5105 if(method == 'GET' && (this.disableCaching && o.disableCaching !== false) || o.disableCaching === true){
5106 url += (url.indexOf('?') != -1 ? '&' : '?') + '_dc=' + (new Date().getTime());
5109 if(typeof o.autoAbort == 'boolean'){
5113 }else if(this.autoAbort !== false){
5116 if((method == 'GET' && p) || o.xmlData || o.jsonData){
5117 url += (url.indexOf('?') != -1 ? '&' : '?') + p;
5120 this.transId = Ext.lib.Ajax.request(method, url, cb, p, o);
5121 return this.transId;
5123 Ext.callback(o.callback, o.scope, [o, null, null]);
5129 isLoading : function(transId){
5131 return Ext.lib.Ajax.isCallInProgress(transId);
5133 return this.transId ? true : false;
5138 abort : function(transId){
5139 if(transId || this.isLoading()){
5140 Ext.lib.Ajax.abort(transId || this.transId);
5145 handleResponse : function(response){
5146 this.transId = false;
5147 var options = response.argument.options;
5148 response.argument = options ? options.argument : null;
5149 this.fireEvent("requestcomplete", this, response, options);
5150 Ext.callback(options.success, options.scope, [response, options]);
5151 Ext.callback(options.callback, options.scope, [options, true, response]);
5155 handleFailure : function(response, e){
5156 this.transId = false;
5157 var options = response.argument.options;
5158 response.argument = options ? options.argument : null;
5159 this.fireEvent("requestexception", this, response, options, e);
5160 Ext.callback(options.failure, options.scope, [response, options]);
5161 Ext.callback(options.callback, options.scope, [options, false, response]);
5165 doFormUpload : function(o, ps, url){
5167 var frame = document.createElement('iframe');
5170 frame.className = 'x-hidden';
5172 frame.src = Ext.SSL_SECURE_URL;
5174 document.body.appendChild(frame);
5177 document.frames[id].name = id;
5180 var form = Ext.getDom(o.form);
5182 form.method = 'POST';
5183 form.enctype = form.encoding = 'multipart/form-data';
5191 ps = Ext.urlDecode(ps, false);
5193 if(ps.hasOwnProperty(k)){
5194 hd = document.createElement('input');
5198 form.appendChild(hd);
5210 r.argument = o ? o.argument : null;
5215 doc = frame.contentWindow.document;
5217 doc = (frame.contentDocument || window.frames[id].document);
5219 if(doc && doc.body){
5220 r.responseText = doc.body.innerHTML;
5222 if(doc && doc.XMLDocument){
5223 r.responseXML = doc.XMLDocument;
5225 r.responseXML = doc;
5232 Ext.EventManager.removeListener(frame, 'load', cb, this);
5234 this.fireEvent("requestcomplete", this, r, o);
5236 Ext.callback(o.success, o.scope, [r, o]);
5237 Ext.callback(o.callback, o.scope, [o, true, r]);
5239 setTimeout(function(){Ext.removeNode(frame);}, 100);
5242 Ext.EventManager.on(frame, 'load', cb, this);
5246 for(var i = 0, len = hiddens.length; i < len; i++){
5247 Ext.removeNode(hiddens[i]);
5254 Ext.Ajax = new Ext.data.Connection({
5275 serializeForm : function(form){
5276 return Ext.lib.Ajax.serializeForm(form);
5280 Ext.Updater = function(el, forceNew){
5282 if(!forceNew && el.updateManager){
5283 return el.updateManager;
5288 this.defaultUrl = null;
5298 var d = Ext.Updater.defaults;
5300 this.sslBlankUrl = d.sslBlankUrl;
5302 this.disableCaching = d.disableCaching;
5304 this.indicatorText = d.indicatorText;
5306 this.showLoadIndicator = d.showLoadIndicator;
5308 this.timeout = d.timeout;
5311 this.loadScripts = d.loadScripts;
5314 this.transaction = null;
5317 this.autoRefreshProcId = null;
5319 this.refreshDelegate = this.refresh.createDelegate(this);
5321 this.updateDelegate = this.update.createDelegate(this);
5323 this.formUpdateDelegate = this.formUpdate.createDelegate(this);
5327 this.renderer = new Ext.Updater.BasicRenderer();
5329 Ext.Updater.superclass.constructor.call(this);
5332 Ext.extend(Ext.Updater, Ext.util.Observable, {
5338 update : function(url, params, callback, discardUrl){
5339 if(this.fireEvent("beforeupdate", this.el, url, params) !== false){
5340 var method = this.method, cfg, callerScope;
5341 if(typeof url == "object"){
5344 params = params || cfg.params;
5345 callback = callback || cfg.callback;
5346 discardUrl = discardUrl || cfg.discardUrl;
5347 callerScope = cfg.scope;
5348 if(typeof cfg.method != "undefined"){method = cfg.method;};
5349 if(typeof cfg.nocache != "undefined"){this.disableCaching = cfg.nocache;};
5350 if(typeof cfg.text != "undefined"){this.indicatorText = '<div class="loading-indicator">'+cfg.text+"</div>";};
5351 if(typeof cfg.scripts != "undefined"){this.loadScripts = cfg.scripts;};
5352 if(typeof cfg.timeout != "undefined"){this.timeout = cfg.timeout;};
5356 this.defaultUrl = url;
5358 if(typeof url == "function"){
5359 url = url.call(this);
5362 method = method || (params ? "POST" : "GET");
5363 if(method == "GET"){
5364 url = this.prepareUrl(url);
5367 var o = Ext.apply(cfg ||{}, {
5369 params: (typeof params == "function" && callerScope) ? params.createDelegate(callerScope) : params,
5370 success: this.processSuccess,
5371 failure: this.processFailure,
5373 callback: undefined,
5374 timeout: (this.timeout*1000),
5379 "callback": callback,
5380 "scope": callerScope || window,
5385 this.transaction = Ext.Ajax.request(o);
5390 formUpdate : function(form, url, reset, callback){
5391 if(this.fireEvent("beforeupdate", this.el, form, url) !== false){
5392 if(typeof url == "function"){
5393 url = url.call(this);
5395 form = Ext.getDom(form)
5396 this.transaction = Ext.Ajax.request({
5399 success: this.processSuccess,
5400 failure: this.processFailure,
5402 timeout: (this.timeout*1000),
5406 "callback": callback,
5410 this.showLoading.defer(1, this);
5415 refresh : function(callback){
5416 if(this.defaultUrl == null){
5419 this.update(this.defaultUrl, null, callback, true);
5423 startAutoRefresh : function(interval, url, params, callback, refreshNow){
5425 this.update(url || this.defaultUrl, params, callback, true);
5427 if(this.autoRefreshProcId){
5428 clearInterval(this.autoRefreshProcId);
5430 this.autoRefreshProcId = setInterval(this.update.createDelegate(this, [url || this.defaultUrl, params, callback, true]), interval*1000);
5434 stopAutoRefresh : function(){
5435 if(this.autoRefreshProcId){
5436 clearInterval(this.autoRefreshProcId);
5437 delete this.autoRefreshProcId;
5441 isAutoRefreshing : function(){
5442 return this.autoRefreshProcId ? true : false;
5445 showLoading : function(){
5446 if(this.showLoadIndicator){
5447 this.el.update(this.indicatorText);
5452 prepareUrl : function(url){
5453 if(this.disableCaching){
5454 var append = "_dc=" + (new Date().getTime());
5455 if(url.indexOf("?") !== -1){
5456 url += "&" + append;
5458 url += "?" + append;
5465 processSuccess : function(response){
5466 this.transaction = null;
5467 if(response.argument.form && response.argument.reset){
5469 response.argument.form.reset();
5472 if(this.loadScripts){
5473 this.renderer.render(this.el, response, this,
5474 this.updateComplete.createDelegate(this, [response]));
5476 this.renderer.render(this.el, response, this);
5477 this.updateComplete(response);
5481 updateComplete : function(response){
5482 this.fireEvent("update", this.el, response);
5483 if(typeof response.argument.callback == "function"){
5484 response.argument.callback.call(response.argument.scope, this.el, true, response, response.argument.options);
5489 processFailure : function(response){
5490 this.transaction = null;
5491 this.fireEvent("failure", this.el, response);
5492 if(typeof response.argument.callback == "function"){
5493 response.argument.callback.call(response.argument.scope, this.el, false, response, response.argument.options);
5498 setRenderer : function(renderer){
5499 this.renderer = renderer;
5502 getRenderer : function(){
5503 return this.renderer;
5507 setDefaultUrl : function(defaultUrl){
5508 this.defaultUrl = defaultUrl;
5513 if(this.transaction){
5514 Ext.Ajax.abort(this.transaction);
5519 isUpdating : function(){
5520 if(this.transaction){
5521 return Ext.Ajax.isLoading(this.transaction);
5528 Ext.Updater.defaults = {
5533 loadScripts : false,
5536 sslBlankUrl : (Ext.SSL_SECURE_URL || "javascript:false"),
5538 disableCaching : false,
5540 showLoadIndicator : true,
5542 indicatorText : '<div class="loading-indicator">Loading...</div>'
5546 Ext.Updater.updateElement = function(el, url, params, options){
5547 var um = Ext.get(el).getUpdater();
5548 Ext.apply(um, options);
5549 um.update(url, params, options ? options.callback : null);
5552 Ext.Updater.update = Ext.Updater.updateElement;
5554 Ext.Updater.BasicRenderer = function(){};
5556 Ext.Updater.BasicRenderer.prototype = {
5558 render : function(el, response, updateManager, callback){
5559 el.update(response.responseText, updateManager.loadScripts, callback);
5563 Ext.UpdateManager = Ext.Updater;
5569 Date.parseFunctions = {count:0};
5570 Date.parseRegexes = [];
5571 Date.formatFunctions = {count:0};
5573 Date.prototype.dateFormat = function(format) {
5574 if (Date.formatFunctions[format] == null) {
5575 Date.createNewFormat(format);
5577 var func = Date.formatFunctions[format];
5578 return this[func]();
5583 Date.prototype.format = Date.prototype.dateFormat;
5585 Date.createNewFormat = function(format) {
5586 var funcName = "format" + Date.formatFunctions.count++;
5587 Date.formatFunctions[format] = funcName;
5588 var code = "Date.prototype." + funcName + " = function(){return ";
5589 var special = false;
5591 for (var i = 0; i < format.length; ++i) {
5592 ch = format.charAt(i);
5593 if (!special && ch == "\\") {
5598 code += "'" + String.escape(ch) + "' + ";
5601 code += Date.getFormatCode(ch);
5604 eval(code.substring(0, code.length - 3) + ";}");
5607 Date.getFormatCode = function(character) {
5608 switch (character) {
5610 return "String.leftPad(this.getDate(), 2, '0') + ";
5612 return "Date.getShortDayName(this.getDay()) + "; case "j":
5613 return "this.getDate() + ";
5615 return "Date.dayNames[this.getDay()] + ";
5617 return "(this.getDay() ? this.getDay() : 7) + ";
5619 return "this.getSuffix() + ";
5621 return "this.getDay() + ";
5623 return "this.getDayOfYear() + ";
5625 return "String.leftPad(this.getWeekOfYear(), 2, '0') + ";
5627 return "Date.monthNames[this.getMonth()] + ";
5629 return "String.leftPad(this.getMonth() + 1, 2, '0') + ";
5631 return "Date.getShortMonthName(this.getMonth()) + "; case "n":
5632 return "(this.getMonth() + 1) + ";
5634 return "this.getDaysInMonth() + ";
5636 return "(this.isLeapYear() ? 1 : 0) + ";
5638 return "(this.getFullYear() + (this.getWeekOfYear() == 1 && this.getMonth() > 0 ? +1 : (this.getWeekOfYear() >= 52 && this.getMonth() < 11 ? -1 : 0))) + ";
5640 return "this.getFullYear() + ";
5642 return "('' + this.getFullYear()).substring(2, 4) + ";
5644 return "(this.getHours() < 12 ? 'am' : 'pm') + ";
5646 return "(this.getHours() < 12 ? 'AM' : 'PM') + ";
5648 return "((this.getHours() % 12) ? this.getHours() % 12 : 12) + ";
5650 return "this.getHours() + ";
5652 return "String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0') + ";
5654 return "String.leftPad(this.getHours(), 2, '0') + ";
5656 return "String.leftPad(this.getMinutes(), 2, '0') + ";
5658 return "String.leftPad(this.getSeconds(), 2, '0') + ";
5660 return "String.leftPad(this.getMilliseconds(), 3, '0') + ";
5662 return "this.getGMTOffset() + ";
5664 return "this.getGMTOffset(true) + ";
5666 return "this.getTimezone() + ";
5668 return "(this.getTimezoneOffset() * -60) + ";
5670 for (var df = Date.getFormatCode, c = "Y-m-dTH:i:sP", code = "", i = 0, l = c.length; i < l; ++i) {
5671 var e = c.charAt(i);
5672 code += e == "T" ? "'T' + " : df(e); }
5675 return "Math.round(this.getTime() / 1000) + ";
5677 return "'" + String.escape(character) + "' + ";
5682 Date.parseDate = function(input, format) {
5683 if (Date.parseFunctions[format] == null) {
5684 Date.createParser(format);
5686 var func = Date.parseFunctions[format];
5687 return Date[func](input);
5690 Date.createParser = function(format) {
5691 var funcName = "parse" + Date.parseFunctions.count++;
5692 var regexNum = Date.parseRegexes.length;
5693 var currentGroup = 1;
5694 Date.parseFunctions[format] = funcName;
5696 var code = "Date." + funcName + " = function(input){\n"
5697 + "var y = -1, m = -1, d = -1, h = -1, i = -1, s = -1, ms = -1, o, z, u, v;\n"
5698 + "input = String(input);var d = new Date();\n"
5699 + "y = d.getFullYear();\n"
5700 + "m = d.getMonth();\n"
5701 + "d = d.getDate();\n"
5702 + "var results = input.match(Date.parseRegexes[" + regexNum + "]);\n"
5703 + "if (results && results.length > 0) {";
5706 var special = false;
5708 for (var i = 0; i < format.length; ++i) {
5709 ch = format.charAt(i);
5710 if (!special && ch == "\\") {
5715 regex += String.escape(ch);
5718 var obj = Date.formatCodeToRegex(ch, currentGroup);
5719 currentGroup += obj.g;
5721 if (obj.g && obj.c) {
5728 + "{v = new Date(u * 1000);}" + "else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0 && ms >= 0)\n"
5729 + "{v = new Date(y, m, d, h, i, s, ms);}\n"
5730 + "else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0)\n"
5731 + "{v = new Date(y, m, d, h, i, s);}\n"
5732 + "else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0)\n"
5733 + "{v = new Date(y, m, d, h, i);}\n"
5734 + "else if (y >= 0 && m >= 0 && d > 0 && h >= 0)\n"
5735 + "{v = new Date(y, m, d, h);}\n"
5736 + "else if (y >= 0 && m >= 0 && d > 0)\n"
5737 + "{v = new Date(y, m, d);}\n"
5738 + "else if (y >= 0 && m >= 0)\n"
5739 + "{v = new Date(y, m);}\n"
5740 + "else if (y >= 0)\n"
5741 + "{v = new Date(y);}\n"
5742 + "}return (v && (z || o))?\n" + " (z ? v.add(Date.SECOND, (v.getTimezoneOffset() * 60) + (z*1)) :\n" + " v.add(Date.HOUR, (v.getGMTOffset() / 100) + (o / -100))) : v\n" + ";}";
5744 Date.parseRegexes[regexNum] = new RegExp("^" + regex + "$", "i");
5748 Date.formatCodeToRegex = function(character, currentGroup) {
5750 switch (character) {
5753 c:"d = parseInt(results[" + currentGroup + "], 10);\n",
5754 s:"(\\d{2})"}; case "D":
5755 for (var a = [], i = 0; i < 7; a.push(Date.getShortDayName(i)), ++i); return {g:0,
5757 s:"(?:" + a.join("|") +")"};
5760 c:"d = parseInt(results[" + currentGroup + "], 10);\n",
5761 s:"(\\d{1,2})"}; case "l":
5764 s:"(?:" + Date.dayNames.join("|") + ")"};
5768 s:"[1-7]"}; case "S":
5771 s:"(?:st|nd|rd|th)"};
5775 s:"[0-6]"}; case "z":
5778 s:"(?:\\d{1,3}"}; case "W":
5781 s:"(?:\\d{2})"}; case "F":
5783 c:"m = parseInt(Date.getMonthNumber(results[" + currentGroup + "]), 10);\n", s:"(" + Date.monthNames.join("|") + ")"};
5786 c:"m = parseInt(results[" + currentGroup + "], 10) - 1;\n",
5787 s:"(\\d{2})"}; case "M":
5788 for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i); return {g:1,
5789 c:"m = parseInt(Date.getMonthNumber(results[" + currentGroup + "]), 10);\n", s:"(" + a.join("|") + ")"};
5792 c:"m = parseInt(results[" + currentGroup + "], 10) - 1;\n",
5793 s:"(\\d{1,2})"}; case "t":
5796 s:"(?:\\d{2})"}; case "L":
5803 c:"y = parseInt(results[" + currentGroup + "], 10);\n",
5804 s:"(\\d{4})"}; case "y":
5806 c:"var ty = parseInt(results[" + currentGroup + "], 10);\n"
5807 + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n",
5808 s:"(\\d{1,2})"}; case "a":
5810 c:"if (results[" + currentGroup + "] == 'am') {\n"
5811 + "if (h == 12) { h = 0; }\n"
5812 + "} else { if (h < 12) { h += 12; }}",
5816 c:"if (results[" + currentGroup + "] == 'AM') {\n"
5817 + "if (h == 12) { h = 0; }\n"
5818 + "} else { if (h < 12) { h += 12; }}",
5823 c:"h = parseInt(results[" + currentGroup + "], 10);\n",
5824 s:"(\\d{1,2})"}; case "h":
5827 c:"h = parseInt(results[" + currentGroup + "], 10);\n",
5828 s:"(\\d{2})"}; case "i":
5830 c:"i = parseInt(results[" + currentGroup + "], 10);\n",
5831 s:"(\\d{2})"}; case "s":
5833 c:"s = parseInt(results[" + currentGroup + "], 10);\n",
5834 s:"(\\d{2})"}; case "u":
5836 c:"ms = parseInt(results[" + currentGroup + "], 10);\n",
5837 s:"(\\d{3})"}; case "O":
5840 "o = results[", currentGroup, "];\n",
5841 "var sn = o.substring(0,1);\n", "var hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60);\n", "var mn = o.substring(3,5) % 60;\n", "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))?\n", " (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"
5843 s: "([+\-]\\d{4})"}; case "P":
5846 "o = results[", currentGroup, "];\n",
5847 "var sn = o.substring(0,1);\n", "var hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60);\n", "var mn = o.substring(4,6) % 60;\n", "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))?\n", " (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"
5849 s: "([+\-]\\d{2}:\\d{2})"}; case "T":
5852 s:"[A-Z]{1,4}"}; case "Z":
5854 c:"z = results[" + currentGroup + "] * 1;\n" + "z = (-43200 <= z && z <= 50400)? z : null;\n",
5855 s:"([+\-]?\\d{1,5})"}; case "c":
5856 var df = Date.formatCodeToRegex, calc = [];
5857 var arr = [df("Y", 1), df("m", 2), df("d", 3), df("h", 4), df("i", 5), df("s", 6), df("P", 7)];
5858 for (var i = 0, l = arr.length; i < l; ++i) {
5859 calc.push(arr[i].c);
5863 s:arr[0].s + "-" + arr[1].s + "-" + arr[2].s + "T" + arr[3].s + ":" + arr[4].s + ":" + arr[5].s + arr[6].s};
5866 c:"u = parseInt(results[" + currentGroup + "], 10);\n",
5867 s:"(-?\\d+)"}; default:
5870 s:Ext.escapeRe(character)};
5875 Date.prototype.getTimezone = function() {
5876 return this.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, "");
5880 Date.prototype.getGMTOffset = function(colon) {
5881 return (this.getTimezoneOffset() > 0 ? "-" : "+")
5882 + String.leftPad(Math.abs(Math.floor(this.getTimezoneOffset() / 60)), 2, "0")
5883 + (colon ? ":" : "")
5884 + String.leftPad(this.getTimezoneOffset() % 60, 2, "0");
5888 Date.prototype.getDayOfYear = function() {
5890 Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
5891 for (var i = 0; i < this.getMonth(); ++i) {
5892 num += Date.daysInMonth[i];
5894 return num + this.getDate() - 1;
5898 Date.prototype.getWeekOfYear = function() {
5899 var ms1d = 864e5; var ms7d = 7 * ms1d; var DC3 = Date.UTC(this.getFullYear(), this.getMonth(), this.getDate() + 3) / ms1d; var AWN = Math.floor(DC3 / 7); var Wyr = new Date(AWN * ms7d).getUTCFullYear();
5900 return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
5904 Date.prototype.isLeapYear = function() {
5905 var year = this.getFullYear();
5906 return !!((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
5910 Date.prototype.getFirstDayOfMonth = function() {
5911 var day = (this.getDay() - (this.getDate() - 1)) % 7;
5912 return (day < 0) ? (day + 7) : day;
5916 Date.prototype.getLastDayOfMonth = function() {
5917 var day = (this.getDay() + (Date.daysInMonth[this.getMonth()] - this.getDate())) % 7;
5918 return (day < 0) ? (day + 7) : day;
5923 Date.prototype.getFirstDateOfMonth = function() {
5924 return new Date(this.getFullYear(), this.getMonth(), 1);
5928 Date.prototype.getLastDateOfMonth = function() {
5929 return new Date(this.getFullYear(), this.getMonth(), this.getDaysInMonth());
5932 Date.prototype.getDaysInMonth = function() {
5933 Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
5934 return Date.daysInMonth[this.getMonth()];
5938 Date.prototype.getSuffix = function() {
5939 switch (this.getDate()) {
5955 Date.daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31];
5973 Date.getShortMonthName = function(month) {
5974 return Date.monthNames[month].substring(0, 3);
5988 Date.getShortDayName = function(day) {
5989 return Date.dayNames[day].substring(0, 3);
5995 Date.monthNumbers = {
6010 Date.getMonthNumber = function(name) {
6011 return Date.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()];
6015 Date.prototype.clone = function() {
6016 return new Date(this.getTime());
6020 Date.prototype.clearTime = function(clone){
6022 return this.clone().clearTime();
6027 this.setMilliseconds(0);
6032 Date.brokenSetMonth = Date.prototype.setMonth;
6033 Date.prototype.setMonth = function(num){
6035 var n = Math.ceil(-num);
6036 var back_year = Math.ceil(n/12);
6037 var month = (n % 12) ? 12 - n % 12 : 0 ;
6038 this.setFullYear(this.getFullYear() - back_year);
6039 return Date.brokenSetMonth.call(this, month);
6041 return Date.brokenSetMonth.apply(this, arguments);
6062 Date.prototype.add = function(interval, value){
6063 var d = this.clone();
6064 if (!interval || value === 0) return d;
6065 switch(interval.toLowerCase()){
6067 d.setMilliseconds(this.getMilliseconds() + value);
6070 d.setSeconds(this.getSeconds() + value);
6073 d.setMinutes(this.getMinutes() + value);
6076 d.setHours(this.getHours() + value);
6079 d.setDate(this.getDate() + value);
6082 var day = this.getDate();
6084 day = Math.min(day, this.getFirstDateOfMonth().add('mo', value).getLastDateOfMonth().getDate());
6087 d.setMonth(this.getMonth() + value);
6090 d.setFullYear(this.getFullYear() + value);
6097 Date.prototype.between = function(start, end){
6098 var t = this.getTime();
6099 return start.getTime() <= t && t <= end.getTime();
6102 Ext.util.DelayedTask = function(fn, scope, args){
6103 var id = null, d, t;
6105 var call = function(){
6106 var now = new Date().getTime();
6110 fn.apply(scope, args || []);
6114 this.delay = function(delay, newFn, newScope, newArgs){
6115 if(id && delay != d){
6119 t = new Date().getTime();
6121 scope = newScope || scope;
6122 args = newArgs || args;
6124 id = setInterval(call, d);
6129 this.cancel = function(){
6137 Ext.util.TaskRunner = function(interval){
6138 interval = interval || 10;
6139 var tasks = [], removeQueue = [];
6141 var running = false;
6143 var stopThread = function(){
6149 var startThread = function(){
6152 id = setInterval(runTasks, interval);
6156 var removeTask = function(t){
6157 removeQueue.push(t);
6159 t.onStop.apply(t.scope || t);
6163 var runTasks = function(){
6164 if(removeQueue.length > 0){
6165 for(var i = 0, len = removeQueue.length; i < len; i++){
6166 tasks.remove(removeQueue[i]);
6169 if(tasks.length < 1){
6174 var now = new Date().getTime();
6175 for(var i = 0, len = tasks.length; i < len; ++i){
6177 var itime = now - t.taskRunTime;
6178 if(t.interval <= itime){
6179 var rt = t.run.apply(t.scope || t, t.args || [++t.taskRunCount]);
6180 t.taskRunTime = now;
6181 if(rt === false || t.taskRunCount === t.repeat){
6186 if(t.duration && t.duration <= (now - t.taskStartTime)){
6193 this.start = function(task){
6195 task.taskStartTime = new Date().getTime();
6196 task.taskRunTime = 0;
6197 task.taskRunCount = 0;
6203 this.stop = function(task){
6209 this.stopAll = function(){
6211 for(var i = 0, len = tasks.length; i < len; i++){
6212 if(tasks[i].onStop){
6222 Ext.TaskMgr = new Ext.util.TaskRunner();
6224 Ext.util.MixedCollection = function(allowFunctions, keyFn){
6240 this.allowFunctions = allowFunctions === true;
6242 this.getKey = keyFn;
6244 Ext.util.MixedCollection.superclass.constructor.call(this);
6247 Ext.extend(Ext.util.MixedCollection, Ext.util.Observable, {
6248 allowFunctions : false,
6251 add : function(key, o){
6252 if(arguments.length == 1){
6254 key = this.getKey(o);
6256 if(typeof key == "undefined" || key === null){
6259 this.keys.push(null);
6261 var old = this.map[key];
6263 return this.replace(key, o);
6268 this.keys.push(key);
6270 this.fireEvent("add", this.length-1, o, key);
6275 getKey : function(o){
6280 replace : function(key, o){
6281 if(arguments.length == 1){
6283 key = this.getKey(o);
6285 var old = this.item(key);
6286 if(typeof key == "undefined" || key === null || typeof old == "undefined"){
6287 return this.add(key, o);
6289 var index = this.indexOfKey(key);
6290 this.items[index] = o;
6292 this.fireEvent("replace", key, old, o);
6297 addAll : function(objs){
6298 if(arguments.length > 1 || Ext.isArray(objs)){
6299 var args = arguments.length > 1 ? arguments : objs;
6300 for(var i = 0, len = args.length; i < len; i++){
6304 for(var key in objs){
6305 if(this.allowFunctions || typeof objs[key] != "function"){
6306 this.add(key, objs[key]);
6313 each : function(fn, scope){
6314 var items = [].concat(this.items);
6315 for(var i = 0, len = items.length; i < len; i++){
6316 if(fn.call(scope || items[i], items[i], i, len) === false){
6323 eachKey : function(fn, scope){
6324 for(var i = 0, len = this.keys.length; i < len; i++){
6325 fn.call(scope || window, this.keys[i], this.items[i], i, len);
6330 find : function(fn, scope){
6331 for(var i = 0, len = this.items.length; i < len; i++){
6332 if(fn.call(scope || window, this.items[i], this.keys[i])){
6333 return this.items[i];
6340 insert : function(index, key, o){
6341 if(arguments.length == 2){
6343 key = this.getKey(o);
6345 if(index >= this.length){
6346 return this.add(key, o);
6349 this.items.splice(index, 0, o);
6350 if(typeof key != "undefined" && key != null){
6353 this.keys.splice(index, 0, key);
6354 this.fireEvent("add", index, o, key);
6359 remove : function(o){
6360 return this.removeAt(this.indexOf(o));
6364 removeAt : function(index){
6365 if(index < this.length && index >= 0){
6367 var o = this.items[index];
6368 this.items.splice(index, 1);
6369 var key = this.keys[index];
6370 if(typeof key != "undefined"){
6371 delete this.map[key];
6373 this.keys.splice(index, 1);
6374 this.fireEvent("remove", o, key);
6381 removeKey : function(key){
6382 return this.removeAt(this.indexOfKey(key));
6386 getCount : function(){
6391 indexOf : function(o){
6392 return this.items.indexOf(o);
6396 indexOfKey : function(key){
6397 return this.keys.indexOf(key);
6401 item : function(key){
6402 var item = typeof this.map[key] != "undefined" ? this.map[key] : this.items[key];
6403 return typeof item != 'function' || this.allowFunctions ? item : null;
6407 itemAt : function(index){
6408 return this.items[index];
6412 key : function(key){
6413 return this.map[key];
6417 contains : function(o){
6418 return this.indexOf(o) != -1;
6422 containsKey : function(key){
6423 return typeof this.map[key] != "undefined";
6432 this.fireEvent("clear");
6437 return this.items[0];
6442 return this.items[this.length-1];
6446 _sort : function(property, dir, fn){
6447 var dsc = String(dir).toUpperCase() == "DESC" ? -1 : 1;
6448 fn = fn || function(a, b){
6451 var c = [], k = this.keys, items = this.items;
6452 for(var i = 0, len = items.length; i < len; i++){
6453 c[c.length] = {key: k[i], value: items[i], index: i};
6455 c.sort(function(a, b){
6456 var v = fn(a[property], b[property]) * dsc;
6458 v = (a.index < b.index ? -1 : 1);
6462 for(var i = 0, len = c.length; i < len; i++){
6463 items[i] = c[i].value;
6466 this.fireEvent("sort", this);
6470 sort : function(dir, fn){
6471 this._sort("value", dir, fn);
6475 keySort : function(dir, fn){
6476 this._sort("key", dir, fn || function(a, b){
6477 return String(a).toUpperCase()-String(b).toUpperCase();
6482 getRange : function(start, end){
6483 var items = this.items;
6484 if(items.length < 1){
6488 end = Math.min(typeof end == "undefined" ? this.length-1 : end, this.length-1);
6491 for(var i = start; i <= end; i++) {
6492 r[r.length] = items[i];
6495 for(var i = start; i >= end; i--) {
6496 r[r.length] = items[i];
6503 filter : function(property, value, anyMatch, caseSensitive){
6504 if(Ext.isEmpty(value, false)){
6505 return this.clone();
6507 value = this.createValueMatcher(value, anyMatch, caseSensitive);
6508 return this.filterBy(function(o){
6509 return o && value.test(o[property]);
6514 filterBy : function(fn, scope){
6515 var r = new Ext.util.MixedCollection();
6516 r.getKey = this.getKey;
6517 var k = this.keys, it = this.items;
6518 for(var i = 0, len = it.length; i < len; i++){
6519 if(fn.call(scope||this, it[i], k[i])){
6527 findIndex : function(property, value, start, anyMatch, caseSensitive){
6528 if(Ext.isEmpty(value, false)){
6531 value = this.createValueMatcher(value, anyMatch, caseSensitive);
6532 return this.findIndexBy(function(o){
6533 return o && value.test(o[property]);
6538 findIndexBy : function(fn, scope, start){
6539 var k = this.keys, it = this.items;
6540 for(var i = (start||0), len = it.length; i < len; i++){
6541 if(fn.call(scope||this, it[i], k[i])){
6545 if(typeof start == 'number' && start > 0){
6546 for(var i = 0; i < start; i++){
6547 if(fn.call(scope||this, it[i], k[i])){
6556 createValueMatcher : function(value, anyMatch, caseSensitive){
6558 value = String(value);
6559 value = new RegExp((anyMatch === true ? '' : '^') + Ext.escapeRe(value), caseSensitive ? '' : 'i');
6566 var r = new Ext.util.MixedCollection();
6567 var k = this.keys, it = this.items;
6568 for(var i = 0, len = it.length; i < len; i++){
6571 r.getKey = this.getKey;
6576 Ext.util.MixedCollection.prototype.get = Ext.util.MixedCollection.prototype.item;
6578 Ext.util.JSON = new (function(){
6579 var useHasOwn = {}.hasOwnProperty ? true : false;
6584 var pad = function(n) {
6585 return n < 10 ? "0" + n : n;
6598 var encodeString = function(s){
6599 if (/["\\\x00-\x1f]/.test(s)) {
6600 return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) {
6607 Math.floor(c / 16).toString(16) +
6608 (c % 16).toString(16);
6611 return '"' + s + '"';
6614 var encodeArray = function(o){
6615 var a = ["["], b, i, l = o.length, v;
6616 for (i = 0; i < l; i += 1) {
6627 a.push(v === null ? "null" : Ext.util.JSON.encode(v));
6635 var encodeDate = function(o){
6636 return '"' + o.getFullYear() + "-" +
6637 pad(o.getMonth() + 1) + "-" +
6638 pad(o.getDate()) + "T" +
6639 pad(o.getHours()) + ":" +
6640 pad(o.getMinutes()) + ":" +
6641 pad(o.getSeconds()) + '"';
6645 this.encode = function(o){
6646 if(typeof o == "undefined" || o === null){
6648 }else if(Ext.isArray(o)){
6649 return encodeArray(o);
6650 }else if(Ext.isDate(o)){
6651 return encodeDate(o);
6652 }else if(typeof o == "string"){
6653 return encodeString(o);
6654 }else if(typeof o == "number"){
6655 return isFinite(o) ? String(o) : "null";
6656 }else if(typeof o == "boolean"){
6659 var a = ["{"], b, i, v;
6661 if(!useHasOwn || o.hasOwnProperty(i)) {
6672 a.push(this.encode(i), ":",
6673 v === null ? "null" : this.encode(v));
6684 this.decode = function(json){
6685 return eval("(" + json + ')');
6689 Ext.encode = Ext.util.JSON.encode;
6691 Ext.decode = Ext.util.JSON.decode;
6694 Ext.util.Format = function(){
6695 var trimRe = /^\s+|\s+$/g;
6698 ellipsis : function(value, len){
6699 if(value && value.length > len){
6700 return value.substr(0, len-3)+"...";
6706 undef : function(value){
6707 return value !== undefined ? value : "";
6711 defaultValue : function(value, defaultValue){
6712 return value !== undefined && value !== '' ? value : defaultValue;
6716 htmlEncode : function(value){
6717 return !value ? value : String(value).replace(/&/g, "&").replace(/>/g, ">").replace(/</g, "<").replace(/"/g, """);
6721 htmlDecode : function(value){
6722 return !value ? value : String(value).replace(/&/g, "&").replace(/>/g, ">").replace(/</g, "<").replace(/"/g, '"');
6726 trim : function(value){
6727 return String(value).replace(trimRe, "");
6731 substr : function(value, start, length){
6732 return String(value).substr(start, length);
6736 lowercase : function(value){
6737 return String(value).toLowerCase();
6741 uppercase : function(value){
6742 return String(value).toUpperCase();
6746 capitalize : function(value){
6747 return !value ? value : value.charAt(0).toUpperCase() + value.substr(1).toLowerCase();
6751 call : function(value, fn){
6752 if(arguments.length > 2){
6753 var args = Array.prototype.slice.call(arguments, 2);
6754 args.unshift(value);
6755 return eval(fn).apply(window, args);
6757 return eval(fn).call(window, value);
6762 usMoney : function(v){
6763 v = (Math.round((v-0)*100))/100;
6764 v = (v == Math.floor(v)) ? v + ".00" : ((v*10 == Math.floor(v*10)) ? v + "0" : v);
6766 var ps = v.split('.');
6768 var sub = ps[1] ? '.'+ ps[1] : '.00';
6769 var r = /(\d+)(\d{3})/;
6770 while (r.test(whole)) {
6771 whole = whole.replace(r, '$1' + ',' + '$2');
6774 if(v.charAt(0) == '-'){
6775 return '-$' + v.substr(1);
6781 date : function(v, format){
6786 v = new Date(Date.parse(v));
6788 return v.dateFormat(format || "m/d/Y");
6792 dateRenderer : function(format){
6794 return Ext.util.Format.date(v, format);
6799 stripTagsRE : /<\/?[^>]+>/gi,
6802 stripTags : function(v){
6803 return !v ? v : String(v).replace(this.stripTagsRE, "");
6806 stripScriptsRe : /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,
6809 stripScripts : function(v){
6810 return !v ? v : String(v).replace(this.stripScriptsRe, "");
6814 fileSize : function(size){
6816 return size + " bytes";
6817 } else if(size < 1048576) {
6818 return (Math.round(((size*10) / 1024))/10) + " KB";
6820 return (Math.round(((size*10) / 1048576))/10) + " MB";
6826 return function(v, a){
6828 fns[a] = new Function('v', 'return v ' + a + ';');
6836 Ext.XTemplate = function(){
6837 Ext.XTemplate.superclass.constructor.apply(this, arguments);
6840 s = ['<tpl>', s, '</tpl>'].join('');
6842 var re = /<tpl\b[^>]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/;
6844 var nameRe = /^<tpl\b[^>]*?for="(.*?)"/;
6845 var ifRe = /^<tpl\b[^>]*?if="(.*?)"/;
6846 var execRe = /^<tpl\b[^>]*?exec="(.*?)"/;
6850 while(m = s.match(re)){
6851 var m2 = m[0].match(nameRe);
6852 var m3 = m[0].match(ifRe);
6853 var m4 = m[0].match(execRe);
6854 var exp = null, fn = null, exec = null;
6855 var name = m2 && m2[1] ? m2[1] : '';
6857 exp = m3 && m3[1] ? m3[1] : null;
6859 fn = new Function('values', 'parent', 'xindex', 'xcount', 'with(values){ return '+(Ext.util.Format.htmlDecode(exp))+'; }');
6863 exp = m4 && m4[1] ? m4[1] : null;
6865 exec = new Function('values', 'parent', 'xindex', 'xcount', 'with(values){ '+(Ext.util.Format.htmlDecode(exp))+'; }');
6870 case '.': name = new Function('values', 'parent', 'with(values){ return values; }'); break;
6871 case '..': name = new Function('values', 'parent', 'with(values){ return parent; }'); break;
6872 default: name = new Function('values', 'parent', 'with(values){ return '+name+'; }');
6882 s = s.replace(m[0], '{xtpl'+ id + '}');
6885 for(var i = tpls.length-1; i >= 0; --i){
6886 this.compileTpl(tpls[i]);
6888 this.master = tpls[tpls.length-1];
6891 Ext.extend(Ext.XTemplate, Ext.Template, {
6893 re : /\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\\]\s?[\d\.\+\-\*\\\(\)]+)?\}/g,
6895 codeRe : /\{\[((?:\\\]|.|\n)*?)\]\}/g,
6898 applySubTemplate : function(id, values, parent, xindex, xcount){
6899 var t = this.tpls[id];
6900 if(t.test && !t.test.call(this, values, parent, xindex, xcount)){
6903 if(t.exec && t.exec.call(this, values, parent, xindex, xcount)){
6906 var vs = t.target ? t.target.call(this, values, parent) : values;
6907 parent = t.target ? values : parent;
6908 if(t.target && Ext.isArray(vs)){
6910 for(var i = 0, len = vs.length; i < len; i++){
6911 buf[buf.length] = t.compiled.call(this, vs[i], parent, i+1, len);
6913 return buf.join('');
6915 return t.compiled.call(this, vs, parent, xindex, xcount);
6919 compileTpl : function(tpl){
6920 var fm = Ext.util.Format;
6921 var useF = this.disableFormats !== true;
6922 var sep = Ext.isGecko ? "+" : ",";
6923 var fn = function(m, name, format, args, math){
6924 if(name.substr(0, 4) == 'xtpl'){
6925 return "'"+ sep +'this.applySubTemplate('+name.substr(4)+', values, parent, xindex, xcount)'+sep+"'";
6930 }else if(name === '#'){
6932 }else if(name.indexOf('.') != -1){
6935 v = "values['" + name + "']";
6938 v = '(' + v + math + ')';
6941 args = args ? ',' + args : "";
6942 if(format.substr(0, 5) != "this."){
6943 format = "fm." + format + '(';
6945 format = 'this.call("'+ format.substr(5) + '", ';
6949 args= ''; format = "("+v+" === undefined ? '' : ";
6951 return "'"+ sep + format + v + args + ")"+sep+"'";
6953 var codeFn = function(m, code){
6954 return "'"+ sep +'('+code+')'+sep+"'";
6960 body = "tpl.compiled = function(values, parent, xindex, xcount){ return '" +
6961 tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn) +
6964 body = ["tpl.compiled = function(values, parent, xindex, xcount){ return ['"];
6965 body.push(tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn));
6966 body.push("'].join('');};");
6967 body = body.join('');
6974 apply : function(values){
6975 return this.master.compiled.call(this, values, {}, 1, 1);
6979 applyTemplate : function(values){
6980 return this.master.compiled.call(this, values, {}, 1, 1);
6984 compile : function(){return this;}
6993 Ext.XTemplate.from = function(el){
6994 el = Ext.getDom(el);
6995 return new Ext.XTemplate(el.value || el.innerHTML);
6998 Ext.util.CSS = function(){
7002 var camelRe = /(-[a-z])/gi;
7003 var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };
7007 createStyleSheet : function(cssText, id){
7009 var head = doc.getElementsByTagName("head")[0];
7010 var rules = doc.createElement("style");
7011 rules.setAttribute("type", "text/css");
7013 rules.setAttribute("id", id);
7016 head.appendChild(rules);
7017 ss = rules.styleSheet;
7018 ss.cssText = cssText;
7021 rules.appendChild(doc.createTextNode(cssText));
7023 rules.cssText = cssText;
7025 head.appendChild(rules);
7026 ss = rules.styleSheet ? rules.styleSheet : (rules.sheet || doc.styleSheets[doc.styleSheets.length-1]);
7028 this.cacheStyleSheet(ss);
7033 removeStyleSheet : function(id){
7034 var existing = doc.getElementById(id);
7036 existing.parentNode.removeChild(existing);
7041 swapStyleSheet : function(id, url){
7042 this.removeStyleSheet(id);
7043 var ss = doc.createElement("link");
7044 ss.setAttribute("rel", "stylesheet");
7045 ss.setAttribute("type", "text/css");
7046 ss.setAttribute("id", id);
7047 ss.setAttribute("href", url);
7048 doc.getElementsByTagName("head")[0].appendChild(ss);
7052 refreshCache : function(){
7053 return this.getRules(true);
7057 cacheStyleSheet : function(ss){
7062 var ssRules = ss.cssRules || ss.rules;
7063 for(var j = ssRules.length-1; j >= 0; --j){
7064 rules[ssRules[j].selectorText] = ssRules[j];
7070 getRules : function(refreshCache){
7071 if(rules == null || refreshCache){
7073 var ds = doc.styleSheets;
7074 for(var i =0, len = ds.length; i < len; i++){
7076 this.cacheStyleSheet(ds[i]);
7084 getRule : function(selector, refreshCache){
7085 var rs = this.getRules(refreshCache);
7086 if(!Ext.isArray(selector)){
7087 return rs[selector];
7089 for(var i = 0; i < selector.length; i++){
7090 if(rs[selector[i]]){
7091 return rs[selector[i]];
7099 updateRule : function(selector, property, value){
7100 if(!Ext.isArray(selector)){
7101 var rule = this.getRule(selector);
7103 rule.style[property.replace(camelRe, camelFn)] = value;
7107 for(var i = 0; i < selector.length; i++){
7108 if(this.updateRule(selector[i], property, value)){
7118 Ext.util.ClickRepeater = function(el, config)
7120 this.el = Ext.get(el);
7121 this.el.unselectable();
7123 Ext.apply(this, config);
7134 this.el.on("mousedown", this.handleMouseDown, this);
7135 if(this.preventDefault || this.stopDefault){
7136 this.el.on("click", function(e){
7137 if(this.preventDefault){
7140 if(this.stopDefault){
7147 this.on("click", this.handler, this.scope || this);
7150 Ext.util.ClickRepeater.superclass.constructor.call(this);
7153 Ext.extend(Ext.util.ClickRepeater, Ext.util.Observable, {
7156 preventDefault : true,
7157 stopDefault : false,
7160 handleMouseDown : function(){
7161 clearTimeout(this.timer);
7163 if(this.pressClass){
7164 this.el.addClass(this.pressClass);
7166 this.mousedownTime = new Date();
7168 Ext.getDoc().on("mouseup", this.handleMouseUp, this);
7169 this.el.on("mouseout", this.handleMouseOut, this);
7171 this.fireEvent("mousedown", this);
7172 this.fireEvent("click", this);
7174 if (this.accelerate) {
7177 this.timer = this.click.defer(this.delay || this.interval, this);
7181 this.fireEvent("click", this);
7182 this.timer = this.click.defer(this.accelerate ?
7183 this.easeOutExpo(this.mousedownTime.getElapsed(),
7187 this.interval, this);
7190 easeOutExpo : function (t, b, c, d) {
7191 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
7194 handleMouseOut : function(){
7195 clearTimeout(this.timer);
7196 if(this.pressClass){
7197 this.el.removeClass(this.pressClass);
7199 this.el.on("mouseover", this.handleMouseReturn, this);
7202 handleMouseReturn : function(){
7203 this.el.un("mouseover", this.handleMouseReturn);
7204 if(this.pressClass){
7205 this.el.addClass(this.pressClass);
7210 handleMouseUp : function(){
7211 clearTimeout(this.timer);
7212 this.el.un("mouseover", this.handleMouseReturn);
7213 this.el.un("mouseout", this.handleMouseOut);
7214 Ext.getDoc().un("mouseup", this.handleMouseUp);
7215 this.el.removeClass(this.pressClass);
7216 this.fireEvent("mouseup", this);
7220 Ext.KeyNav = function(el, config){
7221 this.el = Ext.get(el);
7222 Ext.apply(this, config);
7224 this.disabled = true;
7229 Ext.KeyNav.prototype = {
7233 defaultEventAction: "stopEvent",
7235 forceKeyDown : false,
7237 prepareEvent : function(e){
7239 var h = this.keyToHandler[k];
7240 if(Ext.isSafari && h && k >= 37 && k <= 40){
7245 relay : function(e){
7247 var h = this.keyToHandler[k];
7249 if(this.doRelay(e, this[h], h) !== true){
7250 e[this.defaultEventAction]();
7255 doRelay : function(e, h, hname){
7256 return h.call(this.scope || this, e);
7290 if(this.forceKeyDown || Ext.isIE || Ext.isAir){
7291 this.el.on("keydown", this.relay, this);
7293 this.el.on("keydown", this.prepareEvent, this);
7294 this.el.on("keypress", this.relay, this);
7296 this.disabled = false;
7301 disable: function(){
7303 if(this.forceKeyDown || Ext.isIE || Ext.isAir){
7304 this.el.un("keydown", this.relay);
7306 this.el.un("keydown", this.prepareEvent);
7307 this.el.un("keypress", this.relay);
7309 this.disabled = true;
7314 Ext.KeyMap = function(el, config, eventName){
7315 this.el = Ext.get(el);
7316 this.eventName = eventName || "keydown";
7319 this.addBinding(config);
7324 Ext.KeyMap.prototype = {
7329 addBinding : function(config){
7330 if(Ext.isArray(config)){
7331 for(var i = 0, len = config.length; i < len; i++){
7332 this.addBinding(config[i]);
7336 var keyCode = config.key,
7337 shift = config.shift,
7340 fn = config.fn || config.handler,
7341 scope = config.scope;
7343 if(typeof keyCode == "string"){
7345 var keyString = keyCode.toUpperCase();
7346 for(var j = 0, len = keyString.length; j < len; j++){
7347 ks.push(keyString.charCodeAt(j));
7351 var keyArray = Ext.isArray(keyCode);
7353 var handler = function(e){
7354 if((!shift || e.shiftKey) && (!ctrl || e.ctrlKey) && (!alt || e.altKey)){
7357 for(var i = 0, len = keyCode.length; i < len; i++){
7358 if(keyCode[i] == k){
7362 fn.call(scope || window, k, e);
7371 fn.call(scope || window, k, e);
7376 this.bindings.push(handler);
7380 on : function(key, fn, scope){
7381 var keyCode, shift, ctrl, alt;
7382 if(typeof key == "object" && !Ext.isArray(key)){
7401 handleKeyDown : function(e){
7403 var b = this.bindings;
7404 for(var i = 0, len = b.length; i < len; i++){
7411 isEnabled : function(){
7412 return this.enabled;
7418 this.el.on(this.eventName, this.handleKeyDown, this);
7419 this.enabled = true;
7424 disable: function(){
7426 this.el.removeListener(this.eventName, this.handleKeyDown, this);
7427 this.enabled = false;
7432 Ext.util.TextMetrics = function(){
7436 measure : function(el, text, fixedWidth){
7438 shared = Ext.util.TextMetrics.Instance(el, fixedWidth);
7441 shared.setFixedWidth(fixedWidth || 'auto');
7442 return shared.getSize(text);
7446 createInstance : function(el, fixedWidth){
7447 return Ext.util.TextMetrics.Instance(el, fixedWidth);
7452 Ext.util.TextMetrics.Instance = function(bindTo, fixedWidth){
7453 var ml = new Ext.Element(document.createElement('div'));
7454 document.body.appendChild(ml.dom);
7455 ml.position('absolute');
7456 ml.setLeftTop(-1000, -1000);
7460 ml.setWidth(fixedWidth);
7465 getSize : function(text){
7467 var s = ml.getSize();
7473 bind : function(el){
7475 Ext.fly(el).getStyles('font-size','font-style', 'font-weight', 'font-family','line-height')
7480 setFixedWidth : function(width){
7485 getWidth : function(text){
7486 ml.dom.style.width = 'auto';
7487 return this.getSize(text).width;
7491 getHeight : function(text){
7492 return this.getSize(text).height;
7496 instance.bind(bindTo);
7501 Ext.Element.measureText = Ext.util.TextMetrics.measure;
7506 var Event=Ext.EventManager;
7507 var Dom=Ext.lib.Dom;
7510 Ext.dd.DragDrop = function(id, sGroup, config) {
7512 this.init(id, sGroup, config);
7516 Ext.dd.DragDrop.prototype = {
7531 invalidHandleTypes: null,
7534 invalidHandleIds: null,
7537 invalidHandleClasses: null,
7552 lock: function() { this.locked = true; },
7555 unlock: function() { this.locked = false; },
7588 maintainOffset: false,
7597 primaryButtonOnly: true,
7603 hasOuterHandles: false,
7606 b4StartDrag: function(x, y) { },
7609 startDrag: function(x, y) { },
7612 b4Drag: function(e) { },
7615 onDrag: function(e) { },
7618 onDragEnter: function(e, id) { },
7621 b4DragOver: function(e) { },
7624 onDragOver: function(e, id) { },
7627 b4DragOut: function(e) { },
7630 onDragOut: function(e, id) { },
7633 b4DragDrop: function(e) { },
7636 onDragDrop: function(e, id) { },
7639 onInvalidDrop: function(e) { },
7642 b4EndDrag: function(e) { },
7645 endDrag: function(e) { },
7648 b4MouseDown: function(e) { },
7651 onMouseDown: function(e) { },
7654 onMouseUp: function(e) { },
7657 onAvailable: function () {
7661 defaultPadding : {left:0, right:0, top:0, bottom:0},
7664 constrainTo : function(constrainTo, pad, inContent){
7665 if(typeof pad == "number"){
7666 pad = {left: pad, right:pad, top:pad, bottom:pad};
7668 pad = pad || this.defaultPadding;
7669 var b = Ext.get(this.getEl()).getBox();
7670 var ce = Ext.get(constrainTo);
7671 var s = ce.getScroll();
7673 if(cd == document.body){
7674 c = { x: s.left, y: s.top, width: Ext.lib.Dom.getViewWidth(), height: Ext.lib.Dom.getViewHeight()};
7676 var xy = ce.getXY();
7677 c = {x : xy[0]+s.left, y: xy[1]+s.top, width: cd.clientWidth, height: cd.clientHeight};
7681 var topSpace = b.y - c.y;
7682 var leftSpace = b.x - c.x;
7684 this.resetConstraints();
7685 this.setXConstraint(leftSpace - (pad.left||0),
7686 c.width - leftSpace - b.width - (pad.right||0),
7689 this.setYConstraint(topSpace - (pad.top||0),
7690 c.height - topSpace - b.height - (pad.bottom||0),
7697 if (!this._domRef) {
7698 this._domRef = Ext.getDom(this.id);
7701 return this._domRef;
7705 getDragEl: function() {
7706 return Ext.getDom(this.dragElId);
7710 init: function(id, sGroup, config) {
7711 this.initTarget(id, sGroup, config);
7712 Event.on(this.id, "mousedown", this.handleMouseDown, this);
7717 initTarget: function(id, sGroup, config) {
7720 this.config = config || {};
7723 this.DDM = Ext.dd.DDM;
7729 if (typeof id !== "string") {
7737 this.addToGroup((sGroup) ? sGroup : "default");
7741 this.handleElId = id;
7744 this.setDragElId(id);
7747 this.invalidHandleTypes = { A: "A" };
7748 this.invalidHandleIds = {};
7749 this.invalidHandleClasses = [];
7753 this.handleOnAvailable();
7757 applyConfig: function() {
7761 this.padding = this.config.padding || [0, 0, 0, 0];
7762 this.isTarget = (this.config.isTarget !== false);
7763 this.maintainOffset = (this.config.maintainOffset);
7764 this.primaryButtonOnly = (this.config.primaryButtonOnly !== false);
7769 handleOnAvailable: function() {
7770 this.available = true;
7771 this.resetConstraints();
7776 setPadding: function(iTop, iRight, iBot, iLeft) {
7778 if (!iRight && 0 !== iRight) {
7779 this.padding = [iTop, iTop, iTop, iTop];
7780 } else if (!iBot && 0 !== iBot) {
7781 this.padding = [iTop, iRight, iTop, iRight];
7783 this.padding = [iTop, iRight, iBot, iLeft];
7788 setInitPosition: function(diffX, diffY) {
7789 var el = this.getEl();
7791 if (!this.DDM.verifyEl(el)) {
7795 var dx = diffX || 0;
7796 var dy = diffY || 0;
7798 var p = Dom.getXY( el );
7800 this.initPageX = p[0] - dx;
7801 this.initPageY = p[1] - dy;
7803 this.lastPageX = p[0];
7804 this.lastPageY = p[1];
7807 this.setStartPosition(p);
7811 setStartPosition: function(pos) {
7812 var p = pos || Dom.getXY( this.getEl() );
7813 this.deltaSetXY = null;
7815 this.startPageX = p[0];
7816 this.startPageY = p[1];
7820 addToGroup: function(sGroup) {
7821 this.groups[sGroup] = true;
7822 this.DDM.regDragDrop(this, sGroup);
7826 removeFromGroup: function(sGroup) {
7827 if (this.groups[sGroup]) {
7828 delete this.groups[sGroup];
7831 this.DDM.removeDDFromGroup(this, sGroup);
7835 setDragElId: function(id) {
7840 setHandleElId: function(id) {
7841 if (typeof id !== "string") {
7844 this.handleElId = id;
7845 this.DDM.regHandle(this.id, id);
7849 setOuterHandleElId: function(id) {
7850 if (typeof id !== "string") {
7853 Event.on(id, "mousedown",
7854 this.handleMouseDown, this);
7855 this.setHandleElId(id);
7857 this.hasOuterHandles = true;
7862 Event.un(this.id, "mousedown",
7863 this.handleMouseDown);
7864 this._domRef = null;
7865 this.DDM._remove(this);
7868 destroy : function(){
7873 isLocked: function() {
7874 return (this.DDM.isLocked() || this.locked);
7878 handleMouseDown: function(e, oDD){
7879 if (this.primaryButtonOnly && e.button != 0) {
7883 if (this.isLocked()) {
7887 this.DDM.refreshCache(this.groups);
7889 var pt = new Ext.lib.Point(Ext.lib.Event.getPageX(e), Ext.lib.Event.getPageY(e));
7890 if (!this.hasOuterHandles && !this.DDM.isOverTarget(pt, this) ) {
7892 if (this.clickValidator(e)) {
7895 this.setStartPosition();
7898 this.b4MouseDown(e);
7899 this.onMouseDown(e);
7901 this.DDM.handleMouseDown(e, this);
7903 this.DDM.stopEvent(e);
7911 clickValidator: function(e) {
7912 var target = e.getTarget();
7913 return ( this.isValidHandleChild(target) &&
7914 (this.id == this.handleElId ||
7915 this.DDM.handleWasClicked(target, this.id)) );
7919 addInvalidHandleType: function(tagName) {
7920 var type = tagName.toUpperCase();
7921 this.invalidHandleTypes[type] = type;
7925 addInvalidHandleId: function(id) {
7926 if (typeof id !== "string") {
7929 this.invalidHandleIds[id] = id;
7933 addInvalidHandleClass: function(cssClass) {
7934 this.invalidHandleClasses.push(cssClass);
7938 removeInvalidHandleType: function(tagName) {
7939 var type = tagName.toUpperCase();
7941 delete this.invalidHandleTypes[type];
7945 removeInvalidHandleId: function(id) {
7946 if (typeof id !== "string") {
7949 delete this.invalidHandleIds[id];
7953 removeInvalidHandleClass: function(cssClass) {
7954 for (var i=0, len=this.invalidHandleClasses.length; i<len; ++i) {
7955 if (this.invalidHandleClasses[i] == cssClass) {
7956 delete this.invalidHandleClasses[i];
7962 isValidHandleChild: function(node) {
7968 nodeName = node.nodeName.toUpperCase();
7970 nodeName = node.nodeName;
7972 valid = valid && !this.invalidHandleTypes[nodeName];
7973 valid = valid && !this.invalidHandleIds[node.id];
7975 for (var i=0, len=this.invalidHandleClasses.length; valid && i<len; ++i) {
7976 valid = !Dom.hasClass(node, this.invalidHandleClasses[i]);
7985 setXTicks: function(iStartX, iTickSize) {
7987 this.xTickSize = iTickSize;
7991 for (var i = this.initPageX; i >= this.minX; i = i - iTickSize) {
7993 this.xTicks[this.xTicks.length] = i;
7998 for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) {
8000 this.xTicks[this.xTicks.length] = i;
8005 this.xTicks.sort(this.DDM.numericSort) ;
8009 setYTicks: function(iStartY, iTickSize) {
8011 this.yTickSize = iTickSize;
8015 for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) {
8017 this.yTicks[this.yTicks.length] = i;
8022 for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) {
8024 this.yTicks[this.yTicks.length] = i;
8029 this.yTicks.sort(this.DDM.numericSort) ;
8033 setXConstraint: function(iLeft, iRight, iTickSize) {
8034 this.leftConstraint = iLeft;
8035 this.rightConstraint = iRight;
8037 this.minX = this.initPageX - iLeft;
8038 this.maxX = this.initPageX + iRight;
8039 if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); }
8041 this.constrainX = true;
8045 clearConstraints: function() {
8046 this.constrainX = false;
8047 this.constrainY = false;
8052 clearTicks: function() {
8060 setYConstraint: function(iUp, iDown, iTickSize) {
8061 this.topConstraint = iUp;
8062 this.bottomConstraint = iDown;
8064 this.minY = this.initPageY - iUp;
8065 this.maxY = this.initPageY + iDown;
8066 if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); }
8068 this.constrainY = true;
8073 resetConstraints: function() {
8077 if (this.initPageX || this.initPageX === 0) {
8079 var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0;
8080 var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0;
8082 this.setInitPosition(dx, dy);
8086 this.setInitPosition();
8089 if (this.constrainX) {
8090 this.setXConstraint( this.leftConstraint,
8091 this.rightConstraint,
8095 if (this.constrainY) {
8096 this.setYConstraint( this.topConstraint,
8097 this.bottomConstraint,
8103 getTick: function(val, tickArray) {
8109 } else if (tickArray[0] >= val) {
8112 return tickArray[0];
8114 for (var i=0, len=tickArray.length; i<len; ++i) {
8116 if (tickArray[next] && tickArray[next] >= val) {
8117 var diff1 = val - tickArray[i];
8118 var diff2 = tickArray[next] - val;
8119 return (diff2 > diff1) ? tickArray[i] : tickArray[next];
8125 return tickArray[tickArray.length - 1];
8130 toString: function() {
8131 return ("DragDrop " + this.id);
8141 if (!Ext.dd.DragDropMgr) {
8144 Ext.dd.DragDropMgr = function() {
8146 var Event = Ext.EventManager;
8169 preventDefault: true,
8172 stopPropagation: true,
8182 this.initialized = true;
8195 _execOnAll: function(sMethod, args) {
8196 for (var i in this.ids) {
8197 for (var j in this.ids[i]) {
8198 var oDD = this.ids[i][j];
8199 if (! this.isTypeOfDD(oDD)) {
8202 oDD[sMethod].apply(oDD, args);
8208 _onLoad: function() {
8213 Event.on(document, "mouseup", this.handleMouseUp, this, true);
8214 Event.on(document, "mousemove", this.handleMouseMove, this, true);
8215 Event.on(window, "unload", this._onUnload, this, true);
8216 Event.on(window, "resize", this._onResize, this, true);
8222 _onResize: function(e) {
8223 this._execOnAll("resetConstraints", []);
8227 lock: function() { this.locked = true; },
8230 unlock: function() { this.locked = false; },
8233 isLocked: function() { return this.locked; },
8242 clickPixelThresh: 3,
8245 clickTimeThresh: 350,
8248 dragThreshMet: false,
8260 regDragDrop: function(oDD, sGroup) {
8261 if (!this.initialized) { this.init(); }
8263 if (!this.ids[sGroup]) {
8264 this.ids[sGroup] = {};
8266 this.ids[sGroup][oDD.id] = oDD;
8270 removeDDFromGroup: function(oDD, sGroup) {
8271 if (!this.ids[sGroup]) {
8272 this.ids[sGroup] = {};
8275 var obj = this.ids[sGroup];
8276 if (obj && obj[oDD.id]) {
8282 _remove: function(oDD) {
8283 for (var g in oDD.groups) {
8284 if (g && this.ids[g][oDD.id]) {
8285 delete this.ids[g][oDD.id];
8288 delete this.handleIds[oDD.id];
8292 regHandle: function(sDDId, sHandleId) {
8293 if (!this.handleIds[sDDId]) {
8294 this.handleIds[sDDId] = {};
8296 this.handleIds[sDDId][sHandleId] = sHandleId;
8300 isDragDrop: function(id) {
8301 return ( this.getDDById(id) ) ? true : false;
8305 getRelated: function(p_oDD, bTargetsOnly) {
8307 for (var i in p_oDD.groups) {
8308 for (j in this.ids[i]) {
8309 var dd = this.ids[i][j];
8310 if (! this.isTypeOfDD(dd)) {
8313 if (!bTargetsOnly || dd.isTarget) {
8314 oDDs[oDDs.length] = dd;
8323 isLegalTarget: function (oDD, oTargetDD) {
8324 var targets = this.getRelated(oDD, true);
8325 for (var i=0, len=targets.length;i<len;++i) {
8326 if (targets[i].id == oTargetDD.id) {
8335 isTypeOfDD: function (oDD) {
8336 return (oDD && oDD.__ygDragDrop);
8340 isHandle: function(sDDId, sHandleId) {
8341 return ( this.handleIds[sDDId] &&
8342 this.handleIds[sDDId][sHandleId] );
8346 getDDById: function(id) {
8347 for (var i in this.ids) {
8348 if (this.ids[i][id]) {
8349 return this.ids[i][id];
8356 handleMouseDown: function(e, oDD) {
8358 Ext.QuickTips.disable();
8360 this.currentTarget = e.getTarget();
8362 this.dragCurrent = oDD;
8364 var el = oDD.getEl();
8367 this.startX = e.getPageX();
8368 this.startY = e.getPageY();
8370 this.deltaX = this.startX - el.offsetLeft;
8371 this.deltaY = this.startY - el.offsetTop;
8373 this.dragThreshMet = false;
8375 this.clickTimeout = setTimeout(
8377 var DDM = Ext.dd.DDM;
8378 DDM.startDrag(DDM.startX, DDM.startY);
8380 this.clickTimeThresh );
8384 startDrag: function(x, y) {
8385 clearTimeout(this.clickTimeout);
8386 if (this.dragCurrent) {
8387 this.dragCurrent.b4StartDrag(x, y);
8388 this.dragCurrent.startDrag(x, y);
8390 this.dragThreshMet = true;
8394 handleMouseUp: function(e) {
8397 Ext.QuickTips.enable();
8399 if (! this.dragCurrent) {
8403 clearTimeout(this.clickTimeout);
8405 if (this.dragThreshMet) {
8406 this.fireEvents(e, true);
8416 stopEvent: function(e){
8417 if(this.stopPropagation) {
8418 e.stopPropagation();
8421 if (this.preventDefault) {
8427 stopDrag: function(e) {
8429 if (this.dragCurrent) {
8430 if (this.dragThreshMet) {
8431 this.dragCurrent.b4EndDrag(e);
8432 this.dragCurrent.endDrag(e);
8435 this.dragCurrent.onMouseUp(e);
8438 this.dragCurrent = null;
8439 this.dragOvers = {};
8443 handleMouseMove: function(e) {
8444 if (! this.dragCurrent) {
8451 if (Ext.isIE && (e.button !== 0 && e.button !== 1 && e.button !== 2)) {
8453 return this.handleMouseUp(e);
8456 if (!this.dragThreshMet) {
8457 var diffX = Math.abs(this.startX - e.getPageX());
8458 var diffY = Math.abs(this.startY - e.getPageY());
8459 if (diffX > this.clickPixelThresh ||
8460 diffY > this.clickPixelThresh) {
8461 this.startDrag(this.startX, this.startY);
8465 if (this.dragThreshMet) {
8466 this.dragCurrent.b4Drag(e);
8467 this.dragCurrent.onDrag(e);
8468 if(!this.dragCurrent.moveOnly){
8469 this.fireEvents(e, false);
8479 fireEvents: function(e, isDrop) {
8480 var dc = this.dragCurrent;
8484 if (!dc || dc.isLocked()) {
8488 var pt = e.getPoint();
8500 for (var i in this.dragOvers) {
8502 var ddo = this.dragOvers[i];
8504 if (! this.isTypeOfDD(ddo)) {
8508 if (! this.isOverTarget(pt, ddo, this.mode)) {
8509 outEvts.push( ddo );
8513 delete this.dragOvers[i];
8516 for (var sGroup in dc.groups) {
8518 if ("string" != typeof sGroup) {
8522 for (i in this.ids[sGroup]) {
8523 var oDD = this.ids[sGroup][i];
8524 if (! this.isTypeOfDD(oDD)) {
8528 if (oDD.isTarget && !oDD.isLocked() && oDD != dc) {
8529 if (this.isOverTarget(pt, oDD, this.mode)) {
8532 dropEvts.push( oDD );
8537 if (!oldOvers[oDD.id]) {
8538 enterEvts.push( oDD );
8541 overEvts.push( oDD );
8544 this.dragOvers[oDD.id] = oDD;
8552 if (outEvts.length) {
8553 dc.b4DragOut(e, outEvts);
8554 dc.onDragOut(e, outEvts);
8557 if (enterEvts.length) {
8558 dc.onDragEnter(e, enterEvts);
8561 if (overEvts.length) {
8562 dc.b4DragOver(e, overEvts);
8563 dc.onDragOver(e, overEvts);
8566 if (dropEvts.length) {
8567 dc.b4DragDrop(e, dropEvts);
8568 dc.onDragDrop(e, dropEvts);
8574 for (i=0, len=outEvts.length; i<len; ++i) {
8575 dc.b4DragOut(e, outEvts[i].id);
8576 dc.onDragOut(e, outEvts[i].id);
8580 for (i=0,len=enterEvts.length; i<len; ++i) {
8582 dc.onDragEnter(e, enterEvts[i].id);
8586 for (i=0,len=overEvts.length; i<len; ++i) {
8587 dc.b4DragOver(e, overEvts[i].id);
8588 dc.onDragOver(e, overEvts[i].id);
8592 for (i=0, len=dropEvts.length; i<len; ++i) {
8593 dc.b4DragDrop(e, dropEvts[i].id);
8594 dc.onDragDrop(e, dropEvts[i].id);
8600 if (isDrop && !dropEvts.length) {
8601 dc.onInvalidDrop(e);
8607 getBestMatch: function(dds) {
8615 var len = dds.length;
8621 for (var i=0; i<len; ++i) {
8626 if (dd.cursorIsOver) {
8632 winner.overlap.getArea() < dd.overlap.getArea()) {
8643 refreshCache: function(groups) {
8644 for (var sGroup in groups) {
8645 if ("string" != typeof sGroup) {
8648 for (var i in this.ids[sGroup]) {
8649 var oDD = this.ids[sGroup][i];
8651 if (this.isTypeOfDD(oDD)) {
8653 var loc = this.getLocation(oDD);
8655 this.locationCache[oDD.id] = loc;
8657 delete this.locationCache[oDD.id];
8668 verifyEl: function(el) {
8673 parent = el.offsetParent;
8676 parent = el.offsetParent;
8687 getLocation: function(oDD) {
8688 if (! this.isTypeOfDD(oDD)) {
8692 var el = oDD.getEl(), pos, x1, x2, y1, y2, t, r, b, l;
8695 pos= Ext.lib.Dom.getXY(el);
8703 x2 = x1 + el.offsetWidth;
8705 y2 = y1 + el.offsetHeight;
8707 t = y1 - oDD.padding[0];
8708 r = x2 + oDD.padding[1];
8709 b = y2 + oDD.padding[2];
8710 l = x1 - oDD.padding[3];
8712 return new Ext.lib.Region( t, r, b, l );
8716 isOverTarget: function(pt, oTarget, intersect) {
8718 var loc = this.locationCache[oTarget.id];
8719 if (!loc || !this.useCache) {
8720 loc = this.getLocation(oTarget);
8721 this.locationCache[oTarget.id] = loc;
8729 oTarget.cursorIsOver = loc.contains( pt );
8736 var dc = this.dragCurrent;
8737 if (!dc || !dc.getTargetCoord ||
8738 (!intersect && !dc.constrainX && !dc.constrainY)) {
8739 return oTarget.cursorIsOver;
8742 oTarget.overlap = null;
8748 var pos = dc.getTargetCoord(pt.x, pt.y);
8750 var el = dc.getDragEl();
8751 var curRegion = new Ext.lib.Region( pos.y,
8752 pos.x + el.offsetWidth,
8753 pos.y + el.offsetHeight,
8756 var overlap = curRegion.intersect(loc);
8759 oTarget.overlap = overlap;
8760 return (intersect) ? true : oTarget.cursorIsOver;
8767 _onUnload: function(e, me) {
8768 Ext.dd.DragDropMgr.unregAll();
8772 unregAll: function() {
8774 if (this.dragCurrent) {
8776 this.dragCurrent = null;
8779 this._execOnAll("unreg", []);
8781 for (var i in this.elementCache) {
8782 delete this.elementCache[i];
8785 this.elementCache = {};
8793 getElWrapper: function(id) {
8794 var oWrapper = this.elementCache[id];
8795 if (!oWrapper || !oWrapper.el) {
8796 oWrapper = this.elementCache[id] =
8797 new this.ElementWrapper(Ext.getDom(id));
8803 getElement: function(id) {
8804 return Ext.getDom(id);
8808 getCss: function(id) {
8809 var el = Ext.getDom(id);
8810 return (el) ? el.style : null;
8814 ElementWrapper: function(el) {
8816 this.el = el || null;
8818 this.id = this.el && el.id;
8820 this.css = this.el && el.style;
8824 getPosX: function(el) {
8825 return Ext.lib.Dom.getX(el);
8829 getPosY: function(el) {
8830 return Ext.lib.Dom.getY(el);
8834 swapNode: function(n1, n2) {
8838 var p = n2.parentNode;
8839 var s = n2.nextSibling;
8842 p.insertBefore(n1, n2);
8843 } else if (n2 == n1.nextSibling) {
8844 p.insertBefore(n2, n1);
8846 n1.parentNode.replaceChild(n2, n1);
8847 p.insertBefore(n1, s);
8853 getScroll: function () {
8854 var t, l, dde=document.documentElement, db=document.body;
8855 if (dde && (dde.scrollTop || dde.scrollLeft)) {
8864 return { top: t, left: l };
8868 getStyle: function(el, styleProp) {
8869 return Ext.fly(el).getStyle(styleProp);
8873 getScrollTop: function () { return this.getScroll().top; },
8876 getScrollLeft: function () { return this.getScroll().left; },
8879 moveToEl: function (moveEl, targetEl) {
8880 var aCoord = Ext.lib.Dom.getXY(targetEl);
8881 Ext.lib.Dom.setXY(moveEl, aCoord);
8885 numericSort: function(a, b) { return (a - b); },
8891 _addListeners: function() {
8892 var DDM = Ext.dd.DDM;
8893 if ( Ext.lib.Event && document ) {
8896 if (DDM._timeoutCount > 2000) {
8898 setTimeout(DDM._addListeners, 10);
8899 if (document && document.body) {
8900 DDM._timeoutCount += 1;
8907 handleWasClicked: function(node, id) {
8908 if (this.isHandle(id, node.id)) {
8912 var p = node.parentNode;
8915 if (this.isHandle(id, p.id)) {
8931 Ext.dd.DDM = Ext.dd.DragDropMgr;
8932 Ext.dd.DDM._addListeners();
8937 Ext.dd.DD = function(id, sGroup, config) {
8939 this.init(id, sGroup, config);
8943 Ext.extend(Ext.dd.DD, Ext.dd.DragDrop, {
8949 autoOffset: function(iPageX, iPageY) {
8950 var x = iPageX - this.startPageX;
8951 var y = iPageY - this.startPageY;
8952 this.setDelta(x, y);
8956 setDelta: function(iDeltaX, iDeltaY) {
8957 this.deltaX = iDeltaX;
8958 this.deltaY = iDeltaY;
8962 setDragElPos: function(iPageX, iPageY) {
8966 var el = this.getDragEl();
8967 this.alignElWithMouse(el, iPageX, iPageY);
8971 alignElWithMouse: function(el, iPageX, iPageY) {
8972 var oCoord = this.getTargetCoord(iPageX, iPageY);
8973 var fly = el.dom ? el : Ext.fly(el, '_dd');
8974 if (!this.deltaSetXY) {
8975 var aCoord = [oCoord.x, oCoord.y];
8977 var newLeft = fly.getLeft(true);
8978 var newTop = fly.getTop(true);
8979 this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ];
8981 fly.setLeftTop(oCoord.x + this.deltaSetXY[0], oCoord.y + this.deltaSetXY[1]);
8984 this.cachePosition(oCoord.x, oCoord.y);
8985 this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
8990 cachePosition: function(iPageX, iPageY) {
8992 this.lastPageX = iPageX;
8993 this.lastPageY = iPageY;
8995 var aCoord = Ext.lib.Dom.getXY(this.getEl());
8996 this.lastPageX = aCoord[0];
8997 this.lastPageY = aCoord[1];
9002 autoScroll: function(x, y, h, w) {
9006 var clientH = Ext.lib.Dom.getViewHeight();
9009 var clientW = Ext.lib.Dom.getViewWidth();
9012 var st = this.DDM.getScrollTop();
9015 var sl = this.DDM.getScrollLeft();
9026 var toBot = (clientH + st - y - this.deltaY);
9029 var toRight = (clientW + sl - x - this.deltaX);
9039 var scrAmt = (document.all) ? 80 : 30;
9043 if ( bot > clientH && toBot < thresh ) {
9044 window.scrollTo(sl, st + scrAmt);
9049 if ( y < st && st > 0 && y - st < thresh ) {
9050 window.scrollTo(sl, st - scrAmt);
9055 if ( right > clientW && toRight < thresh ) {
9056 window.scrollTo(sl + scrAmt, st);
9061 if ( x < sl && sl > 0 && x - sl < thresh ) {
9062 window.scrollTo(sl - scrAmt, st);
9068 getTargetCoord: function(iPageX, iPageY) {
9071 var x = iPageX - this.deltaX;
9072 var y = iPageY - this.deltaY;
9074 if (this.constrainX) {
9075 if (x < this.minX) { x = this.minX; }
9076 if (x > this.maxX) { x = this.maxX; }
9079 if (this.constrainY) {
9080 if (y < this.minY) { y = this.minY; }
9081 if (y > this.maxY) { y = this.maxY; }
9084 x = this.getTick(x, this.xTicks);
9085 y = this.getTick(y, this.yTicks);
9092 applyConfig: function() {
9093 Ext.dd.DD.superclass.applyConfig.call(this);
9094 this.scroll = (this.config.scroll !== false);
9098 b4MouseDown: function(e) {
9100 this.autoOffset(e.getPageX(),
9105 b4Drag: function(e) {
9106 this.setDragElPos(e.getPageX(),
9110 toString: function() {
9111 return ("DD " + this.id);
9121 Ext.dd.DDProxy = function(id, sGroup, config) {
9123 this.init(id, sGroup, config);
9129 Ext.dd.DDProxy.dragElId = "ygddfdiv";
9131 Ext.extend(Ext.dd.DDProxy, Ext.dd.DD, {
9140 createFrame: function() {
9142 var body = document.body;
9144 if (!body || !body.firstChild) {
9145 setTimeout( function() { self.createFrame(); }, 50 );
9149 var div = this.getDragEl();
9152 div = document.createElement("div");
9153 div.id = this.dragElId;
9156 s.position = "absolute";
9157 s.visibility = "hidden";
9159 s.border = "2px solid #aaa";
9165 body.insertBefore(div, body.firstChild);
9170 initFrame: function() {
9174 applyConfig: function() {
9175 Ext.dd.DDProxy.superclass.applyConfig.call(this);
9177 this.resizeFrame = (this.config.resizeFrame !== false);
9178 this.centerFrame = (this.config.centerFrame);
9179 this.setDragElId(this.config.dragElId || Ext.dd.DDProxy.dragElId);
9183 showFrame: function(iPageX, iPageY) {
9184 var el = this.getEl();
9185 var dragEl = this.getDragEl();
9186 var s = dragEl.style;
9188 this._resizeProxy();
9190 if (this.centerFrame) {
9191 this.setDelta( Math.round(parseInt(s.width, 10)/2),
9192 Math.round(parseInt(s.height, 10)/2) );
9195 this.setDragElPos(iPageX, iPageY);
9197 Ext.fly(dragEl).show();
9201 _resizeProxy: function() {
9202 if (this.resizeFrame) {
9203 var el = this.getEl();
9204 Ext.fly(this.getDragEl()).setSize(el.offsetWidth, el.offsetHeight);
9209 b4MouseDown: function(e) {
9210 var x = e.getPageX();
9211 var y = e.getPageY();
9212 this.autoOffset(x, y);
9213 this.setDragElPos(x, y);
9217 b4StartDrag: function(x, y) {
9219 this.showFrame(x, y);
9223 b4EndDrag: function(e) {
9224 Ext.fly(this.getDragEl()).hide();
9230 endDrag: function(e) {
9232 var lel = this.getEl();
9233 var del = this.getDragEl();
9236 del.style.visibility = "";
9241 lel.style.visibility = "hidden";
9242 Ext.dd.DDM.moveToEl(lel, del);
9243 del.style.visibility = "hidden";
9244 lel.style.visibility = "";
9249 beforeMove : function(){
9253 afterDrag : function(){
9257 toString: function() {
9258 return ("DDProxy " + this.id);
9263 Ext.dd.DDTarget = function(id, sGroup, config) {
9265 this.initTarget(id, sGroup, config);
9270 Ext.extend(Ext.dd.DDTarget, Ext.dd.DragDrop, {
9271 toString: function() {
9272 return ("DDTarget " + this.id);
9276 Ext.dd.DragTracker = function(config){
9277 Ext.apply(this, config);
9287 this.dragRegion = new Ext.lib.Region(0,0,0,0);
9290 this.initEl(this.el);
9294 Ext.extend(Ext.dd.DragTracker, Ext.util.Observable, {
9299 initEl: function(el){
9300 this.el = Ext.get(el);
9301 el.on('mousedown', this.onMouseDown, this,
9302 this.delegate ? {delegate: this.delegate} : undefined);
9305 destroy : function(){
9306 this.el.un('mousedown', this.onMouseDown, this);
9309 onMouseDown: function(e, target){
9310 if(this.fireEvent('mousedown', this, e) !== false && this.onBeforeStart(e) !== false){
9311 this.startXY = this.lastXY = e.getXY();
9312 this.dragTarget = this.delegate ? target : this.el.dom;
9314 var doc = Ext.getDoc();
9315 doc.on('mouseup', this.onMouseUp, this);
9316 doc.on('mousemove', this.onMouseMove, this);
9317 doc.on('selectstart', this.stopSelect, this);
9319 this.timer = this.triggerStart.defer(this.autoStart === true ? 1000 : this.autoStart, this);
9324 onMouseMove: function(e, target){
9326 var xy = e.getXY(), s = this.startXY;
9329 if(Math.abs(s[0]-xy[0]) > this.tolerance || Math.abs(s[1]-xy[1]) > this.tolerance){
9330 this.triggerStart();
9335 this.fireEvent('mousemove', this, e);
9337 this.fireEvent('drag', this, e);
9340 onMouseUp: function(e){
9341 var doc = Ext.getDoc();
9342 doc.un('mousemove', this.onMouseMove, this);
9343 doc.un('mouseup', this.onMouseUp, this);
9344 doc.un('selectstart', this.stopSelect, this);
9347 this.active = false;
9348 delete this.elRegion;
9349 this.fireEvent('mouseup', this, e);
9351 this.fireEvent('dragend', this, e);
9354 triggerStart: function(isTimer){
9357 this.onStart(this.startXY);
9358 this.fireEvent('dragstart', this, this.startXY);
9361 clearStart : function(){
9363 clearTimeout(this.timer);
9368 stopSelect : function(e){
9373 onBeforeStart : function(e){
9377 onStart : function(xy){
9381 onDrag : function(e){
9385 onEnd : function(e){
9389 getDragTarget : function(){
9390 return this.dragTarget;
9393 getDragCt : function(){
9397 getXY : function(constrain){
9399 this.constrainModes[constrain].call(this, this.lastXY) : this.lastXY;
9402 getOffset : function(constrain){
9403 var xy = this.getXY(constrain);
9404 var s = this.startXY;
9405 return [s[0]-xy[0], s[1]-xy[1]];
9409 'point' : function(xy){
9412 this.elRegion = this.getDragCt().getRegion();
9415 var dr = this.dragRegion;
9422 dr.constrainTo(this.elRegion);
9424 return [dr.left, dr.top];
9429 Ext.dd.ScrollManager = function(){
9430 var ddm = Ext.dd.DragDropMgr;
9435 var onStop = function(e){
9440 var triggerRefresh = function(){
9441 if(ddm.dragCurrent){
9442 ddm.refreshCache(ddm.dragCurrent.groups);
9446 var doScroll = function(){
9447 if(ddm.dragCurrent){
9448 var dds = Ext.dd.ScrollManager;
9449 var inc = proc.el.ddScrollConfig ?
9450 proc.el.ddScrollConfig.increment : dds.increment;
9452 if(proc.el.scroll(proc.dir, inc)){
9456 proc.el.scroll(proc.dir, inc, true, dds.animDuration, triggerRefresh);
9461 var clearProc = function(){
9463 clearInterval(proc.id);
9470 var startProc = function(el, dir){
9474 proc.id = setInterval(doScroll, Ext.dd.ScrollManager.frequency);
9477 var onFire = function(e, isDrop){
9478 if(isDrop || !ddm.dragCurrent){ return; }
9479 var dds = Ext.dd.ScrollManager;
9480 if(!dragEl || dragEl != ddm.dragCurrent){
9481 dragEl = ddm.dragCurrent;
9486 var xy = Ext.lib.Event.getXY(e);
9487 var pt = new Ext.lib.Point(xy[0], xy[1]);
9489 var el = els[id], r = el._region;
9490 var c = el.ddScrollConfig ? el.ddScrollConfig : dds;
9491 if(r && r.contains(pt) && el.isScrollable()){
9492 if(r.bottom - pt.y <= c.vthresh){
9494 startProc(el, "down");
9497 }else if(r.right - pt.x <= c.hthresh){
9499 startProc(el, "left");
9502 }else if(pt.y - r.top <= c.vthresh){
9504 startProc(el, "up");
9507 }else if(pt.x - r.left <= c.hthresh){
9509 startProc(el, "right");
9518 ddm.fireEvents = ddm.fireEvents.createSequence(onFire, ddm);
9519 ddm.stopDrag = ddm.stopDrag.createSequence(onStop, ddm);
9523 register : function(el){
9524 if(Ext.isArray(el)){
9525 for(var i = 0, len = el.length; i < len; i++) {
9526 this.register(el[i]);
9535 unregister : function(el){
9536 if(Ext.isArray(el)){
9537 for(var i = 0, len = el.length; i < len; i++) {
9538 this.unregister(el[i]);
9564 refreshCache : function(){
9566 if(typeof els[id] == 'object'){
9567 els[id]._region = els[id].getRegion();
9574 Ext.dd.Registry = function(){
9579 var getId = function(el, autogen){
9580 if(typeof el == "string"){
9584 if(!id && autogen !== false){
9585 id = "extdd-" + (++autoIdSeed);
9593 register : function(el, data){
9595 if(typeof el == "string"){
9596 el = document.getElementById(el);
9599 elements[getId(el)] = data;
9600 if(data.isHandle !== false){
9601 handles[data.ddel.id] = data;
9604 var hs = data.handles;
9605 for(var i = 0, len = hs.length; i < len; i++){
9606 handles[getId(hs[i])] = data;
9612 unregister : function(el){
9613 var id = getId(el, false);
9614 var data = elements[id];
9616 delete elements[id];
9618 var hs = data.handles;
9619 for(var i = 0, len = hs.length; i < len; i++){
9620 delete handles[getId(hs[i], false)];
9627 getHandle : function(id){
9628 if(typeof id != "string"){
9635 getHandleFromEvent : function(e){
9636 var t = Ext.lib.Event.getTarget(e);
9637 return t ? handles[t.id] : null;
9641 getTarget : function(id){
9642 if(typeof id != "string"){
9645 return elements[id];
9649 getTargetFromEvent : function(e){
9650 var t = Ext.lib.Event.getTarget(e);
9651 return t ? elements[t.id] || handles[t.id] : null;
9656 Ext.dd.StatusProxy = function(config){
9657 Ext.apply(this, config);
9658 this.id = this.id || Ext.id();
9659 this.el = new Ext.Layer({
9661 id: this.id, tag: "div", cls: "x-dd-drag-proxy "+this.dropNotAllowed, children: [
9662 {tag: "div", cls: "x-dd-drop-icon"},
9663 {tag: "div", cls: "x-dd-drag-ghost"}
9666 shadow: !config || config.shadow !== false
9668 this.ghost = Ext.get(this.el.dom.childNodes[1]);
9669 this.dropStatus = this.dropNotAllowed;
9672 Ext.dd.StatusProxy.prototype = {
9674 dropAllowed : "x-dd-drop-ok",
9676 dropNotAllowed : "x-dd-drop-nodrop",
9679 setStatus : function(cssClass){
9680 cssClass = cssClass || this.dropNotAllowed;
9681 if(this.dropStatus != cssClass){
9682 this.el.replaceClass(this.dropStatus, cssClass);
9683 this.dropStatus = cssClass;
9688 reset : function(clearGhost){
9689 this.el.dom.className = "x-dd-drag-proxy " + this.dropNotAllowed;
9690 this.dropStatus = this.dropNotAllowed;
9692 this.ghost.update("");
9697 update : function(html){
9698 if(typeof html == "string"){
9699 this.ghost.update(html);
9701 this.ghost.update("");
9702 html.style.margin = "0";
9703 this.ghost.dom.appendChild(html);
9713 getGhost : function(){
9718 hide : function(clear){
9727 if(this.anim && this.anim.isAnimated && this.anim.isAnimated()){
9743 repair : function(xy, callback, scope){
9744 this.callback = callback;
9746 if(xy && this.animRepair !== false){
9747 this.el.addClass("x-dd-drag-repair");
9748 this.el.hideUnders(true);
9749 this.anim = this.el.shift({
9750 duration: this.repairDuration || .5,
9754 callback: this.afterRepair,
9763 afterRepair : function(){
9765 if(typeof this.callback == "function"){
9766 this.callback.call(this.scope || this);
9768 this.callback = null;
9773 Ext.dd.DragSource = function(el, config){
9774 this.el = Ext.get(el);
9779 Ext.apply(this, config);
9782 this.proxy = new Ext.dd.StatusProxy();
9784 Ext.dd.DragSource.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group,
9785 {dragElId : this.proxy.id, resizeFrame: false, isTarget: false, scroll: this.scroll === true});
9787 this.dragging = false;
9790 Ext.extend(Ext.dd.DragSource, Ext.dd.DDProxy, {
9793 dropAllowed : "x-dd-drop-ok",
9795 dropNotAllowed : "x-dd-drop-nodrop",
9798 getDragData : function(e){
9799 return this.dragData;
9803 onDragEnter : function(e, id){
9804 var target = Ext.dd.DragDropMgr.getDDById(id);
9805 this.cachedTarget = target;
9806 if(this.beforeDragEnter(target, e, id) !== false){
9807 if(target.isNotifyTarget){
9808 var status = target.notifyEnter(this, e, this.dragData);
9809 this.proxy.setStatus(status);
9811 this.proxy.setStatus(this.dropAllowed);
9814 if(this.afterDragEnter){
9816 this.afterDragEnter(target, e, id);
9822 beforeDragEnter : function(target, e, id){
9827 alignElWithMouse: function() {
9828 Ext.dd.DragSource.superclass.alignElWithMouse.apply(this, arguments);
9833 onDragOver : function(e, id){
9834 var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
9835 if(this.beforeDragOver(target, e, id) !== false){
9836 if(target.isNotifyTarget){
9837 var status = target.notifyOver(this, e, this.dragData);
9838 this.proxy.setStatus(status);
9841 if(this.afterDragOver){
9843 this.afterDragOver(target, e, id);
9849 beforeDragOver : function(target, e, id){
9854 onDragOut : function(e, id){
9855 var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
9856 if(this.beforeDragOut(target, e, id) !== false){
9857 if(target.isNotifyTarget){
9858 target.notifyOut(this, e, this.dragData);
9861 if(this.afterDragOut){
9863 this.afterDragOut(target, e, id);
9866 this.cachedTarget = null;
9870 beforeDragOut : function(target, e, id){
9875 onDragDrop : function(e, id){
9876 var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
9877 if(this.beforeDragDrop(target, e, id) !== false){
9878 if(target.isNotifyTarget){
9879 if(target.notifyDrop(this, e, this.dragData)){
9880 this.onValidDrop(target, e, id);
9882 this.onInvalidDrop(target, e, id);
9885 this.onValidDrop(target, e, id);
9888 if(this.afterDragDrop){
9890 this.afterDragDrop(target, e, id);
9893 delete this.cachedTarget;
9897 beforeDragDrop : function(target, e, id){
9902 onValidDrop : function(target, e, id){
9904 if(this.afterValidDrop){
9906 this.afterValidDrop(target, e, id);
9911 getRepairXY : function(e, data){
9912 return this.el.getXY();
9916 onInvalidDrop : function(target, e, id){
9917 this.beforeInvalidDrop(target, e, id);
9918 if(this.cachedTarget){
9919 if(this.cachedTarget.isNotifyTarget){
9920 this.cachedTarget.notifyOut(this, e, this.dragData);
9922 this.cacheTarget = null;
9924 this.proxy.repair(this.getRepairXY(e, this.dragData), this.afterRepair, this);
9926 if(this.afterInvalidDrop){
9928 this.afterInvalidDrop(e, id);
9933 afterRepair : function(){
9935 this.el.highlight(this.hlColor || "c3daf9");
9937 this.dragging = false;
9941 beforeInvalidDrop : function(target, e, id){
9946 handleMouseDown : function(e){
9950 var data = this.getDragData(e);
9951 if(data && this.onBeforeDrag(data, e) !== false){
9952 this.dragData = data;
9954 Ext.dd.DragSource.superclass.handleMouseDown.apply(this, arguments);
9959 onBeforeDrag : function(data, e){
9964 onStartDrag : Ext.emptyFn,
9967 startDrag : function(x, y){
9969 this.dragging = true;
9970 this.proxy.update("");
9971 this.onInitDrag(x, y);
9976 onInitDrag : function(x, y){
9977 var clone = this.el.dom.cloneNode(true);
9978 clone.id = Ext.id();
9979 this.proxy.update(clone);
9980 this.onStartDrag(x, y);
9985 getProxy : function(){
9990 hideProxy : function(){
9992 this.proxy.reset(true);
9993 this.dragging = false;
9997 triggerCacheRefresh : function(){
9998 Ext.dd.DDM.refreshCache(this.groups);
10002 b4EndDrag: function(e) {
10006 endDrag : function(e){
10007 this.onEndDrag(this.dragData, e);
10011 onEndDrag : function(data, e){
10015 autoOffset : function(x, y) {
10016 this.setDelta(-12, -20);
10020 Ext.dd.DropTarget = function(el, config){
10021 this.el = Ext.get(el);
10023 Ext.apply(this, config);
10025 if(this.containerScroll){
10026 Ext.dd.ScrollManager.register(this.el);
10029 Ext.dd.DropTarget.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group,
10034 Ext.extend(Ext.dd.DropTarget, Ext.dd.DDTarget, {
10038 dropAllowed : "x-dd-drop-ok",
10040 dropNotAllowed : "x-dd-drop-nodrop",
10046 isNotifyTarget : true,
10049 notifyEnter : function(dd, e, data){
10050 if(this.overClass){
10051 this.el.addClass(this.overClass);
10053 return this.dropAllowed;
10057 notifyOver : function(dd, e, data){
10058 return this.dropAllowed;
10062 notifyOut : function(dd, e, data){
10063 if(this.overClass){
10064 this.el.removeClass(this.overClass);
10069 notifyDrop : function(dd, e, data){
10074 Ext.dd.DragZone = function(el, config){
10075 Ext.dd.DragZone.superclass.constructor.call(this, el, config);
10076 if(this.containerScroll){
10077 Ext.dd.ScrollManager.register(this.el);
10081 Ext.extend(Ext.dd.DragZone, Ext.dd.DragSource, {
10086 getDragData : function(e){
10087 return Ext.dd.Registry.getHandleFromEvent(e);
10091 onInitDrag : function(x, y){
10092 this.proxy.update(this.dragData.ddel.cloneNode(true));
10093 this.onStartDrag(x, y);
10098 afterRepair : function(){
10100 Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9");
10102 this.dragging = false;
10106 getRepairXY : function(e){
10107 return Ext.Element.fly(this.dragData.ddel).getXY();
10111 Ext.dd.DropZone = function(el, config){
10112 Ext.dd.DropZone.superclass.constructor.call(this, el, config);
10115 Ext.extend(Ext.dd.DropZone, Ext.dd.DropTarget, {
10117 getTargetFromEvent : function(e){
10118 return Ext.dd.Registry.getTargetFromEvent(e);
10122 onNodeEnter : function(n, dd, e, data){
10127 onNodeOver : function(n, dd, e, data){
10128 return this.dropAllowed;
10132 onNodeOut : function(n, dd, e, data){
10137 onNodeDrop : function(n, dd, e, data){
10142 onContainerOver : function(dd, e, data){
10143 return this.dropNotAllowed;
10147 onContainerDrop : function(dd, e, data){
10152 notifyEnter : function(dd, e, data){
10153 return this.dropNotAllowed;
10157 notifyOver : function(dd, e, data){
10158 var n = this.getTargetFromEvent(e);
10160 if(this.lastOverNode){
10161 this.onNodeOut(this.lastOverNode, dd, e, data);
10162 this.lastOverNode = null;
10164 return this.onContainerOver(dd, e, data);
10166 if(this.lastOverNode != n){
10167 if(this.lastOverNode){
10168 this.onNodeOut(this.lastOverNode, dd, e, data);
10170 this.onNodeEnter(n, dd, e, data);
10171 this.lastOverNode = n;
10173 return this.onNodeOver(n, dd, e, data);
10177 notifyOut : function(dd, e, data){
10178 if(this.lastOverNode){
10179 this.onNodeOut(this.lastOverNode, dd, e, data);
10180 this.lastOverNode = null;
10185 notifyDrop : function(dd, e, data){
10186 if(this.lastOverNode){
10187 this.onNodeOut(this.lastOverNode, dd, e, data);
10188 this.lastOverNode = null;
10190 var n = this.getTargetFromEvent(e);
10192 this.onNodeDrop(n, dd, e, data) :
10193 this.onContainerDrop(dd, e, data);
10197 triggerCacheRefresh : function(){
10198 Ext.dd.DDM.refreshCache(this.groups);
10203 Ext.data.SortTypes = {
10205 none : function(s){
10210 stripTagsRE : /<\/?[^>]+>/gi,
10213 asText : function(s){
10214 return String(s).replace(this.stripTagsRE, "");
10218 asUCText : function(s){
10219 return String(s).toUpperCase().replace(this.stripTagsRE, "");
10223 asUCString : function(s) {
10224 return String(s).toUpperCase();
10228 asDate : function(s) {
10233 return s.getTime();
10235 return Date.parse(String(s));
10239 asFloat : function(s) {
10240 var val = parseFloat(String(s).replace(/,/g, ""));
10241 if(isNaN(val)) val = 0;
10246 asInt : function(s) {
10247 var val = parseInt(String(s).replace(/,/g, ""));
10248 if(isNaN(val)) val = 0;
10253 Ext.data.Record = function(data, id){
10254 this.id = (id || id === 0) ? id : ++Ext.data.Record.AUTO_ID;
10259 Ext.data.Record.create = function(o){
10260 var f = Ext.extend(Ext.data.Record, {});
10261 var p = f.prototype;
10262 p.fields = new Ext.util.MixedCollection(false, function(field){
10265 for(var i = 0, len = o.length; i < len; i++){
10266 p.fields.add(new Ext.data.Field(o[i]));
10268 f.getField = function(name){
10269 return p.fields.get(name);
10274 Ext.data.Record.AUTO_ID = 1000;
10275 Ext.data.Record.EDIT = 'edit';
10276 Ext.data.Record.REJECT = 'reject';
10277 Ext.data.Record.COMMIT = 'commit';
10279 Ext.data.Record.prototype = {
10290 join : function(store){
10291 this.store = store;
10295 set : function(name, value){
10296 if(String(this.data[name]) == String(value)){
10300 if(!this.modified){
10301 this.modified = {};
10303 if(typeof this.modified[name] == 'undefined'){
10304 this.modified[name] = this.data[name];
10306 this.data[name] = value;
10307 if(!this.editing && this.store){
10308 this.store.afterEdit(this);
10313 get : function(name){
10314 return this.data[name];
10318 beginEdit : function(){
10319 this.editing = true;
10320 this.modified = {};
10324 cancelEdit : function(){
10325 this.editing = false;
10326 delete this.modified;
10330 endEdit : function(){
10331 this.editing = false;
10332 if(this.dirty && this.store){
10333 this.store.afterEdit(this);
10338 reject : function(silent){
10339 var m = this.modified;
10341 if(typeof m[n] != "function"){
10342 this.data[n] = m[n];
10345 this.dirty = false;
10346 delete this.modified;
10347 this.editing = false;
10348 if(this.store && silent !== true){
10349 this.store.afterReject(this);
10354 commit : function(silent){
10355 this.dirty = false;
10356 delete this.modified;
10357 this.editing = false;
10358 if(this.store && silent !== true){
10359 this.store.afterCommit(this);
10364 getChanges : function(){
10365 var m = this.modified, cs = {};
10367 if(m.hasOwnProperty(n)){
10368 cs[n] = this.data[n];
10375 hasError : function(){
10376 return this.error != null;
10380 clearError : function(){
10385 copy : function(newId) {
10386 return new this.constructor(Ext.apply({}, this.data), newId || this.id);
10390 isModified : function(fieldName){
10391 return this.modified && this.modified.hasOwnProperty(fieldName);
10395 Ext.StoreMgr = Ext.apply(new Ext.util.MixedCollection(), {
10396 register : function(){
10397 for(var i = 0, s; s = arguments[i]; i++){
10402 unregister : function(){
10403 for(var i = 0, s; s = arguments[i]; i++){
10404 this.remove(this.lookup(s));
10409 lookup : function(id){
10410 return typeof id == "object" ? id : this.get(id);
10414 getKey : function(o){
10415 return o.storeId || o.id;
10419 Ext.data.Store = function(config){
10420 this.data = new Ext.util.MixedCollection(false);
10421 this.data.getKey = function(o){
10425 this.baseParams = {};
10427 this.paramNames = {
10434 if(config && config.data){
10435 this.inlineData = config.data;
10436 delete config.data;
10439 Ext.apply(this, config);
10441 if(this.url && !this.proxy){
10442 this.proxy = new Ext.data.HttpProxy({url: this.url});
10446 if(!this.recordType){
10447 this.recordType = this.reader.recordType;
10449 if(this.reader.onMetaChange){
10450 this.reader.onMetaChange = this.onMetaChange.createDelegate(this);
10454 if(this.recordType){
10455 this.fields = this.recordType.prototype.fields;
10457 this.modified = [];
10481 this.relayEvents(this.proxy, ["loadexception"]);
10484 this.sortToggle = {};
10486 this.setDefaultSort(this.sortInfo.field, this.sortInfo.direction);
10489 Ext.data.Store.superclass.constructor.call(this);
10491 if(this.storeId || this.id){
10492 Ext.StoreMgr.register(this);
10494 if(this.inlineData){
10495 this.loadData(this.inlineData);
10496 delete this.inlineData;
10497 }else if(this.autoLoad){
10498 this.load.defer(10, this, [
10499 typeof this.autoLoad == 'object' ?
10500 this.autoLoad : undefined]);
10503 Ext.extend(Ext.data.Store, Ext.util.Observable, {
10513 remoteSort : false,
10516 pruneModifiedRecords : false,
10519 lastOptions : null,
10521 destroy : function(){
10523 Ext.StoreMgr.unregister(this);
10526 this.purgeListeners();
10530 add : function(records){
10531 records = [].concat(records);
10532 if(records.length < 1){
10535 for(var i = 0, len = records.length; i < len; i++){
10536 records[i].join(this);
10538 var index = this.data.length;
10539 this.data.addAll(records);
10541 this.snapshot.addAll(records);
10543 this.fireEvent("add", this, records, index);
10547 addSorted : function(record){
10548 var index = this.findInsertIndex(record);
10549 this.insert(index, record);
10553 remove : function(record){
10554 var index = this.data.indexOf(record);
10555 this.data.removeAt(index);
10556 if(this.pruneModifiedRecords){
10557 this.modified.remove(record);
10560 this.snapshot.remove(record);
10562 this.fireEvent("remove", this, record, index);
10566 removeAll : function(){
10569 this.snapshot.clear();
10571 if(this.pruneModifiedRecords){
10572 this.modified = [];
10574 this.fireEvent("clear", this);
10578 insert : function(index, records){
10579 records = [].concat(records);
10580 for(var i = 0, len = records.length; i < len; i++){
10581 this.data.insert(index, records[i]);
10582 records[i].join(this);
10584 this.fireEvent("add", this, records, index);
10588 indexOf : function(record){
10589 return this.data.indexOf(record);
10593 indexOfId : function(id){
10594 return this.data.indexOfKey(id);
10598 getById : function(id){
10599 return this.data.key(id);
10603 getAt : function(index){
10604 return this.data.itemAt(index);
10608 getRange : function(start, end){
10609 return this.data.getRange(start, end);
10613 storeOptions : function(o){
10614 o = Ext.apply({}, o);
10617 this.lastOptions = o;
10621 load : function(options){
10622 options = options || {};
10623 if(this.fireEvent("beforeload", this, options) !== false){
10624 this.storeOptions(options);
10625 var p = Ext.apply(options.params || {}, this.baseParams);
10626 if(this.sortInfo && this.remoteSort){
10627 var pn = this.paramNames;
10628 p[pn["sort"]] = this.sortInfo.field;
10629 p[pn["dir"]] = this.sortInfo.direction;
10631 this.proxy.load(p, this.reader, this.loadRecords, this, options);
10639 reload : function(options){
10640 this.load(Ext.applyIf(options||{}, this.lastOptions));
10645 loadRecords : function(o, options, success){
10646 if(!o || success === false){
10647 if(success !== false){
10648 this.fireEvent("load", this, [], options);
10650 if(options.callback){
10651 options.callback.call(options.scope || this, [], options, false);
10655 var r = o.records, t = o.totalRecords || r.length;
10656 if(!options || options.add !== true){
10657 if(this.pruneModifiedRecords){
10658 this.modified = [];
10660 for(var i = 0, len = r.length; i < len; i++){
10664 this.data = this.snapshot;
10665 delete this.snapshot;
10668 this.data.addAll(r);
10669 this.totalLength = t;
10671 this.fireEvent("datachanged", this);
10673 this.totalLength = Math.max(t, this.data.length+r.length);
10676 this.fireEvent("load", this, r, options);
10677 if(options.callback){
10678 options.callback.call(options.scope || this, r, options, true);
10683 loadData : function(o, append){
10684 var r = this.reader.readRecords(o);
10685 this.loadRecords(r, {add: append}, true);
10689 getCount : function(){
10690 return this.data.length || 0;
10694 getTotalCount : function(){
10695 return this.totalLength || 0;
10699 getSortState : function(){
10700 return this.sortInfo;
10704 applySort : function(){
10705 if(this.sortInfo && !this.remoteSort){
10706 var s = this.sortInfo, f = s.field;
10707 this.sortData(f, s.direction);
10712 sortData : function(f, direction){
10713 direction = direction || 'ASC';
10714 var st = this.fields.get(f).sortType;
10715 var fn = function(r1, r2){
10716 var v1 = st(r1.data[f]), v2 = st(r2.data[f]);
10717 return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
10719 this.data.sort(direction, fn);
10720 if(this.snapshot && this.snapshot != this.data){
10721 this.snapshot.sort(direction, fn);
10726 setDefaultSort : function(field, dir){
10727 dir = dir ? dir.toUpperCase() : "ASC";
10728 this.sortInfo = {field: field, direction: dir};
10729 this.sortToggle[field] = dir;
10733 sort : function(fieldName, dir){
10734 var f = this.fields.get(fieldName);
10739 if(this.sortInfo && this.sortInfo.field == f.name){
10740 dir = (this.sortToggle[f.name] || "ASC").toggle("ASC", "DESC");
10745 var st = (this.sortToggle) ? this.sortToggle[f.name] : null;
10746 var si = (this.sortInfo) ? this.sortInfo : null;
10748 this.sortToggle[f.name] = dir;
10749 this.sortInfo = {field: f.name, direction: dir};
10750 if(!this.remoteSort){
10752 this.fireEvent("datachanged", this);
10754 if (!this.load(this.lastOptions)) {
10756 this.sortToggle[f.name] = st;
10759 this.sortInfo = si;
10766 each : function(fn, scope){
10767 this.data.each(fn, scope);
10771 getModifiedRecords : function(){
10772 return this.modified;
10776 createFilterFn : function(property, value, anyMatch, caseSensitive){
10777 if(Ext.isEmpty(value, false)){
10780 value = this.data.createValueMatcher(value, anyMatch, caseSensitive);
10781 return function(r){
10782 return value.test(r.data[property]);
10787 sum : function(property, start, end){
10788 var rs = this.data.items, v = 0;
10789 start = start || 0;
10790 end = (end || end === 0) ? end : rs.length-1;
10792 for(var i = start; i <= end; i++){
10793 v += (rs[i].data[property] || 0);
10799 filter : function(property, value, anyMatch, caseSensitive){
10800 var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
10801 return fn ? this.filterBy(fn) : this.clearFilter();
10805 filterBy : function(fn, scope){
10806 this.snapshot = this.snapshot || this.data;
10807 this.data = this.queryBy(fn, scope||this);
10808 this.fireEvent("datachanged", this);
10812 query : function(property, value, anyMatch, caseSensitive){
10813 var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
10814 return fn ? this.queryBy(fn) : this.data.clone();
10818 queryBy : function(fn, scope){
10819 var data = this.snapshot || this.data;
10820 return data.filterBy(fn, scope||this);
10824 find : function(property, value, start, anyMatch, caseSensitive){
10825 var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
10826 return fn ? this.data.findIndexBy(fn, null, start) : -1;
10830 findBy : function(fn, scope, start){
10831 return this.data.findIndexBy(fn, scope, start);
10835 collect : function(dataIndex, allowNull, bypassFilter){
10836 var d = (bypassFilter === true && this.snapshot) ?
10837 this.snapshot.items : this.data.items;
10838 var v, sv, r = [], l = {};
10839 for(var i = 0, len = d.length; i < len; i++){
10840 v = d[i].data[dataIndex];
10842 if((allowNull || !Ext.isEmpty(v)) && !l[sv]){
10851 clearFilter : function(suppressEvent){
10852 if(this.isFiltered()){
10853 this.data = this.snapshot;
10854 delete this.snapshot;
10855 if(suppressEvent !== true){
10856 this.fireEvent("datachanged", this);
10862 isFiltered : function(){
10863 return this.snapshot && this.snapshot != this.data;
10867 afterEdit : function(record){
10868 if(this.modified.indexOf(record) == -1){
10869 this.modified.push(record);
10871 this.fireEvent("update", this, record, Ext.data.Record.EDIT);
10875 afterReject : function(record){
10876 this.modified.remove(record);
10877 this.fireEvent("update", this, record, Ext.data.Record.REJECT);
10881 afterCommit : function(record){
10882 this.modified.remove(record);
10883 this.fireEvent("update", this, record, Ext.data.Record.COMMIT);
10887 commitChanges : function(){
10888 var m = this.modified.slice(0);
10889 this.modified = [];
10890 for(var i = 0, len = m.length; i < len; i++){
10896 rejectChanges : function(){
10897 var m = this.modified.slice(0);
10898 this.modified = [];
10899 for(var i = 0, len = m.length; i < len; i++){
10905 onMetaChange : function(meta, rtype, o){
10906 this.recordType = rtype;
10907 this.fields = rtype.prototype.fields;
10908 delete this.snapshot;
10909 this.sortInfo = meta.sortInfo;
10910 this.modified = [];
10911 this.fireEvent('metachange', this, this.reader.meta);
10915 findInsertIndex : function(record){
10916 this.suspendEvents();
10917 var data = this.data.clone();
10918 this.data.add(record);
10920 var index = this.data.indexOf(record);
10922 this.resumeEvents();
10927 Ext.data.SimpleStore = function(config){
10928 Ext.data.SimpleStore.superclass.constructor.call(this, Ext.apply(config, {
10929 reader: new Ext.data.ArrayReader({
10932 Ext.data.Record.create(config.fields)
10936 Ext.extend(Ext.data.SimpleStore, Ext.data.Store, {
10937 loadData : function(data, append){
10938 if(this.expandData === true){
10940 for(var i = 0, len = data.length; i < len; i++){
10941 r[r.length] = [data[i]];
10945 Ext.data.SimpleStore.superclass.loadData.call(this, data, append);
10949 Ext.data.JsonStore = function(c){
10950 Ext.data.JsonStore.superclass.constructor.call(this, Ext.apply(c, {
10951 proxy: !c.data ? new Ext.data.HttpProxy({url: c.url}) : undefined,
10952 reader: new Ext.data.JsonReader(c, c.fields)
10955 Ext.extend(Ext.data.JsonStore, Ext.data.Store);
10959 Ext.data.Field = function(config){
10960 if(typeof config == "string"){
10961 config = {name: config};
10963 Ext.apply(this, config);
10966 this.type = "auto";
10969 var st = Ext.data.SortTypes;
10971 if(typeof this.sortType == "string"){
10972 this.sortType = st[this.sortType];
10976 if(!this.sortType){
10979 this.sortType = st.asUCString;
10982 this.sortType = st.asDate;
10985 this.sortType = st.none;
10990 var stripRe = /[\$,%]/g;
10995 var cv, dateFormat = this.dateFormat;
11000 cv = function(v){ return v; };
11003 cv = function(v){ return (v === undefined || v === null) ? '' : String(v); };
11007 return v !== undefined && v !== null && v !== '' ?
11008 parseInt(String(v).replace(stripRe, ""), 10) : '';
11013 return v !== undefined && v !== null && v !== '' ?
11014 parseFloat(String(v).replace(stripRe, ""), 10) : '';
11019 cv = function(v){ return v === true || v === "true" || v == 1; };
11030 if(dateFormat == "timestamp"){
11031 return new Date(v*1000);
11033 if(dateFormat == "time"){
11034 return new Date(parseInt(v, 10));
11036 return Date.parseDate(v, dateFormat);
11038 var parsed = Date.parse(v);
11039 return parsed ? new Date(parsed) : null;
11048 Ext.data.Field.prototype = {
11056 Ext.data.DataReader = function(meta, recordType){
11059 this.recordType = Ext.isArray(recordType) ?
11060 Ext.data.Record.create(recordType) : recordType;
11063 Ext.data.DataReader.prototype = {
11067 Ext.data.DataProxy = function(){
11076 Ext.data.DataProxy.superclass.constructor.call(this);
11079 Ext.extend(Ext.data.DataProxy, Ext.util.Observable);
11081 Ext.data.MemoryProxy = function(data){
11082 Ext.data.MemoryProxy.superclass.constructor.call(this);
11086 Ext.extend(Ext.data.MemoryProxy, Ext.data.DataProxy, {
11088 load : function(params, reader, callback, scope, arg){
11089 params = params || {};
11092 result = reader.readRecords(this.data);
11094 this.fireEvent("loadexception", this, arg, null, e);
11095 callback.call(scope, null, arg, false);
11098 callback.call(scope, result, arg, true);
11102 update : function(params, records){
11107 Ext.data.HttpProxy = function(conn){
11108 Ext.data.HttpProxy.superclass.constructor.call(this);
11111 this.useAjax = !conn || !conn.events;
11114 Ext.extend(Ext.data.HttpProxy, Ext.data.DataProxy, {
11116 getConnection : function(){
11117 return this.useAjax ? Ext.Ajax : this.conn;
11121 load : function(params, reader, callback, scope, arg){
11122 if(this.fireEvent("beforeload", this, params) !== false){
11124 params : params || {},
11126 callback : callback,
11131 callback : this.loadResponse,
11135 Ext.applyIf(o, this.conn);
11136 if(this.activeRequest){
11137 Ext.Ajax.abort(this.activeRequest);
11139 this.activeRequest = Ext.Ajax.request(o);
11141 this.conn.request(o);
11144 callback.call(scope||this, null, arg, false);
11149 loadResponse : function(o, success, response){
11150 delete this.activeRequest;
11152 this.fireEvent("loadexception", this, o, response);
11153 o.request.callback.call(o.request.scope, null, o.request.arg, false);
11158 result = o.reader.read(response);
11160 this.fireEvent("loadexception", this, o, response, e);
11161 o.request.callback.call(o.request.scope, null, o.request.arg, false);
11164 this.fireEvent("load", this, o, o.request.arg);
11165 o.request.callback.call(o.request.scope, result, o.request.arg, true);
11169 update : function(dataSet){
11174 updateResponse : function(dataSet){
11179 Ext.data.ScriptTagProxy = function(config){
11180 Ext.data.ScriptTagProxy.superclass.constructor.call(this);
11181 Ext.apply(this, config);
11182 this.head = document.getElementsByTagName("head")[0];
11185 Ext.data.ScriptTagProxy.TRANS_ID = 1000;
11187 Ext.extend(Ext.data.ScriptTagProxy, Ext.data.DataProxy, {
11192 callbackParam : "callback",
11197 load : function(params, reader, callback, scope, arg){
11198 if(this.fireEvent("beforeload", this, params) !== false){
11200 var p = Ext.urlEncode(Ext.apply(params, this.extraParams));
11202 var url = this.url;
11203 url += (url.indexOf("?") != -1 ? "&" : "?") + p;
11205 url += "&_dc=" + (new Date().getTime());
11207 var transId = ++Ext.data.ScriptTagProxy.TRANS_ID;
11210 cb : "stcCallback"+transId,
11211 scriptId : "stcScript"+transId,
11215 callback : callback,
11221 window[trans.cb] = function(o){
11222 conn.handleResponse(o, trans);
11225 url += String.format("&{0}={1}", this.callbackParam, trans.cb);
11227 if(this.autoAbort !== false){
11231 trans.timeoutId = this.handleFailure.defer(this.timeout, this, [trans]);
11233 var script = document.createElement("script");
11234 script.setAttribute("src", url);
11235 script.setAttribute("type", "text/javascript");
11236 script.setAttribute("id", trans.scriptId);
11237 this.head.appendChild(script);
11239 this.trans = trans;
11241 callback.call(scope||this, null, arg, false);
11246 isLoading : function(){
11247 return this.trans ? true : false;
11251 abort : function(){
11252 if(this.isLoading()){
11253 this.destroyTrans(this.trans);
11258 destroyTrans : function(trans, isLoaded){
11259 this.head.removeChild(document.getElementById(trans.scriptId));
11260 clearTimeout(trans.timeoutId);
11262 window[trans.cb] = undefined;
11264 delete window[trans.cb];
11268 window[trans.cb] = function(){
11269 window[trans.cb] = undefined;
11271 delete window[trans.cb];
11278 handleResponse : function(o, trans){
11279 this.trans = false;
11280 this.destroyTrans(trans, true);
11283 result = trans.reader.readRecords(o);
11285 this.fireEvent("loadexception", this, o, trans.arg, e);
11286 trans.callback.call(trans.scope||window, null, trans.arg, false);
11289 this.fireEvent("load", this, o, trans.arg);
11290 trans.callback.call(trans.scope||window, result, trans.arg, true);
11294 handleFailure : function(trans){
11295 this.trans = false;
11296 this.destroyTrans(trans, false);
11297 this.fireEvent("loadexception", this, null, trans.arg);
11298 trans.callback.call(trans.scope||window, null, trans.arg, false);
11302 Ext.data.JsonReader = function(meta, recordType){
11304 Ext.data.JsonReader.superclass.constructor.call(this, meta, recordType || meta.fields);
11306 Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
11309 read : function(response){
11310 var json = response.responseText;
11311 var o = eval("("+json+")");
11313 throw {message: "JsonReader.read: Json object not found"};
11317 this.meta = o.metaData;
11318 this.recordType = Ext.data.Record.create(o.metaData.fields);
11319 this.onMetaChange(this.meta, this.recordType, o);
11321 return this.readRecords(o);
11325 onMetaChange : function(meta, recordType, o){
11330 simpleAccess: function(obj, subsc) {
11335 getJsonAccessor: function(){
11337 return function(expr) {
11339 return(re.test(expr))
11340 ? new Function("obj", "return obj." + expr)
11345 return Ext.emptyFn;
11350 readRecords : function(o){
11353 var s = this.meta, Record = this.recordType,
11354 f = Record.prototype.fields, fi = f.items, fl = f.length;
11358 if(s.totalProperty) {
11359 this.getTotal = this.getJsonAccessor(s.totalProperty);
11361 if(s.successProperty) {
11362 this.getSuccess = this.getJsonAccessor(s.successProperty);
11364 this.getRoot = s.root ? this.getJsonAccessor(s.root) : function(p){return p;};
11366 var g = this.getJsonAccessor(s.id);
11367 this.getId = function(rec) {
11369 return (r === undefined || r === "") ? null : r;
11372 this.getId = function(){return null;};
11375 for(var i = 0; i < fl; i++){
11377 var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
11378 this.ef[i] = this.getJsonAccessor(map);
11382 var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;
11383 if(s.totalProperty){
11384 var v = parseInt(this.getTotal(o), 10);
11389 if(s.successProperty){
11390 var v = this.getSuccess(o);
11391 if(v === false || v === 'false'){
11396 for(var i = 0; i < c; i++){
11399 var id = this.getId(n);
11400 for(var j = 0; j < fl; j++){
11402 var v = this.ef[j](n);
11403 values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, n);
11405 var record = new Record(values, id);
11407 records[i] = record;
11412 totalRecords : totalRecords
11417 Ext.data.XmlReader = function(meta, recordType){
11419 Ext.data.XmlReader.superclass.constructor.call(this, meta, recordType || meta.fields);
11421 Ext.extend(Ext.data.XmlReader, Ext.data.DataReader, {
11423 read : function(response){
11424 var doc = response.responseXML;
11426 throw {message: "XmlReader.read: XML Document not available"};
11428 return this.readRecords(doc);
11432 readRecords : function(doc){
11434 this.xmlData = doc;
11435 var root = doc.documentElement || doc;
11436 var q = Ext.DomQuery;
11437 var recordType = this.recordType, fields = recordType.prototype.fields;
11438 var sid = this.meta.id;
11439 var totalRecords = 0, success = true;
11440 if(this.meta.totalRecords){
11441 totalRecords = q.selectNumber(this.meta.totalRecords, root, 0);
11444 if(this.meta.success){
11445 var sv = q.selectValue(this.meta.success, root, true);
11446 success = sv !== false && sv !== 'false';
11449 var ns = q.select(this.meta.record, root);
11450 for(var i = 0, len = ns.length; i < len; i++) {
11453 var id = sid ? q.selectValue(sid, n) : undefined;
11454 for(var j = 0, jlen = fields.length; j < jlen; j++){
11455 var f = fields.items[j];
11456 var v = q.selectValue(f.mapping || f.name, n, f.defaultValue);
11457 v = f.convert(v, n);
11458 values[f.name] = v;
11460 var record = new recordType(values, id);
11462 records[records.length] = record;
11468 totalRecords : totalRecords || records.length
11473 Ext.data.ArrayReader = Ext.extend(Ext.data.JsonReader, {
11475 readRecords : function(o){
11476 var sid = this.meta ? this.meta.id : null;
11477 var recordType = this.recordType, fields = recordType.prototype.fields;
11480 for(var i = 0; i < root.length; i++){
11483 var id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);
11484 for(var j = 0, jlen = fields.length; j < jlen; j++){
11485 var f = fields.items[j];
11486 var k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;
11487 var v = n[k] !== undefined ? n[k] : f.defaultValue;
11488 v = f.convert(v, n);
11489 values[f.name] = v;
11491 var record = new recordType(values, id);
11493 records[records.length] = record;
11497 totalRecords : records.length
11502 Ext.data.Tree = function(root){
11503 this.nodeHash = {};
11507 this.setRootNode(root);
11528 Ext.data.Tree.superclass.constructor.call(this);
11531 Ext.extend(Ext.data.Tree, Ext.util.Observable, {
11533 pathSeparator: "/",
11536 proxyNodeEvent : function(){
11537 return this.fireEvent.apply(this, arguments);
11541 getRootNode : function(){
11546 setRootNode : function(node){
11548 node.ownerTree = this;
11549 node.isRoot = true;
11550 this.registerNode(node);
11555 getNodeById : function(id){
11556 return this.nodeHash[id];
11560 registerNode : function(node){
11561 this.nodeHash[node.id] = node;
11565 unregisterNode : function(node){
11566 delete this.nodeHash[node.id];
11569 toString : function(){
11570 return "[Tree"+(this.id?" "+this.id:"")+"]";
11575 Ext.data.Node = function(attributes){
11577 this.attributes = attributes || {};
11578 this.leaf = this.attributes.leaf;
11580 this.id = this.attributes.id;
11582 this.id = Ext.id(null, "ynode-");
11583 this.attributes.id = this.id;
11586 this.childNodes = [];
11587 if(!this.childNodes.indexOf){
11588 this.childNodes.indexOf = function(o){
11589 for(var i = 0, len = this.length; i < len; i++){
11590 if(this[i] == o) return i;
11596 this.parentNode = null;
11598 this.firstChild = null;
11600 this.lastChild = null;
11602 this.previousSibling = null;
11604 this.nextSibling = null;
11616 "beforeappend" : true,
11618 "beforeremove" : true,
11620 "beforemove" : true,
11622 "beforeinsert" : true
11624 this.listeners = this.attributes.listeners;
11625 Ext.data.Node.superclass.constructor.call(this);
11628 Ext.extend(Ext.data.Node, Ext.util.Observable, {
11630 fireEvent : function(evtName){
11632 if(Ext.data.Node.superclass.fireEvent.apply(this, arguments) === false){
11636 var ot = this.getOwnerTree();
11638 if(ot.proxyNodeEvent.apply(ot, arguments) === false){
11646 isLeaf : function(){
11647 return this.leaf === true;
11651 setFirstChild : function(node){
11652 this.firstChild = node;
11656 setLastChild : function(node){
11657 this.lastChild = node;
11662 isLast : function(){
11663 return (!this.parentNode ? true : this.parentNode.lastChild == this);
11667 isFirst : function(){
11668 return (!this.parentNode ? true : this.parentNode.firstChild == this);
11671 hasChildNodes : function(){
11672 return !this.isLeaf() && this.childNodes.length > 0;
11676 appendChild : function(node){
11678 if(Ext.isArray(node)){
11680 }else if(arguments.length > 1){
11685 for(var i = 0, len = multi.length; i < len; i++) {
11686 this.appendChild(multi[i]);
11689 if(this.fireEvent("beforeappend", this.ownerTree, this, node) === false){
11692 var index = this.childNodes.length;
11693 var oldParent = node.parentNode;
11696 if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index) === false){
11699 oldParent.removeChild(node);
11701 index = this.childNodes.length;
11703 this.setFirstChild(node);
11705 this.childNodes.push(node);
11706 node.parentNode = this;
11707 var ps = this.childNodes[index-1];
11709 node.previousSibling = ps;
11710 ps.nextSibling = node;
11712 node.previousSibling = null;
11714 node.nextSibling = null;
11715 this.setLastChild(node);
11716 node.setOwnerTree(this.getOwnerTree());
11717 this.fireEvent("append", this.ownerTree, this, node, index);
11719 node.fireEvent("move", this.ownerTree, node, oldParent, this, index);
11726 removeChild : function(node){
11727 var index = this.childNodes.indexOf(node);
11731 if(this.fireEvent("beforeremove", this.ownerTree, this, node) === false){
11736 this.childNodes.splice(index, 1);
11739 if(node.previousSibling){
11740 node.previousSibling.nextSibling = node.nextSibling;
11742 if(node.nextSibling){
11743 node.nextSibling.previousSibling = node.previousSibling;
11747 if(this.firstChild == node){
11748 this.setFirstChild(node.nextSibling);
11750 if(this.lastChild == node){
11751 this.setLastChild(node.previousSibling);
11754 node.setOwnerTree(null);
11756 node.parentNode = null;
11757 node.previousSibling = null;
11758 node.nextSibling = null;
11759 this.fireEvent("remove", this.ownerTree, this, node);
11764 insertBefore : function(node, refNode){
11766 return this.appendChild(node);
11769 if(node == refNode){
11773 if(this.fireEvent("beforeinsert", this.ownerTree, this, node, refNode) === false){
11776 var index = this.childNodes.indexOf(refNode);
11777 var oldParent = node.parentNode;
11778 var refIndex = index;
11781 if(oldParent == this && this.childNodes.indexOf(node) < index){
11787 if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index, refNode) === false){
11790 oldParent.removeChild(node);
11793 this.setFirstChild(node);
11795 this.childNodes.splice(refIndex, 0, node);
11796 node.parentNode = this;
11797 var ps = this.childNodes[refIndex-1];
11799 node.previousSibling = ps;
11800 ps.nextSibling = node;
11802 node.previousSibling = null;
11804 node.nextSibling = refNode;
11805 refNode.previousSibling = node;
11806 node.setOwnerTree(this.getOwnerTree());
11807 this.fireEvent("insert", this.ownerTree, this, node, refNode);
11809 node.fireEvent("move", this.ownerTree, node, oldParent, this, refIndex, refNode);
11815 remove : function(){
11816 this.parentNode.removeChild(this);
11821 item : function(index){
11822 return this.childNodes[index];
11826 replaceChild : function(newChild, oldChild){
11827 this.insertBefore(newChild, oldChild);
11828 this.removeChild(oldChild);
11833 indexOf : function(child){
11834 return this.childNodes.indexOf(child);
11838 getOwnerTree : function(){
11840 if(!this.ownerTree){
11844 this.ownerTree = p.ownerTree;
11850 return this.ownerTree;
11854 getDepth : function(){
11857 while(p.parentNode){
11865 setOwnerTree : function(tree){
11867 if(tree != this.ownerTree){
11868 if(this.ownerTree){
11869 this.ownerTree.unregisterNode(this);
11871 this.ownerTree = tree;
11872 var cs = this.childNodes;
11873 for(var i = 0, len = cs.length; i < len; i++) {
11874 cs[i].setOwnerTree(tree);
11877 tree.registerNode(this);
11883 getPath : function(attr){
11884 attr = attr || "id";
11885 var p = this.parentNode;
11886 var b = [this.attributes[attr]];
11888 b.unshift(p.attributes[attr]);
11891 var sep = this.getOwnerTree().pathSeparator;
11892 return sep + b.join(sep);
11896 bubble : function(fn, scope, args){
11899 if(fn.apply(scope || p, args || [p]) === false){
11907 cascade : function(fn, scope, args){
11908 if(fn.apply(scope || this, args || [this]) !== false){
11909 var cs = this.childNodes;
11910 for(var i = 0, len = cs.length; i < len; i++) {
11911 cs[i].cascade(fn, scope, args);
11917 eachChild : function(fn, scope, args){
11918 var cs = this.childNodes;
11919 for(var i = 0, len = cs.length; i < len; i++) {
11920 if(fn.apply(scope || this, args || [cs[i]]) === false){
11927 findChild : function(attribute, value){
11928 var cs = this.childNodes;
11929 for(var i = 0, len = cs.length; i < len; i++) {
11930 if(cs[i].attributes[attribute] == value){
11938 findChildBy : function(fn, scope){
11939 var cs = this.childNodes;
11940 for(var i = 0, len = cs.length; i < len; i++) {
11941 if(fn.call(scope||cs[i], cs[i]) === true){
11949 sort : function(fn, scope){
11950 var cs = this.childNodes;
11951 var len = cs.length;
11953 var sortFn = scope ? function(){fn.apply(scope, arguments);} : fn;
11955 for(var i = 0; i < len; i++){
11957 n.previousSibling = cs[i-1];
11958 n.nextSibling = cs[i+1];
11960 this.setFirstChild(n);
11963 this.setLastChild(n);
11970 contains : function(node){
11971 return node.isAncestor(this);
11975 isAncestor : function(node){
11976 var p = this.parentNode;
11986 toString : function(){
11987 return "[Node"+(this.id?" "+this.id:"")+"]";
11991 Ext.data.GroupingStore = Ext.extend(Ext.data.Store, {
11994 remoteGroup : false,
11999 clearGrouping : function(){
12000 this.groupField = false;
12001 if(this.remoteGroup){
12002 if(this.baseParams){
12003 delete this.baseParams.groupBy;
12008 this.fireEvent('datachanged', this);
12013 groupBy : function(field, forceRegroup){
12014 if(this.groupField == field && !forceRegroup){
12017 this.groupField = field;
12018 if(this.remoteGroup){
12019 if(!this.baseParams){
12020 this.baseParams = {};
12022 this.baseParams['groupBy'] = field;
12024 if(this.groupOnSort){
12028 if(this.remoteGroup){
12031 var si = this.sortInfo || {};
12032 if(si.field != field){
12035 this.sortData(field);
12037 this.fireEvent('datachanged', this);
12042 applySort : function(){
12043 Ext.data.GroupingStore.superclass.applySort.call(this);
12044 if(!this.groupOnSort && !this.remoteGroup){
12045 var gs = this.getGroupState();
12046 if(gs && gs != this.sortInfo.field){
12047 this.sortData(this.groupField);
12053 applyGrouping : function(alwaysFireChange){
12054 if(this.groupField !== false){
12055 this.groupBy(this.groupField, true);
12058 if(alwaysFireChange === true){
12059 this.fireEvent('datachanged', this);
12066 getGroupState : function(){
12067 return this.groupOnSort && this.groupField !== false ?
12068 (this.sortInfo ? this.sortInfo.field : undefined) : this.groupField;
12072 Ext.ComponentMgr = function(){
12073 var all = new Ext.util.MixedCollection();
12078 register : function(c){
12083 unregister : function(c){
12088 get : function(id){
12089 return all.get(id);
12093 onAvailable : function(id, fn, scope){
12094 all.on("add", function(index, o){
12096 fn.call(scope || o, o);
12097 all.un("add", fn, scope);
12106 registerType : function(xtype, cls){
12107 types[xtype] = cls;
12112 create : function(config, defaultType){
12113 return new types[config.xtype || defaultType](config);
12120 Ext.reg = Ext.ComponentMgr.registerType;
12122 Ext.Component = function(config){
12123 config = config || {};
12124 if(config.initialConfig){
12125 if(config.isAction){ this.baseAction = config;
12127 config = config.initialConfig; }else if(config.tagName || config.dom || typeof config == "string"){ config = {applyTo: config, id: config.id || config};
12131 this.initialConfig = config;
12133 Ext.apply(this, config);
12156 'beforestaterestore',
12165 Ext.ComponentMgr.register(this);
12166 Ext.Component.superclass.constructor.call(this);
12168 if(this.baseAction){
12169 this.baseAction.addComponent(this);
12172 this.initComponent();
12175 if(Ext.isArray(this.plugins)){
12176 for(var i = 0, len = this.plugins.length; i < len; i++){
12177 this.plugins[i].init(this);
12180 this.plugins.init(this);
12184 if(this.stateful !== false){
12185 this.initState(config);
12189 this.applyToMarkup(this.applyTo);
12190 delete this.applyTo;
12191 }else if(this.renderTo){
12192 this.render(this.renderTo);
12193 delete this.renderTo;
12197 Ext.Component.AUTO_ID = 1000;
12199 Ext.extend(Ext.Component, Ext.util.Observable, {
12215 disabledClass : "x-item-disabled",
12217 allowDomMove : true,
12221 hideMode: 'display',
12233 ctype : "Ext.Component",
12237 getActionEl : function(){
12238 return this[this.actionMode];
12242 initComponent : Ext.emptyFn,
12245 render : function(container, position){
12246 if(!this.rendered && this.fireEvent("beforerender", this) !== false){
12247 if(!container && this.el){
12248 this.el = Ext.get(this.el);
12249 container = this.el.dom.parentNode;
12250 this.allowDomMove = false;
12252 this.container = Ext.get(container);
12254 this.container.addClass(this.ctCls);
12256 this.rendered = true;
12257 if(position !== undefined){
12258 if(typeof position == 'number'){
12259 position = this.container.dom.childNodes[position];
12261 position = Ext.getDom(position);
12264 this.onRender(this.container, position || null);
12266 this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]);
12269 this.el.addClass(this.cls);
12273 this.el.applyStyles(this.style);
12276 this.fireEvent("render", this);
12277 this.afterRender(this.container);
12285 this.initStateEvents();
12290 initState : function(config){
12291 if(Ext.state.Manager){
12292 var state = Ext.state.Manager.get(this.stateId || this.id);
12294 if(this.fireEvent('beforestaterestore', this, state) !== false){
12295 this.applyState(state);
12296 this.fireEvent('staterestore', this, state);
12302 initStateEvents : function(){
12303 if(this.stateEvents){
12304 for(var i = 0, e; e = this.stateEvents[i]; i++){
12305 this.on(e, this.saveState, this, {delay:100});
12310 applyState : function(state, config){
12312 Ext.apply(this, state);
12316 getState : function(){
12320 saveState : function(){
12321 if(Ext.state.Manager){
12322 var state = this.getState();
12323 if(this.fireEvent('beforestatesave', this, state) !== false){
12324 Ext.state.Manager.set(this.stateId || this.id, state);
12325 this.fireEvent('statesave', this, state);
12331 applyToMarkup : function(el){
12332 this.allowDomMove = false;
12333 this.el = Ext.get(el);
12334 this.render(this.el.dom.parentNode);
12338 addClass : function(cls){
12340 this.el.addClass(cls);
12342 this.cls = this.cls ? this.cls + ' ' + cls : cls;
12347 removeClass : function(cls){
12349 this.el.removeClass(cls);
12350 }else if(this.cls){
12351 this.cls = this.cls.split(' ').remove(cls).join(' ');
12355 onRender : function(ct, position){
12357 if(typeof this.autoEl == 'string'){
12358 this.el = document.createElement(this.autoEl);
12360 var div = document.createElement('div');
12361 Ext.DomHelper.overwrite(div, this.autoEl);
12362 this.el = div.firstChild;
12365 this.el.id = this.getId();
12369 this.el = Ext.get(this.el);
12370 if(this.allowDomMove !== false){
12371 ct.dom.insertBefore(this.el.dom, position);
12376 getAutoCreate : function(){
12377 var cfg = typeof this.autoCreate == "object" ?
12378 this.autoCreate : Ext.apply({}, this.defaultAutoCreate);
12379 if(this.id && !cfg.id){
12385 afterRender : Ext.emptyFn,
12388 destroy : function(){
12389 if(this.fireEvent("beforedestroy", this) !== false){
12390 this.beforeDestroy();
12392 this.el.removeAllListeners();
12394 if(this.actionMode == "container"){
12395 this.container.remove();
12399 Ext.ComponentMgr.unregister(this);
12400 this.fireEvent("destroy", this);
12401 this.purgeListeners();
12405 beforeDestroy : Ext.emptyFn,
12407 onDestroy : Ext.emptyFn,
12410 getEl : function(){
12415 getId : function(){
12416 return this.id || (this.id = "ext-comp-" + (++Ext.Component.AUTO_ID));
12420 getItemId : function(){
12421 return this.itemId || this.getId();
12425 focus : function(selectText, delay){
12427 this.focus.defer(typeof delay == 'number' ? delay : 10, this, [selectText, false]);
12432 if(selectText === true){
12433 this.el.dom.select();
12447 disable : function(){
12451 this.disabled = true;
12452 this.fireEvent("disable", this);
12456 onDisable : function(){
12457 this.getActionEl().addClass(this.disabledClass);
12458 this.el.dom.disabled = true;
12462 enable : function(){
12466 this.disabled = false;
12467 this.fireEvent("enable", this);
12471 onEnable : function(){
12472 this.getActionEl().removeClass(this.disabledClass);
12473 this.el.dom.disabled = false;
12477 setDisabled : function(disabled){
12478 this[disabled ? "disable" : "enable"]();
12483 if(this.fireEvent("beforeshow", this) !== false){
12484 this.hidden = false;
12485 if(this.autoRender){
12486 this.render(typeof this.autoRender == 'boolean' ? Ext.getBody() : this.autoRender);
12491 this.fireEvent("show", this);
12496 onShow : function(){
12497 if(this.hideParent){
12498 this.container.removeClass('x-hide-' + this.hideMode);
12500 this.getActionEl().removeClass('x-hide-' + this.hideMode);
12507 if(this.fireEvent("beforehide", this) !== false){
12508 this.hidden = true;
12512 this.fireEvent("hide", this);
12517 onHide : function(){
12518 if(this.hideParent){
12519 this.container.addClass('x-hide-' + this.hideMode);
12521 this.getActionEl().addClass('x-hide-' + this.hideMode);
12526 setVisible: function(visible){
12536 isVisible : function(){
12537 return this.rendered && this.getActionEl().isVisible();
12541 cloneConfig : function(overrides){
12542 overrides = overrides || {};
12543 var id = overrides.id || Ext.id();
12544 var cfg = Ext.applyIf(overrides, this.initialConfig);
12545 cfg.id = id; return new this.constructor(cfg);
12549 getXType : function(){
12550 return this.constructor.xtype;
12554 isXType : function(xtype, shallow){
12556 ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 :
12557 this.constructor.xtype == xtype;
12561 getXTypes : function(){
12562 var tc = this.constructor;
12564 var c = [], sc = this;
12565 while(sc && sc.constructor.xtype){
12566 c.unshift(sc.constructor.xtype);
12567 sc = sc.constructor.superclass;
12570 tc.xtypes = c.join('/');
12576 findParentBy: function(fn) {
12577 for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt);
12582 findParentByType: function(xtype) {
12583 return typeof xtype == 'function' ?
12584 this.findParentBy(function(p){
12585 return p.constructor === xtype;
12587 this.findParentBy(function(p){
12588 return p.constructor.xtype === xtype;
12593 Ext.reg('component', Ext.Component);
12596 Ext.Action = function(config){
12597 this.initialConfig = config;
12601 Ext.Action.prototype = {
12613 setText : function(text){
12614 this.initialConfig.text = text;
12615 this.callEach('setText', [text]);
12619 getText : function(){
12620 return this.initialConfig.text;
12624 setIconClass : function(cls){
12625 this.initialConfig.iconCls = cls;
12626 this.callEach('setIconClass', [cls]);
12630 getIconClass : function(){
12631 return this.initialConfig.iconCls;
12635 setDisabled : function(v){
12636 this.initialConfig.disabled = v;
12637 this.callEach('setDisabled', [v]);
12641 enable : function(){
12642 this.setDisabled(false);
12646 disable : function(){
12647 this.setDisabled(true);
12651 isDisabled : function(){
12652 return this.initialConfig.disabled;
12656 setHidden : function(v){
12657 this.initialConfig.hidden = v;
12658 this.callEach('setVisible', [!v]);
12663 this.setHidden(false);
12668 this.setHidden(true);
12672 isHidden : function(){
12673 return this.initialConfig.hidden;
12677 setHandler : function(fn, scope){
12678 this.initialConfig.handler = fn;
12679 this.initialConfig.scope = scope;
12680 this.callEach('setHandler', [fn, scope]);
12684 each : function(fn, scope){
12685 Ext.each(this.items, fn, scope);
12689 callEach : function(fnName, args){
12690 var cs = this.items;
12691 for(var i = 0, len = cs.length; i < len; i++){
12692 cs[i][fnName].apply(cs[i], args);
12697 addComponent : function(comp){
12698 this.items.push(comp);
12699 comp.on('destroy', this.removeComponent, this);
12703 removeComponent : function(comp){
12704 this.items.remove(comp);
12707 execute : function(){
12708 this.initialConfig.handler.apply(this.initialConfig.scope || window, arguments);
12713 Ext.Layer = function(config, existingEl){
12714 config = config || {};
12715 var dh = Ext.DomHelper;
12716 var cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body;
12718 this.dom = Ext.getDom(existingEl);
12721 var o = config.dh || {tag: "div", cls: "x-layer"};
12722 this.dom = dh.append(pel, o);
12725 this.addClass(config.cls);
12727 this.constrain = config.constrain !== false;
12728 this.visibilityMode = Ext.Element.VISIBILITY;
12730 this.id = this.dom.id = config.id;
12732 this.id = Ext.id(this.dom);
12734 this.zindex = config.zindex || this.getZIndex();
12735 this.position("absolute", this.zindex);
12737 this.shadowOffset = config.shadowOffset || 4;
12738 this.shadow = new Ext.Shadow({
12739 offset : this.shadowOffset,
12740 mode : config.shadow
12743 this.shadowOffset = 0;
12745 this.useShim = config.shim !== false && Ext.useShims;
12746 this.useDisplay = config.useDisplay;
12750 var supr = Ext.Element.prototype;
12755 Ext.extend(Ext.Layer, Ext.Element, {
12757 getZIndex : function(){
12758 return this.zindex || parseInt(this.getStyle("z-index"), 10) || 11000;
12761 getShim : function(){
12768 var shim = shims.shift();
12770 shim = this.createShim();
12771 shim.enableDisplayMode('block');
12772 shim.dom.style.display = 'none';
12773 shim.dom.style.visibility = 'visible';
12775 var pn = this.dom.parentNode;
12776 if(shim.dom.parentNode != pn){
12777 pn.insertBefore(shim.dom, this.dom);
12779 shim.setStyle('z-index', this.getZIndex()-2);
12784 hideShim : function(){
12786 this.shim.setDisplayed(false);
12787 shims.push(this.shim);
12792 disableShadow : function(){
12794 this.shadowDisabled = true;
12795 this.shadow.hide();
12796 this.lastShadowOffset = this.shadowOffset;
12797 this.shadowOffset = 0;
12801 enableShadow : function(show){
12803 this.shadowDisabled = false;
12804 this.shadowOffset = this.lastShadowOffset;
12805 delete this.lastShadowOffset;
12815 sync : function(doShow){
12816 var sw = this.shadow;
12817 if(!this.updating && this.isVisible() && (sw || this.useShim)){
12818 var sh = this.getShim();
12820 var w = this.getWidth(),
12821 h = this.getHeight();
12823 var l = this.getLeft(true),
12824 t = this.getTop(true);
12826 if(sw && !this.shadowDisabled){
12827 if(doShow && !sw.isVisible()){
12830 sw.realign(l, t, w, h);
12837 var a = sw.adjusts, s = sh.dom.style;
12838 s.left = (Math.min(l, l+a.l))+"px";
12839 s.top = (Math.min(t, t+a.t))+"px";
12840 s.width = (w+a.w)+"px";
12841 s.height = (h+a.h)+"px";
12848 sh.setLeftTop(l, t);
12855 destroy : function(){
12858 this.shadow.hide();
12860 this.removeAllListeners();
12861 Ext.removeNode(this.dom);
12862 Ext.Element.uncache(this.id);
12865 remove : function(){
12870 beginUpdate : function(){
12871 this.updating = true;
12875 endUpdate : function(){
12876 this.updating = false;
12881 hideUnders : function(negOffset){
12883 this.shadow.hide();
12889 constrainXY : function(){
12890 if(this.constrain){
12891 var vw = Ext.lib.Dom.getViewWidth(),
12892 vh = Ext.lib.Dom.getViewHeight();
12893 var s = Ext.getDoc().getScroll();
12895 var xy = this.getXY();
12896 var x = xy[0], y = xy[1];
12897 var w = this.dom.offsetWidth+this.shadowOffset, h = this.dom.offsetHeight+this.shadowOffset;
12901 if((x + w) > vw+s.left){
12902 x = vw - w - this.shadowOffset;
12905 if((y + h) > vh+s.top){
12906 y = vh - h - this.shadowOffset;
12920 var ay = this.avoidY;
12921 if(y <= ay && (y+h) >= ay){
12927 supr.setXY.call(this, xy);
12933 isVisible : function(){
12934 return this.visible;
12938 showAction : function(){
12939 this.visible = true;
12940 if(this.useDisplay === true){
12941 this.setDisplayed("");
12942 }else if(this.lastXY){
12943 supr.setXY.call(this, this.lastXY);
12944 }else if(this.lastLT){
12945 supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]);
12950 hideAction : function(){
12951 this.visible = false;
12952 if(this.useDisplay === true){
12953 this.setDisplayed(false);
12955 this.setLeftTop(-10000,-10000);
12960 setVisible : function(v, a, d, c, e){
12965 var cb = function(){
12970 }.createDelegate(this);
12971 supr.setVisible.call(this, true, true, d, cb, e);
12974 this.hideUnders(true);
12983 }.createDelegate(this);
12985 supr.setVisible.call(this, v, a, d, cb, e);
12994 storeXY : function(xy){
12995 delete this.lastLT;
12999 storeLeftTop : function(left, top){
13000 delete this.lastXY;
13001 this.lastLT = [left, top];
13005 beforeFx : function(){
13006 this.beforeAction();
13007 return Ext.Layer.superclass.beforeFx.apply(this, arguments);
13011 afterFx : function(){
13012 Ext.Layer.superclass.afterFx.apply(this, arguments);
13013 this.sync(this.isVisible());
13017 beforeAction : function(){
13018 if(!this.updating && this.shadow){
13019 this.shadow.hide();
13024 setLeft : function(left){
13025 this.storeLeftTop(left, this.getTop(true));
13026 supr.setLeft.apply(this, arguments);
13030 setTop : function(top){
13031 this.storeLeftTop(this.getLeft(true), top);
13032 supr.setTop.apply(this, arguments);
13036 setLeftTop : function(left, top){
13037 this.storeLeftTop(left, top);
13038 supr.setLeftTop.apply(this, arguments);
13042 setXY : function(xy, a, d, c, e){
13044 this.beforeAction();
13046 var cb = this.createCB(c);
13047 supr.setXY.call(this, xy, a, d, cb, e);
13054 createCB : function(c){
13066 setX : function(x, a, d, c, e){
13067 this.setXY([x, this.getY()], a, d, c, e);
13071 setY : function(y, a, d, c, e){
13072 this.setXY([this.getX(), y], a, d, c, e);
13076 setSize : function(w, h, a, d, c, e){
13077 this.beforeAction();
13078 var cb = this.createCB(c);
13079 supr.setSize.call(this, w, h, a, d, cb, e);
13086 setWidth : function(w, a, d, c, e){
13087 this.beforeAction();
13088 var cb = this.createCB(c);
13089 supr.setWidth.call(this, w, a, d, cb, e);
13096 setHeight : function(h, a, d, c, e){
13097 this.beforeAction();
13098 var cb = this.createCB(c);
13099 supr.setHeight.call(this, h, a, d, cb, e);
13106 setBounds : function(x, y, w, h, a, d, c, e){
13107 this.beforeAction();
13108 var cb = this.createCB(c);
13110 this.storeXY([x, y]);
13111 supr.setXY.call(this, [x, y]);
13112 supr.setSize.call(this, w, h, a, d, cb, e);
13115 supr.setBounds.call(this, x, y, w, h, a, d, cb, e);
13121 setZIndex : function(zindex){
13122 this.zindex = zindex;
13123 this.setStyle("z-index", zindex + 2);
13125 this.shadow.setZIndex(zindex + 1);
13128 this.shim.setStyle("z-index", zindex);
13134 Ext.Shadow = function(config){
13135 Ext.apply(this, config);
13136 if(typeof this.mode != "string"){
13137 this.mode = this.defaultMode;
13139 var o = this.offset, a = {h: 0};
13140 var rad = Math.floor(this.offset/2);
13141 switch(this.mode.toLowerCase()){ case "drop":
13146 a.l -= this.offset + rad;
13147 a.t -= this.offset + rad;
13158 a.l -= (this.offset - rad);
13159 a.t -= this.offset + rad;
13161 a.w -= (this.offset - rad)*2;
13172 a.l -= (this.offset - rad);
13173 a.t -= (this.offset - rad);
13175 a.w -= (this.offset + rad + 1);
13176 a.h -= (this.offset + rad);
13185 Ext.Shadow.prototype = {
13190 defaultMode: "drop",
13193 show : function(target){
13194 target = Ext.get(target);
13196 this.el = Ext.Shadow.Pool.pull();
13197 if(this.el.dom.nextSibling != target.dom){
13198 this.el.insertBefore(target);
13201 this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10)-1);
13203 this.el.dom.style.filter="progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius="+(this.offset)+")";
13206 target.getLeft(true),
13207 target.getTop(true),
13211 this.el.dom.style.display = "block";
13215 isVisible : function(){
13216 return this.el ? true : false;
13220 realign : function(l, t, w, h){
13224 var a = this.adjusts, d = this.el.dom, s = d.style;
13226 s.left = (l+a.l)+"px";
13227 s.top = (t+a.t)+"px";
13228 var sw = (w+a.w), sh = (h+a.h), sws = sw +"px", shs = sh + "px";
13229 if(s.width != sws || s.height != shs){
13233 var cn = d.childNodes;
13234 var sww = Math.max(0, (sw-12))+"px";
13235 cn[0].childNodes[1].style.width = sww;
13236 cn[1].childNodes[1].style.width = sww;
13237 cn[2].childNodes[1].style.width = sww;
13238 cn[1].style.height = Math.max(0, (sh-12))+"px";
13246 this.el.dom.style.display = "none";
13247 Ext.Shadow.Pool.push(this.el);
13253 setZIndex : function(z){
13256 this.el.setStyle("z-index", z);
13261 Ext.Shadow.Pool = function(){
13263 var markup = Ext.isIE ?
13264 '<div class="x-ie-shadow"></div>' :
13265 '<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>';
13268 var sh = p.shift();
13270 sh = Ext.get(Ext.DomHelper.insertHtml("beforeBegin", document.body.firstChild, markup));
13271 sh.autoBoxAdjust = false;
13276 push : function(sh){
13282 Ext.BoxComponent = Ext.extend(Ext.Component, {
13293 initComponent : function(){
13294 Ext.BoxComponent.superclass.initComponent.call(this);
13304 deferHeight: false,
13307 setSize : function(w, h){
13308 if(typeof w == 'object'){
13312 if(!this.boxReady){
13318 if(this.lastSize && this.lastSize.width == w && this.lastSize.height == h){
13321 this.lastSize = {width: w, height: h};
13322 var adj = this.adjustSize(w, h);
13323 var aw = adj.width, ah = adj.height;
13324 if(aw !== undefined || ah !== undefined){ var rz = this.getResizeEl();
13325 if(!this.deferHeight && aw !== undefined && ah !== undefined){
13326 rz.setSize(aw, ah);
13327 }else if(!this.deferHeight && ah !== undefined){
13329 }else if(aw !== undefined){
13332 this.onResize(aw, ah, w, h);
13333 this.fireEvent('resize', this, aw, ah, w, h);
13339 setWidth : function(width){
13340 return this.setSize(width);
13344 setHeight : function(height){
13345 return this.setSize(undefined, height);
13349 getSize : function(){
13350 return this.el.getSize();
13354 getPosition : function(local){
13355 if(local === true){
13356 return [this.el.getLeft(true), this.el.getTop(true)];
13358 return this.xy || this.el.getXY();
13362 getBox : function(local){
13363 var s = this.el.getSize();
13364 if(local === true){
13365 s.x = this.el.getLeft(true);
13366 s.y = this.el.getTop(true);
13368 var xy = this.xy || this.el.getXY();
13376 updateBox : function(box){
13377 this.setSize(box.width, box.height);
13378 this.setPagePosition(box.x, box.y);
13382 getResizeEl : function(){
13383 return this.resizeEl || this.el;
13386 getPositionEl : function(){
13387 return this.positionEl || this.el;
13391 setPosition : function(x, y){
13392 if(x && typeof x[1] == 'number'){
13398 if(!this.boxReady){
13401 var adj = this.adjustPosition(x, y);
13402 var ax = adj.x, ay = adj.y;
13404 var el = this.getPositionEl();
13405 if(ax !== undefined || ay !== undefined){
13406 if(ax !== undefined && ay !== undefined){
13407 el.setLeftTop(ax, ay);
13408 }else if(ax !== undefined){
13410 }else if(ay !== undefined){
13413 this.onPosition(ax, ay);
13414 this.fireEvent('move', this, ax, ay);
13420 setPagePosition : function(x, y){
13421 if(x && typeof x[1] == 'number'){
13427 if(!this.boxReady){
13430 if(x === undefined || y === undefined){ return;
13432 var p = this.el.translatePoints(x, y);
13433 this.setPosition(p.left, p.top);
13437 onRender : function(ct, position){
13438 Ext.BoxComponent.superclass.onRender.call(this, ct, position);
13440 this.resizeEl = Ext.get(this.resizeEl);
13442 if(this.positionEl){
13443 this.positionEl = Ext.get(this.positionEl);
13447 afterRender : function(){
13448 Ext.BoxComponent.superclass.afterRender.call(this);
13449 this.boxReady = true;
13450 this.setSize(this.width, this.height);
13451 if(this.x || this.y){
13452 this.setPosition(this.x, this.y);
13453 }else if(this.pageX || this.pageY){
13454 this.setPagePosition(this.pageX, this.pageY);
13459 syncSize : function(){
13460 delete this.lastSize;
13461 this.setSize(this.autoWidth ? undefined : this.el.getWidth(), this.autoHeight ? undefined : this.el.getHeight());
13466 onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
13471 onPosition : function(x, y){
13475 adjustSize : function(w, h){
13476 if(this.autoWidth){
13479 if(this.autoHeight){
13482 return {width : w, height: h};
13485 adjustPosition : function(x, y){
13486 return {x : x, y: y};
13489 Ext.reg('box', Ext.BoxComponent);
13491 Ext.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){
13494 this.el = Ext.get(dragElement, true);
13495 this.el.dom.unselectable = "on";
13497 this.resizingEl = Ext.get(resizingElement, true);
13500 this.orientation = orientation || Ext.SplitBar.HORIZONTAL;
13506 this.maxSize = 2000;
13509 this.animate = false;
13512 this.useShim = false;
13517 if(!existingProxy){
13519 this.proxy = Ext.SplitBar.createProxy(this.orientation);
13521 this.proxy = Ext.get(existingProxy).dom;
13524 this.dd = new Ext.dd.DDProxy(this.el.dom.id, "XSplitBars", {dragElId : this.proxy.id});
13527 this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this);
13530 this.dd.endDrag = this.onEndProxyDrag.createDelegate(this);
13533 this.dragSpecs = {};
13536 this.adapter = new Ext.SplitBar.BasicLayoutAdapter();
13537 this.adapter.init(this);
13539 if(this.orientation == Ext.SplitBar.HORIZONTAL){
13541 this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? Ext.SplitBar.LEFT : Ext.SplitBar.RIGHT);
13542 this.el.addClass("x-splitbar-h");
13545 this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? Ext.SplitBar.TOP : Ext.SplitBar.BOTTOM);
13546 this.el.addClass("x-splitbar-v");
13560 Ext.SplitBar.superclass.constructor.call(this);
13563 Ext.extend(Ext.SplitBar, Ext.util.Observable, {
13564 onStartProxyDrag : function(x, y){
13565 this.fireEvent("beforeresize", this);
13566 this.overlay = Ext.DomHelper.append(document.body, {cls: "x-drag-overlay", html: " "}, true);
13567 this.overlay.unselectable();
13568 this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
13569 this.overlay.show();
13570 Ext.get(this.proxy).setDisplayed("block");
13571 var size = this.adapter.getElementSize(this);
13572 this.activeMinSize = this.getMinimumSize();;
13573 this.activeMaxSize = this.getMaximumSize();;
13574 var c1 = size - this.activeMinSize;
13575 var c2 = Math.max(this.activeMaxSize - size, 0);
13576 if(this.orientation == Ext.SplitBar.HORIZONTAL){
13577 this.dd.resetConstraints();
13578 this.dd.setXConstraint(
13579 this.placement == Ext.SplitBar.LEFT ? c1 : c2,
13580 this.placement == Ext.SplitBar.LEFT ? c2 : c1
13582 this.dd.setYConstraint(0, 0);
13584 this.dd.resetConstraints();
13585 this.dd.setXConstraint(0, 0);
13586 this.dd.setYConstraint(
13587 this.placement == Ext.SplitBar.TOP ? c1 : c2,
13588 this.placement == Ext.SplitBar.TOP ? c2 : c1
13591 this.dragSpecs.startSize = size;
13592 this.dragSpecs.startPoint = [x, y];
13593 Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd, x, y);
13597 onEndProxyDrag : function(e){
13598 Ext.get(this.proxy).setDisplayed(false);
13599 var endPoint = Ext.lib.Event.getXY(e);
13601 this.overlay.remove();
13602 delete this.overlay;
13605 if(this.orientation == Ext.SplitBar.HORIZONTAL){
13606 newSize = this.dragSpecs.startSize +
13607 (this.placement == Ext.SplitBar.LEFT ?
13608 endPoint[0] - this.dragSpecs.startPoint[0] :
13609 this.dragSpecs.startPoint[0] - endPoint[0]
13612 newSize = this.dragSpecs.startSize +
13613 (this.placement == Ext.SplitBar.TOP ?
13614 endPoint[1] - this.dragSpecs.startPoint[1] :
13615 this.dragSpecs.startPoint[1] - endPoint[1]
13618 newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize);
13619 if(newSize != this.dragSpecs.startSize){
13620 if(this.fireEvent('beforeapply', this, newSize) !== false){
13621 this.adapter.setElementSize(this, newSize);
13622 this.fireEvent("moved", this, newSize);
13623 this.fireEvent("resize", this, newSize);
13629 getAdapter : function(){
13630 return this.adapter;
13634 setAdapter : function(adapter){
13635 this.adapter = adapter;
13636 this.adapter.init(this);
13640 getMinimumSize : function(){
13641 return this.minSize;
13645 setMinimumSize : function(minSize){
13646 this.minSize = minSize;
13650 getMaximumSize : function(){
13651 return this.maxSize;
13655 setMaximumSize : function(maxSize){
13656 this.maxSize = maxSize;
13660 setCurrentSize : function(size){
13661 var oldAnimate = this.animate;
13662 this.animate = false;
13663 this.adapter.setElementSize(this, size);
13664 this.animate = oldAnimate;
13668 destroy : function(removeEl){
13670 this.shim.remove();
13673 Ext.removeNode(this.proxy);
13681 Ext.SplitBar.createProxy = function(dir){
13682 var proxy = new Ext.Element(document.createElement("div"));
13683 proxy.unselectable();
13684 var cls = 'x-splitbar-proxy';
13685 proxy.addClass(cls + ' ' + (dir == Ext.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v'));
13686 document.body.appendChild(proxy.dom);
13691 Ext.SplitBar.BasicLayoutAdapter = function(){
13694 Ext.SplitBar.BasicLayoutAdapter.prototype = {
13696 init : function(s){
13700 getElementSize : function(s){
13701 if(s.orientation == Ext.SplitBar.HORIZONTAL){
13702 return s.resizingEl.getWidth();
13704 return s.resizingEl.getHeight();
13709 setElementSize : function(s, newSize, onComplete){
13710 if(s.orientation == Ext.SplitBar.HORIZONTAL){
13712 s.resizingEl.setWidth(newSize);
13714 onComplete(s, newSize);
13717 s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut');
13722 s.resizingEl.setHeight(newSize);
13724 onComplete(s, newSize);
13727 s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut');
13734 Ext.SplitBar.AbsoluteLayoutAdapter = function(container){
13735 this.basic = new Ext.SplitBar.BasicLayoutAdapter();
13736 this.container = Ext.get(container);
13739 Ext.SplitBar.AbsoluteLayoutAdapter.prototype = {
13740 init : function(s){
13741 this.basic.init(s);
13744 getElementSize : function(s){
13745 return this.basic.getElementSize(s);
13748 setElementSize : function(s, newSize, onComplete){
13749 this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s]));
13752 moveSplitter : function(s){
13753 var yes = Ext.SplitBar;
13754 switch(s.placement){
13756 s.el.setX(s.resizingEl.getRight());
13759 s.el.setStyle("right", (this.container.getWidth() - s.resizingEl.getLeft()) + "px");
13762 s.el.setY(s.resizingEl.getBottom());
13765 s.el.setY(s.resizingEl.getTop() - s.el.getHeight());
13772 Ext.SplitBar.VERTICAL = 1;
13775 Ext.SplitBar.HORIZONTAL = 2;
13778 Ext.SplitBar.LEFT = 1;
13781 Ext.SplitBar.RIGHT = 2;
13784 Ext.SplitBar.TOP = 3;
13787 Ext.SplitBar.BOTTOM = 4;
13790 Ext.Container = Ext.extend(Ext.BoxComponent, {
13803 defaultType: 'panel',
13805 initComponent : function(){
13806 Ext.Container.superclass.initComponent.call(this);
13822 var items = this.items;
13825 if(Ext.isArray(items)){
13826 this.add.apply(this, items);
13833 initItems : function(){
13835 this.items = new Ext.util.MixedCollection(false, this.getComponentId);
13836 this.getLayout(); }
13839 setLayout : function(layout){
13840 if(this.layout && this.layout != layout){
13841 this.layout.setContainer(null);
13844 this.layout = layout;
13845 layout.setContainer(this);
13848 render : function(){
13849 Ext.Container.superclass.render.apply(this, arguments);
13851 if(typeof this.layout == 'string'){
13852 this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);
13854 this.setLayout(this.layout);
13856 if(this.activeItem !== undefined){
13857 var item = this.activeItem;
13858 delete this.activeItem;
13859 this.layout.setActiveItem(item);
13866 if(this.monitorResize === true){
13867 Ext.EventManager.onWindowResize(this.doLayout, this, [false]);
13871 getLayoutTarget : function(){
13875 getComponentId : function(comp){
13876 return comp.itemId || comp.id;
13880 add : function(comp){
13884 var a = arguments, len = a.length;
13886 for(var i = 0; i < len; i++) {
13891 var c = this.lookupComponent(this.applyDefaults(comp));
13892 var pos = this.items.length;
13893 if(this.fireEvent('beforeadd', this, c, pos) !== false && this.onBeforeAdd(c) !== false){
13896 this.fireEvent('add', this, c, pos);
13902 insert : function(index, comp){
13906 var a = arguments, len = a.length;
13908 for(var i = len-1; i >= 1; --i) {
13909 this.insert(index, a[i]);
13913 var c = this.lookupComponent(this.applyDefaults(comp));
13915 if(c.ownerCt == this && this.items.indexOf(c) < index){
13919 if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){
13920 this.items.insert(index, c);
13922 this.fireEvent('add', this, c, index);
13927 applyDefaults : function(c){
13929 if(typeof c == 'string'){
13930 c = Ext.ComponentMgr.get(c);
13931 Ext.apply(c, this.defaults);
13932 }else if(!c.events){
13933 Ext.applyIf(c, this.defaults);
13935 Ext.apply(c, this.defaults);
13941 onBeforeAdd : function(item){
13943 item.ownerCt.remove(item, false);
13945 if(this.hideBorders === true){
13946 item.border = (item.border === true);
13951 remove : function(comp, autoDestroy){
13952 var c = this.getComponent(comp);
13953 if(c && this.fireEvent('beforeremove', this, c) !== false){
13954 this.items.remove(c);
13956 if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){
13959 if(this.layout && this.layout.activeItem == c){
13960 delete this.layout.activeItem;
13962 this.fireEvent('remove', this, c);
13968 getComponent : function(comp){
13969 if(typeof comp == 'object'){
13972 return this.items.get(comp);
13975 lookupComponent : function(comp){
13976 if(typeof comp == 'string'){
13977 return Ext.ComponentMgr.get(comp);
13978 }else if(!comp.events){
13979 return this.createComponent(comp);
13984 createComponent : function(config){
13985 return Ext.ComponentMgr.create(config, this.defaultType);
13989 doLayout : function(shallow){
13990 if(this.rendered && this.layout){
13991 this.layout.layout();
13993 if(shallow !== false && this.items){
13994 var cs = this.items.items;
13995 for(var i = 0, len = cs.length; i < len; i++) {
14005 getLayout : function(){
14007 var layout = new Ext.layout.ContainerLayout(this.layoutConfig);
14008 this.setLayout(layout);
14010 return this.layout;
14013 onDestroy : function(){
14015 var cs = this.items.items;
14016 for(var i = 0, len = cs.length; i < len; i++) {
14017 Ext.destroy(cs[i]);
14020 if(this.monitorResize){
14021 Ext.EventManager.removeResizeListener(this.doLayout, this);
14023 Ext.Container.superclass.onDestroy.call(this);
14027 bubble : function(fn, scope, args){
14030 if(fn.apply(scope || p, args || [p]) === false){
14038 cascade : function(fn, scope, args){
14039 if(fn.apply(scope || this, args || [this]) !== false){
14041 var cs = this.items.items;
14042 for(var i = 0, len = cs.length; i < len; i++){
14044 cs[i].cascade(fn, scope, args);
14046 fn.apply(scope || this, args || [cs[i]]);
14054 findById : function(id){
14056 this.cascade(function(c){
14057 if(ct != c && c.id === id){
14066 findByType : function(xtype){
14067 return typeof xtype == 'function' ?
14068 this.findBy(function(c){
14069 return c.constructor === xtype;
14071 this.findBy(function(c){
14072 return c.constructor.xtype === xtype;
14077 find : function(prop, value){
14078 return this.findBy(function(c){
14079 return c[prop] === value;
14084 findBy : function(fn, scope){
14085 var m = [], ct = this;
14086 this.cascade(function(c){
14087 if(ct != c && fn.call(scope || c, c, ct) === true){
14095 Ext.Container.LAYOUTS = {};
14096 Ext.reg('container', Ext.Container);
14098 Ext.layout.ContainerLayout = function(config){
14099 Ext.apply(this, config);
14102 Ext.layout.ContainerLayout.prototype = {
14108 monitorResize:false,
14111 layout : function(){
14112 var target = this.container.getLayoutTarget();
14113 this.onLayout(this.container, target);
14114 this.container.fireEvent('afterlayout', this.container, this);
14117 onLayout : function(ct, target){
14118 this.renderAll(ct, target);
14121 isValidParent : function(c, target){
14122 var el = c.getPositionEl ? c.getPositionEl() : c.getEl();
14123 return el.dom.parentNode == target.dom;
14126 renderAll : function(ct, target){
14127 var items = ct.items.items;
14128 for(var i = 0, len = items.length; i < len; i++) {
14130 if(c && (!c.rendered || !this.isValidParent(c, target))){
14131 this.renderItem(c, i, target);
14136 renderItem : function(c, position, target){
14137 if(c && !c.rendered){
14138 c.render(target, position);
14140 var t = c.getPositionEl ? c.getPositionEl() : c;
14141 t.addClass(this.extraCls);
14143 if (this.renderHidden && c != this.activeItem) {
14146 }else if(c && !this.isValidParent(c, target)){
14148 c.addClass(this.extraCls);
14150 if(typeof position == 'number'){
14151 position = target.dom.childNodes[position];
14153 target.dom.insertBefore(c.getEl().dom, position || null);
14154 if (this.renderHidden && c != this.activeItem) {
14160 onResize: function(){
14161 if(this.container.collapsed){
14164 var b = this.container.bufferResize;
14166 if(!this.resizeTask){
14167 this.resizeTask = new Ext.util.DelayedTask(this.layout, this);
14168 this.resizeBuffer = typeof b == 'number' ? b : 100;
14170 this.resizeTask.delay(this.resizeBuffer);
14176 setContainer : function(ct){
14177 if(this.monitorResize && ct != this.container){
14178 if(this.container){
14179 this.container.un('resize', this.onResize, this);
14182 ct.on('resize', this.onResize, this);
14185 this.container = ct;
14188 parseMargins : function(v){
14189 var ms = v.split(' ');
14190 var len = ms.length;
14201 top:parseInt(ms[0], 10) || 0,
14202 right:parseInt(ms[1], 10) || 0,
14203 bottom:parseInt(ms[2], 10) || 0,
14204 left:parseInt(ms[3], 10) || 0
14208 Ext.Container.LAYOUTS['auto'] = Ext.layout.ContainerLayout;
14210 Ext.layout.FitLayout = Ext.extend(Ext.layout.ContainerLayout, {
14212 monitorResize:true,
14215 onLayout : function(ct, target){
14216 Ext.layout.FitLayout.superclass.onLayout.call(this, ct, target);
14217 if(!this.container.collapsed){
14218 this.setItemSize(this.activeItem || ct.items.itemAt(0), target.getStyleSize());
14223 setItemSize : function(item, size){
14224 if(item && size.height > 0){
14225 item.setSize(size);
14229 Ext.Container.LAYOUTS['fit'] = Ext.layout.FitLayout;
14231 Ext.layout.CardLayout = Ext.extend(Ext.layout.FitLayout, {
14233 deferredRender : false,
14236 renderHidden : true,
14239 setActiveItem : function(item){
14240 item = this.container.getComponent(item);
14241 if(this.activeItem != item){
14242 if(this.activeItem){
14243 this.activeItem.hide();
14245 this.activeItem = item;
14252 renderAll : function(ct, target){
14253 if(this.deferredRender){
14254 this.renderItem(this.activeItem, undefined, target);
14256 Ext.layout.CardLayout.superclass.renderAll.call(this, ct, target);
14260 Ext.Container.LAYOUTS['card'] = Ext.layout.CardLayout;
14262 Ext.layout.AnchorLayout = Ext.extend(Ext.layout.ContainerLayout, {
14264 monitorResize:true,
14267 getAnchorViewSize : function(ct, target){
14268 return target.dom == document.body ?
14269 target.getViewSize() : target.getStyleSize();
14273 onLayout : function(ct, target){
14274 Ext.layout.AnchorLayout.superclass.onLayout.call(this, ct, target);
14276 var size = this.getAnchorViewSize(ct, target);
14278 var w = size.width, h = size.height;
14280 if(w < 20 || h < 20){
14287 if(typeof ct.anchorSize == 'number'){
14288 aw = ct.anchorSize;
14290 aw = ct.anchorSize.width;
14291 ah = ct.anchorSize.height;
14294 aw = ct.initialConfig.width;
14295 ah = ct.initialConfig.height;
14298 var cs = ct.items.items, len = cs.length, i, c, a, cw, ch;
14299 for(i = 0; i < len; i++){
14304 var vs = c.anchor.split(' ');
14305 c.anchorSpec = a = {
14306 right: this.parseAnchor(vs[0], c.initialConfig.width, aw),
14307 bottom: this.parseAnchor(vs[1], c.initialConfig.height, ah)
14310 cw = a.right ? this.adjustWidthAnchor(a.right(w), c) : undefined;
14311 ch = a.bottom ? this.adjustHeightAnchor(a.bottom(h), c) : undefined;
14314 c.setSize(cw || undefined, ch || undefined);
14321 parseAnchor : function(a, start, cstart){
14322 if(a && a != 'none'){
14324 if(/^(r|right|b|bottom)$/i.test(a)){
14325 var diff = cstart - start;
14326 return function(v){
14332 }else if(a.indexOf('%') != -1){
14333 var ratio = parseFloat(a.replace('%', ''))*.01;
14334 return function(v){
14337 return Math.floor(v*ratio);
14341 a = parseInt(a, 10);
14343 return function(v){
14356 adjustWidthAnchor : function(value, comp){
14361 adjustHeightAnchor : function(value, comp){
14367 Ext.Container.LAYOUTS['anchor'] = Ext.layout.AnchorLayout;
14369 Ext.layout.ColumnLayout = Ext.extend(Ext.layout.ContainerLayout, {
14371 monitorResize:true,
14373 extraCls: 'x-column',
14378 isValidParent : function(c, target){
14379 return c.getEl().dom.parentNode == this.innerCt.dom;
14383 onLayout : function(ct, target){
14384 var cs = ct.items.items, len = cs.length, c, i;
14387 target.addClass('x-column-layout-ct');
14391 this.innerCt = target.createChild({cls:'x-column-inner'});
14392 this.innerCt.createChild({cls:'x-clear'});
14394 this.renderAll(ct, this.innerCt);
14396 var size = target.getViewSize();
14398 if(size.width < 1 && size.height < 1){
14402 var w = size.width - target.getPadding('lr') - this.scrollOffset,
14403 h = size.height - target.getPadding('tb'),
14406 this.innerCt.setWidth(w);
14411 for(i = 0; i < len; i++){
14413 if(!c.columnWidth){
14414 pw -= (c.getSize().width + c.getEl().getMargins('lr'));
14418 pw = pw < 0 ? 0 : pw;
14420 for(i = 0; i < len; i++){
14423 c.setSize(Math.floor(c.columnWidth*pw) - c.getEl().getMargins('lr'));
14431 Ext.Container.LAYOUTS['column'] = Ext.layout.ColumnLayout;
14433 Ext.layout.BorderLayout = Ext.extend(Ext.layout.ContainerLayout, {
14434 monitorResize:true,
14437 onLayout : function(ct, target){
14439 if(!this.rendered){
14441 target.addClass('x-border-layout-ct');
14442 var items = ct.items.items;
14444 for(var i = 0, len = items.length; i < len; i++) {
14446 var pos = c.region;
14450 c.collapsed = false;
14452 c.cls = c.cls ? c.cls +' x-border-panel' : 'x-border-panel';
14453 c.render(target, i);
14455 this[pos] = pos != 'center' && c.split ?
14456 new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) :
14457 new Ext.layout.BorderLayout.Region(this, c.initialConfig, pos);
14458 this[pos].render(target, c);
14460 this.rendered = true;
14463 var size = target.getViewSize();
14464 if(size.width < 20 || size.height < 20){ if(collapsed){
14465 this.restoreCollapsed = collapsed;
14468 }else if(this.restoreCollapsed){
14469 collapsed = this.restoreCollapsed;
14470 delete this.restoreCollapsed;
14473 var w = size.width, h = size.height;
14474 var centerW = w, centerH = h, centerY = 0, centerX = 0;
14476 var n = this.north, s = this.south, west = this.west, e = this.east, c = this.center;
14478 throw 'No center region defined in BorderLayout ' + ct.id;
14481 if(n && n.isVisible()){
14482 var b = n.getSize();
14483 var m = n.getMargins();
14484 b.width = w - (m.left+m.right);
14487 centerY = b.height + b.y + m.bottom;
14488 centerH -= centerY;
14491 if(s && s.isVisible()){
14492 var b = s.getSize();
14493 var m = s.getMargins();
14494 b.width = w - (m.left+m.right);
14496 var totalHeight = (b.height + m.top + m.bottom);
14497 b.y = h - totalHeight + m.top;
14498 centerH -= totalHeight;
14501 if(west && west.isVisible()){
14502 var b = west.getSize();
14503 var m = west.getMargins();
14504 b.height = centerH - (m.top+m.bottom);
14506 b.y = centerY + m.top;
14507 var totalWidth = (b.width + m.left + m.right);
14508 centerX += totalWidth;
14509 centerW -= totalWidth;
14510 west.applyLayout(b);
14512 if(e && e.isVisible()){
14513 var b = e.getSize();
14514 var m = e.getMargins();
14515 b.height = centerH - (m.top+m.bottom);
14516 var totalWidth = (b.width + m.left + m.right);
14517 b.x = w - totalWidth + m.left;
14518 b.y = centerY + m.top;
14519 centerW -= totalWidth;
14523 var m = c.getMargins();
14525 x: centerX + m.left,
14526 y: centerY + m.top,
14527 width: centerW - (m.left+m.right),
14528 height: centerH - (m.top+m.bottom)
14530 c.applyLayout(centerBox);
14533 for(var i = 0, len = collapsed.length; i < len; i++){
14534 collapsed[i].collapse(false);
14538 if(Ext.isIE && Ext.isStrict){ target.repaint();
14546 Ext.layout.BorderLayout.Region = function(layout, config, pos){
14547 Ext.apply(this, config);
14548 this.layout = layout;
14549 this.position = pos;
14551 if(typeof this.margins == 'string'){
14552 this.margins = this.layout.parseMargins(this.margins);
14554 this.margins = Ext.applyIf(this.margins || {}, this.defaultMargins);
14555 if(this.collapsible){
14556 if(typeof this.cmargins == 'string'){
14557 this.cmargins = this.layout.parseMargins(this.cmargins);
14559 if(this.collapseMode == 'mini' && !this.cmargins){
14560 this.cmargins = {left:0,top:0,right:0,bottom:0};
14562 this.cmargins = Ext.applyIf(this.cmargins || {},
14563 pos == 'north' || pos == 'south' ? this.defaultNSCMargins : this.defaultEWCMargins);
14568 Ext.layout.BorderLayout.Region.prototype = {
14575 collapsible : false,
14585 defaultMargins : {left:0,top:0,right:0,bottom:0},
14586 defaultNSCMargins : {left:5,top:5,right:5,bottom:5},
14587 defaultEWCMargins : {left:5,top:0,right:5,bottom:0},
14590 isCollapsed : false,
14596 render : function(ct, p){
14598 p.el.enableDisplayMode();
14599 this.targetEl = ct;
14602 var gs = p.getState, ps = this.position;
14603 p.getState = function(){
14604 return Ext.apply(gs.call(p) || {}, this.state);
14605 }.createDelegate(this);
14607 if(ps != 'center'){
14608 p.allowQueuedExpand = false;
14610 beforecollapse: this.beforeCollapse,
14611 collapse: this.onCollapse,
14612 beforeexpand: this.beforeExpand,
14613 expand: this.onExpand,
14618 if(this.collapsible){
14619 p.collapseEl = 'el';
14620 p.slideAnchor = this.getSlideAnchor();
14622 if(p.tools && p.tools.toggle){
14623 p.tools.toggle.addClass('x-tool-collapse-'+ps);
14624 p.tools.toggle.addClassOnOver('x-tool-collapse-'+ps+'-over');
14629 getCollapsedEl : function(){
14630 if(!this.collapsedEl){
14631 if(!this.toolTemplate){
14632 var tt = new Ext.Template(
14633 '<div class="x-tool x-tool-{id}"> </div>'
14635 tt.disableFormats = true;
14637 Ext.layout.BorderLayout.Region.prototype.toolTemplate = tt;
14639 this.collapsedEl = this.targetEl.createChild({
14640 cls: "x-layout-collapsed x-layout-collapsed-"+this.position,
14641 id: this.panel.id + '-xcollapsed'
14643 this.collapsedEl.enableDisplayMode('block');
14645 if(this.collapseMode == 'mini'){
14646 this.collapsedEl.addClass('x-layout-cmini-'+this.position);
14647 this.miniCollapsedEl = this.collapsedEl.createChild({
14648 cls: "x-layout-mini x-layout-mini-"+this.position, html: " "
14650 this.miniCollapsedEl.addClassOnOver('x-layout-mini-over');
14651 this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
14652 this.collapsedEl.on('click', this.onExpandClick, this, {stopEvent:true});
14654 var t = this.toolTemplate.append(
14655 this.collapsedEl.dom,
14656 {id:'expand-'+this.position}, true);
14657 t.addClassOnOver('x-tool-expand-'+this.position+'-over');
14658 t.on('click', this.onExpandClick, this, {stopEvent:true});
14660 if(this.floatable !== false){
14661 this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
14662 this.collapsedEl.on("click", this.collapseClick, this);
14666 return this.collapsedEl;
14669 onExpandClick : function(e){
14671 this.afterSlideIn();
14672 this.panel.expand(false);
14674 this.panel.expand();
14678 onCollapseClick : function(e){
14679 this.panel.collapse();
14682 beforeCollapse : function(p, animate){
14683 this.lastAnim = animate;
14685 this.splitEl.hide();
14687 this.getCollapsedEl().show();
14688 this.panel.el.setStyle('z-index', 100);
14689 this.isCollapsed = true;
14690 this.layout.layout();
14693 onCollapse : function(animate){
14694 this.panel.el.setStyle('z-index', 1);
14695 if(this.lastAnim === false || this.panel.animCollapse === false){
14696 this.getCollapsedEl().dom.style.visibility = 'visible';
14698 this.getCollapsedEl().slideIn(this.panel.slideAnchor, {duration:.2});
14700 this.state.collapsed = true;
14701 this.panel.saveState();
14704 beforeExpand : function(animate){
14705 var c = this.getCollapsedEl();
14707 if(this.position == 'east' || this.position == 'west'){
14708 this.panel.setSize(undefined, c.getHeight());
14710 this.panel.setSize(c.getWidth(), undefined);
14713 c.dom.style.visibility = 'hidden';
14714 this.panel.el.setStyle('z-index', 100);
14717 onExpand : function(){
14718 this.isCollapsed = false;
14720 this.splitEl.show();
14722 this.layout.layout();
14723 this.panel.el.setStyle('z-index', 1);
14724 this.state.collapsed = false;
14725 this.panel.saveState();
14728 collapseClick : function(e){
14730 e.stopPropagation();
14733 e.stopPropagation();
14738 onHide : function(){
14739 if(this.isCollapsed){
14740 this.getCollapsedEl().hide();
14741 }else if(this.splitEl){
14742 this.splitEl.hide();
14746 onShow : function(){
14747 if(this.isCollapsed){
14748 this.getCollapsedEl().show();
14749 }else if(this.splitEl){
14750 this.splitEl.show();
14755 isVisible : function(){
14756 return !this.panel.hidden;
14760 getMargins : function(){
14761 return this.isCollapsed && this.cmargins ? this.cmargins : this.margins;
14765 getSize : function(){
14766 return this.isCollapsed ? this.getCollapsedEl().getSize() : this.panel.getSize();
14770 setPanel : function(panel){
14771 this.panel = panel;
14775 getMinWidth: function(){
14776 return this.minWidth;
14780 getMinHeight: function(){
14781 return this.minHeight;
14784 applyLayoutCollapsed : function(box){
14785 var ce = this.getCollapsedEl();
14786 ce.setLeftTop(box.x, box.y);
14787 ce.setSize(box.width, box.height);
14790 applyLayout : function(box){
14791 if(this.isCollapsed){
14792 this.applyLayoutCollapsed(box);
14794 this.panel.setPosition(box.x, box.y);
14795 this.panel.setSize(box.width, box.height);
14799 beforeSlide: function(){
14800 this.panel.beforeEffect();
14803 afterSlide : function(){
14804 this.panel.afterEffect();
14807 initAutoHide : function(){
14808 if(this.autoHide !== false){
14809 if(!this.autoHideHd){
14810 var st = new Ext.util.DelayedTask(this.slideIn, this);
14811 this.autoHideHd = {
14812 "mouseout": function(e){
14813 if(!e.within(this.el, true)){
14817 "mouseover" : function(e){
14823 this.el.on(this.autoHideHd);
14827 clearAutoHide : function(){
14828 if(this.autoHide !== false){
14829 this.el.un("mouseout", this.autoHideHd.mouseout);
14830 this.el.un("mouseover", this.autoHideHd.mouseover);
14834 clearMonitor : function(){
14835 Ext.getDoc().un("click", this.slideInIf, this);
14838 slideOut : function(){
14839 if(this.isSlid || this.el.hasActiveFx()){
14842 this.isSlid = true;
14843 var ts = this.panel.tools;
14844 if(ts && ts.toggle){
14848 if(this.position == 'east' || this.position == 'west'){
14849 this.panel.setSize(undefined, this.collapsedEl.getHeight());
14851 this.panel.setSize(this.collapsedEl.getWidth(), undefined);
14853 this.restoreLT = [this.el.dom.style.left, this.el.dom.style.top];
14854 this.el.alignTo(this.collapsedEl, this.getCollapseAnchor());
14855 this.el.setStyle("z-index", 102);
14856 if(this.animFloat !== false){
14857 this.beforeSlide();
14858 this.el.slideIn(this.getSlideAnchor(), {
14859 callback: function(){
14861 this.initAutoHide();
14862 Ext.getDoc().on("click", this.slideInIf, this);
14868 this.initAutoHide();
14869 Ext.getDoc().on("click", this.slideInIf, this);
14873 afterSlideIn : function(){
14874 this.clearAutoHide();
14875 this.isSlid = false;
14876 this.clearMonitor();
14877 this.el.setStyle("z-index", "");
14878 this.el.dom.style.left = this.restoreLT[0];
14879 this.el.dom.style.top = this.restoreLT[1];
14881 var ts = this.panel.tools;
14882 if(ts && ts.toggle){
14887 slideIn : function(cb){
14888 if(!this.isSlid || this.el.hasActiveFx()){
14892 this.isSlid = false;
14893 if(this.animFloat !== false){
14894 this.beforeSlide();
14895 this.el.slideOut(this.getSlideAnchor(), {
14896 callback: function(){
14899 this.afterSlideIn();
14907 this.afterSlideIn();
14911 slideInIf : function(e){
14912 if(!e.within(this.el)){
14938 getAnchor : function(){
14939 return this.anchors[this.position];
14942 getCollapseAnchor : function(){
14943 return this.canchors[this.position];
14946 getSlideAnchor : function(){
14947 return this.sanchors[this.position];
14950 getAlignAdj : function(){
14951 var cm = this.cmargins;
14952 switch(this.position){
14968 getExpandAdj : function(){
14969 var c = this.collapsedEl, cm = this.cmargins;
14970 switch(this.position){
14972 return [-(cm.right+c.getWidth()+cm.left), 0];
14975 return [cm.right+c.getWidth()+cm.left, 0];
14978 return [0, -(cm.top+cm.bottom+c.getHeight())];
14981 return [0, cm.top+cm.bottom+c.getHeight()];
14988 Ext.layout.BorderLayout.SplitRegion = function(layout, config, pos){
14989 Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this, layout, config, pos);
14990 this.applyLayout = this.applyFns[pos];
14993 Ext.extend(Ext.layout.BorderLayout.SplitRegion, Ext.layout.BorderLayout.Region, {
14995 splitTip : "Drag to resize.",
14997 collapsibleSplitTip : "Drag to resize. Double click to hide.",
14999 useSplitTips : false,
15003 orientation: Ext.SplitBar.VERTICAL,
15004 placement: Ext.SplitBar.TOP,
15005 maxFn : 'getVMaxSize',
15006 minProp: 'minHeight',
15007 maxProp: 'maxHeight'
15010 orientation: Ext.SplitBar.VERTICAL,
15011 placement: Ext.SplitBar.BOTTOM,
15012 maxFn : 'getVMaxSize',
15013 minProp: 'minHeight',
15014 maxProp: 'maxHeight'
15017 orientation: Ext.SplitBar.HORIZONTAL,
15018 placement: Ext.SplitBar.RIGHT,
15019 maxFn : 'getHMaxSize',
15020 minProp: 'minWidth',
15021 maxProp: 'maxWidth'
15024 orientation: Ext.SplitBar.HORIZONTAL,
15025 placement: Ext.SplitBar.LEFT,
15026 maxFn : 'getHMaxSize',
15027 minProp: 'minWidth',
15028 maxProp: 'maxWidth'
15033 west : function(box){
15034 if(this.isCollapsed){
15035 return this.applyLayoutCollapsed(box);
15037 var sd = this.splitEl.dom, s = sd.style;
15038 this.panel.setPosition(box.x, box.y);
15039 var sw = sd.offsetWidth;
15040 s.left = (box.x+box.width-sw)+'px';
15041 s.top = (box.y)+'px';
15042 s.height = Math.max(0, box.height)+'px';
15043 this.panel.setSize(box.width-sw, box.height);
15045 east : function(box){
15046 if(this.isCollapsed){
15047 return this.applyLayoutCollapsed(box);
15049 var sd = this.splitEl.dom, s = sd.style;
15050 var sw = sd.offsetWidth;
15051 this.panel.setPosition(box.x+sw, box.y);
15052 s.left = (box.x)+'px';
15053 s.top = (box.y)+'px';
15054 s.height = Math.max(0, box.height)+'px';
15055 this.panel.setSize(box.width-sw, box.height);
15057 north : function(box){
15058 if(this.isCollapsed){
15059 return this.applyLayoutCollapsed(box);
15061 var sd = this.splitEl.dom, s = sd.style;
15062 var sh = sd.offsetHeight;
15063 this.panel.setPosition(box.x, box.y);
15064 s.left = (box.x)+'px';
15065 s.top = (box.y+box.height-sh)+'px';
15066 s.width = Math.max(0, box.width)+'px';
15067 this.panel.setSize(box.width, box.height-sh);
15069 south : function(box){
15070 if(this.isCollapsed){
15071 return this.applyLayoutCollapsed(box);
15073 var sd = this.splitEl.dom, s = sd.style;
15074 var sh = sd.offsetHeight;
15075 this.panel.setPosition(box.x, box.y+sh);
15076 s.left = (box.x)+'px';
15077 s.top = (box.y)+'px';
15078 s.width = Math.max(0, box.width)+'px';
15079 this.panel.setSize(box.width, box.height-sh);
15083 render : function(ct, p){
15084 Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p);
15086 var ps = this.position;
15088 this.splitEl = ct.createChild({
15089 cls: "x-layout-split x-layout-split-"+ps, html: " ",
15090 id: this.panel.id + '-xsplit'
15093 if(this.collapseMode == 'mini'){
15094 this.miniSplitEl = this.splitEl.createChild({
15095 cls: "x-layout-mini x-layout-mini-"+ps, html: " "
15097 this.miniSplitEl.addClassOnOver('x-layout-mini-over');
15098 this.miniSplitEl.on('click', this.onCollapseClick, this, {stopEvent:true});
15101 var s = this.splitSettings[ps];
15103 this.split = new Ext.SplitBar(this.splitEl.dom, p.el, s.orientation);
15104 this.split.placement = s.placement;
15105 this.split.getMaximumSize = this[s.maxFn].createDelegate(this);
15106 this.split.minSize = this.minSize || this[s.minProp];
15107 this.split.on("beforeapply", this.onSplitMove, this);
15108 this.split.useShim = this.useShim === true;
15109 this.maxSize = this.maxSize || this[s.maxProp];
15112 this.splitEl.hide();
15115 if(this.useSplitTips){
15116 this.splitEl.dom.title = this.collapsible ? this.collapsibleSplitTip : this.splitTip;
15118 if(this.collapsible){
15119 this.splitEl.on("dblclick", this.onCollapseClick, this);
15123 getSize : function(){
15124 if(this.isCollapsed){
15125 return this.collapsedEl.getSize();
15127 var s = this.panel.getSize();
15128 if(this.position == 'north' || this.position == 'south'){
15129 s.height += this.splitEl.dom.offsetHeight;
15131 s.width += this.splitEl.dom.offsetWidth;
15136 getHMaxSize : function(){
15137 var cmax = this.maxSize || 10000;
15138 var center = this.layout.center;
15139 return Math.min(cmax, (this.el.getWidth()+center.el.getWidth())-center.getMinWidth());
15142 getVMaxSize : function(){
15143 var cmax = this.maxSize || 10000;
15144 var center = this.layout.center;
15145 return Math.min(cmax, (this.el.getHeight()+center.el.getHeight())-center.getMinHeight());
15148 onSplitMove : function(split, newSize){
15149 var s = this.panel.getSize();
15150 this.lastSplitSize = newSize;
15151 if(this.position == 'north' || this.position == 'south'){
15152 this.panel.setSize(s.width, newSize);
15153 this.state.height = newSize;
15155 this.panel.setSize(newSize, s.height);
15156 this.state.width = newSize;
15158 this.layout.layout();
15159 this.panel.saveState();
15164 getSplitBar : function(){
15169 Ext.Container.LAYOUTS['border'] = Ext.layout.BorderLayout;
15171 Ext.layout.FormLayout = Ext.extend(Ext.layout.AnchorLayout, {
15175 labelSeparator : ':',
15177 getAnchorViewSize : function(ct, target){
15178 return ct.body.getStyleSize();
15181 setContainer : function(ct){
15182 Ext.layout.FormLayout.superclass.setContainer.call(this, ct);
15185 ct.addClass('x-form-label-'+ct.labelAlign);
15189 this.labelStyle = "display:none";
15190 this.elementStyle = "padding-left:0;";
15191 this.labelAdjust = 0;
15193 this.labelSeparator = ct.labelSeparator || this.labelSeparator;
15194 ct.labelWidth = ct.labelWidth || 100;
15195 if(typeof ct.labelWidth == 'number'){
15196 var pad = (typeof ct.labelPad == 'number' ? ct.labelPad : 5);
15197 this.labelAdjust = ct.labelWidth+pad;
15198 this.labelStyle = "width:"+ct.labelWidth+"px;";
15199 this.elementStyle = "padding-left:"+(ct.labelWidth+pad)+'px';
15201 if(ct.labelAlign == 'top'){
15202 this.labelStyle = "width:auto;";
15203 this.labelAdjust = 0;
15204 this.elementStyle = "padding-left:0;";
15208 if(!this.fieldTpl){
15209 var t = new Ext.Template(
15210 '<div class="x-form-item {5}" tabIndex="-1">',
15211 '<label for="{0}" style="{2}" class="x-form-item-label">{1}{4}</label>',
15212 '<div class="x-form-element" id="x-form-el-{0}" style="{3}">',
15213 '</div><div class="{6}"></div>',
15216 t.disableFormats = true;
15218 Ext.layout.FormLayout.prototype.fieldTpl = t;
15222 renderItem : function(c, position, target){
15223 if(c && !c.rendered && c.isFormField && c.inputType != 'hidden'){
15225 c.id, c.fieldLabel,
15226 c.labelStyle||this.labelStyle||'',
15227 this.elementStyle||'',
15228 typeof c.labelSeparator == 'undefined' ? this.labelSeparator : c.labelSeparator,
15229 (c.itemCls||this.container.itemCls||'') + (c.hideLabel ? ' x-hide-label' : ''),
15230 c.clearCls || 'x-form-clear-left'
15232 if(typeof position == 'number'){
15233 position = target.dom.childNodes[position] || null;
15236 this.fieldTpl.insertBefore(position, args);
15238 this.fieldTpl.append(target, args);
15240 c.render('x-form-el-'+c.id);
15242 Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
15246 adjustWidthAnchor : function(value, comp){
15247 return value - (comp.isFormField ? (comp.hideLabel ? 0 : this.labelAdjust) : 0);
15250 isValidParent : function(c, target){
15257 Ext.Container.LAYOUTS['form'] = Ext.layout.FormLayout;
15259 Ext.layout.Accordion = Ext.extend(Ext.layout.FitLayout, {
15265 titleCollapse : true,
15267 hideCollapseTool : false,
15269 collapseFirst : false,
15275 activeOnTop : false,
15277 renderItem : function(c){
15278 if(this.animate === false){
15279 c.animCollapse = false;
15281 c.collapsible = true;
15282 if(this.autoWidth){
15283 c.autoWidth = true;
15285 if(this.titleCollapse){
15286 c.titleCollapse = true;
15288 if(this.hideCollapseTool){
15289 c.hideCollapseTool = true;
15291 if(this.collapseFirst !== undefined){
15292 c.collapseFirst = this.collapseFirst;
15294 if(!this.activeItem && !c.collapsed){
15295 this.activeItem = c;
15296 }else if(this.activeItem){
15297 c.collapsed = true;
15299 Ext.layout.Accordion.superclass.renderItem.apply(this, arguments);
15300 c.header.addClass('x-accordion-hd');
15301 c.on('beforeexpand', this.beforeExpand, this);
15305 beforeExpand : function(p, anim){
15306 var ai = this.activeItem;
15309 delete this.activeItem;
15310 ai.collapse({callback:function(){
15311 p.expand(anim || true);
15315 ai.collapse(this.animate);
15318 this.activeItem = p;
15319 if(this.activeOnTop){
15320 p.el.dom.parentNode.insertBefore(p.el.dom, p.el.dom.parentNode.firstChild);
15326 setItemSize : function(item, size){
15327 if(this.fill && item){
15328 var items = this.container.items.items;
15330 for(var i = 0, len = items.length; i < len; i++){
15333 hh += (p.getSize().height - p.bwrap.getHeight());
15337 item.setSize(size);
15341 Ext.Container.LAYOUTS['accordion'] = Ext.layout.Accordion;
15343 Ext.layout.TableLayout = Ext.extend(Ext.layout.ContainerLayout, {
15347 monitorResize:false,
15350 setContainer : function(ct){
15351 Ext.layout.TableLayout.superclass.setContainer.call(this, ct);
15353 this.currentRow = 0;
15354 this.currentColumn = 0;
15359 onLayout : function(ct, target){
15360 var cs = ct.items.items, len = cs.length, c, i;
15363 target.addClass('x-table-layout-ct');
15365 this.table = target.createChild(
15366 {tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, null, true);
15368 this.renderAll(ct, target);
15373 getRow : function(index){
15374 var row = this.table.tBodies[0].childNodes[index];
15376 row = document.createElement('tr');
15377 this.table.tBodies[0].appendChild(row);
15383 getNextCell : function(c){
15384 var cell = this.getNextNonSpan(this.currentColumn, this.currentRow);
15385 var curCol = this.currentColumn = cell[0], curRow = this.currentRow = cell[1];
15386 for(var rowIndex = curRow; rowIndex < curRow + (c.rowspan || 1); rowIndex++){
15387 if(!this.cells[rowIndex]){
15388 this.cells[rowIndex] = [];
15390 for(var colIndex = curCol; colIndex < curCol + (c.colspan || 1); colIndex++){
15391 this.cells[rowIndex][colIndex] = true;
15394 var td = document.createElement('td');
15398 var cls = 'x-table-layout-cell';
15400 cls += ' ' + c.cellCls;
15402 td.className = cls;
15404 td.colSpan = c.colspan;
15407 td.rowSpan = c.rowspan;
15409 this.getRow(curRow).appendChild(td);
15414 getNextNonSpan: function(colIndex, rowIndex){
15415 var cols = this.columns;
15416 while((cols && colIndex >= cols) || (this.cells[rowIndex] && this.cells[rowIndex][colIndex])) {
15417 if(cols && colIndex >= cols){
15424 return [colIndex, rowIndex];
15428 renderItem : function(c, position, target){
15429 if(c && !c.rendered){
15430 c.render(this.getNextCell(c));
15435 isValidParent : function(c, target){
15442 Ext.Container.LAYOUTS['table'] = Ext.layout.TableLayout;
15444 Ext.layout.AbsoluteLayout = Ext.extend(Ext.layout.AnchorLayout, {
15445 extraCls: 'x-abs-layout-item',
15448 setContainer : function(ct){
15449 Ext.layout.AbsoluteLayout.superclass.setContainer.call(this, ct);
15450 if(ct.isXType('form')){
15451 this.isForm = true;
15455 onLayout : function(ct, target){
15456 if(this.isForm){ ct.body.position(); } else { target.position(); }
15457 Ext.layout.AbsoluteLayout.superclass.onLayout.call(this, ct, target);
15461 getAnchorViewSize : function(ct, target){
15462 return this.isForm ? ct.body.getStyleSize() : Ext.layout.AbsoluteLayout.superclass.getAnchorViewSize.call(this, ct, target);
15466 isValidParent : function(c, target){
15467 return this.isForm ? true : Ext.layout.AbsoluteLayout.superclass.isValidParent.call(this, c, target);
15471 adjustWidthAnchor : function(value, comp){
15472 return value ? value - comp.getPosition(true)[0] : value;
15476 adjustHeightAnchor : function(value, comp){
15477 return value ? value - comp.getPosition(true)[1] : value;
15481 Ext.Container.LAYOUTS['absolute'] = Ext.layout.AbsoluteLayout;
15483 Ext.Viewport = Ext.extend(Ext.Container, {
15496 initComponent : function() {
15497 Ext.Viewport.superclass.initComponent.call(this);
15498 document.getElementsByTagName('html')[0].className += ' x-viewport';
15499 this.el = Ext.getBody();
15500 this.el.setHeight = Ext.emptyFn;
15501 this.el.setWidth = Ext.emptyFn;
15502 this.el.setSize = Ext.emptyFn;
15503 this.el.dom.scroll = 'no';
15504 this.allowDomMove = false;
15505 this.autoWidth = true;
15506 this.autoHeight = true;
15507 Ext.EventManager.onWindowResize(this.fireResize, this);
15508 this.renderTo = this.el;
15511 fireResize : function(w, h){
15512 this.fireEvent('resize', this, w, h, w, h);
15515 Ext.reg('viewport', Ext.Viewport);
15517 Ext.Panel = Ext.extend(Ext.Container, {
15551 baseCls : 'x-panel',
15553 collapsedCls : 'x-panel-collapsed',
15555 maskDisabled: true,
15557 animCollapse: Ext.enableFx,
15559 headerAsText: true,
15561 buttonAlign: 'right',
15565 collapseFirst: true,
15571 toolTarget : 'header',
15572 collapseEl : 'bwrap',
15579 collapseDefaults: {
15583 initComponent : function(){
15584 Ext.Panel.superclass.initComponent.call(this);
15610 this.elements += ',tbar';
15611 if(typeof this.tbar == 'object'){
15612 this.topToolbar = this.tbar;
15617 this.elements += ',bbar';
15618 if(typeof this.bbar == 'object'){
15619 this.bottomToolbar = this.bbar;
15624 if(this.header === true){
15625 this.elements += ',header';
15626 delete this.header;
15627 }else if(this.title && this.header !== false){
15628 this.elements += ',header';
15631 if(this.footer === true){
15632 this.elements += ',footer';
15633 delete this.footer;
15637 var btns = this.buttons;
15640 for(var i = 0, len = btns.length; i < len; i++) {
15641 if(btns[i].render){ this.buttons.push(btns[i]);
15643 this.addButton(btns[i]);
15648 this.on('render', this.doAutoLoad, this, {delay:10});
15652 createElement : function(name, pnode){
15654 pnode.appendChild(this[name].dom);
15658 if(name === 'bwrap' || this.elements.indexOf(name) != -1){
15659 if(this[name+'Cfg']){
15660 this[name] = Ext.fly(pnode).createChild(this[name+'Cfg']);
15662 var el = document.createElement('div');
15663 el.className = this[name+'Cls'];
15664 this[name] = Ext.get(pnode.appendChild(el));
15669 onRender : function(ct, position){
15670 Ext.Panel.superclass.onRender.call(this, ct, position);
15672 this.createClasses();
15674 if(this.el){ this.el.addClass(this.baseCls);
15675 this.header = this.el.down('.'+this.headerCls);
15676 this.bwrap = this.el.down('.'+this.bwrapCls);
15677 var cp = this.bwrap ? this.bwrap : this.el;
15678 this.tbar = cp.down('.'+this.tbarCls);
15679 this.body = cp.down('.'+this.bodyCls);
15680 this.bbar = cp.down('.'+this.bbarCls);
15681 this.footer = cp.down('.'+this.footerCls);
15682 this.fromMarkup = true;
15684 this.el = ct.createChild({
15689 var el = this.el, d = el.dom;
15692 this.el.addClass(this.cls);
15696 this.elements += ',footer';
15701 el.insertHtml('afterBegin', String.format(Ext.Element.boxMarkup, this.baseCls));
15703 this.createElement('header', d.firstChild.firstChild.firstChild);
15704 this.createElement('bwrap', d);
15706 var bw = this.bwrap.dom;
15707 var ml = d.childNodes[1], bl = d.childNodes[2];
15708 bw.appendChild(ml);
15709 bw.appendChild(bl);
15711 var mc = bw.firstChild.firstChild.firstChild;
15712 this.createElement('tbar', mc);
15713 this.createElement('body', mc);
15714 this.createElement('bbar', mc);
15715 this.createElement('footer', bw.lastChild.firstChild.firstChild);
15718 this.bwrap.dom.lastChild.className += ' x-panel-nofooter';
15721 this.createElement('header', d);
15722 this.createElement('bwrap', d);
15724 var bw = this.bwrap.dom;
15725 this.createElement('tbar', bw);
15726 this.createElement('body', bw);
15727 this.createElement('bbar', bw);
15728 this.createElement('footer', bw);
15731 this.body.addClass(this.bodyCls + '-noheader');
15733 this.tbar.addClass(this.tbarCls + '-noheader');
15738 if(this.border === false){
15739 this.el.addClass(this.baseCls + '-noborder');
15740 this.body.addClass(this.bodyCls + '-noborder');
15742 this.header.addClass(this.headerCls + '-noborder');
15745 this.footer.addClass(this.footerCls + '-noborder');
15748 this.tbar.addClass(this.tbarCls + '-noborder');
15751 this.bbar.addClass(this.bbarCls + '-noborder');
15755 if(this.bodyBorder === false){
15756 this.body.addClass(this.bodyCls + '-noborder');
15759 if(this.bodyStyle){
15760 this.body.applyStyles(this.bodyStyle);
15763 this.bwrap.enableDisplayMode('block');
15766 this.header.unselectable();
15768 if(this.headerAsText){
15769 this.header.dom.innerHTML =
15770 '<span class="' + this.headerTextCls + '">'+this.header.dom.innerHTML+'</span>';
15773 this.setIconClass(this.iconCls);
15779 this.makeFloating(this.floating);
15782 if(this.collapsible){
15783 this.tools = this.tools ? this.tools.slice(0) : [];
15784 if(!this.hideCollapseTool){
15785 this.tools[this.collapseFirst?'unshift':'push']({
15787 handler : this.toggleCollapse,
15791 if(this.titleCollapse && this.header){
15792 this.header.on('click', this.toggleCollapse, this);
15793 this.header.setStyle('cursor', 'pointer');
15797 var ts = this.tools;
15799 this.addTool.apply(this, ts);
15804 if(this.buttons && this.buttons.length > 0){
15805 var tb = this.footer.createChild({cls:'x-panel-btns-ct', cn: {
15806 cls:"x-panel-btns x-panel-btns-"+this.buttonAlign,
15807 html:'<table cellspacing="0"><tbody><tr></tr></tbody></table><div class="x-clear"></div>'
15809 var tr = tb.getElementsByTagName('tr')[0];
15810 for(var i = 0, len = this.buttons.length; i < len; i++) {
15811 var b = this.buttons[i];
15812 var td = document.createElement('td');
15813 td.className = 'x-panel-btn-td';
15814 b.render(tr.appendChild(td));
15818 if(this.tbar && this.topToolbar){
15819 if(Ext.isArray(this.topToolbar)){
15820 this.topToolbar = new Ext.Toolbar(this.topToolbar);
15822 this.topToolbar.render(this.tbar);
15824 if(this.bbar && this.bottomToolbar){
15825 if(Ext.isArray(this.bottomToolbar)){
15826 this.bottomToolbar = new Ext.Toolbar(this.bottomToolbar);
15828 this.bottomToolbar.render(this.bbar);
15833 setIconClass : function(cls){
15834 var old = this.iconCls;
15835 this.iconCls = cls;
15836 if(this.rendered && this.header){
15838 this.header.addClass('x-panel-icon');
15839 this.header.replaceClass(old, this.iconCls);
15841 var hd = this.header.dom;
15842 var img = hd.firstChild && String(hd.firstChild.tagName).toLowerCase() == 'img' ? hd.firstChild : null;
15844 Ext.fly(img).replaceClass(old, this.iconCls);
15846 Ext.DomHelper.insertBefore(hd.firstChild, {
15847 tag:'img', src: Ext.BLANK_IMAGE_URL, cls:'x-panel-inline-icon '+this.iconCls
15854 makeFloating : function(cfg){
15855 this.floating = true;
15856 this.el = new Ext.Layer(
15857 typeof cfg == 'object' ? cfg : {
15858 shadow: this.shadow !== undefined ? this.shadow : 'sides',
15859 shadowOffset: this.shadowOffset,
15861 shim: this.shim === false ? false : undefined
15867 getTopToolbar : function(){
15868 return this.topToolbar;
15872 getBottomToolbar : function(){
15873 return this.bottomToolbar;
15877 addButton : function(config, handler, scope){
15881 minWidth: this.minButtonWidth,
15884 if(typeof config == "string"){
15887 Ext.apply(bc, config);
15889 var btn = new Ext.Button(bc);
15890 btn.ownerCt = this;
15894 this.buttons.push(btn);
15898 addTool : function(){
15899 if(!this[this.toolTarget]) { return;
15901 if(!this.toolTemplate){
15902 var tt = new Ext.Template(
15903 '<div class="x-tool x-tool-{id}"> </div>'
15905 tt.disableFormats = true;
15907 Ext.Panel.prototype.toolTemplate = tt;
15909 for(var i = 0, a = arguments, len = a.length; i < len; i++) {
15910 var tc = a[i], overCls = 'x-tool-'+tc.id+'-over';
15911 var t = this.toolTemplate.insertFirst(this[this.toolTarget], tc, true);
15912 this.tools[tc.id] = t;
15913 t.enableDisplayMode('block');
15914 t.on('click', this.createToolHandler(t, tc, overCls, this));
15922 if(typeof tc.qtip == 'object'){
15923 Ext.QuickTips.register(Ext.apply({
15927 t.dom.qtip = tc.qtip;
15930 t.addClassOnOver(overCls);
15934 onShow : function(){
15936 return this.el.show();
15938 Ext.Panel.superclass.onShow.call(this);
15941 onHide : function(){
15943 return this.el.hide();
15945 Ext.Panel.superclass.onHide.call(this);
15948 createToolHandler : function(t, tc, overCls, panel){
15949 return function(e){
15950 t.removeClass(overCls);
15953 tc.handler.call(tc.scope || t, e, t, panel);
15958 afterRender : function(){
15959 if(this.fromMarkup && this.height === undefined && !this.autoHeight){
15960 this.height = this.el.getHeight();
15962 if(this.floating && !this.hidden && !this.initHidden){
15966 this.setTitle(this.title);
15968 this.setAutoScroll();
15970 this.body.update(typeof this.html == 'object' ?
15971 Ext.DomHelper.markup(this.html) :
15975 if(this.contentEl){
15976 var ce = Ext.getDom(this.contentEl);
15977 Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']);
15978 this.body.dom.appendChild(ce);
15980 if(this.collapsed){
15981 this.collapsed = false;
15982 this.collapse(false);
15984 Ext.Panel.superclass.afterRender.call(this); this.initEvents();
15987 setAutoScroll : function(){
15988 if(this.rendered && this.autoScroll){
15989 this.body.setOverflow('auto');
15993 getKeyMap : function(){
15995 this.keyMap = new Ext.KeyMap(this.el, this.keys);
15997 return this.keyMap;
16000 initEvents : function(){
16004 if(this.draggable){
16005 this.initDraggable();
16009 initDraggable : function(){
16010 this.dd = new Ext.Panel.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);
16013 beforeEffect : function(){
16015 this.el.beforeAction();
16017 this.el.addClass('x-panel-animated');
16020 afterEffect : function(){
16022 this.el.removeClass('x-panel-animated');
16025 createEffect : function(a, cb, scope){
16033 }else if(!a.callback){
16035 }else { o.callback = function(){
16037 Ext.callback(a.callback, a.scope);
16040 return Ext.applyIf(o, a);
16044 collapse : function(animate){
16045 if(this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforecollapse', this, animate) === false){
16048 var doAnim = animate === true || (animate !== false && this.animCollapse);
16049 this.beforeEffect();
16050 this.onCollapse(doAnim, animate);
16054 onCollapse : function(doAnim, animArg){
16056 this[this.collapseEl].slideOut(this.slideAnchor,
16057 Ext.apply(this.createEffect(animArg||true, this.afterCollapse, this),
16058 this.collapseDefaults));
16060 this[this.collapseEl].hide();
16061 this.afterCollapse();
16065 afterCollapse : function(){
16066 this.collapsed = true;
16067 this.el.addClass(this.collapsedCls);
16068 this.afterEffect();
16069 this.fireEvent('collapse', this);
16073 expand : function(animate){
16074 if(!this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforeexpand', this, animate) === false){
16077 var doAnim = animate === true || (animate !== false && this.animCollapse);
16078 this.el.removeClass(this.collapsedCls);
16079 this.beforeEffect();
16080 this.onExpand(doAnim, animate);
16084 onExpand : function(doAnim, animArg){
16086 this[this.collapseEl].slideIn(this.slideAnchor,
16087 Ext.apply(this.createEffect(animArg||true, this.afterExpand, this),
16088 this.expandDefaults));
16090 this[this.collapseEl].show();
16091 this.afterExpand();
16095 afterExpand : function(){
16096 this.collapsed = false;
16097 this.afterEffect();
16098 this.fireEvent('expand', this);
16102 toggleCollapse : function(animate){
16103 this[this.collapsed ? 'expand' : 'collapse'](animate);
16107 onDisable : function(){
16108 if(this.rendered && this.maskDisabled){
16111 Ext.Panel.superclass.onDisable.call(this);
16114 onEnable : function(){
16115 if(this.rendered && this.maskDisabled){
16118 Ext.Panel.superclass.onEnable.call(this);
16121 onResize : function(w, h){
16122 if(w !== undefined || h !== undefined){
16123 if(!this.collapsed){
16124 if(typeof w == 'number'){
16125 this.body.setWidth(
16126 this.adjustBodyWidth(w - this.getFrameWidth()));
16127 }else if(w == 'auto'){
16128 this.body.setWidth(w);
16131 if(typeof h == 'number'){
16132 this.body.setHeight(
16133 this.adjustBodyHeight(h - this.getFrameHeight()));
16134 }else if(h == 'auto'){
16135 this.body.setHeight(h);
16138 this.queuedBodySize = {width: w, height: h};
16139 if(!this.queuedExpand && this.allowQueuedExpand !== false){
16140 this.queuedExpand = true;
16141 this.on('expand', function(){
16142 delete this.queuedExpand;
16143 this.onResize(this.queuedBodySize.width, this.queuedBodySize.height);
16145 }, this, {single:true});
16148 this.fireEvent('bodyresize', this, w, h);
16153 adjustBodyHeight : function(h){
16157 adjustBodyWidth : function(w){
16161 onPosition : function(){
16165 onDestroy : function(){
16167 for(var k in this.tools){
16168 Ext.destroy(this.tools[k]);
16172 for(var b in this.buttons){
16173 Ext.destroy(this.buttons[b]);
16180 Ext.Panel.superclass.onDestroy.call(this);
16184 getFrameWidth : function(){
16185 var w = this.el.getFrameWidth('lr');
16188 var l = this.bwrap.dom.firstChild;
16189 w += (Ext.fly(l).getFrameWidth('l') + Ext.fly(l.firstChild).getFrameWidth('r'));
16190 var mc = this.bwrap.dom.firstChild.firstChild.firstChild;
16191 w += Ext.fly(mc).getFrameWidth('lr');
16197 getFrameHeight : function(){
16198 var h = this.el.getFrameWidth('tb');
16199 h += (this.tbar ? this.tbar.getHeight() : 0) +
16200 (this.bbar ? this.bbar.getHeight() : 0);
16203 var hd = this.el.dom.firstChild;
16204 var ft = this.bwrap.dom.lastChild;
16205 h += (hd.offsetHeight + ft.offsetHeight);
16206 var mc = this.bwrap.dom.firstChild.firstChild.firstChild;
16207 h += Ext.fly(mc).getFrameWidth('tb');
16209 h += (this.header ? this.header.getHeight() : 0) +
16210 (this.footer ? this.footer.getHeight() : 0);
16216 getInnerWidth : function(){
16217 return this.getSize().width - this.getFrameWidth();
16221 getInnerHeight : function(){
16222 return this.getSize().height - this.getFrameHeight();
16225 syncShadow : function(){
16227 this.el.sync(true);
16231 getLayoutTarget : function(){
16236 setTitle : function(title, iconCls){
16237 this.title = title;
16238 if(this.header && this.headerAsText){
16239 this.header.child('span').update(title);
16242 this.setIconClass(iconCls);
16244 this.fireEvent('titlechange', this, title);
16249 getUpdater : function(){
16250 return this.body.getUpdater();
16255 var um = this.body.getUpdater();
16256 um.update.apply(um, arguments);
16260 beforeDestroy : function(){
16261 Ext.Element.uncache(
16270 createClasses : function(){
16271 this.headerCls = this.baseCls + '-header';
16272 this.headerTextCls = this.baseCls + '-header-text';
16273 this.bwrapCls = this.baseCls + '-bwrap';
16274 this.tbarCls = this.baseCls + '-tbar';
16275 this.bodyCls = this.baseCls + '-body';
16276 this.bbarCls = this.baseCls + '-bbar';
16277 this.footerCls = this.baseCls + '-footer';
16280 createGhost : function(cls, useShim, appendTo){
16281 var el = document.createElement('div');
16282 el.className = 'x-panel-ghost ' + (cls ? cls : '');
16284 el.appendChild(this.el.dom.firstChild.cloneNode(true));
16286 Ext.fly(el.appendChild(document.createElement('ul'))).setHeight(this.bwrap.getHeight());
16287 el.style.width = this.el.dom.offsetWidth + 'px';;
16289 this.container.dom.appendChild(el);
16291 Ext.getDom(appendTo).appendChild(el);
16293 if(useShim !== false && this.el.useShim !== false){
16294 var layer = new Ext.Layer({shadow:false, useDisplay:true, constrain:false}, el);
16298 return new Ext.Element(el);
16302 doAutoLoad : function(){
16304 typeof this.autoLoad == 'object' ?
16305 this.autoLoad : {url: this.autoLoad});
16310 Ext.reg('panel', Ext.Panel);
16313 Ext.Window = Ext.extend(Ext.Panel, {
16321 baseCls : 'x-window',
16331 constrainHeader:false,
16335 minimizable : false,
16337 maximizable : false,
16343 expandOnShow: true,
16345 closeAction: 'close',
16351 monitorResize : true,
16354 elements: 'header,body',
16360 initComponent : function(){
16361 Ext.Window.superclass.initComponent.call(this);
16376 getState : function(){
16377 return Ext.apply(Ext.Window.superclass.getState.call(this) || {}, this.getBox());
16380 onRender : function(ct, position){
16381 Ext.Window.superclass.onRender.call(this, ct, position);
16384 this.el.addClass('x-window-plain');
16387 this.focusEl = this.el.createChild({
16388 tag: "a", href:"#", cls:"x-dlg-focus",
16389 tabIndex:"-1", html: " "});
16390 this.focusEl.swallowEvent('click', true);
16392 this.proxy = this.el.createProxy("x-window-proxy");
16393 this.proxy.enableDisplayMode('block');
16396 this.mask = this.container.createChild({cls:"ext-el-mask"}, this.el.dom);
16397 this.mask.enableDisplayMode("block");
16402 initEvents : function(){
16403 Ext.Window.superclass.initEvents.call(this);
16404 if(this.animateTarget){
16405 this.setAnimateTarget(this.animateTarget);
16408 if(this.resizable){
16409 this.resizer = new Ext.Resizable(this.el, {
16410 minWidth: this.minWidth,
16411 minHeight:this.minHeight,
16412 handles: this.resizeHandles || "all",
16414 resizeElement : this.resizerAction
16416 this.resizer.window = this;
16417 this.resizer.on("beforeresize", this.beforeResize, this);
16420 if(this.draggable){
16421 this.header.addClass("x-window-draggable");
16425 this.el.on("mousedown", this.toFront, this);
16426 this.manager = this.manager || Ext.WindowMgr;
16427 this.manager.register(this);
16428 this.hidden = true;
16429 if(this.maximized){
16430 this.maximized = false;
16434 var km = this.getKeyMap();
16435 km.on(27, this.onEsc, this);
16440 initDraggable : function(){
16441 this.dd = new Ext.Window.DD(this);
16444 onEsc : function(){
16445 this[this.closeAction]();
16448 beforeDestroy : function(){
16455 Ext.Window.superclass.beforeDestroy.call(this);
16458 onDestroy : function(){
16460 this.manager.unregister(this);
16462 Ext.Window.superclass.onDestroy.call(this);
16465 initTools : function(){
16466 if(this.minimizable){
16469 handler: this.minimize.createDelegate(this, [])
16472 if(this.maximizable){
16475 handler: this.maximize.createDelegate(this, [])
16479 handler: this.restore.createDelegate(this, []),
16482 this.header.on('dblclick', this.toggleMaximize, this);
16487 handler: this[this.closeAction].createDelegate(this, [])
16492 resizerAction : function(){
16493 var box = this.proxy.getBox();
16495 this.window.handleResize(box);
16499 beforeResize : function(){
16500 this.resizer.minHeight = Math.max(this.minHeight, this.getFrameHeight() + 40); this.resizer.minWidth = Math.max(this.minWidth, this.getFrameWidth() + 40);
16501 this.resizeBox = this.el.getBox();
16504 updateHandles : function(){
16505 if(Ext.isIE && this.resizer){
16506 this.resizer.syncHandleHeight();
16511 handleResize : function(box){
16512 var rz = this.resizeBox;
16513 if(rz.x != box.x || rz.y != box.y){
16514 this.updateBox(box);
16519 this.updateHandles();
16521 this.fireEvent("resize", this, box.width, box.height);
16525 focus : function(){
16526 var f = this.focusEl, db = this.defaultButton, t = typeof db;
16527 if(t != 'undefined'){
16529 f = this.buttons[db];
16530 }else if(t == 'string'){
16531 f = Ext.getCmp(db);
16536 f.focus.defer(10, f);
16540 setAnimateTarget : function(el){
16542 this.animateTarget = el;
16545 beforeShow : function(){
16546 delete this.el.lastXY;
16547 delete this.el.lastLT;
16548 if(this.x === undefined || this.y === undefined){
16549 var xy = this.el.getAlignToXY(this.container, 'c-c');
16550 var pos = this.el.translatePoints(xy[0], xy[1]);
16551 this.x = this.x === undefined? pos.left : this.x;
16552 this.y = this.y === undefined? pos.top : this.y;
16554 this.el.setLeftTop(this.x, this.y);
16556 if(this.expandOnShow){
16557 this.expand(false);
16561 Ext.getBody().addClass("x-body-masked");
16562 this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
16568 show : function(animateTarget, cb, scope){
16569 if(!this.rendered){
16570 this.render(Ext.getBody());
16572 if(this.hidden === false){
16576 if(this.fireEvent("beforeshow", this) === false){
16580 this.on('show', cb, scope, {single:true});
16582 this.hidden = false;
16583 if(animateTarget !== undefined){
16584 this.setAnimateTarget(animateTarget);
16587 if(this.animateTarget){
16594 afterShow : function(){
16596 this.el.setStyle('display', 'block');
16598 if(this.maximized){
16599 this.fitContainer();
16601 if(Ext.isMac && Ext.isGecko){ this.cascade(this.setAutoScroll);
16604 if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
16605 Ext.EventManager.onWindowResize(this.onWindowResize, this);
16607 this.doConstrain();
16612 this.keyMap.enable();
16615 this.updateHandles();
16616 this.fireEvent("show", this);
16619 animShow : function(){
16621 this.proxy.setBox(this.animateTarget.getBox());
16622 this.proxy.setOpacity(0);
16623 var b = this.getBox(false);
16624 b.callback = this.afterShow;
16627 b.easing = 'easeNone';
16630 this.el.setStyle('display', 'none');
16631 this.proxy.shift(b);
16635 hide : function(animateTarget, cb, scope){
16636 if(this.hidden || this.fireEvent("beforehide", this) === false){
16640 this.on('hide', cb, scope, {single:true});
16642 this.hidden = true;
16643 if(animateTarget !== undefined){
16644 this.setAnimateTarget(animateTarget);
16646 if(this.animateTarget){
16654 afterHide : function(){
16656 if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
16657 Ext.EventManager.removeResizeListener(this.onWindowResize, this);
16661 Ext.getBody().removeClass("x-body-masked");
16664 this.keyMap.disable();
16666 this.fireEvent("hide", this);
16669 animHide : function(){
16670 this.proxy.setOpacity(.5);
16672 var tb = this.getBox(false);
16673 this.proxy.setBox(tb);
16675 var b = this.animateTarget.getBox();
16676 b.callback = this.afterHide;
16679 b.easing = 'easeNone';
16682 this.proxy.shift(b);
16685 onWindowResize : function(){
16686 if(this.maximized){
16687 this.fitContainer();
16690 this.mask.setSize('100%', '100%');
16691 var force = this.mask.dom.offsetHeight;
16692 this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
16694 this.doConstrain();
16697 doConstrain : function(){
16698 if(this.constrain || this.constrainHeader){
16700 if(this.constrain){
16702 right:this.el.shadowOffset,
16703 left:this.el.shadowOffset,
16704 bottom:this.el.shadowOffset
16707 var s = this.getSize();
16709 right:-(s.width - 100),
16710 bottom:-(s.height - 25)
16714 var xy = this.el.getConstrainToXY(this.container, true, offsets);
16716 this.setPosition(xy[0], xy[1]);
16721 ghost : function(cls){
16722 var ghost = this.createGhost(cls);
16723 var box = this.getBox(true);
16724 ghost.setLeftTop(box.x, box.y);
16725 ghost.setWidth(box.width);
16727 this.activeGhost = ghost;
16731 unghost : function(show, matchPosition){
16732 if(show !== false){
16735 if(Ext.isMac && Ext.isGecko){ this.cascade(this.setAutoScroll);
16738 if(matchPosition !== false){
16739 this.setPosition(this.activeGhost.getLeft(true), this.activeGhost.getTop(true));
16741 this.activeGhost.hide();
16742 this.activeGhost.remove();
16743 delete this.activeGhost;
16747 minimize : function(){
16748 this.fireEvent('minimize', this);
16752 close : function(){
16753 if(this.fireEvent("beforeclose", this) !== false){
16754 this.hide(null, function(){
16755 this.fireEvent('close', this);
16762 maximize : function(){
16763 if(!this.maximized){
16764 this.expand(false);
16765 this.restoreSize = this.getSize();
16766 this.restorePos = this.getPosition(true);
16767 this.tools.maximize.hide();
16768 this.tools.restore.show();
16769 this.maximized = true;
16770 this.el.disableShadow();
16775 if(this.collapsible){
16776 this.tools.toggle.hide();
16778 this.el.addClass('x-window-maximized');
16779 this.container.addClass('x-window-maximized-ct');
16781 this.setPosition(0, 0);
16782 this.fitContainer();
16783 this.fireEvent('maximize', this);
16788 restore : function(){
16789 if(this.maximized){
16790 this.el.removeClass('x-window-maximized');
16791 this.tools.restore.hide();
16792 this.tools.maximize.show();
16793 this.setPosition(this.restorePos[0], this.restorePos[1]);
16794 this.setSize(this.restoreSize.width, this.restoreSize.height);
16795 delete this.restorePos;
16796 delete this.restoreSize;
16797 this.maximized = false;
16798 this.el.enableShadow(true);
16803 if(this.collapsible){
16804 this.tools.toggle.show();
16806 this.container.removeClass('x-window-maximized-ct');
16808 this.doConstrain();
16809 this.fireEvent('restore', this);
16814 toggleMaximize : function(){
16815 this[this.maximized ? 'restore' : 'maximize']();
16818 fitContainer : function(){
16819 var vs = this.container.getViewSize();
16820 this.setSize(vs.width, vs.height);
16823 setZIndex : function(index){
16825 this.mask.setStyle("z-index", index);
16827 this.el.setZIndex(++index);
16831 this.resizer.proxy.setStyle("z-index", ++index);
16834 this.lastZIndex = index;
16838 alignTo : function(element, position, offsets){
16839 var xy = this.el.getAlignToXY(element, position, offsets);
16840 this.setPagePosition(xy[0], xy[1]);
16845 anchorTo : function(el, alignment, offsets, monitorScroll, _pname){
16846 var action = function(){
16847 this.alignTo(el, alignment, offsets);
16849 Ext.EventManager.onWindowResize(action, this);
16850 var tm = typeof monitorScroll;
16851 if(tm != 'undefined'){
16852 Ext.EventManager.on(window, 'scroll', action, this,
16853 {buffer: tm == 'number' ? monitorScroll : 50});
16856 this[_pname] = action;
16861 toFront : function(){
16862 if(this.manager.bringToFront(this)){
16869 setActive : function(active){
16871 if(!this.maximized){
16872 this.el.enableShadow(true);
16874 this.fireEvent('activate', this);
16876 this.el.disableShadow();
16877 this.fireEvent('deactivate', this);
16882 toBack : function(){
16883 this.manager.sendToBack(this);
16888 center : function(){
16889 var xy = this.el.getAlignToXY(this.container, 'c-c');
16890 this.setPagePosition(xy[0], xy[1]);
16894 Ext.reg('window', Ext.Window);
16896 Ext.Window.DD = function(win){
16898 Ext.Window.DD.superclass.constructor.call(this, win.el.id, 'WindowDD-'+win.id);
16899 this.setHandleElId(win.header.id);
16900 this.scroll = false;
16903 Ext.extend(Ext.Window.DD, Ext.dd.DD, {
16905 headerOffsets:[100, 25],
16906 startDrag : function(){
16908 this.proxy = w.ghost();
16909 if(w.constrain !== false){
16910 var so = w.el.shadowOffset;
16911 this.constrainTo(w.container, {right: so, left: so, bottom: so});
16912 }else if(w.constrainHeader !== false){
16913 var s = this.proxy.getSize();
16914 this.constrainTo(w.container, {right: -(s.width-this.headerOffsets[0]), bottom: -(s.height-this.headerOffsets[1])});
16917 b4Drag : Ext.emptyFn,
16919 onDrag : function(e){
16920 this.alignElWithMouse(this.proxy, e.getPageX(), e.getPageY());
16923 endDrag : function(e){
16924 this.win.unghost();
16925 this.win.saveState();
16929 Ext.WindowGroup = function(){
16931 var accessList = [];
16934 var sortWindows = function(d1, d2){
16935 return (!d1._lastAccess || d1._lastAccess < d2._lastAccess) ? -1 : 1;
16938 var orderWindows = function(){
16939 var a = accessList, len = a.length;
16941 a.sort(sortWindows);
16942 var seed = a[0].manager.zseed;
16943 for(var i = 0; i < len; i++){
16945 if(win && !win.hidden){
16946 win.setZIndex(seed + (i*10));
16953 var setActiveWin = function(win){
16956 front.setActive(false);
16960 win.setActive(true);
16965 var activateLast = function(){
16966 for(var i = accessList.length-1; i >=0; --i) {
16967 if(!accessList[i].hidden){
16968 setActiveWin(accessList[i]);
16972 setActiveWin(null);
16979 register : function(win){
16980 list[win.id] = win;
16981 accessList.push(win);
16982 win.on('hide', activateLast);
16985 unregister : function(win){
16986 delete list[win.id];
16987 win.un('hide', activateLast);
16988 accessList.remove(win);
16992 get : function(id){
16993 return typeof id == "object" ? id : list[id];
16997 bringToFront : function(win){
16998 win = this.get(win);
17000 win._lastAccess = new Date().getTime();
17008 sendToBack : function(win){
17009 win = this.get(win);
17010 win._lastAccess = -(new Date().getTime());
17016 hideAll : function(){
17017 for(var id in list){
17018 if(list[id] && typeof list[id] != "function" && list[id].isVisible()){
17025 getActive : function(){
17030 getBy : function(fn, scope){
17032 for(var i = accessList.length-1; i >=0; --i) {
17033 var win = accessList[i];
17034 if(fn.call(scope||win, win) !== false){
17042 each : function(fn, scope){
17043 for(var id in list){
17044 if(list[id] && typeof list[id] != "function"){
17045 if(fn.call(scope || list[id], list[id]) === false){
17056 Ext.WindowMgr = new Ext.WindowGroup();
17058 Ext.dd.PanelProxy = function(panel, config){
17059 this.panel = panel;
17060 this.id = this.panel.id +'-ddproxy';
17061 Ext.apply(this, config);
17064 Ext.dd.PanelProxy.prototype = {
17066 insertProxy : true,
17069 setStatus : Ext.emptyFn,
17070 reset : Ext.emptyFn,
17071 update : Ext.emptyFn,
17072 stop : Ext.emptyFn,
17076 getEl : function(){
17081 getGhost : function(){
17086 getProxy : function(){
17094 this.proxy.remove();
17097 this.panel.el.dom.style.display = '';
17098 this.ghost.remove();
17106 this.ghost = this.panel.createGhost(undefined, undefined, Ext.getBody());
17107 this.ghost.setXY(this.panel.el.getXY())
17108 if(this.insertProxy){
17109 this.proxy = this.panel.el.insertSibling({cls:'x-panel-dd-spacer'});
17110 this.proxy.setSize(this.panel.getSize());
17112 this.panel.el.dom.style.display = 'none';
17117 repair : function(xy, callback, scope){
17119 if(typeof callback == "function"){
17120 callback.call(scope || this);
17125 moveProxy : function(parentNode, before){
17127 parentNode.insertBefore(this.proxy.dom, before);
17133 Ext.Panel.DD = function(panel, cfg){
17134 this.panel = panel;
17135 this.dragData = {panel: panel};
17136 this.proxy = new Ext.dd.PanelProxy(panel, cfg);
17137 Ext.Panel.DD.superclass.constructor.call(this, panel.el, cfg);
17138 this.setHandleElId(panel.header.id);
17139 panel.header.setStyle('cursor', 'move');
17140 this.scroll = false;
17143 Ext.extend(Ext.Panel.DD, Ext.dd.DragSource, {
17144 showFrame: Ext.emptyFn,
17145 startDrag: Ext.emptyFn,
17146 b4StartDrag: function(x, y) {
17149 b4MouseDown: function(e) {
17150 var x = e.getPageX();
17151 var y = e.getPageY();
17152 this.autoOffset(x, y);
17154 onInitDrag : function(x, y){
17155 this.onStartDrag(x, y);
17158 createFrame : Ext.emptyFn,
17159 getDragEl : function(e){
17160 return this.proxy.ghost.dom;
17162 endDrag : function(e){
17164 this.panel.saveState();
17167 autoOffset : function(x, y) {
17168 x -= this.startPageX;
17169 y -= this.startPageY;
17170 this.setDelta(x, y);
17174 Ext.state.Provider = function(){
17176 this.addEvents("statechange");
17178 Ext.state.Provider.superclass.constructor.call(this);
17180 Ext.extend(Ext.state.Provider, Ext.util.Observable, {
17182 get : function(name, defaultValue){
17183 return typeof this.state[name] == "undefined" ?
17184 defaultValue : this.state[name];
17188 clear : function(name){
17189 delete this.state[name];
17190 this.fireEvent("statechange", this, name, null);
17194 set : function(name, value){
17195 this.state[name] = value;
17197 this.fireEvent("statechange", this, name, value);
17201 decodeValue : function(cookie){
17202 var re = /^(a|n|d|b|s|o)\:(.*)$/;
17203 var matches = re.exec(unescape(cookie));
17204 if(!matches || !matches[1]) return;
17205 var type = matches[1];
17206 var v = matches[2];
17209 return parseFloat(v);
17211 return new Date(Date.parse(v));
17216 var values = v.split("^");
17217 for(var i = 0, len = values.length; i < len; i++){
17218 all.push(this.decodeValue(values[i]));
17223 var values = v.split("^");
17224 for(var i = 0, len = values.length; i < len; i++){
17225 var kv = values[i].split("=");
17226 all[kv[0]] = this.decodeValue(kv[1]);
17235 encodeValue : function(v){
17237 if(typeof v == "number"){
17239 }else if(typeof v == "boolean"){
17240 enc = "b:" + (v ? "1" : "0");
17241 }else if(Ext.isDate(v)){
17242 enc = "d:" + v.toGMTString();
17243 }else if(Ext.isArray(v)){
17245 for(var i = 0, len = v.length; i < len; i++){
17246 flat += this.encodeValue(v[i]);
17247 if(i != len-1) flat += "^";
17250 }else if(typeof v == "object"){
17253 if(typeof v[key] != "function" && v[key] !== undefined){
17254 flat += key + "=" + this.encodeValue(v[key]) + "^";
17257 enc = "o:" + flat.substring(0, flat.length-1);
17261 return escape(enc);
17266 Ext.state.Manager = function(){
17267 var provider = new Ext.state.Provider();
17271 setProvider : function(stateProvider){
17272 provider = stateProvider;
17276 get : function(key, defaultValue){
17277 return provider.get(key, defaultValue);
17281 set : function(key, value){
17282 provider.set(key, value);
17286 clear : function(key){
17287 provider.clear(key);
17291 getProvider : function(){
17298 Ext.state.CookieProvider = function(config){
17299 Ext.state.CookieProvider.superclass.constructor.call(this);
17301 this.expires = new Date(new Date().getTime()+(1000*60*60*24*7));
17302 this.domain = null;
17303 this.secure = false;
17304 Ext.apply(this, config);
17305 this.state = this.readCookies();
17308 Ext.extend(Ext.state.CookieProvider, Ext.state.Provider, {
17310 set : function(name, value){
17311 if(typeof value == "undefined" || value === null){
17315 this.setCookie(name, value);
17316 Ext.state.CookieProvider.superclass.set.call(this, name, value);
17320 clear : function(name){
17321 this.clearCookie(name);
17322 Ext.state.CookieProvider.superclass.clear.call(this, name);
17326 readCookies : function(){
17328 var c = document.cookie + ";";
17329 var re = /\s?(.*?)=(.*?);/g;
17331 while((matches = re.exec(c)) != null){
17332 var name = matches[1];
17333 var value = matches[2];
17334 if(name && name.substring(0,3) == "ys-"){
17335 cookies[name.substr(3)] = this.decodeValue(value);
17342 setCookie : function(name, value){
17343 document.cookie = "ys-"+ name + "=" + this.encodeValue(value) +
17344 ((this.expires == null) ? "" : ("; expires=" + this.expires.toGMTString())) +
17345 ((this.path == null) ? "" : ("; path=" + this.path)) +
17346 ((this.domain == null) ? "" : ("; domain=" + this.domain)) +
17347 ((this.secure == true) ? "; secure" : "");
17351 clearCookie : function(name){
17352 document.cookie = "ys-" + name + "=null; expires=Thu, 01-Jan-70 00:00:01 GMT" +
17353 ((this.path == null) ? "" : ("; path=" + this.path)) +
17354 ((this.domain == null) ? "" : ("; domain=" + this.domain)) +
17355 ((this.secure == true) ? "; secure" : "");
17359 Ext.DataView = Ext.extend(Ext.BoxComponent, {
17369 selectedClass : "x-view-selected",
17377 initComponent : function(){
17378 Ext.DataView.superclass.initComponent.call(this);
17379 if(typeof this.tpl == "string"){
17380 this.tpl = new Ext.XTemplate(this.tpl);
17401 this.all = new Ext.CompositeElementLite();
17402 this.selected = new Ext.CompositeElementLite();
17406 onRender : function(){
17408 this.el = document.createElement('div');
17410 Ext.DataView.superclass.onRender.apply(this, arguments);
17414 afterRender : function(){
17415 Ext.DataView.superclass.afterRender.call(this);
17418 "click": this.onClick,
17419 "dblclick": this.onDblClick,
17420 "contextmenu": this.onContextMenu,
17424 if(this.overClass){
17426 "mouseover": this.onMouseOver,
17427 "mouseout": this.onMouseOut,
17433 this.setStore(this.store, true);
17438 refresh : function(){
17439 this.clearSelections(false, true);
17440 this.el.update("");
17442 var records = this.store.getRange();
17443 if(records.length < 1){
17444 this.el.update(this.emptyText);
17448 this.tpl.overwrite(this.el, this.collectData(records, 0));
17449 this.all.fill(Ext.query(this.itemSelector, this.el.dom));
17450 this.updateIndexes(0);
17454 prepareData : function(data){
17459 collectData : function(records, startIndex){
17461 for(var i = 0, len = records.length; i < len; i++){
17462 r[r.length] = this.prepareData(records[i].data, startIndex+i, records[i]);
17468 bufferRender : function(records){
17469 var div = document.createElement('div');
17470 this.tpl.overwrite(div, this.collectData(records));
17471 return Ext.query(this.itemSelector, div);
17475 onUpdate : function(ds, record){
17476 var index = this.store.indexOf(record);
17477 var sel = this.isSelected(index);
17478 var original = this.all.elements[index];
17479 var node = this.bufferRender([record], index)[0];
17481 this.all.replaceElement(index, node, true);
17483 this.selected.replaceElement(original, node);
17484 this.all.item(index).addClass(this.selectedClass);
17486 this.updateIndexes(index, index);
17490 onAdd : function(ds, records, index){
17491 if(this.all.getCount() == 0){
17495 var nodes = this.bufferRender(records, index), n;
17496 if(index < this.all.getCount()){
17497 n = this.all.item(index).insertSibling(nodes, 'before', true);
17498 this.all.elements.splice(index, 0, n);
17500 n = this.all.last().insertSibling(nodes, 'after', true);
17501 this.all.elements.push(n);
17503 this.updateIndexes(index);
17507 onRemove : function(ds, record, index){
17508 this.deselect(index);
17509 this.all.removeElement(index, true);
17510 this.updateIndexes(index);
17514 refreshNode : function(index){
17515 this.onUpdate(this.store, this.store.getAt(index));
17519 updateIndexes : function(startIndex, endIndex){
17520 var ns = this.all.elements;
17521 startIndex = startIndex || 0;
17522 endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length - 1));
17523 for(var i = startIndex; i <= endIndex; i++){
17524 ns[i].viewIndex = i;
17529 setStore : function(store, initial){
17530 if(!initial && this.store){
17531 this.store.un("beforeload", this.onBeforeLoad, this);
17532 this.store.un("datachanged", this.refresh, this);
17533 this.store.un("add", this.onAdd, this);
17534 this.store.un("remove", this.onRemove, this);
17535 this.store.un("update", this.onUpdate, this);
17536 this.store.un("clear", this.refresh, this);
17539 store = Ext.StoreMgr.lookup(store);
17540 store.on("beforeload", this.onBeforeLoad, this);
17541 store.on("datachanged", this.refresh, this);
17542 store.on("add", this.onAdd, this);
17543 store.on("remove", this.onRemove, this);
17544 store.on("update", this.onUpdate, this);
17545 store.on("clear", this.refresh, this);
17547 this.store = store;
17554 findItemFromChild : function(node){
17555 return Ext.fly(node).findParent(this.itemSelector, this.el);
17559 onClick : function(e){
17560 var item = e.getTarget(this.itemSelector, this.el);
17562 var index = this.indexOf(item);
17563 if(this.onItemClick(item, index, e) !== false){
17564 this.fireEvent("click", this, index, item, e);
17567 if(this.fireEvent("containerclick", this, e) !== false){
17568 this.clearSelections();
17574 onContextMenu : function(e){
17575 var item = e.getTarget(this.itemSelector, this.el);
17577 this.fireEvent("contextmenu", this, this.indexOf(item), item, e);
17582 onDblClick : function(e){
17583 var item = e.getTarget(this.itemSelector, this.el);
17585 this.fireEvent("dblclick", this, this.indexOf(item), item, e);
17590 onMouseOver : function(e){
17591 var item = e.getTarget(this.itemSelector, this.el);
17592 if(item && item !== this.lastItem){
17593 this.lastItem = item;
17594 Ext.fly(item).addClass(this.overClass);
17599 onMouseOut : function(e){
17601 if(!e.within(this.lastItem, true)){
17602 Ext.fly(this.lastItem).removeClass(this.overClass);
17603 delete this.lastItem;
17609 onItemClick : function(item, index, e){
17610 if(this.fireEvent("beforeclick", this, index, item, e) === false){
17613 if(this.multiSelect){
17614 this.doMultiSelection(item, index, e);
17615 e.preventDefault();
17616 }else if(this.singleSelect){
17617 this.doSingleSelection(item, index, e);
17618 e.preventDefault();
17624 doSingleSelection : function(item, index, e){
17625 if(e.ctrlKey && this.isSelected(index)){
17626 this.deselect(index);
17628 this.select(index, false);
17633 doMultiSelection : function(item, index, e){
17634 if(e.shiftKey && this.last !== false){
17635 var last = this.last;
17636 this.selectRange(last, index, e.ctrlKey);
17639 if((e.ctrlKey||this.simpleSelect) && this.isSelected(index)){
17640 this.deselect(index);
17642 this.select(index, e.ctrlKey || e.shiftKey || this.simpleSelect);
17648 getSelectionCount : function(){
17649 return this.selected.getCount()
17653 getSelectedNodes : function(){
17654 return this.selected.elements;
17658 getSelectedIndexes : function(){
17659 var indexes = [], s = this.selected.elements;
17660 for(var i = 0, len = s.length; i < len; i++){
17661 indexes.push(s[i].viewIndex);
17667 getSelectedRecords : function(){
17668 var r = [], s = this.selected.elements;
17669 for(var i = 0, len = s.length; i < len; i++){
17670 r[r.length] = this.store.getAt(s[i].viewIndex);
17676 getRecords : function(nodes){
17677 var r = [], s = nodes;
17678 for(var i = 0, len = s.length; i < len; i++){
17679 r[r.length] = this.store.getAt(s[i].viewIndex);
17685 getRecord : function(node){
17686 return this.store.getAt(node.viewIndex);
17690 clearSelections : function(suppressEvent, skipUpdate){
17691 if(this.multiSelect || this.singleSelect){
17693 this.selected.removeClass(this.selectedClass);
17695 this.selected.clear();
17697 if(!suppressEvent){
17698 this.fireEvent("selectionchange", this, this.selected.elements);
17704 isSelected : function(node){
17705 return this.selected.contains(this.getNode(node));
17709 deselect : function(node){
17710 if(this.isSelected(node)){
17711 var node = this.getNode(node);
17712 this.selected.removeElement(node);
17713 if(this.last == node.viewIndex){
17716 Ext.fly(node).removeClass(this.selectedClass);
17717 this.fireEvent("selectionchange", this, this.selected.elements);
17722 select : function(nodeInfo, keepExisting, suppressEvent){
17723 if(Ext.isArray(nodeInfo)){
17725 this.clearSelections(true);
17727 for(var i = 0, len = nodeInfo.length; i < len; i++){
17728 this.select(nodeInfo[i], true, true);
17731 var node = this.getNode(nodeInfo);
17733 this.clearSelections(true);
17735 if(node && !this.isSelected(node)){
17736 if(this.fireEvent("beforeselect", this, node, this.selected.elements) !== false){
17737 Ext.fly(node).addClass(this.selectedClass);
17738 this.selected.add(node);
17739 this.last = node.viewIndex;
17740 if(!suppressEvent){
17741 this.fireEvent("selectionchange", this, this.selected.elements);
17749 selectRange : function(start, end, keepExisting){
17751 this.clearSelections(true);
17753 this.select(this.getNodes(start, end), true);
17757 getNode : function(nodeInfo){
17758 if(typeof nodeInfo == "string"){
17759 return document.getElementById(nodeInfo);
17760 }else if(typeof nodeInfo == "number"){
17761 return this.all.elements[nodeInfo];
17767 getNodes : function(start, end){
17768 var ns = this.all.elements;
17769 start = start || 0;
17770 end = typeof end == "undefined" ? ns.length - 1 : end;
17773 for(i = start; i <= end; i++){
17777 for(i = start; i >= end; i--){
17785 indexOf : function(node){
17786 node = this.getNode(node);
17787 if(typeof node.viewIndex == "number"){
17788 return node.viewIndex;
17790 return this.all.indexOf(node);
17794 onBeforeLoad : function(){
17795 if(this.loadingText){
17796 this.clearSelections(false, true);
17797 this.el.update('<div class="loading-indicator">'+this.loadingText+'</div>');
17803 Ext.reg('dataview', Ext.DataView);
17805 Ext.ColorPalette = function(config){
17806 Ext.ColorPalette.superclass.constructor.call(this, config);
17813 this.on("select", this.handler, this.scope, true);
17816 Ext.extend(Ext.ColorPalette, Ext.Component, {
17818 itemCls : "x-color-palette",
17821 clickEvent:'click',
17822 ctype: "Ext.ColorPalette",
17825 allowReselect : false,
17829 "000000", "993300", "333300", "003300", "003366", "000080", "333399", "333333",
17830 "800000", "FF6600", "808000", "008000", "008080", "0000FF", "666699", "808080",
17831 "FF0000", "FF9900", "99CC00", "339966", "33CCCC", "3366FF", "800080", "969696",
17832 "FF00FF", "FFCC00", "FFFF00", "00FF00", "00FFFF", "00CCFF", "993366", "C0C0C0",
17833 "FF99CC", "FFCC99", "FFFF99", "CCFFCC", "CCFFFF", "99CCFF", "CC99FF", "FFFFFF"
17836 onRender : function(container, position){
17837 var t = this.tpl || new Ext.XTemplate(
17838 '<tpl for="."><a href="#" class="color-{.}" hidefocus="on"><em><span style="background:#{.}" unselectable="on"> </span></em></a></tpl>'
17840 var el = document.createElement("div");
17841 el.className = this.itemCls;
17842 t.overwrite(el, this.colors);
17843 container.dom.insertBefore(el, position);
17844 this.el = Ext.get(el);
17845 this.el.on(this.clickEvent, this.handleClick, this, {delegate: "a"});
17846 if(this.clickEvent != 'click'){
17847 this.el.on('click', Ext.emptyFn, this, {delegate: "a", preventDefault:true});
17851 afterRender : function(){
17852 Ext.ColorPalette.superclass.afterRender.call(this);
17854 var s = this.value;
17860 handleClick : function(e, t){
17861 e.preventDefault();
17862 if(!this.disabled){
17863 var c = t.className.match(/(?:^|\s)color-(.{6})(?:\s|$)/)[1];
17864 this.select(c.toUpperCase());
17869 select : function(color){
17870 color = color.replace("#", "");
17871 if(color != this.value || this.allowReselect){
17874 el.child("a.color-"+this.value).removeClass("x-color-palette-sel");
17876 el.child("a.color-"+color).addClass("x-color-palette-sel");
17877 this.value = color;
17878 this.fireEvent("select", this, color);
17884 Ext.reg('colorpalette', Ext.ColorPalette);
17886 Ext.DatePicker = Ext.extend(Ext.Component, {
17888 todayText : "Today",
17890 okText : " OK ",
17892 cancelText : "Cancel",
17894 todayTip : "{0} (Spacebar)",
17900 minText : "This date is before the minimum date",
17902 maxText : "This date is after the maximum date",
17906 disabledDays : null,
17908 disabledDaysText : "",
17910 disabledDatesRE : null,
17912 disabledDatesText : "",
17914 constrainToViewport : true,
17916 monthNames : Date.monthNames,
17918 dayNames : Date.dayNames,
17920 nextText: 'Next Month (Control+Right)',
17922 prevText: 'Previous Month (Control+Left)',
17924 monthYearText: 'Choose a month (Control+Up/Down to move years)',
17928 initComponent : function(){
17929 Ext.DatePicker.superclass.initComponent.call(this);
17931 this.value = this.value ?
17932 this.value.clearTime() : new Date().clearTime();
17940 this.on("select", this.handler, this.scope || this);
17943 this.initDisabledDays();
17947 initDisabledDays : function(){
17948 if(!this.disabledDatesRE && this.disabledDates){
17949 var dd = this.disabledDates;
17951 for(var i = 0; i < dd.length; i++){
17953 if(i != dd.length-1) re += "|";
17955 this.disabledDatesRE = new RegExp(re + ")");
17960 setValue : function(value){
17961 var old = this.value;
17962 this.value = value.clearTime(true);
17964 this.update(this.value);
17969 getValue : function(){
17974 focus : function(){
17976 this.update(this.activeDate);
17981 onRender : function(container, position){
17983 '<table cellspacing="0">',
17984 '<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>',
17985 '<tr><td colspan="3"><table class="x-date-inner" cellspacing="0"><thead><tr>'];
17986 var dn = this.dayNames;
17987 for(var i = 0; i < 7; i++){
17988 var d = this.startDay+i;
17992 m.push("<th><span>", dn[d].substr(0,1), "</span></th>");
17994 m[m.length] = "</tr></thead><tbody><tr>";
17995 for(var i = 0; i < 42; i++) {
17996 if(i % 7 == 0 && i != 0){
17997 m[m.length] = "</tr><tr>";
17999 m[m.length] = '<td><a href="#" hidefocus="on" class="x-date-date" tabIndex="1"><em><span></span></em></a></td>';
18001 m[m.length] = '</tr></tbody></table></td></tr><tr><td colspan="3" class="x-date-bottom" align="center"></td></tr></table><div class="x-date-mp"></div>';
18003 var el = document.createElement("div");
18004 el.className = "x-date-picker";
18005 el.innerHTML = m.join("");
18007 container.dom.insertBefore(el, position);
18009 this.el = Ext.get(el);
18010 this.eventEl = Ext.get(el.firstChild);
18012 new Ext.util.ClickRepeater(this.el.child("td.x-date-left a"), {
18013 handler: this.showPrevMonth,
18015 preventDefault:true,
18019 new Ext.util.ClickRepeater(this.el.child("td.x-date-right a"), {
18020 handler: this.showNextMonth,
18022 preventDefault:true,
18026 this.eventEl.on("mousewheel", this.handleMouseWheel, this);
18028 this.monthPicker = this.el.down('div.x-date-mp');
18029 this.monthPicker.enableDisplayMode('block');
18031 var kn = new Ext.KeyNav(this.eventEl, {
18032 "left" : function(e){
18034 this.showPrevMonth() :
18035 this.update(this.activeDate.add("d", -1));
18038 "right" : function(e){
18040 this.showNextMonth() :
18041 this.update(this.activeDate.add("d", 1));
18044 "up" : function(e){
18046 this.showNextYear() :
18047 this.update(this.activeDate.add("d", -7));
18050 "down" : function(e){
18052 this.showPrevYear() :
18053 this.update(this.activeDate.add("d", 7));
18056 "pageUp" : function(e){
18057 this.showNextMonth();
18060 "pageDown" : function(e){
18061 this.showPrevMonth();
18064 "enter" : function(e){
18065 e.stopPropagation();
18072 this.eventEl.on("click", this.handleDateClick, this, {delegate: "a.x-date-date"});
18074 this.eventEl.addKeyListener(Ext.EventObject.SPACE, this.selectToday, this);
18076 this.el.unselectable();
18078 this.cells = this.el.select("table.x-date-inner tbody td");
18079 this.textNodes = this.el.query("table.x-date-inner tbody span");
18081 this.mbtn = new Ext.Button({
18083 tooltip: this.monthYearText,
18084 renderTo: this.el.child("td.x-date-middle", true)
18087 this.mbtn.on('click', this.showMonthPicker, this);
18088 this.mbtn.el.child(this.mbtn.menuClassTarget).addClass("x-btn-with-menu");
18091 var today = (new Date()).dateFormat(this.format);
18092 this.todayBtn = new Ext.Button({
18093 renderTo: this.el.child("td.x-date-bottom", true),
18094 text: String.format(this.todayText, today),
18095 tooltip: String.format(this.todayTip, today),
18096 handler: this.selectToday,
18103 this.update(this.value);
18106 createMonthPicker : function(){
18107 if(!this.monthPicker.dom.firstChild){
18108 var buf = ['<table border="0" cellspacing="0">'];
18109 for(var i = 0; i < 6; i++){
18111 '<tr><td class="x-date-mp-month"><a href="#">', this.monthNames[i].substr(0, 3), '</a></td>',
18112 '<td class="x-date-mp-month x-date-mp-sep"><a href="#">', this.monthNames[i+6].substr(0, 3), '</a></td>',
18114 '<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>' :
18115 '<td class="x-date-mp-year"><a href="#"></a></td><td class="x-date-mp-year"><a href="#"></a></td></tr>'
18119 '<tr class="x-date-mp-btns"><td colspan="4"><button type="button" class="x-date-mp-ok">',
18121 '</button><button type="button" class="x-date-mp-cancel">',
18123 '</button></td></tr>',
18126 this.monthPicker.update(buf.join(''));
18127 this.monthPicker.on('click', this.onMonthClick, this);
18128 this.monthPicker.on('dblclick', this.onMonthDblClick, this);
18130 this.mpMonths = this.monthPicker.select('td.x-date-mp-month');
18131 this.mpYears = this.monthPicker.select('td.x-date-mp-year');
18133 this.mpMonths.each(function(m, a, i){
18136 m.dom.xmonth = 5 + Math.round(i * .5);
18138 m.dom.xmonth = Math.round((i-1) * .5);
18144 showMonthPicker : function(){
18145 this.createMonthPicker();
18146 var size = this.el.getSize();
18147 this.monthPicker.setSize(size);
18148 this.monthPicker.child('table').setSize(size);
18150 this.mpSelMonth = (this.activeDate || this.value).getMonth();
18151 this.updateMPMonth(this.mpSelMonth);
18152 this.mpSelYear = (this.activeDate || this.value).getFullYear();
18153 this.updateMPYear(this.mpSelYear);
18155 this.monthPicker.slideIn('t', {duration:.2});
18158 updateMPYear : function(y){
18160 var ys = this.mpYears.elements;
18161 for(var i = 1; i <= 10; i++){
18162 var td = ys[i-1], y2;
18164 y2 = y + Math.round(i * .5);
18165 td.firstChild.innerHTML = y2;
18168 y2 = y - (5-Math.round(i * .5));
18169 td.firstChild.innerHTML = y2;
18172 this.mpYears.item(i-1)[y2 == this.mpSelYear ? 'addClass' : 'removeClass']('x-date-mp-sel');
18176 updateMPMonth : function(sm){
18177 this.mpMonths.each(function(m, a, i){
18178 m[m.dom.xmonth == sm ? 'addClass' : 'removeClass']('x-date-mp-sel');
18182 selectMPMonth: function(m){
18186 onMonthClick : function(e, t){
18188 var el = new Ext.Element(t), pn;
18189 if(el.is('button.x-date-mp-cancel')){
18190 this.hideMonthPicker();
18192 else if(el.is('button.x-date-mp-ok')){
18193 this.update(new Date(this.mpSelYear, this.mpSelMonth, (this.activeDate || this.value).getDate()));
18194 this.hideMonthPicker();
18196 else if(pn = el.up('td.x-date-mp-month', 2)){
18197 this.mpMonths.removeClass('x-date-mp-sel');
18198 pn.addClass('x-date-mp-sel');
18199 this.mpSelMonth = pn.dom.xmonth;
18201 else if(pn = el.up('td.x-date-mp-year', 2)){
18202 this.mpYears.removeClass('x-date-mp-sel');
18203 pn.addClass('x-date-mp-sel');
18204 this.mpSelYear = pn.dom.xyear;
18206 else if(el.is('a.x-date-mp-prev')){
18207 this.updateMPYear(this.mpyear-10);
18209 else if(el.is('a.x-date-mp-next')){
18210 this.updateMPYear(this.mpyear+10);
18214 onMonthDblClick : function(e, t){
18216 var el = new Ext.Element(t), pn;
18217 if(pn = el.up('td.x-date-mp-month', 2)){
18218 this.update(new Date(this.mpSelYear, pn.dom.xmonth, (this.activeDate || this.value).getDate()));
18219 this.hideMonthPicker();
18221 else if(pn = el.up('td.x-date-mp-year', 2)){
18222 this.update(new Date(pn.dom.xyear, this.mpSelMonth, (this.activeDate || this.value).getDate()));
18223 this.hideMonthPicker();
18227 hideMonthPicker : function(disableAnim){
18228 if(this.monthPicker){
18229 if(disableAnim === true){
18230 this.monthPicker.hide();
18232 this.monthPicker.slideOut('t', {duration:.2});
18238 showPrevMonth : function(e){
18239 this.update(this.activeDate.add("mo", -1));
18243 showNextMonth : function(e){
18244 this.update(this.activeDate.add("mo", 1));
18248 showPrevYear : function(){
18249 this.update(this.activeDate.add("y", -1));
18253 showNextYear : function(){
18254 this.update(this.activeDate.add("y", 1));
18258 handleMouseWheel : function(e){
18259 var delta = e.getWheelDelta();
18261 this.showPrevMonth();
18263 } else if(delta < 0){
18264 this.showNextMonth();
18270 handleDateClick : function(e, t){
18272 if(t.dateValue && !Ext.fly(t.parentNode).hasClass("x-date-disabled")){
18273 this.setValue(new Date(t.dateValue));
18274 this.fireEvent("select", this, this.value);
18279 selectToday : function(){
18280 this.setValue(new Date().clearTime());
18281 this.fireEvent("select", this, this.value);
18285 update : function(date){
18286 var vd = this.activeDate;
18287 this.activeDate = date;
18289 var t = date.getTime();
18290 if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){
18291 this.cells.removeClass("x-date-selected");
18292 this.cells.each(function(c){
18293 if(c.dom.firstChild.dateValue == t){
18294 c.addClass("x-date-selected");
18295 setTimeout(function(){
18296 try{c.dom.firstChild.focus();}catch(e){}
18304 var days = date.getDaysInMonth();
18305 var firstOfMonth = date.getFirstDateOfMonth();
18306 var startingPos = firstOfMonth.getDay()-this.startDay;
18308 if(startingPos <= this.startDay){
18312 var pm = date.add("mo", -1);
18313 var prevStart = pm.getDaysInMonth()-startingPos;
18315 var cells = this.cells.elements;
18316 var textEls = this.textNodes;
18317 days += startingPos;
18320 var day = 86400000;
18321 var d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart)).clearTime();
18322 var today = new Date().clearTime().getTime();
18323 var sel = date.clearTime().getTime();
18324 var min = this.minDate ? this.minDate.clearTime() : Number.NEGATIVE_INFINITY;
18325 var max = this.maxDate ? this.maxDate.clearTime() : Number.POSITIVE_INFINITY;
18326 var ddMatch = this.disabledDatesRE;
18327 var ddText = this.disabledDatesText;
18328 var ddays = this.disabledDays ? this.disabledDays.join("") : false;
18329 var ddaysText = this.disabledDaysText;
18330 var format = this.format;
18332 var setCellClass = function(cal, cell){
18334 var t = d.getTime();
18335 cell.firstChild.dateValue = t;
18337 cell.className += " x-date-today";
18338 cell.title = cal.todayText;
18341 cell.className += " x-date-selected";
18342 setTimeout(function(){
18343 try{cell.firstChild.focus();}catch(e){}
18348 cell.className = " x-date-disabled";
18349 cell.title = cal.minText;
18353 cell.className = " x-date-disabled";
18354 cell.title = cal.maxText;
18358 if(ddays.indexOf(d.getDay()) != -1){
18359 cell.title = ddaysText;
18360 cell.className = " x-date-disabled";
18363 if(ddMatch && format){
18364 var fvalue = d.dateFormat(format);
18365 if(ddMatch.test(fvalue)){
18366 cell.title = ddText.replace("%0", fvalue);
18367 cell.className = " x-date-disabled";
18373 for(; i < startingPos; i++) {
18374 textEls[i].innerHTML = (++prevStart);
18375 d.setDate(d.getDate()+1);
18376 cells[i].className = "x-date-prevday";
18377 setCellClass(this, cells[i]);
18379 for(; i < days; i++){
18380 intDay = i - startingPos + 1;
18381 textEls[i].innerHTML = (intDay);
18382 d.setDate(d.getDate()+1);
18383 cells[i].className = "x-date-active";
18384 setCellClass(this, cells[i]);
18387 for(; i < 42; i++) {
18388 textEls[i].innerHTML = (++extraDays);
18389 d.setDate(d.getDate()+1);
18390 cells[i].className = "x-date-nextday";
18391 setCellClass(this, cells[i]);
18394 this.mbtn.setText(this.monthNames[date.getMonth()] + " " + date.getFullYear());
18396 if(!this.internalRender){
18397 var main = this.el.dom.firstChild;
18398 var w = main.offsetWidth;
18399 this.el.setWidth(w + this.el.getBorderWidth("lr"));
18400 Ext.fly(main).setWidth(w);
18401 this.internalRender = true;
18405 if(Ext.isOpera && !this.secondPass){
18406 main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + "px";
18407 this.secondPass = true;
18408 this.update.defer(10, this, [date]);
18414 beforeDestroy : function() {
18415 this.mbtn.destroy();
18416 this.todayBtn.destroy();
18421 Ext.reg('datepicker', Ext.DatePicker);
18423 Ext.TabPanel = Ext.extend(Ext.Panel, {
18426 monitorResize : true,
18428 deferredRender : true,
18436 enableTabScroll: false,
18438 scrollIncrement : 0,
18440 scrollRepeatInterval : 400,
18442 scrollDuration : .35,
18446 tabPosition: 'top',
18448 baseCls: 'x-tab-panel',
18452 autoTabSelector:'div.x-tab',
18460 wheelIncrement : 20,
18463 idDelimiter : '__',
18465 itemCls : 'x-tab-item',
18468 headerAsText: false,
18472 initComponent : function(){
18473 this.frame = false;
18474 Ext.TabPanel.superclass.initComponent.call(this);
18483 this.setLayout(new Ext.layout.CardLayout({
18484 deferredRender: this.deferredRender
18486 if(this.tabPosition == 'top'){
18487 this.elements += ',header';
18488 this.stripTarget = 'header';
18490 this.elements += ',footer';
18491 this.stripTarget = 'footer';
18494 this.stack = Ext.TabPanel.AccessStack();
18499 render : function(){
18500 Ext.TabPanel.superclass.render.apply(this, arguments);
18501 if(this.activeTab !== undefined){
18502 var item = this.activeTab;
18503 delete this.activeTab;
18504 this.setActiveTab(item);
18508 onRender : function(ct, position){
18509 Ext.TabPanel.superclass.onRender.call(this, ct, position);
18512 var pos = this.tabPosition == 'top' ? 'header' : 'footer';
18513 this[pos].addClass('x-tab-panel-'+pos+'-plain');
18516 var st = this[this.stripTarget];
18518 this.stripWrap = st.createChild({cls:'x-tab-strip-wrap', cn:{
18519 tag:'ul', cls:'x-tab-strip x-tab-strip-'+this.tabPosition}});
18520 this.stripSpacer = st.createChild({cls:'x-tab-strip-spacer'});
18521 this.strip = new Ext.Element(this.stripWrap.dom.firstChild);
18523 this.edge = this.strip.createChild({tag:'li', cls:'x-tab-edge'});
18524 this.strip.createChild({cls:'x-clear'});
18526 this.body.addClass('x-tab-panel-body-'+this.tabPosition);
18529 var tt = new Ext.Template(
18530 '<li class="{cls}" id="{id}"><a class="x-tab-strip-close" onclick="return false;"></a>',
18531 '<a class="x-tab-right" href="#" onclick="return false;"><em class="x-tab-left">',
18532 '<span class="x-tab-strip-inner"><span class="x-tab-strip-text {iconCls}">{text}</span></span>',
18535 tt.disableFormats = true;
18537 Ext.TabPanel.prototype.itemTpl = tt;
18540 this.items.each(this.initTab, this);
18543 afterRender : function(){
18544 Ext.TabPanel.superclass.afterRender.call(this);
18546 this.readTabs(false);
18550 initEvents : function(){
18551 Ext.TabPanel.superclass.initEvents.call(this);
18552 this.on('add', this.onAdd, this);
18553 this.on('remove', this.onRemove, this);
18555 this.strip.on('mousedown', this.onStripMouseDown, this);
18556 this.strip.on('click', this.onStripClick, this);
18557 this.strip.on('contextmenu', this.onStripContextMenu, this);
18558 if(this.enableTabScroll){
18559 this.strip.on('mousewheel', this.onWheel, this);
18563 findTargets : function(e){
18565 var itemEl = e.getTarget('li', this.strip);
18567 item = this.getComponent(itemEl.id.split(this.idDelimiter)[1]);
18577 close : e.getTarget('.x-tab-strip-close', this.strip),
18583 onStripMouseDown : function(e){
18584 e.preventDefault();
18588 var t = this.findTargets(e);
18590 this.remove(t.item);
18593 if(t.item && t.item != this.activeTab){
18594 this.setActiveTab(t.item);
18598 onStripClick : function(e){
18599 var t = this.findTargets(e);
18600 if(!t.close && t.item && t.item != this.activeTab){
18601 this.setActiveTab(t.item);
18605 onStripContextMenu : function(e){
18606 e.preventDefault();
18607 var t = this.findTargets(e);
18609 this.fireEvent('contextmenu', this, t.item, e);
18614 readTabs : function(removeExisting){
18615 if(removeExisting === true){
18616 this.items.each(function(item){
18620 var tabs = this.el.query(this.autoTabSelector);
18621 for(var i = 0, len = tabs.length; i < len; i++){
18623 var title = tab.getAttribute('title');
18624 tab.removeAttribute('title');
18632 initTab : function(item, index){
18633 var before = this.strip.dom.childNodes[index];
18634 var cls = item.closable ? 'x-tab-strip-closable' : '';
18636 cls += ' x-item-disabled';
18639 cls += ' x-tab-with-icon';
18642 cls += ' ' + item.tabCls;
18646 id: this.id + this.idDelimiter + item.getItemId(),
18649 iconCls: item.iconCls || ''
18652 this.itemTpl.insertBefore(before, p) :
18653 this.itemTpl.append(this.strip, p);
18655 Ext.fly(el).addClassOnOver('x-tab-strip-over');
18658 Ext.fly(el).child('span.x-tab-strip-text', true).qtip = item.tabTip;
18660 item.on('disable', this.onItemDisabled, this);
18661 item.on('enable', this.onItemEnabled, this);
18662 item.on('titlechange', this.onItemTitleChanged, this);
18663 item.on('beforeshow', this.onBeforeShowItem, this);
18666 onAdd : function(tp, item, index){
18667 this.initTab(item, index);
18668 if(this.items.getCount() == 1){
18671 this.delegateUpdates();
18674 onBeforeAdd : function(item){
18675 var existing = item.events ? (this.items.containsKey(item.getItemId()) ? item : null) : this.items.get(item);
18677 this.setActiveTab(item);
18680 Ext.TabPanel.superclass.onBeforeAdd.apply(this, arguments);
18681 var es = item.elements;
18682 item.elements = es ? es.replace(',header', '') : es;
18683 item.border = (item.border === true);
18686 onRemove : function(tp, item){
18687 Ext.removeNode(this.getTabEl(item));
18688 this.stack.remove(item);
18689 if(item == this.activeTab){
18690 var next = this.stack.next();
18692 this.setActiveTab(next);
18694 this.setActiveTab(0);
18697 this.delegateUpdates();
18700 onBeforeShowItem : function(item){
18701 if(item != this.activeTab){
18702 this.setActiveTab(item);
18707 onItemDisabled : function(item){
18708 var el = this.getTabEl(item);
18710 Ext.fly(el).addClass('x-item-disabled');
18712 this.stack.remove(item);
18715 onItemEnabled : function(item){
18716 var el = this.getTabEl(item);
18718 Ext.fly(el).removeClass('x-item-disabled');
18722 onItemTitleChanged : function(item){
18723 var el = this.getTabEl(item);
18725 Ext.fly(el).child('span.x-tab-strip-text', true).innerHTML = item.title;
18730 getTabEl : function(item){
18731 var itemId = (typeof item === 'number')?this.items.items[item].getItemId() : item.getItemId();
18732 return document.getElementById(this.id+this.idDelimiter+itemId);
18735 onResize : function(){
18736 Ext.TabPanel.superclass.onResize.apply(this, arguments);
18737 this.delegateUpdates();
18741 beginUpdate : function(){
18742 this.suspendUpdates = true;
18746 endUpdate : function(){
18747 this.suspendUpdates = false;
18748 this.delegateUpdates();
18752 hideTabStripItem : function(item){
18753 item = this.getComponent(item);
18754 var el = this.getTabEl(item);
18756 el.style.display = 'none';
18757 this.delegateUpdates();
18762 unhideTabStripItem : function(item){
18763 item = this.getComponent(item);
18764 var el = this.getTabEl(item);
18766 el.style.display = '';
18767 this.delegateUpdates();
18771 delegateUpdates : function(){
18772 if(this.suspendUpdates){
18775 if(this.resizeTabs && this.rendered){
18776 this.autoSizeTabs();
18778 if(this.enableTabScroll && this.rendered){
18779 this.autoScrollTabs();
18783 autoSizeTabs : function(){
18784 var count = this.items.length;
18785 var ce = this.tabPosition != 'bottom' ? 'header' : 'footer';
18786 var ow = this[ce].dom.offsetWidth;
18787 var aw = this[ce].dom.clientWidth;
18789 if(!this.resizeTabs || count < 1 || !aw){ return;
18792 var each = Math.max(Math.min(Math.floor((aw-4) / count) - this.tabMargin, this.tabWidth), this.minTabWidth); this.lastTabWidth = each;
18793 var lis = this.stripWrap.dom.getElementsByTagName('li');
18794 for(var i = 0, len = lis.length-1; i < len; i++) { var li = lis[i];
18795 var inner = li.childNodes[1].firstChild.firstChild;
18796 var tw = li.offsetWidth;
18797 var iw = inner.offsetWidth;
18798 inner.style.width = (each - (tw-iw)) + 'px';
18802 adjustBodyWidth : function(w){
18804 this.header.setWidth(w);
18807 this.footer.setWidth(w);
18813 setActiveTab : function(item){
18814 item = this.getComponent(item);
18815 if(!item || this.fireEvent('beforetabchange', this, item, this.activeTab) === false){
18818 if(!this.rendered){
18819 this.activeTab = item;
18822 if(this.activeTab != item){
18823 if(this.activeTab){
18824 var oldEl = this.getTabEl(this.activeTab);
18826 Ext.fly(oldEl).removeClass('x-tab-strip-active');
18828 this.activeTab.fireEvent('deactivate', this.activeTab);
18830 var el = this.getTabEl(item);
18831 Ext.fly(el).addClass('x-tab-strip-active');
18832 this.activeTab = item;
18833 this.stack.add(item);
18835 this.layout.setActiveItem(item);
18836 if(this.layoutOnTabChange && item.doLayout){
18839 if(this.scrolling){
18840 this.scrollToTab(item, this.animScroll);
18843 item.fireEvent('activate', item);
18844 this.fireEvent('tabchange', this, item);
18849 getActiveTab : function(){
18850 return this.activeTab || null;
18854 getItem : function(item){
18855 return this.getComponent(item);
18858 autoScrollTabs : function(){
18859 var count = this.items.length;
18860 var ow = this.header.dom.offsetWidth;
18861 var tw = this.header.dom.clientWidth;
18863 var wrap = this.stripWrap;
18865 var cw = wd.offsetWidth;
18866 var pos = this.getScrollPos();
18867 var l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos;
18869 if(!this.enableTabScroll || count < 1 || cw < 20){ return;
18874 if(this.scrolling){
18875 this.scrolling = false;
18876 this.header.removeClass('x-tab-scrolling');
18877 this.scrollLeft.hide();
18878 this.scrollRight.hide();
18880 wd.style.marginLeft = '';
18881 wd.style.marginRight = '';
18885 if(!this.scrolling){
18886 this.header.addClass('x-tab-scrolling');
18888 wd.style.marginLeft = '18px';
18889 wd.style.marginRight = '18px';
18892 tw -= wrap.getMargins('lr');
18893 wrap.setWidth(tw > 20 ? tw : 20);
18894 if(!this.scrolling){
18895 if(!this.scrollLeft){
18896 this.createScrollers();
18898 this.scrollLeft.show();
18899 this.scrollRight.show();
18902 this.scrolling = true;
18903 if(pos > (l-tw)){ wd.scrollLeft = l-tw;
18904 }else{ this.scrollToTab(this.activeTab, false);
18906 this.updateScrollButtons();
18910 createScrollers : function(){
18911 var h = this.stripWrap.dom.offsetHeight;
18913 var sl = this.header.insertFirst({
18914 cls:'x-tab-scroller-left'
18917 sl.addClassOnOver('x-tab-scroller-left-over');
18918 this.leftRepeater = new Ext.util.ClickRepeater(sl, {
18919 interval : this.scrollRepeatInterval,
18920 handler: this.onScrollLeft,
18923 this.scrollLeft = sl;
18925 var sr = this.header.insertFirst({
18926 cls:'x-tab-scroller-right'
18929 sr.addClassOnOver('x-tab-scroller-right-over');
18930 this.rightRepeater = new Ext.util.ClickRepeater(sr, {
18931 interval : this.scrollRepeatInterval,
18932 handler: this.onScrollRight,
18935 this.scrollRight = sr;
18938 getScrollWidth : function(){
18939 return this.edge.getOffsetsTo(this.stripWrap)[0] + this.getScrollPos();
18942 getScrollPos : function(){
18943 return parseInt(this.stripWrap.dom.scrollLeft, 10) || 0;
18946 getScrollArea : function(){
18947 return parseInt(this.stripWrap.dom.clientWidth, 10) || 0;
18950 getScrollAnim : function(){
18951 return {duration:this.scrollDuration, callback: this.updateScrollButtons, scope: this};
18954 getScrollIncrement : function(){
18955 return this.scrollIncrement || (this.resizeTabs ? this.lastTabWidth+2 : 100);
18960 scrollToTab : function(item, animate){
18961 if(!item){ return; }
18962 var el = this.getTabEl(item);
18963 var pos = this.getScrollPos(), area = this.getScrollArea();
18964 var left = Ext.fly(el).getOffsetsTo(this.stripWrap)[0] + pos;
18965 var right = left + el.offsetWidth;
18967 this.scrollTo(left, animate);
18968 }else if(right > (pos + area)){
18969 this.scrollTo(right - area, animate);
18973 scrollTo : function(pos, animate){
18974 this.stripWrap.scrollTo('left', pos, animate ? this.getScrollAnim() : false);
18976 this.updateScrollButtons();
18980 onWheel : function(e){
18981 var d = e.getWheelDelta()*this.wheelIncrement*-1;
18984 var pos = this.getScrollPos();
18985 var newpos = pos + d;
18986 var sw = this.getScrollWidth()-this.getScrollArea();
18988 var s = Math.max(0, Math.min(sw, newpos));
18990 this.scrollTo(s, false);
18994 onScrollRight : function(){
18995 var sw = this.getScrollWidth()-this.getScrollArea();
18996 var pos = this.getScrollPos();
18997 var s = Math.min(sw, pos + this.getScrollIncrement());
18999 this.scrollTo(s, this.animScroll);
19003 onScrollLeft : function(){
19004 var pos = this.getScrollPos();
19005 var s = Math.max(0, pos - this.getScrollIncrement());
19007 this.scrollTo(s, this.animScroll);
19011 updateScrollButtons : function(){
19012 var pos = this.getScrollPos();
19013 this.scrollLeft[pos == 0 ? 'addClass' : 'removeClass']('x-tab-scroller-left-disabled');
19014 this.scrollRight[pos >= (this.getScrollWidth()-this.getScrollArea()) ? 'addClass' : 'removeClass']('x-tab-scroller-right-disabled');
19028 Ext.reg('tabpanel', Ext.TabPanel);
19031 Ext.TabPanel.prototype.activate = Ext.TabPanel.prototype.setActiveTab;
19033 Ext.TabPanel.AccessStack = function(){
19036 add : function(item){
19038 if(items.length > 10){
19043 remove : function(item){
19045 for(var i = 0, len = items.length; i < len; i++) {
19046 if(items[i] != item){
19054 return items.pop();
19062 Ext.Button = Ext.extend(Ext.Component, {
19074 enableToggle: false,
19077 menuAlign : "tl-bl?",
19083 menuClassTarget: 'tr',
19086 clickEvent : 'click',
19089 handleMouseEvents : true,
19092 tooltipType : 'qtip',
19094 buttonSelector : "button:first",
19099 initComponent : function(){
19100 Ext.Button.superclass.initComponent.call(this);
19121 this.menu = Ext.menu.MenuMgr.get(this.menu);
19123 if(typeof this.toggleGroup === 'string'){
19124 this.enableToggle = true;
19128 onRender : function(ct, position){
19129 if(!this.template){
19130 if(!Ext.Button.buttonTemplate){
19131 Ext.Button.buttonTemplate = new Ext.Template(
19132 '<table border="0" cellpadding="0" cellspacing="0" class="x-btn-wrap"><tbody><tr>',
19133 '<td class="x-btn-left"><i> </i></td><td class="x-btn-center"><em unselectable="on"><button class="x-btn-text" type="{1}">{0}</button></em></td><td class="x-btn-right"><i> </i></td>',
19134 "</tr></tbody></table>");
19136 this.template = Ext.Button.buttonTemplate;
19138 var btn, targs = [this.text || ' ', this.type];
19141 btn = this.template.insertBefore(position, targs, true);
19143 btn = this.template.append(ct, targs, true);
19145 var btnEl = btn.child(this.buttonSelector);
19146 btnEl.on('focus', this.onFocus, this);
19147 btnEl.on('blur', this.onBlur, this);
19149 this.initButtonEl(btn, btnEl);
19152 this.el.child(this.menuClassTarget).addClass("x-btn-with-menu");
19154 Ext.ButtonToggleMgr.register(this);
19157 initButtonEl : function(btn, btnEl){
19160 btn.addClass("x-btn");
19163 btnEl.setStyle('background-image', 'url(' +this.icon +')');
19166 btnEl.addClass(this.iconCls);
19168 btn.addClass(this.text ? 'x-btn-text-icon' : 'x-btn-icon');
19171 if(this.tabIndex !== undefined){
19172 btnEl.dom.tabIndex = this.tabIndex;
19175 if(typeof this.tooltip == 'object'){
19176 Ext.QuickTips.register(Ext.apply({
19180 btnEl.dom[this.tooltipType] = this.tooltip;
19185 this.el.addClass("x-btn-pressed");
19188 if(this.handleMouseEvents){
19189 btn.on("mouseover", this.onMouseOver, this);
19190 btn.on("mousedown", this.onMouseDown, this);
19194 this.menu.on("show", this.onMenuShow, this);
19195 this.menu.on("hide", this.onMenuHide, this);
19199 this.el.dom.id = this.el.id = this.id;
19203 var repeater = new Ext.util.ClickRepeater(btn,
19204 typeof this.repeat == "object" ? this.repeat : {}
19206 repeater.on("click", this.onClick, this);
19209 btn.on(this.clickEvent, this.onClick, this);
19212 afterRender : function(){
19213 Ext.Button.superclass.afterRender.call(this);
19215 this.autoWidth.defer(1, this);
19222 setIconClass : function(cls){
19224 this.el.child(this.buttonSelector).replaceClass(this.iconCls, cls);
19226 this.iconCls = cls;
19229 beforeDestroy: function(){
19231 var btn = this.el.child(this.buttonSelector);
19233 btn.removeAllListeners();
19237 Ext.destroy(this.menu);
19241 onDestroy : function(){
19243 Ext.ButtonToggleMgr.unregister(this);
19247 autoWidth : function(){
19249 this.el.setWidth("auto");
19250 if(Ext.isIE7 && Ext.isStrict){
19251 var ib = this.el.child(this.buttonSelector);
19252 if(ib && ib.getWidth() > 20){
19254 ib.setWidth(Ext.util.TextMetrics.measure(ib, this.text).width+ib.getFrameWidth('lr'));
19258 if(this.el.getWidth() < this.minWidth){
19259 this.el.setWidth(this.minWidth);
19266 setHandler : function(handler, scope){
19267 this.handler = handler;
19268 this.scope = scope;
19272 setText : function(text){
19275 this.el.child("td.x-btn-center " + this.buttonSelector).update(text);
19281 getText : function(){
19286 toggle : function(state){
19287 state = state === undefined ? !this.pressed : state;
19288 if(state != this.pressed){
19290 this.el.addClass("x-btn-pressed");
19291 this.pressed = true;
19292 this.fireEvent("toggle", this, true);
19294 this.el.removeClass("x-btn-pressed");
19295 this.pressed = false;
19296 this.fireEvent("toggle", this, false);
19298 if(this.toggleHandler){
19299 this.toggleHandler.call(this.scope || this, this, state);
19305 focus : function(){
19306 this.el.child(this.buttonSelector).focus();
19309 onDisable : function(){
19311 if(!Ext.isIE6 || !this.text){
19312 this.el.addClass(this.disabledClass);
19314 this.el.dom.disabled = true;
19316 this.disabled = true;
19319 onEnable : function(){
19321 if(!Ext.isIE6 || !this.text){
19322 this.el.removeClass(this.disabledClass);
19324 this.el.dom.disabled = false;
19326 this.disabled = false;
19330 showMenu : function(){
19332 this.menu.show(this.el, this.menuAlign);
19338 hideMenu : function(){
19346 hasVisibleMenu : function(){
19347 return this.menu && this.menu.isVisible();
19350 onClick : function(e){
19352 e.preventDefault();
19357 if(!this.disabled){
19358 if(this.enableToggle && (this.allowDepress !== false || !this.pressed)){
19361 if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
19364 this.fireEvent("click", this, e);
19366 this.handler.call(this.scope || this, this, e);
19371 isMenuTriggerOver : function(e, internal){
19372 return this.menu && !internal;
19375 isMenuTriggerOut : function(e, internal){
19376 return this.menu && !internal;
19379 onMouseOver : function(e){
19380 if(!this.disabled){
19381 var internal = e.within(this.el, true);
19383 this.el.addClass("x-btn-over");
19384 Ext.getDoc().on('mouseover', this.monitorMouseOver, this);
19385 this.fireEvent('mouseover', this, e);
19387 if(this.isMenuTriggerOver(e, internal)){
19388 this.fireEvent('menutriggerover', this, this.menu, e);
19393 monitorMouseOver : function(e){
19394 if(e.target != this.el.dom && !e.within(this.el)){
19395 Ext.getDoc().un('mouseover', this.monitorMouseOver, this);
19396 this.onMouseOut(e);
19400 onMouseOut : function(e){
19401 var internal = e.within(this.el) && e.target != this.el.dom;
19402 this.el.removeClass("x-btn-over");
19403 this.fireEvent('mouseout', this, e);
19404 if(this.isMenuTriggerOut(e, internal)){
19405 this.fireEvent('menutriggerout', this, this.menu, e);
19408 onFocus : function(e){
19409 if(!this.disabled){
19410 this.el.addClass("x-btn-focus");
19413 onBlur : function(e){
19414 this.el.removeClass("x-btn-focus");
19417 getClickEl : function(e, isUp){
19421 onMouseDown : function(e){
19422 if(!this.disabled && e.button == 0){
19423 this.getClickEl(e).addClass("x-btn-click");
19424 Ext.getDoc().on('mouseup', this.onMouseUp, this);
19427 onMouseUp : function(e){
19429 this.getClickEl(e, true).removeClass("x-btn-click");
19430 Ext.getDoc().un('mouseup', this.onMouseUp, this);
19433 onMenuShow : function(e){
19434 this.ignoreNextClick = 0;
19435 this.el.addClass("x-btn-menu-active");
19436 this.fireEvent('menushow', this, this.menu);
19438 onMenuHide : function(e){
19439 this.el.removeClass("x-btn-menu-active");
19440 this.ignoreNextClick = this.restoreClick.defer(250, this);
19441 this.fireEvent('menuhide', this, this.menu);
19444 restoreClick : function(){
19445 this.ignoreNextClick = 0;
19452 Ext.reg('button', Ext.Button);
19454 Ext.ButtonToggleMgr = function(){
19457 function toggleGroup(btn, state){
19459 var g = groups[btn.toggleGroup];
19460 for(var i = 0, l = g.length; i < l; i++){
19462 g[i].toggle(false);
19469 register : function(btn){
19470 if(!btn.toggleGroup){
19473 var g = groups[btn.toggleGroup];
19475 g = groups[btn.toggleGroup] = [];
19478 btn.on("toggle", toggleGroup);
19481 unregister : function(btn){
19482 if(!btn.toggleGroup){
19485 var g = groups[btn.toggleGroup];
19488 btn.un("toggle", toggleGroup);
19494 Ext.SplitButton = Ext.extend(Ext.Button, {
19496 arrowSelector : 'button:last',
19499 initComponent : function(){
19500 Ext.SplitButton.superclass.initComponent.call(this);
19502 this.addEvents("arrowclick");
19506 onRender : function(ct, position){
19508 var tpl = new Ext.Template(
19509 '<table cellspacing="0" class="x-btn-menu-wrap x-btn"><tr><td>',
19510 '<table cellspacing="0" class="x-btn-wrap x-btn-menu-text-wrap"><tbody>',
19511 '<tr><td class="x-btn-left"><i> </i></td><td class="x-btn-center"><button class="x-btn-text" type="{1}">{0}</button></td></tr>',
19512 "</tbody></table></td><td>",
19513 '<table cellspacing="0" class="x-btn-wrap x-btn-menu-arrow-wrap"><tbody>',
19514 '<tr><td class="x-btn-center"><button class="x-btn-menu-arrow-el" type="button"> </button></td><td class="x-btn-right"><i> </i></td></tr>',
19515 "</tbody></table></td></tr></table>"
19517 var btn, targs = [this.text || ' ', this.type];
19519 btn = tpl.insertBefore(position, targs, true);
19521 btn = tpl.append(ct, targs, true);
19523 var btnEl = btn.child(this.buttonSelector);
19525 this.initButtonEl(btn, btnEl);
19526 this.arrowBtnTable = btn.child("table:last");
19527 if(this.arrowTooltip){
19528 btn.child(this.arrowSelector).dom[this.tooltipType] = this.arrowTooltip;
19533 autoWidth : function(){
19535 var tbl = this.el.child("table:first");
19536 var tbl2 = this.el.child("table:last");
19537 this.el.setWidth("auto");
19538 tbl.setWidth("auto");
19539 if(Ext.isIE7 && Ext.isStrict){
19540 var ib = this.el.child(this.buttonSelector);
19541 if(ib && ib.getWidth() > 20){
19543 ib.setWidth(Ext.util.TextMetrics.measure(ib, this.text).width+ib.getFrameWidth('lr'));
19547 if((tbl.getWidth()+tbl2.getWidth()) < this.minWidth){
19548 tbl.setWidth(this.minWidth-tbl2.getWidth());
19551 this.el.setWidth(tbl.getWidth()+tbl2.getWidth());
19556 setArrowHandler : function(handler, scope){
19557 this.arrowHandler = handler;
19558 this.scope = scope;
19562 onClick : function(e){
19563 e.preventDefault();
19564 if(!this.disabled){
19565 if(e.getTarget(".x-btn-menu-arrow-wrap")){
19566 if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
19569 this.fireEvent("arrowclick", this, e);
19570 if(this.arrowHandler){
19571 this.arrowHandler.call(this.scope || this, this, e);
19574 if(this.enableToggle){
19577 this.fireEvent("click", this, e);
19579 this.handler.call(this.scope || this, this, e);
19586 getClickEl : function(e, isUp){
19588 return (this.lastClickEl = e.getTarget("table", 10, true));
19590 return this.lastClickEl;
19594 onDisable : function(){
19597 this.el.addClass("x-item-disabled");
19599 this.el.child(this.buttonSelector).dom.disabled = true;
19600 this.el.child(this.arrowSelector).dom.disabled = true;
19602 this.disabled = true;
19606 onEnable : function(){
19609 this.el.removeClass("x-item-disabled");
19611 this.el.child(this.buttonSelector).dom.disabled = false;
19612 this.el.child(this.arrowSelector).dom.disabled = false;
19614 this.disabled = false;
19618 isMenuTriggerOver : function(e){
19619 return this.menu && e.within(this.arrowBtnTable) && !e.within(this.arrowBtnTable, true);
19623 isMenuTriggerOut : function(e, internal){
19624 return this.menu && !e.within(this.arrowBtnTable);
19628 onDestroy : function(){
19629 Ext.destroy(this.arrowBtnTable);
19630 Ext.SplitButton.superclass.onDestroy.call(this);
19635 Ext.MenuButton = Ext.SplitButton;
19638 Ext.reg('splitbutton', Ext.SplitButton);
19640 Ext.CycleButton = Ext.extend(Ext.SplitButton, {
19647 getItemText : function(item){
19648 if(item && this.showText === true){
19650 if(this.prependText){
19651 text += this.prependText;
19660 setActiveItem : function(item, suppressEvent){
19661 if(typeof item != 'object'){
19662 item = this.menu.items.get(item);
19665 if(!this.rendered){
19666 this.text = this.getItemText(item);
19667 this.iconCls = item.iconCls;
19669 var t = this.getItemText(item);
19673 this.setIconClass(item.iconCls);
19675 this.activeItem = item;
19677 item.setChecked(true, true);
19679 if(this.forceIcon){
19680 this.setIconClass(this.forceIcon);
19682 if(!suppressEvent){
19683 this.fireEvent('change', this, item);
19689 getActiveItem : function(){
19690 return this.activeItem;
19694 initComponent : function(){
19700 if(this.changeHandler){
19701 this.on('change', this.changeHandler, this.scope||this);
19702 delete this.changeHandler;
19705 this.itemCount = this.items.length;
19707 this.menu = {cls:'x-cycle-menu', items:[]};
19709 for(var i = 0, len = this.itemCount; i < len; i++){
19710 var item = this.items[i];
19711 item.group = item.group || this.id;
19712 item.itemIndex = i;
19713 item.checkHandler = this.checkHandler;
19715 item.checked = item.checked || false;
19716 this.menu.items.push(item);
19721 this.setActiveItem(checked, true);
19722 Ext.CycleButton.superclass.initComponent.call(this);
19724 this.on('click', this.toggleSelected, this);
19728 checkHandler : function(item, pressed){
19730 this.setActiveItem(item);
19735 toggleSelected : function(){
19736 this.menu.render();
19738 var nextIdx, checkItem;
19739 for (var i = 1; i < this.itemCount; i++) {
19740 nextIdx = (this.activeItem.itemIndex + i) % this.itemCount;
19742 checkItem = this.menu.items.itemAt(nextIdx);
19744 if (!checkItem.disabled) {
19745 checkItem.setChecked(true);
19751 Ext.reg('cycle', Ext.CycleButton);
19753 Ext.Toolbar = function(config){
19754 if(Ext.isArray(config)){
19755 config = {buttons:config};
19757 Ext.Toolbar.superclass.constructor.call(this, config);
19762 var T = Ext.Toolbar;
19764 Ext.extend(T, Ext.BoxComponent, {
19769 initComponent : function(){
19770 T.superclass.initComponent.call(this);
19773 this.buttons = this.items;
19776 this.items = new Ext.util.MixedCollection(false, function(o){
19777 return o.itemId || o.id || Ext.id();
19783 cls:'x-toolbar x-small-editor',
19784 html:'<table cellspacing="0"><tr></tr></table>'
19788 onRender : function(ct, position){
19789 this.el = ct.createChild(Ext.apply({ id: this.id },this.autoCreate), position);
19790 this.tr = this.el.child("tr", true);
19794 afterRender : function(){
19795 T.superclass.afterRender.call(this);
19797 this.add.apply(this, this.buttons);
19798 delete this.buttons;
19804 var a = arguments, l = a.length;
19805 for(var i = 0; i < l; i++){
19807 if(el.isFormField){
19809 }else if(el.render){
19811 }else if(typeof el == "string"){
19812 if(el == "separator" || el == "-"){
19813 this.addSeparator();
19814 }else if(el == " "){
19816 }else if(el == "->"){
19821 }else if(el.tagName){
19822 this.addElement(el);
19823 }else if(typeof el == "object"){
19825 this.addField(Ext.ComponentMgr.create(el, 'button'));
19827 this.addButton(el);
19834 addSeparator : function(){
19835 return this.addItem(new T.Separator());
19839 addSpacer : function(){
19840 return this.addItem(new T.Spacer());
19844 addFill : function(){
19845 return this.addItem(new T.Fill());
19849 addElement : function(el){
19850 return this.addItem(new T.Item(el));
19854 addItem : function(item){
19855 var td = this.nextBlock();
19856 this.initMenuTracking(item);
19858 this.items.add(item);
19863 addButton : function(config){
19864 if(Ext.isArray(config)){
19866 for(var i = 0, len = config.length; i < len; i++) {
19867 buttons.push(this.addButton(config[i]));
19872 if(!(config instanceof T.Button)){
19874 new T.SplitButton(config) :
19875 new T.Button(config);
19877 var td = this.nextBlock();
19878 this.initMenuTracking(b);
19885 initMenuTracking : function(item){
19886 if(this.trackMenus && item.menu){
19888 'menutriggerover' : this.onButtonTriggerOver,
19889 'menushow' : this.onButtonMenuShow,
19890 'menuhide' : this.onButtonMenuHide,
19897 addText : function(text){
19898 return this.addItem(new T.TextItem(text));
19902 insertButton : function(index, item){
19903 if(Ext.isArray(item)){
19905 for(var i = 0, len = item.length; i < len; i++) {
19906 buttons.push(this.insertButton(index + i, item[i]));
19910 if (!(item instanceof T.Button)){
19911 item = new T.Button(item);
19913 var td = document.createElement("td");
19914 this.tr.insertBefore(td, this.tr.childNodes[index]);
19915 this.initMenuTracking(item);
19917 this.items.insert(index, item);
19922 addDom : function(config, returnEl){
19923 var td = this.nextBlock();
19924 Ext.DomHelper.overwrite(td, config);
19925 var ti = new T.Item(td.firstChild);
19927 this.items.add(ti);
19932 addField : function(field){
19933 var td = this.nextBlock();
19935 var ti = new T.Item(td.firstChild);
19937 this.items.add(ti);
19942 nextBlock : function(){
19943 var td = document.createElement("td");
19944 this.tr.appendChild(td);
19949 onDestroy : function(){
19950 Ext.Toolbar.superclass.onDestroy.call(this);
19953 Ext.destroy.apply(Ext, this.items.items);
19955 Ext.Element.uncache(this.tr);
19960 onDisable : function(){
19961 this.items.each(function(item){
19969 onEnable : function(){
19970 this.items.each(function(item){
19978 onButtonTriggerOver : function(btn){
19979 if(this.activeMenuBtn && this.activeMenuBtn != btn){
19980 this.activeMenuBtn.hideMenu();
19982 this.activeMenuBtn = btn;
19987 onButtonMenuShow : function(btn){
19988 this.activeMenuBtn = btn;
19992 onButtonMenuHide : function(btn){
19993 delete this.activeMenuBtn;
19998 Ext.reg('toolbar', Ext.Toolbar);
20001 T.Item = function(el){
20002 this.el = Ext.getDom(el);
20003 this.id = Ext.id(this.el);
20004 this.hidden = false;
20007 T.Item.prototype = {
20010 getEl : function(){
20015 render : function(td){
20017 td.appendChild(this.el);
20021 destroy : function(){
20022 if(this.td && this.td.parentNode){
20023 this.td.parentNode.removeChild(this.td);
20029 this.hidden = false;
20030 this.td.style.display = "";
20035 this.hidden = true;
20036 this.td.style.display = "none";
20040 setVisible: function(visible){
20049 focus : function(){
20050 Ext.fly(this.el).focus();
20054 disable : function(){
20055 Ext.fly(this.td).addClass("x-item-disabled");
20056 this.disabled = true;
20057 this.el.disabled = true;
20061 enable : function(){
20062 Ext.fly(this.td).removeClass("x-item-disabled");
20063 this.disabled = false;
20064 this.el.disabled = false;
20067 Ext.reg('tbitem', T.Item);
20071 T.Separator = function(){
20072 var s = document.createElement("span");
20073 s.className = "xtb-sep";
20074 T.Separator.superclass.constructor.call(this, s);
20076 Ext.extend(T.Separator, T.Item, {
20077 enable:Ext.emptyFn,
20078 disable:Ext.emptyFn,
20081 Ext.reg('tbseparator', T.Separator);
20084 T.Spacer = function(){
20085 var s = document.createElement("div");
20086 s.className = "xtb-spacer";
20087 T.Spacer.superclass.constructor.call(this, s);
20089 Ext.extend(T.Spacer, T.Item, {
20090 enable:Ext.emptyFn,
20091 disable:Ext.emptyFn,
20095 Ext.reg('tbspacer', T.Spacer);
20098 T.Fill = Ext.extend(T.Spacer, {
20100 render : function(td){
20101 td.style.width = '100%';
20102 T.Fill.superclass.render.call(this, td);
20105 Ext.reg('tbfill', T.Fill);
20108 T.TextItem = function(t){
20109 var s = document.createElement("span");
20110 s.className = "xtb-text";
20111 s.innerHTML = t.text ? t.text : t;
20112 T.TextItem.superclass.constructor.call(this, s);
20114 Ext.extend(T.TextItem, T.Item, {
20115 enable:Ext.emptyFn,
20116 disable:Ext.emptyFn,
20119 Ext.reg('tbtext', T.TextItem);
20123 T.Button = Ext.extend(Ext.Button, {
20126 onDestroy : function(){
20127 T.Button.superclass.onDestroy.call(this);
20128 if(this.container){
20129 this.container.remove();
20133 Ext.reg('tbbutton', T.Button);
20136 T.SplitButton = Ext.extend(Ext.SplitButton, {
20139 onDestroy : function(){
20140 T.SplitButton.superclass.onDestroy.call(this);
20141 if(this.container){
20142 this.container.remove();
20147 Ext.reg('tbsplit', T.SplitButton);
20149 T.MenuButton = T.SplitButton;
20154 Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {
20160 displayMsg : 'Displaying {0} - {1} of {2}',
20162 emptyMsg : 'No data to display',
20164 beforePageText : "Page",
20166 afterPageText : "of {0}",
20168 firstText : "First Page",
20170 prevText : "Previous Page",
20172 nextText : "Next Page",
20174 lastText : "Last Page",
20176 refreshText : "Refresh",
20179 paramNames : {start: 'start', limit: 'limit'},
20181 initComponent : function(){
20182 Ext.PagingToolbar.superclass.initComponent.call(this);
20184 this.bind(this.store);
20187 onRender : function(ct, position){
20188 Ext.PagingToolbar.superclass.onRender.call(this, ct, position);
20189 this.first = this.addButton({
20190 tooltip: this.firstText,
20191 iconCls: "x-tbar-page-first",
20193 handler: this.onClick.createDelegate(this, ["first"])
20195 this.prev = this.addButton({
20196 tooltip: this.prevText,
20197 iconCls: "x-tbar-page-prev",
20199 handler: this.onClick.createDelegate(this, ["prev"])
20201 this.addSeparator();
20202 this.add(this.beforePageText);
20203 this.field = Ext.get(this.addDom({
20208 cls: "x-tbar-page-number"
20210 this.field.on("keydown", this.onPagingKeydown, this);
20211 this.field.on("focus", function(){this.dom.select();});
20212 this.afterTextEl = this.addText(String.format(this.afterPageText, 1));
20213 this.field.setHeight(18);
20214 this.addSeparator();
20215 this.next = this.addButton({
20216 tooltip: this.nextText,
20217 iconCls: "x-tbar-page-next",
20219 handler: this.onClick.createDelegate(this, ["next"])
20221 this.last = this.addButton({
20222 tooltip: this.lastText,
20223 iconCls: "x-tbar-page-last",
20225 handler: this.onClick.createDelegate(this, ["last"])
20227 this.addSeparator();
20228 this.loading = this.addButton({
20229 tooltip: this.refreshText,
20230 iconCls: "x-tbar-loading",
20231 handler: this.onClick.createDelegate(this, ["refresh"])
20234 if(this.displayInfo){
20235 this.displayEl = Ext.fly(this.el.dom).createChild({cls:'x-paging-info'});
20238 this.onLoad.apply(this, this.dsLoaded);
20242 updateInfo : function(){
20243 if(this.displayEl){
20244 var count = this.store.getCount();
20245 var msg = count == 0 ?
20249 this.cursor+1, this.cursor+count, this.store.getTotalCount()
20251 this.displayEl.update(msg);
20255 onLoad : function(store, r, o){
20256 if(!this.rendered){
20257 this.dsLoaded = [store, r, o];
20260 this.cursor = o.params ? o.params[this.paramNames.start] : 0;
20261 var d = this.getPageData(), ap = d.activePage, ps = d.pages;
20263 this.afterTextEl.el.innerHTML = String.format(this.afterPageText, d.pages);
20264 this.field.dom.value = ap;
20265 this.first.setDisabled(ap == 1);
20266 this.prev.setDisabled(ap == 1);
20267 this.next.setDisabled(ap == ps);
20268 this.last.setDisabled(ap == ps);
20269 this.loading.enable();
20273 getPageData : function(){
20274 var total = this.store.getTotalCount();
20277 activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize),
20278 pages : total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)
20282 onLoadError : function(){
20283 if(!this.rendered){
20286 this.loading.enable();
20289 readPage : function(d){
20290 var v = this.field.dom.value, pageNum;
20291 if (!v || isNaN(pageNum = parseInt(v, 10))) {
20292 this.field.dom.value = d.activePage;
20298 onPagingKeydown : function(e){
20299 var k = e.getKey(), d = this.getPageData(), pageNum;
20300 if (k == e.RETURN) {
20302 if(pageNum = this.readPage(d)){
20303 pageNum = Math.min(Math.max(1, pageNum), d.pages) - 1;
20304 this.doLoad(pageNum * this.pageSize);
20306 }else if (k == e.HOME || k == e.END){
20308 pageNum = k == e.HOME ? 1 : d.pages;
20309 this.field.dom.value = pageNum;
20310 }else if (k == e.UP || k == e.PAGEUP || k == e.DOWN || k == e.PAGEDOWN){
20312 if(pageNum = this.readPage(d)){
20313 var increment = e.shiftKey ? 10 : 1;
20314 if(k == e.DOWN || k == e.PAGEDOWN){
20317 pageNum += increment;
20318 if(pageNum >= 1 & pageNum <= d.pages){
20319 this.field.dom.value = pageNum;
20325 beforeLoad : function(){
20326 if(this.rendered && this.loading){
20327 this.loading.disable();
20331 doLoad : function(start){
20332 var o = {}, pn = this.paramNames;
20333 o[pn.start] = start;
20334 o[pn.limit] = this.pageSize;
20335 this.store.load({params:o});
20338 onClick : function(which){
20339 var store = this.store;
20345 this.doLoad(Math.max(0, this.cursor-this.pageSize));
20348 this.doLoad(this.cursor+this.pageSize);
20351 var total = store.getTotalCount();
20352 var extra = total % this.pageSize;
20353 var lastStart = extra ? (total - extra) : total-this.pageSize;
20354 this.doLoad(lastStart);
20357 this.doLoad(this.cursor);
20363 unbind : function(store){
20364 store = Ext.StoreMgr.lookup(store);
20365 store.un("beforeload", this.beforeLoad, this);
20366 store.un("load", this.onLoad, this);
20367 store.un("loadexception", this.onLoadError, this);
20368 this.store = undefined;
20372 bind : function(store){
20373 store = Ext.StoreMgr.lookup(store);
20374 store.on("beforeload", this.beforeLoad, this);
20375 store.on("load", this.onLoad, this);
20376 store.on("loadexception", this.onLoadError, this);
20377 this.store = store;
20380 Ext.reg('paging', Ext.PagingToolbar);
20382 Ext.Resizable = function(el, config){
20383 this.el = Ext.get(el);
20385 if(config && config.wrap){
20386 config.resizeChild = this.el;
20387 this.el = this.el.wrap(typeof config.wrap == "object" ? config.wrap : {cls:"xresizable-wrap"});
20388 this.el.id = this.el.dom.id = config.resizeChild.id + "-rzwrap";
20389 this.el.setStyle("overflow", "hidden");
20390 this.el.setPositioning(config.resizeChild.getPositioning());
20391 config.resizeChild.clearPositioning();
20392 if(!config.width || !config.height){
20393 var csize = config.resizeChild.getSize();
20394 this.el.setSize(csize.width, csize.height);
20396 if(config.pinned && !config.adjustments){
20397 config.adjustments = "auto";
20401 this.proxy = this.el.createProxy({tag: "div", cls: "x-resizable-proxy", id: this.el.id + "-rzproxy"});
20402 this.proxy.unselectable();
20403 this.proxy.enableDisplayMode('block');
20405 Ext.apply(this, config);
20408 this.disableTrackOver = true;
20409 this.el.addClass("x-resizable-pinned");
20412 var position = this.el.getStyle("position");
20413 if(position != "absolute" && position != "fixed"){
20414 this.el.setStyle("position", "relative");
20417 this.handles = 's,e,se';
20418 if(this.multiDirectional){
20419 this.handles += ',n,w';
20422 if(this.handles == "all"){
20423 this.handles = "n s e w ne nw se sw";
20425 var hs = this.handles.split(/\s*?[,;]\s*?| /);
20426 var ps = Ext.Resizable.positions;
20427 for(var i = 0, len = hs.length; i < len; i++){
20428 if(hs[i] && ps[hs[i]]){
20429 var pos = ps[hs[i]];
20430 this[pos] = new Ext.Resizable.Handle(this, pos, this.disableTrackOver, this.transparent);
20434 this.corner = this.southeast;
20436 if(this.handles.indexOf("n") != -1 || this.handles.indexOf("w") != -1){
20437 this.updateBox = true;
20440 this.activeHandle = null;
20442 if(this.resizeChild){
20443 if(typeof this.resizeChild == "boolean"){
20444 this.resizeChild = Ext.get(this.el.dom.firstChild, true);
20446 this.resizeChild = Ext.get(this.resizeChild, true);
20450 if(this.adjustments == "auto"){
20451 var rc = this.resizeChild;
20452 var hw = this.west, he = this.east, hn = this.north, hs = this.south;
20453 if(rc && (hw || hn)){
20454 rc.position("relative");
20455 rc.setLeft(hw ? hw.el.getWidth() : 0);
20456 rc.setTop(hn ? hn.el.getHeight() : 0);
20458 this.adjustments = [
20459 (he ? -he.el.getWidth() : 0) + (hw ? -hw.el.getWidth() : 0),
20460 (hn ? -hn.el.getHeight() : 0) + (hs ? -hs.el.getHeight() : 0) -1
20464 if(this.draggable){
20465 this.dd = this.dynamic ?
20466 this.el.initDD(null) : this.el.initDDProxy(null, {dragElId: this.proxy.id});
20467 this.dd.setHandleElId(this.resizeChild ? this.resizeChild.id : this.el.id);
20476 if(this.width !== null && this.height !== null){
20477 this.resizeTo(this.width, this.height);
20479 this.updateChildSize();
20482 this.el.dom.style.zoom = 1;
20484 Ext.Resizable.superclass.constructor.call(this);
20487 Ext.extend(Ext.Resizable, Ext.util.Observable, {
20488 resizeChild : false,
20489 adjustments : [0, 0],
20499 multiDirectional : false,
20500 disableTrackOver : false,
20501 easing : 'easeOutStrong',
20502 widthIncrement : 0,
20503 heightIncrement : 0,
20507 preserveRatio : false,
20508 transparent: false,
20520 resizeTo : function(width, height){
20521 this.el.setSize(width, height);
20522 this.updateChildSize();
20523 this.fireEvent("resize", this, width, height, null);
20527 startSizing : function(e, handle){
20528 this.fireEvent("beforeresize", this, e);
20532 this.overlay = this.el.createProxy({tag: "div", cls: "x-resizable-overlay", html: " "}, Ext.getBody());
20533 this.overlay.unselectable();
20534 this.overlay.enableDisplayMode("block");
20535 this.overlay.on("mousemove", this.onMouseMove, this);
20536 this.overlay.on("mouseup", this.onMouseUp, this);
20538 this.overlay.setStyle("cursor", handle.el.getStyle("cursor"));
20540 this.resizing = true;
20541 this.startBox = this.el.getBox();
20542 this.startPoint = e.getXY();
20543 this.offsets = [(this.startBox.x + this.startBox.width) - this.startPoint[0],
20544 (this.startBox.y + this.startBox.height) - this.startPoint[1]];
20546 this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
20547 this.overlay.show();
20549 if(this.constrainTo) {
20550 var ct = Ext.get(this.constrainTo);
20551 this.resizeRegion = ct.getRegion().adjust(
20552 ct.getFrameWidth('t'),
20553 ct.getFrameWidth('l'),
20554 -ct.getFrameWidth('b'),
20555 -ct.getFrameWidth('r')
20559 this.proxy.setStyle('visibility', 'hidden');
20561 this.proxy.setBox(this.startBox);
20563 this.proxy.setStyle('visibility', 'visible');
20569 onMouseDown : function(handle, e){
20572 this.activeHandle = handle;
20573 this.startSizing(e, handle);
20578 onMouseUp : function(e){
20579 var size = this.resizeElement();
20580 this.resizing = false;
20582 this.overlay.hide();
20584 this.fireEvent("resize", this, size.width, size.height, e);
20588 updateChildSize : function(){
20589 if(this.resizeChild){
20591 var child = this.resizeChild;
20592 var adj = this.adjustments;
20593 if(el.dom.offsetWidth){
20594 var b = el.getSize(true);
20595 child.setSize(b.width+adj[0], b.height+adj[1]);
20602 setTimeout(function(){
20603 if(el.dom.offsetWidth){
20604 var b = el.getSize(true);
20605 child.setSize(b.width+adj[0], b.height+adj[1]);
20613 snap : function(value, inc, min){
20614 if(!inc || !value) return value;
20615 var newValue = value;
20616 var m = value % inc;
20619 newValue = value + (inc-m);
20621 newValue = value - m;
20624 return Math.max(min, newValue);
20628 resizeElement : function(){
20629 var box = this.proxy.getBox();
20630 if(this.updateBox){
20631 this.el.setBox(box, false, this.animate, this.duration, null, this.easing);
20633 this.el.setSize(box.width, box.height, this.animate, this.duration, null, this.easing);
20635 this.updateChildSize();
20643 constrain : function(v, diff, m, mx){
20646 }else if(v - diff > mx){
20653 onMouseMove : function(e){
20657 if(this.resizeRegion && !this.resizeRegion.contains(e.getPoint())) {
20662 var curSize = this.curSize || this.startBox;
20663 var x = this.startBox.x, y = this.startBox.y;
20664 var ox = x, oy = y;
20665 var w = curSize.width, h = curSize.height;
20666 var ow = w, oh = h;
20667 var mw = this.minWidth, mh = this.minHeight;
20668 var mxw = this.maxWidth, mxh = this.maxHeight;
20669 var wi = this.widthIncrement;
20670 var hi = this.heightIncrement;
20672 var eventXY = e.getXY();
20673 var diffX = -(this.startPoint[0] - Math.max(this.minX, eventXY[0]));
20674 var diffY = -(this.startPoint[1] - Math.max(this.minY, eventXY[1]));
20676 var pos = this.activeHandle.position;
20681 w = Math.min(Math.max(mw, w), mxw);
20685 h = Math.min(Math.max(mh, h), mxh);
20690 w = Math.min(Math.max(mw, w), mxw);
20691 h = Math.min(Math.max(mh, h), mxh);
20694 diffY = this.constrain(h, diffY, mh, mxh);
20699 diffX = this.constrain(w, diffX, mw, mxw);
20705 w = Math.min(Math.max(mw, w), mxw);
20706 diffY = this.constrain(h, diffY, mh, mxh);
20711 diffX = this.constrain(w, diffX, mw, mxw);
20712 diffY = this.constrain(h, diffY, mh, mxh);
20719 diffX = this.constrain(w, diffX, mw, mxw);
20721 h = Math.min(Math.max(mh, h), mxh);
20727 var sw = this.snap(w, wi, mw);
20728 var sh = this.snap(h, hi, mh);
20729 if(sw != w || sh != h){
20752 if(this.preserveRatio){
20757 h = Math.min(Math.max(mh, h), mxh);
20762 w = Math.min(Math.max(mw, w), mxw);
20767 w = Math.min(Math.max(mw, w), mxw);
20773 w = Math.min(Math.max(mw, w), mxw);
20779 h = Math.min(Math.max(mh, h), mxh);
20787 h = Math.min(Math.max(mh, h), mxh);
20797 h = Math.min(Math.max(mh, h), mxh);
20805 this.proxy.setBounds(x, y, w, h);
20807 this.resizeElement();
20814 handleOver : function(){
20816 this.el.addClass("x-resizable-over");
20821 handleOut : function(){
20822 if(!this.resizing){
20823 this.el.removeClass("x-resizable-over");
20828 getEl : function(){
20833 getResizeChild : function(){
20834 return this.resizeChild;
20838 destroy : function(removeEl){
20839 this.proxy.remove();
20841 this.overlay.removeAllListeners();
20842 this.overlay.remove();
20844 var ps = Ext.Resizable.positions;
20846 if(typeof ps[k] != "function" && this[ps[k]]){
20847 var h = this[ps[k]];
20848 h.el.removeAllListeners();
20853 this.el.update("");
20858 syncHandleHeight : function(){
20859 var h = this.el.getHeight(true);
20861 this.west.el.setHeight(h);
20864 this.east.el.setHeight(h);
20871 Ext.Resizable.positions = {
20872 n: "north", s: "south", e: "east", w: "west", se: "southeast", sw: "southwest", nw: "northwest", ne: "northeast"
20876 Ext.Resizable.Handle = function(rz, pos, disableTrackOver, transparent){
20879 var tpl = Ext.DomHelper.createTemplate(
20880 {tag: "div", cls: "x-resizable-handle x-resizable-handle-{0}"}
20883 Ext.Resizable.Handle.prototype.tpl = tpl;
20885 this.position = pos;
20887 this.el = this.tpl.append(rz.el.dom, [this.position], true);
20888 this.el.unselectable();
20890 this.el.setOpacity(0);
20892 this.el.on("mousedown", this.onMouseDown, this);
20893 if(!disableTrackOver){
20894 this.el.on("mouseover", this.onMouseOver, this);
20895 this.el.on("mouseout", this.onMouseOut, this);
20900 Ext.Resizable.Handle.prototype = {
20901 afterResize : function(rz){
20905 onMouseDown : function(e){
20906 this.rz.onMouseDown(this, e);
20909 onMouseOver : function(e){
20910 this.rz.handleOver(this, e);
20913 onMouseOut : function(e){
20914 this.rz.handleOut(this, e);
20922 Ext.Editor = function(field, config){
20923 this.field = field;
20924 Ext.Editor.superclass.constructor.call(this, config);
20927 Ext.extend(Ext.Editor, Ext.Component, {
20941 swallowKeys : true,
20943 completeOnEnter : false,
20945 cancelOnEsc : false,
20949 initComponent : function(){
20950 Ext.Editor.superclass.initComponent.call(this);
20965 onRender : function(ct, position){
20966 this.el = new Ext.Layer({
20967 shadow: this.shadow,
20973 constrain: this.constrain
20975 this.el.setStyle("overflow", Ext.isGecko ? "auto" : "hidden");
20976 if(this.field.msgTarget != 'title'){
20977 this.field.msgTarget = 'qtip';
20979 this.field.inEditor = true;
20980 this.field.render(this.el);
20982 this.field.el.dom.setAttribute('autocomplete', 'off');
20984 this.field.on("specialkey", this.onSpecialKey, this);
20985 if(this.swallowKeys){
20986 this.field.el.swallowEvent(['keydown','keypress']);
20989 this.field.on("blur", this.onBlur, this);
20990 if(this.field.grow){
20991 this.field.on("autosize", this.el.sync, this.el, {delay:1});
20995 onSpecialKey : function(field, e){
20996 if(this.completeOnEnter && e.getKey() == e.ENTER){
20998 this.completeEdit();
20999 }else if(this.cancelOnEsc && e.getKey() == e.ESC){
21002 this.fireEvent('specialkey', field, e);
21007 startEdit : function(el, value){
21009 this.completeEdit();
21011 this.boundEl = Ext.get(el);
21012 var v = value !== undefined ? value : this.boundEl.dom.innerHTML;
21013 if(!this.rendered){
21014 this.render(this.parentEl || document.body);
21016 if(this.fireEvent("beforestartedit", this, this.boundEl, v) === false){
21019 this.startValue = v;
21020 this.field.setValue(v);
21022 this.el.alignTo(this.boundEl, this.alignment);
21023 this.editing = true;
21027 doAutoSize : function(){
21029 var sz = this.boundEl.getSize();
21030 switch(this.autoSize){
21032 this.setSize(sz.width, "");
21035 this.setSize("", sz.height);
21038 this.setSize(sz.width, sz.height);
21044 setSize : function(w, h){
21045 delete this.field.lastSize;
21046 this.field.setSize(w, h);
21053 realign : function(){
21054 this.el.alignTo(this.boundEl, this.alignment);
21058 completeEdit : function(remainVisible){
21062 var v = this.getValue();
21063 if(this.revertInvalid !== false && !this.field.isValid()){
21064 v = this.startValue;
21065 this.cancelEdit(true);
21067 if(String(v) === String(this.startValue) && this.ignoreNoChange){
21068 this.editing = false;
21072 if(this.fireEvent("beforecomplete", this, v, this.startValue) !== false){
21073 this.editing = false;
21074 if(this.updateEl && this.boundEl){
21075 this.boundEl.update(v);
21077 if(remainVisible !== true){
21080 this.fireEvent("complete", this, v, this.startValue);
21084 onShow : function(){
21086 if(this.hideEl !== false){
21087 this.boundEl.hide();
21090 if(Ext.isIE && !this.fixIEFocus){ this.fixIEFocus = true;
21091 this.deferredFocus.defer(50, this);
21093 this.field.focus();
21095 this.fireEvent("startedit", this.boundEl, this.startValue);
21098 deferredFocus : function(){
21100 this.field.focus();
21105 cancelEdit : function(remainVisible){
21107 this.setValue(this.startValue);
21108 if(remainVisible !== true){
21114 onBlur : function(){
21115 if(this.allowBlur !== true && this.editing){
21116 this.completeEdit();
21120 onHide : function(){
21122 this.completeEdit();
21126 if(this.field.collapse){
21127 this.field.collapse();
21130 if(this.hideEl !== false){
21131 this.boundEl.show();
21136 setValue : function(v){
21137 this.field.setValue(v);
21141 getValue : function(){
21142 return this.field.getValue();
21145 beforeDestroy : function(){
21146 this.field.destroy();
21150 Ext.reg('editor', Ext.Editor);
21152 Ext.MessageBox = function(){
21153 var dlg, opt, mask, waitTimer;
21154 var bodyEl, msgEl, textboxEl, textareaEl, progressBar, pp, iconEl, spacerEl;
21155 var buttons, activeTextEl, bwidth, iconCls = '';
21158 var handleButton = function(button){
21160 Ext.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value], 1);
21164 var handleHide = function(){
21165 if(opt && opt.cls){
21166 dlg.el.removeClass(opt.cls);
21168 progressBar.reset();
21172 var handleEsc = function(d, k, e){
21173 if(opt && opt.closable !== false){
21182 var updateButtons = function(b){
21185 buttons["ok"].hide();
21186 buttons["cancel"].hide();
21187 buttons["yes"].hide();
21188 buttons["no"].hide();
21191 dlg.footer.dom.style.display = '';
21192 for(var k in buttons){
21193 if(typeof buttons[k] != "function"){
21196 buttons[k].setText(typeof b[k] == "string" ? b[k] : Ext.MessageBox.buttonText[k]);
21197 width += buttons[k].el.getWidth()+15;
21208 getDialog : function(titleText){
21210 dlg = new Ext.Window({
21215 constrainHeader:true,
21216 minimizable : false,
21217 maximizable : false,
21221 buttonAlign:"center",
21228 close : function(){
21229 if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){
21230 handleButton("no");
21232 handleButton("cancel");
21237 var bt = this.buttonText;
21239 buttons["ok"] = dlg.addButton(bt["ok"], handleButton.createCallback("ok"));
21240 buttons["yes"] = dlg.addButton(bt["yes"], handleButton.createCallback("yes"));
21241 buttons["no"] = dlg.addButton(bt["no"], handleButton.createCallback("no"));
21242 buttons["cancel"] = dlg.addButton(bt["cancel"], handleButton.createCallback("cancel"));
21243 buttons["ok"].hideMode = buttons["yes"].hideMode = buttons["no"].hideMode = buttons["cancel"].hideMode = 'offsets';
21244 dlg.render(document.body);
21245 dlg.getEl().addClass('x-window-dlg');
21247 bodyEl = dlg.body.createChild({
21248 html:'<div class="ext-mb-icon"></div><div class="ext-mb-content"><span class="ext-mb-text"></span><br /><input type="text" class="ext-mb-input" /><textarea class="ext-mb-textarea"></textarea></div>'
21250 iconEl = Ext.get(bodyEl.dom.firstChild);
21251 var contentEl = bodyEl.dom.childNodes[1];
21252 msgEl = Ext.get(contentEl.firstChild);
21253 textboxEl = Ext.get(contentEl.childNodes[2]);
21254 textboxEl.enableDisplayMode();
21255 textboxEl.addKeyListener([10,13], function(){
21256 if(dlg.isVisible() && opt && opt.buttons){
21257 if(opt.buttons.ok){
21258 handleButton("ok");
21259 }else if(opt.buttons.yes){
21260 handleButton("yes");
21264 textareaEl = Ext.get(contentEl.childNodes[3]);
21265 textareaEl.enableDisplayMode();
21266 progressBar = new Ext.ProgressBar({
21269 bodyEl.createChild({cls:'x-clear'});
21275 updateText : function(text){
21276 if(!dlg.isVisible() && !opt.width){
21277 dlg.setSize(this.maxWidth, 100);
21279 msgEl.update(text || ' ');
21281 var iw = iconCls != '' ? (iconEl.getWidth() + iconEl.getMargins('lr')) : 0;
21282 var mw = msgEl.getWidth() + msgEl.getMargins('lr');
21283 var fw = dlg.getFrameWidth('lr');
21284 var bw = dlg.body.getFrameWidth('lr');
21285 if (Ext.isIE && iw > 0){
21290 var w = Math.max(Math.min(opt.width || iw+mw+fw+bw, this.maxWidth),
21291 Math.max(opt.minWidth || this.minWidth, bwidth || 0));
21293 if(opt.prompt === true){
21294 activeTextEl.setWidth(w-iw-fw-bw);
21296 if(opt.progress === true || opt.wait === true){
21297 progressBar.setSize(w-iw-fw-bw);
21299 dlg.setSize(w, 'auto').center();
21304 updateProgress : function(value, progressText, msg){
21305 progressBar.updateProgress(value, progressText);
21307 this.updateText(msg);
21313 isVisible : function(){
21314 return dlg && dlg.isVisible();
21319 if(this.isVisible()){
21327 show : function(options){
21328 if(this.isVisible()){
21332 var d = this.getDialog(opt.title || " ");
21334 d.setTitle(opt.title || " ");
21335 var allowClose = (opt.closable !== false && opt.progress !== true && opt.wait !== true);
21336 d.tools.close.setDisplayed(allowClose);
21337 activeTextEl = textboxEl;
21338 opt.prompt = opt.prompt || (opt.multiline ? true : false);
21343 textareaEl.setHeight(typeof opt.multiline == "number" ?
21344 opt.multiline : this.defaultTextHeight);
21345 activeTextEl = textareaEl;
21354 activeTextEl.dom.value = opt.value || "";
21356 d.focusEl = activeTextEl;
21358 var bs = opt.buttons;
21361 db = buttons["ok"];
21362 }else if(bs && bs.yes){
21363 db = buttons["yes"];
21369 this.setIcon(opt.icon);
21370 bwidth = updateButtons(opt.buttons);
21371 progressBar.setVisible(opt.progress === true || opt.wait === true);
21372 this.updateProgress(0, opt.progressText);
21373 this.updateText(opt.msg);
21375 d.el.addClass(opt.cls);
21377 d.proxyDrag = opt.proxyDrag === true;
21378 d.modal = opt.modal !== false;
21379 d.mask = opt.modal !== false ? mask : false;
21380 if(!d.isVisible()){
21382 document.body.appendChild(dlg.el.dom);
21383 d.setAnimateTarget(opt.animEl);
21384 d.show(opt.animEl);
21388 d.on('show', function(){
21389 if(allowClose === true){
21392 d.keyMap.disable();
21394 }, this, {single:true});
21396 if(opt.wait === true){
21397 progressBar.wait(opt.waitConfig);
21403 setIcon : function(icon){
21404 if(icon && icon != ''){
21405 iconEl.removeClass('x-hidden');
21406 iconEl.replaceClass(iconCls, icon);
21409 iconEl.replaceClass(iconCls, 'x-hidden');
21416 progress : function(title, msg, progressText){
21423 minWidth: this.minProgressWidth,
21424 progressText: progressText
21430 wait : function(msg, title, config){
21438 minWidth: this.minProgressWidth,
21445 alert : function(title, msg, fn, scope){
21457 confirm : function(title, msg, fn, scope){
21461 buttons: this.YESNO,
21464 icon: this.QUESTION
21470 prompt : function(title, msg, fn, scope, multiline){
21474 buttons: this.OKCANCEL,
21479 multiline: multiline
21487 CANCEL : {cancel:true},
21489 OKCANCEL : {ok:true, cancel:true},
21491 YESNO : {yes:true, no:true},
21493 YESNOCANCEL : {yes:true, no:true, cancel:true},
21495 INFO : 'ext-mb-info',
21497 WARNING : 'ext-mb-warning',
21499 QUESTION : 'ext-mb-question',
21501 ERROR : 'ext-mb-error',
21504 defaultTextHeight : 75,
21510 minProgressWidth : 250,
21522 Ext.Msg = Ext.MessageBox;
21524 Ext.Tip = Ext.extend(Ext.Panel, {
21534 defaultAlign : "tl-bl?",
21536 quickShowInterval : 250,
21542 floating:{shadow:true,shim:true,useDisplay:true,constrain:false},
21546 initComponent : function(){
21547 Ext.Tip.superclass.initComponent.call(this);
21548 if(this.closable && !this.title){
21549 this.elements += ',header';
21554 afterRender : function(){
21555 Ext.Tip.superclass.afterRender.call(this);
21559 handler: this.hide,
21566 showAt : function(xy){
21567 Ext.Tip.superclass.show.call(this);
21568 if(this.measureWidth !== false && (!this.initialConfig || typeof this.initialConfig.width != 'number')){
21569 var bw = this.body.getTextWidth();
21571 bw = Math.max(bw, this.header.child('span').getTextWidth(this.title));
21573 bw += this.getFrameWidth() + (this.closable ? 20 : 0) + this.body.getPadding("lr");
21574 this.setWidth(bw.constrain(this.minWidth, this.maxWidth));
21576 if(this.constrainPosition){
21577 xy = this.el.adjustForConstraints(xy);
21579 this.setPagePosition(xy[0], xy[1]);
21583 showBy : function(el, pos){
21584 if(!this.rendered){
21585 this.render(Ext.getBody());
21587 this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign));
21590 initDraggable : function(){
21591 this.dd = new Ext.Tip.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);
21592 this.header.addClass('x-tip-draggable');
21597 Ext.Tip.DD = function(tip, config){
21598 Ext.apply(this, config);
21600 Ext.Tip.DD.superclass.constructor.call(this, tip.el.id, 'WindowDD-'+tip.id);
21601 this.setHandleElId(tip.header.id);
21602 this.scroll = false;
21605 Ext.extend(Ext.Tip.DD, Ext.dd.DD, {
21608 headerOffsets:[100, 25],
21609 startDrag : function(){
21610 this.tip.el.disableShadow();
21612 endDrag : function(e){
21613 this.tip.el.enableShadow(true);
21617 Ext.ToolTip = Ext.extend(Ext.Tip, {
21625 dismissDelay: 5000,
21627 mouseOffset: [15,18],
21629 trackMouse : false,
21630 constrainPosition: true,
21633 initComponent: function(){
21634 Ext.ToolTip.superclass.initComponent.call(this);
21635 this.lastActive = new Date();
21640 initTarget : function(){
21642 this.target = Ext.get(this.target);
21643 this.target.on('mouseover', this.onTargetOver, this);
21644 this.target.on('mouseout', this.onTargetOut, this);
21645 this.target.on('mousemove', this.onMouseMove, this);
21650 onMouseMove : function(e){
21651 this.targetXY = e.getXY();
21652 if(!this.hidden && this.trackMouse){
21653 this.setPagePosition(this.getTargetXY());
21658 getTargetXY : function(){
21659 return [this.targetXY[0]+this.mouseOffset[0], this.targetXY[1]+this.mouseOffset[1]];
21663 onTargetOver : function(e){
21664 if(this.disabled || e.within(this.target.dom, true)){
21667 this.clearTimer('hide');
21668 this.targetXY = e.getXY();
21673 delayShow : function(){
21674 if(this.hidden && !this.showTimer){
21675 if(this.lastActive.getElapsed() < this.quickShowInterval){
21678 this.showTimer = this.show.defer(this.showDelay, this);
21680 }else if(!this.hidden && this.autoHide !== false){
21686 onTargetOut : function(e){
21687 if(this.disabled || e.within(this.target.dom, true)){
21690 this.clearTimer('show');
21691 if(this.autoHide !== false){
21697 delayHide : function(){
21698 if(!this.hidden && !this.hideTimer){
21699 this.hideTimer = this.hide.defer(this.hideDelay, this);
21705 this.clearTimer('dismiss');
21706 this.lastActive = new Date();
21707 Ext.ToolTip.superclass.hide.call(this);
21712 this.showAt(this.getTargetXY());
21716 showAt : function(xy){
21717 this.lastActive = new Date();
21718 this.clearTimers();
21719 Ext.ToolTip.superclass.showAt.call(this, xy);
21720 if(this.dismissDelay && this.autoHide !== false){
21721 this.dismissTimer = this.hide.defer(this.dismissDelay, this);
21726 clearTimer : function(name){
21727 name = name + 'Timer';
21728 clearTimeout(this[name]);
21733 clearTimers : function(){
21734 this.clearTimer('show');
21735 this.clearTimer('dismiss');
21736 this.clearTimer('hide');
21740 onShow : function(){
21741 Ext.ToolTip.superclass.onShow.call(this);
21742 Ext.getDoc().on('mousedown', this.onDocMouseDown, this);
21746 onHide : function(){
21747 Ext.ToolTip.superclass.onHide.call(this);
21748 Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
21752 onDocMouseDown : function(e){
21753 if(this.autoHide !== false && !e.within(this.el.dom)){
21755 this.enable.defer(100, this);
21760 onDisable : function(){
21761 this.clearTimers();
21766 adjustPosition : function(x, y){
21768 var ay = this.targetXY[1], h = this.getSize().height;
21769 if(this.constrainPosition && y <= ay && (y+h) >= ay){
21772 return {x : x, y: y};
21776 onDestroy : function(){
21777 Ext.ToolTip.superclass.onDestroy.call(this);
21779 this.target.un('mouseover', this.onTargetOver, this);
21780 this.target.un('mouseout', this.onTargetOut, this);
21781 this.target.un('mousemove', this.onMouseMove, this);
21786 Ext.QuickTip = Ext.extend(Ext.ToolTip, {
21789 interceptTitles : false,
21794 attribute : "qtip",
21804 initComponent : function(){
21805 this.target = this.target || Ext.getDoc();
21806 this.targets = this.targets || {};
21807 Ext.QuickTip.superclass.initComponent.call(this);
21811 register : function(config){
21812 var cs = Ext.isArray(config) ? config : arguments;
21813 for(var i = 0, len = cs.length; i < len; i++){
21815 var target = c.target;
21817 if(Ext.isArray(target)){
21818 for(var j = 0, jlen = target.length; j < jlen; j++){
21819 this.targets[Ext.id(target[j])] = c;
21822 this.targets[Ext.id(target)] = c;
21829 unregister : function(el){
21830 delete this.targets[Ext.id(el)];
21834 onTargetOver : function(e){
21838 this.targetXY = e.getXY();
21839 var t = e.getTarget();
21840 if(!t || t.nodeType !== 1 || t == document || t == document.body){
21843 if(this.activeTarget && t == this.activeTarget.el){
21844 this.clearTimer('hide');
21848 if(t && this.targets[t.id]){
21849 this.activeTarget = this.targets[t.id];
21850 this.activeTarget.el = t;
21854 var ttp, et = Ext.fly(t), cfg = this.tagConfig;
21855 var ns = cfg.namespace;
21856 if(this.interceptTitles && t.title){
21859 t.removeAttribute("title");
21860 e.preventDefault();
21862 ttp = t.qtip || et.getAttributeNS(ns, cfg.attribute);
21865 var autoHide = et.getAttributeNS(ns, cfg.hide);
21866 this.activeTarget = {
21869 width: et.getAttributeNS(ns, cfg.width),
21870 autoHide: autoHide != "user" && autoHide !== 'false',
21871 title: et.getAttributeNS(ns, cfg.title),
21872 cls: et.getAttributeNS(ns, cfg.cls),
21873 align: et.getAttributeNS(ns, cfg.align)
21880 onTargetOut : function(e){
21881 this.clearTimer('show');
21882 if(this.autoHide !== false){
21888 showAt : function(xy){
21889 var t = this.activeTarget;
21891 if(!this.rendered){
21892 this.render(Ext.getBody());
21893 this.activeTarget = t;
21896 this.setWidth(t.width);
21897 this.body.setWidth(this.adjustBodyWidth(t.width - this.getFrameWidth()));
21898 this.measureWidth = false;
21900 this.measureWidth = true;
21902 this.setTitle(t.title || '');
21903 this.body.update(t.text);
21904 this.autoHide = t.autoHide;
21905 this.dismissDelay = t.dismissDelay || this.dismissDelay;
21907 this.el.removeClass(this.lastCls);
21908 delete this.lastCls;
21911 this.el.addClass(t.cls);
21912 this.lastCls = t.cls;
21915 xy = this.el.getAlignToXY(t.el, t.align);
21916 this.constrainPosition = false;
21918 this.constrainPosition = true;
21921 Ext.QuickTip.superclass.showAt.call(this, xy);
21926 delete this.activeTarget;
21927 Ext.QuickTip.superclass.hide.call(this);
21931 Ext.QuickTips = function(){
21932 var tip, locks = [];
21937 tip = new Ext.QuickTip({elements:'header,body'});
21942 enable : function(){
21945 if(locks.length < 1){
21952 disable : function(){
21960 isEnabled : function(){
21961 return tip && !tip.disabled;
21965 getQuickTip : function(){
21970 register : function(){
21971 tip.register.apply(tip, arguments);
21975 unregister : function(){
21976 tip.unregister.apply(tip, arguments);
21981 tip.register.apply(tip, arguments);
21986 Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
21987 rootVisible : true,
21988 animate: Ext.enableFx,
21991 hlDrop : Ext.enableFx,
21992 pathSeparator: "/",
21994 initComponent : function(){
21995 Ext.tree.TreePanel.superclass.initComponent.call(this);
21997 if(!this.eventModel){
21998 this.eventModel = new Ext.tree.TreeEventModel(this);
22001 this.nodeHash = {};
22005 this.setRootNode(this.root);
22034 "beforeexpandnode",
22036 "beforecollapsenode",
22054 "beforechildrenrendered",
22068 if(this.singleExpand){
22069 this.on("beforeexpandnode", this.restrictExpand, this);
22074 proxyNodeEvent : function(ename, a1, a2, a3, a4, a5, a6){
22075 if(ename == 'collapse' || ename == 'expand' || ename == 'beforecollapse' || ename == 'beforeexpand' || ename == 'move' || ename == 'beforemove'){
22076 ename = ename+'node';
22079 return this.fireEvent(ename, a1, a2, a3, a4, a5, a6);
22084 getRootNode : function(){
22089 setRootNode : function(node){
22091 node.ownerTree = this;
22092 node.isRoot = true;
22093 this.registerNode(node);
22094 if(!this.rootVisible){
22095 var uiP = node.attributes.uiProvider;
22096 node.ui = uiP ? new uiP(node) : new Ext.tree.RootTreeNodeUI(node);
22102 getNodeById : function(id){
22103 return this.nodeHash[id];
22107 registerNode : function(node){
22108 this.nodeHash[node.id] = node;
22112 unregisterNode : function(node){
22113 delete this.nodeHash[node.id];
22117 toString : function(){
22118 return "[Tree"+(this.id?" "+this.id:"")+"]";
22122 restrictExpand : function(node){
22123 var p = node.parentNode;
22125 if(p.expandedChild && p.expandedChild.parentNode == p){
22126 p.expandedChild.collapse();
22128 p.expandedChild = node;
22133 getChecked : function(a, startNode){
22134 startNode = startNode || this.root;
22136 var f = function(){
22137 if(this.attributes.checked){
22138 r.push(!a ? this : (a == 'id' ? this.id : this.attributes[a]));
22141 startNode.cascade(f);
22146 getEl : function(){
22151 getLoader : function(){
22152 return this.loader;
22156 expandAll : function(){
22157 this.root.expand(true);
22161 collapseAll : function(){
22162 this.root.collapse(true);
22166 getSelectionModel : function(){
22167 if(!this.selModel){
22168 this.selModel = new Ext.tree.DefaultSelectionModel();
22170 return this.selModel;
22174 expandPath : function(path, attr, callback){
22175 attr = attr || "id";
22176 var keys = path.split(this.pathSeparator);
22177 var curNode = this.root;
22178 if(curNode.attributes[attr] != keys[1]){
22180 callback(false, null);
22185 var f = function(){
22186 if(++index == keys.length){
22188 callback(true, curNode);
22192 var c = curNode.findChild(attr, keys[index]);
22195 callback(false, curNode);
22200 c.expand(false, false, f);
22202 curNode.expand(false, false, f);
22206 selectPath : function(path, attr, callback){
22207 attr = attr || "id";
22208 var keys = path.split(this.pathSeparator);
22209 var v = keys.pop();
22210 if(keys.length > 0){
22211 var f = function(success, node){
22212 if(success && node){
22213 var n = node.findChild(attr, v);
22219 }else if(callback){
22220 callback(false, n);
22224 callback(false, n);
22228 this.expandPath(keys.join(this.pathSeparator), attr, f);
22230 this.root.select();
22232 callback(true, this.root);
22238 getTreeEl : function(){
22243 onRender : function(ct, position){
22244 Ext.tree.TreePanel.superclass.onRender.call(this, ct, position);
22245 this.el.addClass('x-tree');
22246 this.innerCt = this.body.createChild({tag:"ul",
22247 cls:"x-tree-root-ct " +
22248 (this.useArrows ? 'x-tree-arrows' : this.lines ? "x-tree-lines" : "x-tree-no-lines")});
22252 initEvents : function(){
22253 Ext.tree.TreePanel.superclass.initEvents.call(this);
22255 if(this.containerScroll){
22256 Ext.dd.ScrollManager.register(this.body);
22258 if((this.enableDD || this.enableDrop) && !this.dropZone){
22260 this.dropZone = new Ext.tree.TreeDropZone(this, this.dropConfig || {
22261 ddGroup: this.ddGroup || "TreeDD", appendOnly: this.ddAppendOnly === true
22264 if((this.enableDD || this.enableDrag) && !this.dragZone){
22266 this.dragZone = new Ext.tree.TreeDragZone(this, this.dragConfig || {
22267 ddGroup: this.ddGroup || "TreeDD",
22268 scroll: this.ddScroll
22271 this.getSelectionModel().init(this);
22275 afterRender : function(){
22276 Ext.tree.TreePanel.superclass.afterRender.call(this);
22277 this.root.render();
22278 if(!this.rootVisible){
22279 this.root.renderChildren();
22283 onDestroy : function(){
22285 this.body.removeAllListeners();
22286 Ext.dd.ScrollManager.unregister(this.body);
22288 this.dropZone.unreg();
22291 this.dragZone.unreg();
22294 this.root.destroy();
22295 this.nodeHash = null;
22296 Ext.tree.TreePanel.superclass.onDestroy.call(this);
22346 Ext.reg('treepanel', Ext.tree.TreePanel);
22347 Ext.tree.TreeEventModel = function(tree){
22349 this.tree.on('render', this.initEvents, this);
22352 Ext.tree.TreeEventModel.prototype = {
22353 initEvents : function(){
22354 var el = this.tree.getTreeEl();
22355 el.on('click', this.delegateClick, this);
22356 if(this.tree.trackMouseOver !== false){
22357 el.on('mouseover', this.delegateOver, this);
22358 el.on('mouseout', this.delegateOut, this);
22360 el.on('dblclick', this.delegateDblClick, this);
22361 el.on('contextmenu', this.delegateContextMenu, this);
22364 getNode : function(e){
22366 if(t = e.getTarget('.x-tree-node-el', 10)){
22367 var id = Ext.fly(t, '_treeEvents').getAttributeNS('ext', 'tree-node-id');
22369 return this.tree.getNodeById(id);
22375 getNodeTarget : function(e){
22376 var t = e.getTarget('.x-tree-node-icon', 1);
22378 t = e.getTarget('.x-tree-node-el', 6);
22383 delegateOut : function(e, t){
22384 if(!this.beforeEvent(e)){
22387 if(e.getTarget('.x-tree-ec-icon', 1)){
22388 var n = this.getNode(e);
22389 this.onIconOut(e, n);
22390 if(n == this.lastEcOver){
22391 delete this.lastEcOver;
22394 if((t = this.getNodeTarget(e)) && !e.within(t, true)){
22395 this.onNodeOut(e, this.getNode(e));
22399 delegateOver : function(e, t){
22400 if(!this.beforeEvent(e)){
22403 if(this.lastEcOver){
22404 this.onIconOut(e, this.lastEcOver);
22405 delete this.lastEcOver;
22407 if(e.getTarget('.x-tree-ec-icon', 1)){
22408 this.lastEcOver = this.getNode(e);
22409 this.onIconOver(e, this.lastEcOver);
22411 if(t = this.getNodeTarget(e)){
22412 this.onNodeOver(e, this.getNode(e));
22416 delegateClick : function(e, t){
22417 if(!this.beforeEvent(e)){
22421 if(e.getTarget('input[type=checkbox]', 1)){
22422 this.onCheckboxClick(e, this.getNode(e));
22424 else if(e.getTarget('.x-tree-ec-icon', 1)){
22425 this.onIconClick(e, this.getNode(e));
22427 else if(this.getNodeTarget(e)){
22428 this.onNodeClick(e, this.getNode(e));
22432 delegateDblClick : function(e, t){
22433 if(this.beforeEvent(e) && this.getNodeTarget(e)){
22434 this.onNodeDblClick(e, this.getNode(e));
22438 delegateContextMenu : function(e, t){
22439 if(this.beforeEvent(e) && this.getNodeTarget(e)){
22440 this.onNodeContextMenu(e, this.getNode(e));
22444 onNodeClick : function(e, node){
22445 node.ui.onClick(e);
22448 onNodeOver : function(e, node){
22452 onNodeOut : function(e, node){
22456 onIconOver : function(e, node){
22457 node.ui.addClass('x-tree-ec-over');
22460 onIconOut : function(e, node){
22461 node.ui.removeClass('x-tree-ec-over');
22464 onIconClick : function(e, node){
22465 node.ui.ecClick(e);
22468 onCheckboxClick : function(e, node){
22469 node.ui.onCheckChange(e);
22472 onNodeDblClick : function(e, node){
22473 node.ui.onDblClick(e);
22476 onNodeContextMenu : function(e, node){
22477 node.ui.onContextMenu(e);
22480 beforeEvent : function(e){
22488 disable: function(){
22489 this.disabled = true;
22492 enable: function(){
22493 this.disabled = false;
22497 Ext.tree.DefaultSelectionModel = function(config){
22498 this.selNode = null;
22508 Ext.apply(this, config);
22509 Ext.tree.DefaultSelectionModel.superclass.constructor.call(this);
22512 Ext.extend(Ext.tree.DefaultSelectionModel, Ext.util.Observable, {
22513 init : function(tree){
22515 tree.getTreeEl().on("keydown", this.onKeyDown, this);
22516 tree.on("click", this.onNodeClick, this);
22519 onNodeClick : function(node, e){
22524 select : function(node){
22525 var last = this.selNode;
22526 if(last != node && this.fireEvent('beforeselect', this, node, last) !== false){
22528 last.ui.onSelectedChange(false);
22530 this.selNode = node;
22531 node.ui.onSelectedChange(true);
22532 this.fireEvent("selectionchange", this, node, last);
22538 unselect : function(node){
22539 if(this.selNode == node){
22540 this.clearSelections();
22545 clearSelections : function(){
22546 var n = this.selNode;
22548 n.ui.onSelectedChange(false);
22549 this.selNode = null;
22550 this.fireEvent("selectionchange", this, null);
22556 getSelectedNode : function(){
22557 return this.selNode;
22561 isSelected : function(node){
22562 return this.selNode == node;
22566 selectPrevious : function(){
22567 var s = this.selNode || this.lastSelNode;
22571 var ps = s.previousSibling;
22573 if(!ps.isExpanded() || ps.childNodes.length < 1){
22574 return this.select(ps);
22576 var lc = ps.lastChild;
22577 while(lc && lc.isExpanded() && lc.childNodes.length > 0){
22580 return this.select(lc);
22582 } else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){
22583 return this.select(s.parentNode);
22589 selectNext : function(){
22590 var s = this.selNode || this.lastSelNode;
22594 if(s.firstChild && s.isExpanded()){
22595 return this.select(s.firstChild);
22596 }else if(s.nextSibling){
22597 return this.select(s.nextSibling);
22598 }else if(s.parentNode){
22600 s.parentNode.bubble(function(){
22601 if(this.nextSibling){
22602 newS = this.getOwnerTree().selModel.select(this.nextSibling);
22611 onKeyDown : function(e){
22612 var s = this.selNode || this.lastSelNode;
22618 var k = e.getKey();
22626 this.selectPrevious();
22629 e.preventDefault();
22630 if(s.hasChildNodes()){
22631 if(!s.isExpanded()){
22633 }else if(s.firstChild){
22634 this.select(s.firstChild, e);
22639 e.preventDefault();
22640 if(s.hasChildNodes() && s.isExpanded()){
22642 }else if(s.parentNode && (this.tree.rootVisible || s.parentNode != this.tree.getRootNode())){
22643 this.select(s.parentNode, e);
22651 Ext.tree.MultiSelectionModel = function(config){
22652 this.selNodes = [];
22658 Ext.apply(this, config);
22659 Ext.tree.MultiSelectionModel.superclass.constructor.call(this);
22662 Ext.extend(Ext.tree.MultiSelectionModel, Ext.util.Observable, {
22663 init : function(tree){
22665 tree.getTreeEl().on("keydown", this.onKeyDown, this);
22666 tree.on("click", this.onNodeClick, this);
22669 onNodeClick : function(node, e){
22670 this.select(node, e, e.ctrlKey);
22674 select : function(node, e, keepExisting){
22675 if(keepExisting !== true){
22676 this.clearSelections(true);
22678 if(this.isSelected(node)){
22679 this.lastSelNode = node;
22682 this.selNodes.push(node);
22683 this.selMap[node.id] = node;
22684 this.lastSelNode = node;
22685 node.ui.onSelectedChange(true);
22686 this.fireEvent("selectionchange", this, this.selNodes);
22691 unselect : function(node){
22692 if(this.selMap[node.id]){
22693 node.ui.onSelectedChange(false);
22694 var sn = this.selNodes;
22695 var index = sn.indexOf(node);
22697 this.selNodes.splice(index, 1);
22699 delete this.selMap[node.id];
22700 this.fireEvent("selectionchange", this, this.selNodes);
22705 clearSelections : function(suppressEvent){
22706 var sn = this.selNodes;
22708 for(var i = 0, len = sn.length; i < len; i++){
22709 sn[i].ui.onSelectedChange(false);
22711 this.selNodes = [];
22713 if(suppressEvent !== true){
22714 this.fireEvent("selectionchange", this, this.selNodes);
22720 isSelected : function(node){
22721 return this.selMap[node.id] ? true : false;
22725 getSelectedNodes : function(){
22726 return this.selNodes;
22729 onKeyDown : Ext.tree.DefaultSelectionModel.prototype.onKeyDown,
22731 selectNext : Ext.tree.DefaultSelectionModel.prototype.selectNext,
22733 selectPrevious : Ext.tree.DefaultSelectionModel.prototype.selectPrevious
22736 Ext.tree.TreeNode = function(attributes){
22737 attributes = attributes || {};
22738 if(typeof attributes == "string"){
22739 attributes = {text: attributes};
22741 this.childrenRendered = false;
22742 this.rendered = false;
22743 Ext.tree.TreeNode.superclass.constructor.call(this, attributes);
22744 this.expanded = attributes.expanded === true;
22745 this.isTarget = attributes.isTarget !== false;
22746 this.draggable = attributes.draggable !== false && attributes.allowDrag !== false;
22747 this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false;
22750 this.text = attributes.text;
22752 this.disabled = attributes.disabled === true;
22778 "beforechildrenrendered"
22781 var uiClass = this.attributes.uiProvider || this.defaultUI || Ext.tree.TreeNodeUI;
22784 this.ui = new uiClass(this);
22786 Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
22787 preventHScroll: true,
22789 isExpanded : function(){
22790 return this.expanded;
22794 getUI : function(){
22799 setFirstChild : function(node){
22800 var of = this.firstChild;
22801 Ext.tree.TreeNode.superclass.setFirstChild.call(this, node);
22802 if(this.childrenRendered && of && node != of){
22803 of.renderIndent(true, true);
22806 this.renderIndent(true, true);
22811 setLastChild : function(node){
22812 var ol = this.lastChild;
22813 Ext.tree.TreeNode.superclass.setLastChild.call(this, node);
22814 if(this.childrenRendered && ol && node != ol){
22815 ol.renderIndent(true, true);
22818 this.renderIndent(true, true);
22824 appendChild : function(){
22825 var node = Ext.tree.TreeNode.superclass.appendChild.apply(this, arguments);
22826 if(node && this.childrenRendered){
22829 this.ui.updateExpandIcon();
22834 removeChild : function(node){
22835 this.ownerTree.getSelectionModel().unselect(node);
22836 Ext.tree.TreeNode.superclass.removeChild.apply(this, arguments);
22838 if(this.childrenRendered){
22841 if(this.childNodes.length < 1){
22842 this.collapse(false, false);
22844 this.ui.updateExpandIcon();
22846 if(!this.firstChild && !this.isHiddenRoot()) {
22847 this.childrenRendered = false;
22853 insertBefore : function(node, refNode){
22854 var newNode = Ext.tree.TreeNode.superclass.insertBefore.apply(this, arguments);
22855 if(newNode && refNode && this.childrenRendered){
22858 this.ui.updateExpandIcon();
22863 setText : function(text){
22864 var oldText = this.text;
22866 this.attributes.text = text;
22868 this.ui.onTextChange(this, text, oldText);
22870 this.fireEvent("textchange", this, text, oldText);
22874 select : function(){
22875 this.getOwnerTree().getSelectionModel().select(this);
22879 unselect : function(){
22880 this.getOwnerTree().getSelectionModel().unselect(this);
22884 isSelected : function(){
22885 return this.getOwnerTree().getSelectionModel().isSelected(this);
22889 expand : function(deep, anim, callback){
22890 if(!this.expanded){
22891 if(this.fireEvent("beforeexpand", this, deep, anim) === false){
22894 if(!this.childrenRendered){
22895 this.renderChildren();
22897 this.expanded = true;
22898 if(!this.isHiddenRoot() && (this.getOwnerTree().animate && anim !== false) || anim){
22899 this.ui.animExpand(function(){
22900 this.fireEvent("expand", this);
22901 if(typeof callback == "function"){
22905 this.expandChildNodes(true);
22907 }.createDelegate(this));
22911 this.fireEvent("expand", this);
22912 if(typeof callback == "function"){
22917 if(typeof callback == "function"){
22922 this.expandChildNodes(true);
22926 isHiddenRoot : function(){
22927 return this.isRoot && !this.getOwnerTree().rootVisible;
22931 collapse : function(deep, anim){
22932 if(this.expanded && !this.isHiddenRoot()){
22933 if(this.fireEvent("beforecollapse", this, deep, anim) === false){
22936 this.expanded = false;
22937 if((this.getOwnerTree().animate && anim !== false) || anim){
22938 this.ui.animCollapse(function(){
22939 this.fireEvent("collapse", this);
22941 this.collapseChildNodes(true);
22943 }.createDelegate(this));
22946 this.ui.collapse();
22947 this.fireEvent("collapse", this);
22951 var cs = this.childNodes;
22952 for(var i = 0, len = cs.length; i < len; i++) {
22953 cs[i].collapse(true, false);
22959 delayedExpand : function(delay){
22960 if(!this.expandProcId){
22961 this.expandProcId = this.expand.defer(delay, this);
22966 cancelExpand : function(){
22967 if(this.expandProcId){
22968 clearTimeout(this.expandProcId);
22970 this.expandProcId = false;
22974 toggle : function(){
22983 ensureVisible : function(callback){
22984 var tree = this.getOwnerTree();
22985 tree.expandPath(this.parentNode.getPath(), false, function(){
22986 var node = tree.getNodeById(this.id);
22987 tree.getTreeEl().scrollChildIntoView(node.ui.anchor);
22988 Ext.callback(callback);
22989 }.createDelegate(this));
22993 expandChildNodes : function(deep){
22994 var cs = this.childNodes;
22995 for(var i = 0, len = cs.length; i < len; i++) {
22996 cs[i].expand(deep);
23001 collapseChildNodes : function(deep){
23002 var cs = this.childNodes;
23003 for(var i = 0, len = cs.length; i < len; i++) {
23004 cs[i].collapse(deep);
23009 disable : function(){
23010 this.disabled = true;
23012 if(this.rendered && this.ui.onDisableChange){
23013 this.ui.onDisableChange(this, true);
23015 this.fireEvent("disabledchange", this, true);
23019 enable : function(){
23020 this.disabled = false;
23021 if(this.rendered && this.ui.onDisableChange){
23022 this.ui.onDisableChange(this, false);
23024 this.fireEvent("disabledchange", this, false);
23028 renderChildren : function(suppressEvent){
23029 if(suppressEvent !== false){
23030 this.fireEvent("beforechildrenrendered", this);
23032 var cs = this.childNodes;
23033 for(var i = 0, len = cs.length; i < len; i++){
23034 cs[i].render(true);
23036 this.childrenRendered = true;
23040 sort : function(fn, scope){
23041 Ext.tree.TreeNode.superclass.sort.apply(this, arguments);
23042 if(this.childrenRendered){
23043 var cs = this.childNodes;
23044 for(var i = 0, len = cs.length; i < len; i++){
23045 cs[i].render(true);
23051 render : function(bulkRender){
23052 this.ui.render(bulkRender);
23053 if(!this.rendered){
23055 this.getOwnerTree().registerNode(this);
23056 this.rendered = true;
23058 this.expanded = false;
23059 this.expand(false, false);
23065 renderIndent : function(deep, refresh){
23067 this.ui.childIndent = null;
23069 this.ui.renderIndent();
23070 if(deep === true && this.childrenRendered){
23071 var cs = this.childNodes;
23072 for(var i = 0, len = cs.length; i < len; i++){
23073 cs[i].renderIndent(true, refresh);
23078 beginUpdate : function(){
23079 this.childrenRendered = false;
23082 endUpdate : function(){
23084 this.renderChildren();
23088 destroy : function(){
23089 for(var i = 0,l = this.childNodes.length; i < l; i++){
23090 this.childNodes[i].destroy();
23092 this.childNodes = null;
23093 if(this.ui.destroy){
23099 Ext.tree.AsyncTreeNode = function(config){
23100 this.loaded = false;
23101 this.loading = false;
23102 Ext.tree.AsyncTreeNode.superclass.constructor.apply(this, arguments);
23104 this.addEvents('beforeload', 'load');
23108 Ext.extend(Ext.tree.AsyncTreeNode, Ext.tree.TreeNode, {
23109 expand : function(deep, anim, callback){
23112 var f = function(){
23114 clearInterval(timer);
23115 this.expand(deep, anim, callback);
23117 }.createDelegate(this);
23118 timer = setInterval(f, 200);
23122 if(this.fireEvent("beforeload", this) === false){
23125 this.loading = true;
23126 this.ui.beforeLoad(this);
23127 var loader = this.loader || this.attributes.loader || this.getOwnerTree().getLoader();
23129 loader.load(this, this.loadComplete.createDelegate(this, [deep, anim, callback]));
23133 Ext.tree.AsyncTreeNode.superclass.expand.call(this, deep, anim, callback);
23137 isLoading : function(){
23138 return this.loading;
23141 loadComplete : function(deep, anim, callback){
23142 this.loading = false;
23143 this.loaded = true;
23144 this.ui.afterLoad(this);
23145 this.fireEvent("load", this);
23146 this.expand(deep, anim, callback);
23150 isLoaded : function(){
23151 return this.loaded;
23154 hasChildNodes : function(){
23155 if(!this.isLeaf() && !this.loaded){
23158 return Ext.tree.AsyncTreeNode.superclass.hasChildNodes.call(this);
23163 reload : function(callback){
23164 this.collapse(false, false);
23165 while(this.firstChild){
23166 this.removeChild(this.firstChild);
23168 this.childrenRendered = false;
23169 this.loaded = false;
23170 if(this.isHiddenRoot()){
23171 this.expanded = false;
23173 this.expand(false, false, callback);
23177 Ext.tree.TreeNodeUI = function(node){
23179 this.rendered = false;
23180 this.animating = false;
23181 this.wasLeaf = true;
23182 this.ecc = 'x-tree-ec-icon x-tree-elbow';
23183 this.emptyIcon = Ext.BLANK_IMAGE_URL;
23186 Ext.tree.TreeNodeUI.prototype = {
23188 removeChild : function(node){
23190 this.ctNode.removeChild(node.ui.getEl());
23195 beforeLoad : function(){
23196 this.addClass("x-tree-node-loading");
23200 afterLoad : function(){
23201 this.removeClass("x-tree-node-loading");
23205 onTextChange : function(node, text, oldText){
23207 this.textNode.innerHTML = text;
23212 onDisableChange : function(node, state){
23213 this.disabled = state;
23214 if (this.checkbox) {
23215 this.checkbox.disabled = state;
23218 this.addClass("x-tree-node-disabled");
23220 this.removeClass("x-tree-node-disabled");
23225 onSelectedChange : function(state){
23228 this.addClass("x-tree-selected");
23231 this.removeClass("x-tree-selected");
23236 onMove : function(tree, node, oldParent, newParent, index, refNode){
23237 this.childIndent = null;
23239 var targetNode = newParent.ui.getContainer();
23241 this.holder = document.createElement("div");
23242 this.holder.appendChild(this.wrap);
23245 var insertBefore = refNode ? refNode.ui.getEl() : null;
23247 targetNode.insertBefore(this.wrap, insertBefore);
23249 targetNode.appendChild(this.wrap);
23251 this.node.renderIndent(true);
23256 addClass : function(cls){
23258 Ext.fly(this.elNode).addClass(cls);
23263 removeClass : function(cls){
23265 Ext.fly(this.elNode).removeClass(cls);
23270 remove : function(){
23272 this.holder = document.createElement("div");
23273 this.holder.appendChild(this.wrap);
23278 fireEvent : function(){
23279 return this.node.fireEvent.apply(this.node, arguments);
23283 initEvents : function(){
23284 this.node.on("move", this.onMove, this);
23286 if(this.node.disabled){
23287 this.addClass("x-tree-node-disabled");
23288 if (this.checkbox) {
23289 this.checkbox.disabled = true;
23292 if(this.node.hidden){
23295 var ot = this.node.getOwnerTree();
23296 var dd = ot.enableDD || ot.enableDrag || ot.enableDrop;
23297 if(dd && (!this.node.isRoot || ot.rootVisible)){
23298 Ext.dd.Registry.register(this.elNode, {
23300 handles: this.getDDHandles(),
23307 getDDHandles : function(){
23308 return [this.iconNode, this.textNode, this.elNode];
23313 this.node.hidden = true;
23315 this.wrap.style.display = "none";
23321 this.node.hidden = false;
23323 this.wrap.style.display = "";
23328 onContextMenu : function(e){
23329 if (this.node.hasListener("contextmenu") || this.node.getOwnerTree().hasListener("contextmenu")) {
23330 e.preventDefault();
23332 this.fireEvent("contextmenu", this.node, e);
23337 onClick : function(e){
23342 if(this.fireEvent("beforeclick", this.node, e) !== false){
23343 var a = e.getTarget('a');
23344 if(!this.disabled && this.node.attributes.href && a){
23345 this.fireEvent("click", this.node, e);
23347 }else if(a && e.ctrlKey){
23350 e.preventDefault();
23355 if(this.node.attributes.singleClickExpand && !this.animating && this.node.hasChildNodes()){
23356 this.node.toggle();
23359 this.fireEvent("click", this.node, e);
23366 onDblClick : function(e){
23367 e.preventDefault();
23372 this.toggleCheck();
23374 if(!this.animating && this.node.hasChildNodes()){
23375 this.node.toggle();
23377 this.fireEvent("dblclick", this.node, e);
23380 onOver : function(e){
23381 this.addClass('x-tree-node-over');
23384 onOut : function(e){
23385 this.removeClass('x-tree-node-over');
23389 onCheckChange : function(){
23390 var checked = this.checkbox.checked;
23391 this.node.attributes.checked = checked;
23392 this.fireEvent('checkchange', this.node, checked);
23396 ecClick : function(e){
23397 if(!this.animating && (this.node.hasChildNodes() || this.node.attributes.expandable)){
23398 this.node.toggle();
23403 startDrop : function(){
23404 this.dropping = true;
23408 endDrop : function(){
23409 setTimeout(function(){
23410 this.dropping = false;
23411 }.createDelegate(this), 50);
23415 expand : function(){
23416 this.updateExpandIcon();
23417 this.ctNode.style.display = "";
23421 focus : function(){
23422 if(!this.node.preventHScroll){
23423 try{this.anchor.focus();
23425 }else if(!Ext.isIE){
23427 var noscroll = this.node.getOwnerTree().getTreeEl().dom;
23428 var l = noscroll.scrollLeft;
23429 this.anchor.focus();
23430 noscroll.scrollLeft = l;
23436 toggleCheck : function(value){
23437 var cb = this.checkbox;
23439 cb.checked = (value === undefined ? !cb.checked : value);
23446 this.anchor.blur();
23451 animExpand : function(callback){
23452 var ct = Ext.get(this.ctNode);
23454 if(!this.node.hasChildNodes()){
23455 this.updateExpandIcon();
23456 this.ctNode.style.display = "";
23457 Ext.callback(callback);
23460 this.animating = true;
23461 this.updateExpandIcon();
23464 callback : function(){
23465 this.animating = false;
23466 Ext.callback(callback);
23469 duration: this.node.ownerTree.duration || .25
23474 highlight : function(){
23475 var tree = this.node.getOwnerTree();
23476 Ext.fly(this.wrap).highlight(
23477 tree.hlColor || "C3DAF9",
23478 {endColor: tree.hlBaseColor}
23483 collapse : function(){
23484 this.updateExpandIcon();
23485 this.ctNode.style.display = "none";
23489 animCollapse : function(callback){
23490 var ct = Ext.get(this.ctNode);
23491 ct.enableDisplayMode('block');
23494 this.animating = true;
23495 this.updateExpandIcon();
23498 callback : function(){
23499 this.animating = false;
23500 Ext.callback(callback);
23503 duration: this.node.ownerTree.duration || .25
23508 getContainer : function(){
23509 return this.ctNode;
23513 getEl : function(){
23518 appendDDGhost : function(ghostNode){
23519 ghostNode.appendChild(this.elNode.cloneNode(true));
23523 getDDRepairXY : function(){
23524 return Ext.lib.Dom.getXY(this.iconNode);
23528 onRender : function(){
23533 render : function(bulkRender){
23534 var n = this.node, a = n.attributes;
23535 var targetNode = n.parentNode ?
23536 n.parentNode.ui.getContainer() : n.ownerTree.innerCt.dom;
23538 if(!this.rendered){
23539 this.rendered = true;
23541 this.renderElements(n, a, targetNode, bulkRender);
23544 if(this.textNode.setAttributeNS){
23545 this.textNode.setAttributeNS("ext", "qtip", a.qtip);
23547 this.textNode.setAttributeNS("ext", "qtitle", a.qtipTitle);
23550 this.textNode.setAttribute("ext:qtip", a.qtip);
23552 this.textNode.setAttribute("ext:qtitle", a.qtipTitle);
23555 }else if(a.qtipCfg){
23556 a.qtipCfg.target = Ext.id(this.textNode);
23557 Ext.QuickTips.register(a.qtipCfg);
23560 if(!this.node.expanded){
23561 this.updateExpandIcon(true);
23564 if(bulkRender === true) {
23565 targetNode.appendChild(this.wrap);
23571 renderElements : function(n, a, targetNode, bulkRender){
23573 this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
23575 var cb = typeof a.checked == 'boolean';
23577 var href = a.href ? a.href : Ext.isGecko ? "" : "#";
23578 var 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">',
23579 '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
23580 '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
23581 '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />',
23582 cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
23583 '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
23584 a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span unselectable="on">',n.text,"</span></a></div>",
23585 '<ul class="x-tree-node-ct" style="display:none;"></ul>',
23589 if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){
23590 this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
23592 this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
23595 this.elNode = this.wrap.childNodes[0];
23596 this.ctNode = this.wrap.childNodes[1];
23597 var cs = this.elNode.childNodes;
23598 this.indentNode = cs[0];
23599 this.ecNode = cs[1];
23600 this.iconNode = cs[2];
23603 this.checkbox = cs[3];
23606 this.anchor = cs[index];
23607 this.textNode = cs[index].firstChild;
23611 getAnchor : function(){
23612 return this.anchor;
23616 getTextEl : function(){
23617 return this.textNode;
23621 getIconEl : function(){
23622 return this.iconNode;
23626 isChecked : function(){
23627 return this.checkbox ? this.checkbox.checked : false;
23631 updateExpandIcon : function(){
23633 var n = this.node, c1, c2;
23634 var cls = n.isLast() ? "x-tree-elbow-end" : "x-tree-elbow";
23635 var hasChild = n.hasChildNodes();
23636 if(hasChild || n.attributes.expandable){
23639 c1 = "x-tree-node-collapsed";
23640 c2 = "x-tree-node-expanded";
23643 c1 = "x-tree-node-expanded";
23644 c2 = "x-tree-node-collapsed";
23647 this.removeClass("x-tree-node-leaf");
23648 this.wasLeaf = false;
23650 if(this.c1 != c1 || this.c2 != c2){
23651 Ext.fly(this.elNode).replaceClass(c1, c2);
23652 this.c1 = c1; this.c2 = c2;
23656 Ext.fly(this.elNode).replaceClass("x-tree-node-expanded", "x-tree-node-leaf");
23659 this.wasLeaf = true;
23662 var ecc = "x-tree-ec-icon "+cls;
23663 if(this.ecc != ecc){
23664 this.ecNode.className = ecc;
23671 getChildIndent : function(){
23672 if(!this.childIndent){
23676 if(!p.isRoot || (p.isRoot && p.ownerTree.rootVisible)){
23678 buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-elbow-line" />');
23680 buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-icon" />');
23685 this.childIndent = buf.join("");
23687 return this.childIndent;
23691 renderIndent : function(){
23694 var p = this.node.parentNode;
23696 indent = p.ui.getChildIndent();
23698 if(this.indentMarkup != indent){
23699 this.indentNode.innerHTML = indent;
23700 this.indentMarkup = indent;
23702 this.updateExpandIcon();
23706 destroy : function(){
23708 Ext.dd.Registry.unregister(this.elNode.id);
23710 delete this.elNode;
23711 delete this.ctNode;
23712 delete this.indentNode;
23713 delete this.ecNode;
23714 delete this.iconNode;
23715 delete this.checkbox;
23716 delete this.anchor;
23717 delete this.textNode;
23718 Ext.removeNode(this.ctNode);
23723 Ext.tree.RootTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
23725 render : function(){
23726 if(!this.rendered){
23727 var targetNode = this.node.ownerTree.innerCt.dom;
23728 this.node.expanded = true;
23729 targetNode.innerHTML = '<div class="x-tree-root-node"></div>';
23730 this.wrap = this.ctNode = targetNode.firstChild;
23733 collapse : Ext.emptyFn,
23734 expand : Ext.emptyFn
23737 Ext.tree.TreeLoader = function(config){
23738 this.baseParams = {};
23739 this.requestMethod = "POST";
23740 Ext.apply(this, config);
23751 Ext.tree.TreeLoader.superclass.constructor.call(this);
23754 Ext.extend(Ext.tree.TreeLoader, Ext.util.Observable, {
23765 clearOnLoad : true,
23768 load : function(node, callback){
23769 if(this.clearOnLoad){
23770 while(node.firstChild){
23771 node.removeChild(node.firstChild);
23774 if(this.doPreload(node)){
23775 if(typeof callback == "function"){
23778 }else if(this.dataUrl||this.url){
23779 this.requestData(node, callback);
23783 doPreload : function(node){
23784 if(node.attributes.children){
23785 if(node.childNodes.length < 1){
23786 var cs = node.attributes.children;
23787 node.beginUpdate();
23788 for(var i = 0, len = cs.length; i < len; i++){
23789 var cn = node.appendChild(this.createNode(cs[i]));
23790 if(this.preloadChildren){
23791 this.doPreload(cn);
23802 getParams: function(node){
23803 var buf = [], bp = this.baseParams;
23804 for(var key in bp){
23805 if(typeof bp[key] != "function"){
23806 buf.push(encodeURIComponent(key), "=", encodeURIComponent(bp[key]), "&");
23809 buf.push("node=", encodeURIComponent(node.id));
23810 return buf.join("");
23813 requestData : function(node, callback){
23814 if(this.fireEvent("beforeload", this, node, callback) !== false){
23815 this.transId = Ext.Ajax.request({
23816 method:this.requestMethod,
23817 url: this.dataUrl||this.url,
23818 success: this.handleResponse,
23819 failure: this.handleFailure,
23821 argument: {callback: callback, node: node},
23822 params: this.getParams(node)
23827 if(typeof callback == "function"){
23833 isLoading : function(){
23834 return this.transId ? true : false;
23837 abort : function(){
23838 if(this.isLoading()){
23839 Ext.Ajax.abort(this.transId);
23844 createNode : function(attr){
23846 if(this.baseAttrs){
23847 Ext.applyIf(attr, this.baseAttrs);
23849 if(this.applyLoader !== false){
23850 attr.loader = this;
23852 if(typeof attr.uiProvider == 'string'){
23853 attr.uiProvider = this.uiProviders[attr.uiProvider] || eval(attr.uiProvider);
23856 new Ext.tree.TreeNode(attr) :
23857 new Ext.tree.AsyncTreeNode(attr));
23860 processResponse : function(response, node, callback){
23861 var json = response.responseText;
23863 var o = eval("("+json+")");
23864 node.beginUpdate();
23865 for(var i = 0, len = o.length; i < len; i++){
23866 var n = this.createNode(o[i]);
23868 node.appendChild(n);
23872 if(typeof callback == "function"){
23873 callback(this, node);
23876 this.handleFailure(response);
23880 handleResponse : function(response){
23881 this.transId = false;
23882 var a = response.argument;
23883 this.processResponse(response, a.node, a.callback);
23884 this.fireEvent("load", this, a.node, response);
23887 handleFailure : function(response){
23888 this.transId = false;
23889 var a = response.argument;
23890 this.fireEvent("loadexception", this, a.node, response);
23891 if(typeof a.callback == "function"){
23892 a.callback(this, a.node);
23897 Ext.tree.TreeFilter = function(tree, config){
23899 this.filtered = {};
23900 Ext.apply(this, config);
23903 Ext.tree.TreeFilter.prototype = {
23910 filter : function(value, attr, startNode){
23911 attr = attr || "text";
23913 if(typeof value == "string"){
23914 var vlen = value.length;
23916 if(vlen == 0 && this.clearBlank){
23920 value = value.toLowerCase();
23922 return n.attributes[attr].substr(0, vlen).toLowerCase() == value;
23924 }else if(value.exec){
23926 return value.test(n.attributes[attr]);
23929 throw 'Illegal filter type, must be string or regex';
23931 this.filterBy(f, null, startNode);
23935 filterBy : function(fn, scope, startNode){
23936 startNode = startNode || this.tree.root;
23937 if(this.autoClear){
23940 var af = this.filtered, rv = this.reverse;
23941 var f = function(n){
23942 if(n == startNode){
23948 var m = fn.call(scope || n, n);
23956 startNode.cascade(f);
23959 if(typeof id != "function"){
23961 if(n && n.parentNode){
23962 n.parentNode.removeChild(n);
23970 clear : function(){
23972 var af = this.filtered;
23974 if(typeof id != "function"){
23981 this.filtered = {};
23986 Ext.tree.TreeSorter = function(tree, config){
23987 Ext.apply(this, config);
23988 tree.on("beforechildrenrendered", this.doSort, this);
23989 tree.on("append", this.updateSort, this);
23990 tree.on("insert", this.updateSort, this);
23991 tree.on("textchange", this.updateSortParent, this);
23993 var dsc = this.dir && this.dir.toLowerCase() == "desc";
23994 var p = this.property || "text";
23995 var sortType = this.sortType;
23996 var fs = this.folderSort;
23997 var cs = this.caseSensitive === true;
23998 var leafAttr = this.leafAttr || 'leaf';
24000 this.sortFn = function(n1, n2){
24002 if(n1.attributes[leafAttr] && !n2.attributes[leafAttr]){
24005 if(!n1.attributes[leafAttr] && n2.attributes[leafAttr]){
24009 var v1 = sortType ? sortType(n1) : (cs ? n1.attributes[p] : n1.attributes[p].toUpperCase());
24010 var v2 = sortType ? sortType(n2) : (cs ? n2.attributes[p] : n2.attributes[p].toUpperCase());
24012 return dsc ? +1 : -1;
24014 return dsc ? -1 : +1;
24021 Ext.tree.TreeSorter.prototype = {
24022 doSort : function(node){
24023 node.sort(this.sortFn);
24026 compareNodes : function(n1, n2){
24027 return (n1.text.toUpperCase() > n2.text.toUpperCase() ? 1 : -1);
24030 updateSort : function(tree, node){
24031 if(node.childrenRendered){
24032 this.doSort.defer(1, this, [node]);
24036 updateSortParent : function(node){
24037 var p = node.parentNode;
24038 if(p && p.childrenRendered){
24039 this.doSort.defer(1, this, [p]);
24044 if(Ext.dd.DropZone){
24046 Ext.tree.TreeDropZone = function(tree, config){
24048 this.allowParentInsert = false;
24050 this.allowContainerDrop = false;
24052 this.appendOnly = false;
24053 Ext.tree.TreeDropZone.superclass.constructor.call(this, tree.innerCt, config);
24057 this.dragOverData = {};
24059 this.lastInsertClass = "x-tree-no-status";
24062 Ext.extend(Ext.tree.TreeDropZone, Ext.dd.DropZone, {
24064 ddGroup : "TreeDD",
24067 expandDelay : 1000,
24070 expandNode : function(node){
24071 if(node.hasChildNodes() && !node.isExpanded()){
24072 node.expand(false, null, this.triggerCacheRefresh.createDelegate(this));
24077 queueExpand : function(node){
24078 this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]);
24082 cancelExpand : function(){
24083 if(this.expandProcId){
24084 clearTimeout(this.expandProcId);
24085 this.expandProcId = false;
24090 isValidDropPoint : function(n, pt, dd, e, data){
24091 if(!n || !data){ return false; }
24092 var targetNode = n.node;
24093 var dropNode = data.node;
24095 if(!(targetNode && targetNode.isTarget && pt)){
24098 if(pt == "append" && targetNode.allowChildren === false){
24101 if((pt == "above" || pt == "below") && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){
24104 if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){
24108 var overEvent = this.dragOverData;
24109 overEvent.tree = this.tree;
24110 overEvent.target = targetNode;
24111 overEvent.data = data;
24112 overEvent.point = pt;
24113 overEvent.source = dd;
24114 overEvent.rawEvent = e;
24115 overEvent.dropNode = dropNode;
24116 overEvent.cancel = false;
24117 var result = this.tree.fireEvent("nodedragover", overEvent);
24118 return overEvent.cancel === false && result !== false;
24122 getDropPoint : function(e, n, dd){
24125 return tn.allowChildren !== false ? "append" : false;
24127 var dragEl = n.ddel;
24128 var t = Ext.lib.Dom.getY(dragEl), b = t + dragEl.offsetHeight;
24129 var y = Ext.lib.Event.getPageY(e);
24130 var noAppend = tn.allowChildren === false || tn.isLeaf();
24131 if(this.appendOnly || tn.parentNode.allowChildren === false){
24132 return noAppend ? false : "append";
24134 var noBelow = false;
24135 if(!this.allowParentInsert){
24136 noBelow = tn.hasChildNodes() && tn.isExpanded();
24138 var q = (b - t) / (noAppend ? 2 : 3);
24139 if(y >= t && y < (t + q)){
24141 }else if(!noBelow && (noAppend || y >= b-q && y <= b)){
24149 onNodeEnter : function(n, dd, e, data){
24150 this.cancelExpand();
24154 onNodeOver : function(n, dd, e, data){
24155 var pt = this.getDropPoint(e, n, dd);
24159 if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){
24160 this.queueExpand(node);
24161 }else if(pt != "append"){
24162 this.cancelExpand();
24166 var returnCls = this.dropNotAllowed;
24167 if(this.isValidDropPoint(n, pt, dd, e, data)){
24172 returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between";
24173 cls = "x-tree-drag-insert-above";
24174 }else if(pt == "below"){
24175 returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between";
24176 cls = "x-tree-drag-insert-below";
24178 returnCls = "x-tree-drop-ok-append";
24179 cls = "x-tree-drag-append";
24181 if(this.lastInsertClass != cls){
24182 Ext.fly(el).replaceClass(this.lastInsertClass, cls);
24183 this.lastInsertClass = cls;
24191 onNodeOut : function(n, dd, e, data){
24192 this.cancelExpand();
24193 this.removeDropIndicators(n);
24197 onNodeDrop : function(n, dd, e, data){
24198 var point = this.getDropPoint(e, n, dd);
24199 var targetNode = n.node;
24200 targetNode.ui.startDrop();
24201 if(!this.isValidDropPoint(n, point, dd, e, data)){
24202 targetNode.ui.endDrop();
24206 var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
24209 target: targetNode,
24214 dropNode: dropNode,
24218 var retval = this.tree.fireEvent("beforenodedrop", dropEvent);
24219 if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
24220 targetNode.ui.endDrop();
24221 return dropEvent.dropStatus;
24224 targetNode = dropEvent.target;
24225 if(point == "append" && !targetNode.isExpanded()){
24226 targetNode.expand(false, null, function(){
24227 this.completeDrop(dropEvent);
24228 }.createDelegate(this));
24230 this.completeDrop(dropEvent);
24236 completeDrop : function(de){
24237 var ns = de.dropNode, p = de.point, t = de.target;
24238 if(!Ext.isArray(ns)){
24242 for(var i = 0, len = ns.length; i < len; i++){
24245 t.parentNode.insertBefore(n, t);
24246 }else if(p == "below"){
24247 t.parentNode.insertBefore(n, t.nextSibling);
24253 if(this.tree.hlDrop){
24257 this.tree.fireEvent("nodedrop", de);
24261 afterNodeMoved : function(dd, data, e, targetNode, dropNode){
24262 if(this.tree.hlDrop){
24263 dropNode.ui.focus();
24264 dropNode.ui.highlight();
24266 this.tree.fireEvent("nodedrop", this.tree, targetNode, data, dd, e);
24270 getTree : function(){
24275 removeDropIndicators : function(n){
24278 Ext.fly(el).removeClass([
24279 "x-tree-drag-insert-above",
24280 "x-tree-drag-insert-below",
24281 "x-tree-drag-append"]);
24282 this.lastInsertClass = "_noclass";
24287 beforeDragDrop : function(target, e, id){
24288 this.cancelExpand();
24293 afterRepair : function(data){
24294 if(data && Ext.enableFx){
24295 data.node.ui.highlight();
24303 if(Ext.dd.DragZone){
24304 Ext.tree.TreeDragZone = function(tree, config){
24305 Ext.tree.TreeDragZone.superclass.constructor.call(this, tree.getTreeEl(), config);
24310 Ext.extend(Ext.tree.TreeDragZone, Ext.dd.DragZone, {
24312 ddGroup : "TreeDD",
24315 onBeforeDrag : function(data, e){
24317 return n && n.draggable && !n.disabled;
24321 onInitDrag : function(e){
24322 var data = this.dragData;
24323 this.tree.getSelectionModel().select(data.node);
24324 this.tree.eventModel.disable();
24325 this.proxy.update("");
24326 data.node.ui.appendDDGhost(this.proxy.ghost.dom);
24327 this.tree.fireEvent("startdrag", this.tree, data.node, e);
24331 getRepairXY : function(e, data){
24332 return data.node.ui.getDDRepairXY();
24336 onEndDrag : function(data, e){
24337 this.tree.eventModel.enable.defer(100, this.tree.eventModel);
24338 this.tree.fireEvent("enddrag", this.tree, data.node, e);
24342 onValidDrop : function(dd, e, id){
24343 this.tree.fireEvent("dragdrop", this.tree, this.dragData.node, dd, e);
24348 beforeInvalidDrop : function(e, id){
24350 var sm = this.tree.getSelectionModel();
24351 sm.clearSelections();
24352 sm.select(this.dragData.node);
24357 Ext.tree.TreeEditor = function(tree, config){
24358 config = config || {};
24359 var field = config.events ? config : new Ext.form.TextField(config);
24360 Ext.tree.TreeEditor.superclass.constructor.call(this, field);
24364 if(!tree.rendered){
24365 tree.on('render', this.initEditor, this);
24367 this.initEditor(tree);
24371 Ext.extend(Ext.tree.TreeEditor, Ext.Editor, {
24378 cls: "x-small-editor x-tree-editor",
24387 initEditor : function(tree){
24388 tree.on('beforeclick', this.beforeNodeClick, this);
24389 tree.on('dblclick', this.onNodeDblClick, this);
24390 this.on('complete', this.updateNode, this);
24391 this.on('beforestartedit', this.fitToTree, this);
24392 this.on('startedit', this.bindScroll, this, {delay:10});
24393 this.on('specialkey', this.onSpecialKey, this);
24396 fitToTree : function(ed, el){
24397 var td = this.tree.getTreeEl().dom, nd = el.dom;
24398 if(td.scrollLeft > nd.offsetLeft){ td.scrollLeft = nd.offsetLeft;
24402 (td.clientWidth > 20 ? td.clientWidth : td.offsetWidth) - Math.max(0, nd.offsetLeft-td.scrollLeft) - 5);
24403 this.setSize(w, '');
24406 triggerEdit : function(node, defer){
24407 this.completeEdit();
24408 if(node.attributes.editable !== false){
24409 this.editNode = node;
24410 this.autoEditTimer = this.startEdit.defer(this.editDelay, this, [node.ui.textNode, node.text]);
24415 bindScroll : function(){
24416 this.tree.getTreeEl().on('scroll', this.cancelEdit, this);
24419 beforeNodeClick : function(node, e){
24420 clearTimeout(this.autoEditTimer);
24421 if(this.tree.getSelectionModel().isSelected(node)){
24423 return this.triggerEdit(node);
24427 onNodeDblClick : function(node, e){
24428 clearTimeout(this.autoEditTimer);
24431 updateNode : function(ed, value){
24432 this.tree.getTreeEl().un('scroll', this.cancelEdit, this);
24433 this.editNode.setText(value);
24436 onHide : function(){
24437 Ext.tree.TreeEditor.superclass.onHide.call(this);
24439 this.editNode.ui.focus.defer(50, this.editNode.ui);
24443 onSpecialKey : function(field, e){
24444 var k = e.getKey();
24448 }else if(k == e.ENTER && !e.hasModifier()){
24450 this.completeEdit();
24455 Ext.menu.Menu = function(config){
24456 if(Ext.isArray(config)){
24457 config = {items:config};
24459 Ext.apply(this, config);
24460 this.id = this.id || Ext.id();
24479 Ext.menu.MenuMgr.register(this);
24480 Ext.menu.Menu.superclass.constructor.call(this);
24481 var mis = this.items;
24484 this.items = new Ext.util.MixedCollection();
24486 this.add.apply(this, mis);
24490 Ext.extend(Ext.menu.Menu, Ext.util.Observable, {
24498 subMenuAlign : "tl-tr?",
24500 defaultAlign : "tl-bl?",
24502 allowOtherMenus : false,
24506 createEl : function(){
24507 return new Ext.Layer({
24509 shadow:this.shadow,
24511 parentEl: this.parentEl || document.body,
24516 render : function(){
24520 var el = this.el = this.createEl();
24523 this.keyNav = new Ext.menu.MenuNav(this);
24526 el.addClass("x-menu-plain");
24529 el.addClass(this.cls);
24531 this.focusEl = el.createChild({
24532 tag: "a", cls: "x-menu-focus", href: "#", onclick: "return false;", tabIndex:"-1"
24534 var ul = el.createChild({tag: "ul", cls: "x-menu-list"});
24535 ul.on("click", this.onClick, this);
24536 ul.on("mouseover", this.onMouseOver, this);
24537 ul.on("mouseout", this.onMouseOut, this);
24538 this.items.each(function(item){
24539 var li = document.createElement("li");
24540 li.className = "x-menu-list-item";
24541 ul.dom.appendChild(li);
24542 item.render(li, this);
24548 autoWidth : function(){
24549 var el = this.el, ul = this.ul;
24553 var w = this.width;
24556 }else if(Ext.isIE){
24557 el.setWidth(this.minWidth);
24558 var t = el.dom.offsetWidth; el.setWidth(ul.getWidth()+el.getFrameWidth("lr"));
24562 delayAutoWidth : function(){
24565 this.awTask = new Ext.util.DelayedTask(this.autoWidth, this);
24567 this.awTask.delay(20);
24571 findTargetItem : function(e){
24572 var t = e.getTarget(".x-menu-list-item", this.ul, true);
24573 if(t && t.menuItemId){
24574 return this.items.get(t.menuItemId);
24578 onClick : function(e){
24580 if(t = this.findTargetItem(e)){
24582 this.fireEvent("click", this, t, e);
24586 setActiveItem : function(item, autoExpand){
24587 if(item != this.activeItem){
24588 if(this.activeItem){
24589 this.activeItem.deactivate();
24591 this.activeItem = item;
24592 item.activate(autoExpand);
24593 }else if(autoExpand){
24598 tryActivate : function(start, step){
24599 var items = this.items;
24600 for(var i = start, len = items.length; i >= 0 && i < len; i+= step){
24601 var item = items.get(i);
24602 if(!item.disabled && item.canActivate){
24603 this.setActiveItem(item, false);
24610 onMouseOver : function(e){
24612 if(t = this.findTargetItem(e)){
24613 if(t.canActivate && !t.disabled){
24614 this.setActiveItem(t, true);
24617 this.fireEvent("mouseover", this, e, t);
24620 onMouseOut : function(e){
24622 if(t = this.findTargetItem(e)){
24623 if(t == this.activeItem && t.shouldDeactivate(e)){
24624 this.activeItem.deactivate();
24625 delete this.activeItem;
24628 this.fireEvent("mouseout", this, e, t);
24632 isVisible : function(){
24633 return this.el && !this.hidden;
24637 show : function(el, pos, parentMenu){
24638 this.parentMenu = parentMenu;
24642 this.fireEvent("beforeshow", this);
24643 this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign), parentMenu, false);
24647 showAt : function(xy, parentMenu, _e){
24648 this.parentMenu = parentMenu;
24653 this.fireEvent("beforeshow", this);
24654 xy = this.el.adjustForConstraints(xy);
24658 this.hidden = false;
24660 this.fireEvent("show", this);
24665 focus : function(){
24667 this.doFocus.defer(50, this);
24671 doFocus : function(){
24673 this.focusEl.focus();
24678 hide : function(deep){
24679 if(this.el && this.isVisible()){
24680 this.fireEvent("beforehide", this);
24681 if(this.activeItem){
24682 this.activeItem.deactivate();
24683 this.activeItem = null;
24686 this.hidden = true;
24687 this.fireEvent("hide", this);
24689 if(deep === true && this.parentMenu){
24690 this.parentMenu.hide(true);
24696 var a = arguments, l = a.length, item;
24697 for(var i = 0; i < l; i++){
24699 if(el.render){ item = this.addItem(el);
24700 }else if(typeof el == "string"){ if(el == "separator" || el == "-"){
24701 item = this.addSeparator();
24703 item = this.addText(el);
24705 }else if(el.tagName || el.el){ item = this.addElement(el);
24706 }else if(typeof el == "object"){ Ext.applyIf(el, this.defaults);
24707 item = this.addMenuItem(el);
24714 getEl : function(){
24722 addSeparator : function(){
24723 return this.addItem(new Ext.menu.Separator());
24727 addElement : function(el){
24728 return this.addItem(new Ext.menu.BaseItem(el));
24732 addItem : function(item){
24733 this.items.add(item);
24735 var li = document.createElement("li");
24736 li.className = "x-menu-list-item";
24737 this.ul.dom.appendChild(li);
24738 item.render(li, this);
24739 this.delayAutoWidth();
24745 addMenuItem : function(config){
24746 if(!(config instanceof Ext.menu.Item)){
24747 if(typeof config.checked == "boolean"){ config = new Ext.menu.CheckItem(config);
24749 config = new Ext.menu.Item(config);
24752 return this.addItem(config);
24756 addText : function(text){
24757 return this.addItem(new Ext.menu.TextItem(text));
24761 insert : function(index, item){
24762 this.items.insert(index, item);
24764 var li = document.createElement("li");
24765 li.className = "x-menu-list-item";
24766 this.ul.dom.insertBefore(li, this.ul.dom.childNodes[index]);
24767 item.render(li, this);
24768 this.delayAutoWidth();
24774 remove : function(item){
24775 this.items.removeKey(item.id);
24780 removeAll : function(){
24782 while(f = this.items.first()){
24788 destroy : function(){
24789 this.beforeDestroy();
24790 Ext.menu.MenuMgr.unregister(this);
24792 this.keyNav.disable();
24796 this.ul.removeAllListeners();
24803 beforeDestroy : Ext.emptyFn
24807 Ext.menu.MenuNav = function(menu){
24808 Ext.menu.MenuNav.superclass.constructor.call(this, menu.el);
24809 this.scope = this.menu = menu;
24812 Ext.extend(Ext.menu.MenuNav, Ext.KeyNav, {
24813 doRelay : function(e, h){
24814 var k = e.getKey();
24815 if(!this.menu.activeItem && e.isNavKeyPress() && k != e.SPACE && k != e.RETURN){
24816 this.menu.tryActivate(0, 1);
24819 return h.call(this.scope || this, e, this.menu);
24822 up : function(e, m){
24823 if(!m.tryActivate(m.items.indexOf(m.activeItem)-1, -1)){
24824 m.tryActivate(m.items.length-1, -1);
24828 down : function(e, m){
24829 if(!m.tryActivate(m.items.indexOf(m.activeItem)+1, 1)){
24830 m.tryActivate(0, 1);
24834 right : function(e, m){
24836 m.activeItem.expandMenu(true);
24840 left : function(e, m){
24842 if(m.parentMenu && m.parentMenu.activeItem){
24843 m.parentMenu.activeItem.activate();
24847 enter : function(e, m){
24849 e.stopPropagation();
24850 m.activeItem.onClick(e);
24851 m.fireEvent("click", this, m.activeItem);
24857 Ext.menu.MenuMgr = function(){
24858 var menus, active, groups = {}, attached = false, lastShow = new Date();
24862 active = new Ext.util.MixedCollection();
24863 Ext.getDoc().addKeyListener(27, function(){
24864 if(active.length > 0){
24870 function hideAll(){
24871 if(active && active.length > 0){
24872 var c = active.clone();
24873 c.each(function(m){
24879 function onHide(m){
24881 if(active.length < 1){
24882 Ext.getDoc().un("mousedown", onMouseDown);
24887 function onShow(m){
24888 var last = active.last();
24889 lastShow = new Date();
24892 Ext.getDoc().on("mousedown", onMouseDown);
24896 m.getEl().setZIndex(parseInt(m.parentMenu.getEl().getStyle("z-index"), 10) + 3);
24897 m.parentMenu.activeChild = m;
24898 }else if(last && last.isVisible()){
24899 m.getEl().setZIndex(parseInt(last.getEl().getStyle("z-index"), 10) + 3);
24903 function onBeforeHide(m){
24905 m.activeChild.hide();
24907 if(m.autoHideTimer){
24908 clearTimeout(m.autoHideTimer);
24909 delete m.autoHideTimer;
24913 function onBeforeShow(m){
24914 var pm = m.parentMenu;
24915 if(!pm && !m.allowOtherMenus){
24917 }else if(pm && pm.activeChild){
24918 pm.activeChild.hide();
24922 function onMouseDown(e){
24923 if(lastShow.getElapsed() > 50 && active.length > 0 && !e.getTarget(".x-menu")){
24928 function onBeforeCheck(mi, state){
24930 var g = groups[mi.group];
24931 for(var i = 0, l = g.length; i < l; i++){
24933 g[i].setChecked(false);
24942 hideAll : function(){
24946 register : function(menu){
24950 menus[menu.id] = menu;
24951 menu.on("beforehide", onBeforeHide);
24952 menu.on("hide", onHide);
24953 menu.on("beforeshow", onBeforeShow);
24954 menu.on("show", onShow);
24955 var g = menu.group;
24956 if(g && menu.events["checkchange"]){
24960 groups[g].push(menu);
24961 menu.on("checkchange", onCheck);
24966 get : function(menu){
24967 if(typeof menu == "string"){ if(!menus){ return null;
24969 return menus[menu];
24970 }else if(menu.events){ return menu;
24971 }else if(typeof menu.length == 'number'){ return new Ext.menu.Menu({items:menu});
24972 }else{ return new Ext.menu.Menu(menu);
24976 unregister : function(menu){
24977 delete menus[menu.id];
24978 menu.un("beforehide", onBeforeHide);
24979 menu.un("hide", onHide);
24980 menu.un("beforeshow", onBeforeShow);
24981 menu.un("show", onShow);
24982 var g = menu.group;
24983 if(g && menu.events["checkchange"]){
24984 groups[g].remove(menu);
24985 menu.un("checkchange", onCheck);
24989 registerCheckable : function(menuItem){
24990 var g = menuItem.group;
24995 groups[g].push(menuItem);
24996 menuItem.on("beforecheckchange", onBeforeCheck);
25000 unregisterCheckable : function(menuItem){
25001 var g = menuItem.group;
25003 groups[g].remove(menuItem);
25004 menuItem.un("beforecheckchange", onBeforeCheck);
25008 getCheckedItem : function(groupId){
25009 var g = groups[groupId];
25011 for(var i = 0, l = g.length; i < l; i++){
25020 setCheckedItem : function(groupId, itemId){
25021 var g = groups[groupId];
25023 for(var i = 0, l = g.length; i < l; i++){
25024 if(g[i].id == itemId){
25025 g[i].setChecked(true);
25035 Ext.menu.BaseItem = function(config){
25036 Ext.menu.BaseItem.superclass.constructor.call(this, config);
25048 this.on("click", this.handler, this.scope);
25052 Ext.extend(Ext.menu.BaseItem, Ext.Component, {
25056 canActivate : false,
25058 activeClass : "x-menu-item-active",
25060 hideOnClick : true,
25064 ctype: "Ext.menu.BaseItem",
25066 actionMode : "container",
25068 render : function(container, parentMenu){
25069 this.parentMenu = parentMenu;
25070 Ext.menu.BaseItem.superclass.render.call(this, container);
25071 this.container.menuItemId = this.id;
25074 onRender : function(container, position){
25075 this.el = Ext.get(this.el);
25076 container.dom.appendChild(this.el.dom);
25080 setHandler : function(handler, scope){
25082 this.un("click", this.handler, this.scope);
25084 this.on("click", this.handler = handler, this.scope = scope);
25087 onClick : function(e){
25088 if(!this.disabled && this.fireEvent("click", this, e) !== false
25089 && this.parentMenu.fireEvent("itemclick", this, e) !== false){
25090 this.handleClick(e);
25096 activate : function(){
25100 var li = this.container;
25101 li.addClass(this.activeClass);
25102 this.region = li.getRegion().adjust(2, 2, -2, -2);
25103 this.fireEvent("activate", this);
25107 deactivate : function(){
25108 this.container.removeClass(this.activeClass);
25109 this.fireEvent("deactivate", this);
25112 shouldDeactivate : function(e){
25113 return !this.region || !this.region.contains(e.getPoint());
25116 handleClick : function(e){
25117 if(this.hideOnClick){
25118 this.parentMenu.hide.defer(this.hideDelay, this.parentMenu, [true]);
25122 expandMenu : function(autoActivate){
25125 hideMenu : function(){
25129 Ext.menu.TextItem = function(text){
25131 Ext.menu.TextItem.superclass.constructor.call(this);
25134 Ext.extend(Ext.menu.TextItem, Ext.menu.BaseItem, {
25137 hideOnClick : false,
25139 itemCls : "x-menu-text",
25141 onRender : function(){
25142 var s = document.createElement("span");
25143 s.className = this.itemCls;
25144 s.innerHTML = this.text;
25146 Ext.menu.TextItem.superclass.onRender.apply(this, arguments);
25150 Ext.menu.Separator = function(config){
25151 Ext.menu.Separator.superclass.constructor.call(this, config);
25154 Ext.extend(Ext.menu.Separator, Ext.menu.BaseItem, {
25156 itemCls : "x-menu-sep",
25158 hideOnClick : false,
25160 onRender : function(li){
25161 var s = document.createElement("span");
25162 s.className = this.itemCls;
25163 s.innerHTML = " ";
25165 li.addClass("x-menu-sep-li");
25166 Ext.menu.Separator.superclass.onRender.apply(this, arguments);
25170 Ext.menu.Item = function(config){
25171 Ext.menu.Item.superclass.constructor.call(this, config);
25173 this.menu = Ext.menu.MenuMgr.get(this.menu);
25176 Ext.extend(Ext.menu.Item, Ext.menu.BaseItem, {
25183 itemCls : "x-menu-item",
25185 canActivate : true,
25190 ctype: "Ext.menu.Item",
25192 onRender : function(container, position){
25193 var el = document.createElement("a");
25194 el.hideFocus = true;
25195 el.unselectable = "on";
25196 el.href = this.href || "#";
25197 if(this.hrefTarget){
25198 el.target = this.hrefTarget;
25200 el.className = this.itemCls + (this.menu ? " x-menu-item-arrow" : "") + (this.cls ? " " + this.cls : "");
25201 el.innerHTML = String.format(
25202 '<img src="{0}" class="x-menu-item-icon {2}" />{1}',
25203 this.icon || Ext.BLANK_IMAGE_URL, this.itemText||this.text, this.iconCls || '');
25205 Ext.menu.Item.superclass.onRender.call(this, container, position);
25209 setText : function(text){
25212 this.el.update(String.format(
25213 '<img src="{0}" class="x-menu-item-icon {2}">{1}',
25214 this.icon || Ext.BLANK_IMAGE_URL, this.text, this.iconCls || ''));
25215 this.parentMenu.autoWidth();
25220 setIconClass : function(cls){
25221 var oldCls = this.iconCls;
25222 this.iconCls = cls;
25224 this.el.child('img.x-menu-item-icon').replaceClass(oldCls, this.iconCls);
25228 handleClick : function(e){
25229 if(!this.href){ e.stopEvent();
25231 Ext.menu.Item.superclass.handleClick.apply(this, arguments);
25234 activate : function(autoExpand){
25235 if(Ext.menu.Item.superclass.activate.apply(this, arguments)){
25244 shouldDeactivate : function(e){
25245 if(Ext.menu.Item.superclass.shouldDeactivate.call(this, e)){
25246 if(this.menu && this.menu.isVisible()){
25247 return !this.menu.getEl().getRegion().contains(e.getPoint());
25254 deactivate : function(){
25255 Ext.menu.Item.superclass.deactivate.apply(this, arguments);
25259 expandMenu : function(autoActivate){
25260 if(!this.disabled && this.menu){
25261 clearTimeout(this.hideTimer);
25262 delete this.hideTimer;
25263 if(!this.menu.isVisible() && !this.showTimer){
25264 this.showTimer = this.deferExpand.defer(this.showDelay, this, [autoActivate]);
25265 }else if (this.menu.isVisible() && autoActivate){
25266 this.menu.tryActivate(0, 1);
25271 deferExpand : function(autoActivate){
25272 delete this.showTimer;
25273 this.menu.show(this.container, this.parentMenu.subMenuAlign || "tl-tr?", this.parentMenu);
25275 this.menu.tryActivate(0, 1);
25279 hideMenu : function(){
25280 clearTimeout(this.showTimer);
25281 delete this.showTimer;
25282 if(!this.hideTimer && this.menu && this.menu.isVisible()){
25283 this.hideTimer = this.deferHide.defer(this.hideDelay, this);
25287 deferHide : function(){
25288 delete this.hideTimer;
25293 Ext.menu.CheckItem = function(config){
25294 Ext.menu.CheckItem.superclass.constructor.call(this, config);
25297 "beforecheckchange" ,
25302 if(this.checkHandler){
25303 this.on('checkchange', this.checkHandler, this.scope);
25305 Ext.menu.MenuMgr.registerCheckable(this);
25307 Ext.extend(Ext.menu.CheckItem, Ext.menu.Item, {
25310 itemCls : "x-menu-item x-menu-check-item",
25312 groupClass : "x-menu-group-item",
25317 ctype: "Ext.menu.CheckItem",
25319 onRender : function(c){
25320 Ext.menu.CheckItem.superclass.onRender.apply(this, arguments);
25322 this.el.addClass(this.groupClass);
25325 this.checked = false;
25326 this.setChecked(true, true);
25330 destroy : function(){
25331 Ext.menu.MenuMgr.unregisterCheckable(this);
25332 Ext.menu.CheckItem.superclass.destroy.apply(this, arguments);
25336 setChecked : function(state, suppressEvent){
25337 if(this.checked != state && this.fireEvent("beforecheckchange", this, state) !== false){
25338 if(this.container){
25339 this.container[state ? "addClass" : "removeClass"]("x-menu-item-checked");
25341 this.checked = state;
25342 if(suppressEvent !== true){
25343 this.fireEvent("checkchange", this, state);
25348 handleClick : function(e){
25349 if(!this.disabled && !(this.checked && this.group)){ this.setChecked(!this.checked);
25351 Ext.menu.CheckItem.superclass.handleClick.apply(this, arguments);
25355 Ext.menu.Adapter = function(component, config){
25356 Ext.menu.Adapter.superclass.constructor.call(this, config);
25357 this.component = component;
25359 Ext.extend(Ext.menu.Adapter, Ext.menu.BaseItem, {
25360 canActivate : true,
25362 onRender : function(container, position){
25363 this.component.render(container);
25364 this.el = this.component.getEl();
25367 activate : function(){
25371 this.component.focus();
25372 this.fireEvent("activate", this);
25376 deactivate : function(){
25377 this.fireEvent("deactivate", this);
25380 disable : function(){
25381 this.component.disable();
25382 Ext.menu.Adapter.superclass.disable.call(this);
25385 enable : function(){
25386 this.component.enable();
25387 Ext.menu.Adapter.superclass.enable.call(this);
25391 Ext.menu.DateItem = function(config){
25392 Ext.menu.DateItem.superclass.constructor.call(this, new Ext.DatePicker(config), config);
25394 this.picker = this.component;
25395 this.addEvents('select');
25397 this.picker.on("render", function(picker){
25398 picker.getEl().swallowEvent("click");
25399 picker.container.addClass("x-menu-date-item");
25402 this.picker.on("select", this.onSelect, this);
25405 Ext.extend(Ext.menu.DateItem, Ext.menu.Adapter, {
25406 onSelect : function(picker, date){
25407 this.fireEvent("select", this, date, picker);
25408 Ext.menu.DateItem.superclass.handleClick.call(this);
25412 Ext.menu.ColorItem = function(config){
25413 Ext.menu.ColorItem.superclass.constructor.call(this, new Ext.ColorPalette(config), config);
25415 this.palette = this.component;
25416 this.relayEvents(this.palette, ["select"]);
25417 if(this.selectHandler){
25418 this.on('select', this.selectHandler, this.scope);
25421 Ext.extend(Ext.menu.ColorItem, Ext.menu.Adapter);
25423 Ext.menu.DateMenu = function(config){
25424 Ext.menu.DateMenu.superclass.constructor.call(this, config);
25426 var di = new Ext.menu.DateItem(config);
25429 this.picker = di.picker;
25431 this.relayEvents(di, ["select"]);
25433 this.on('beforeshow', function(){
25435 this.picker.hideMonthPicker(true);
25439 Ext.extend(Ext.menu.DateMenu, Ext.menu.Menu, {
25442 beforeDestroy : function() {
25443 this.picker.destroy();
25447 Ext.menu.ColorMenu = function(config){
25448 Ext.menu.ColorMenu.superclass.constructor.call(this, config);
25450 var ci = new Ext.menu.ColorItem(config);
25453 this.palette = ci.palette;
25455 this.relayEvents(ci, ["select"]);
25457 Ext.extend(Ext.menu.ColorMenu, Ext.menu.Menu);
25459 Ext.form.Field = Ext.extend(Ext.BoxComponent, {
25468 invalidClass : "x-form-invalid",
25470 invalidText : "The value in this field is invalid",
25472 focusClass : "x-form-focus",
25474 validationEvent : "keyup",
25476 validateOnBlur : true,
25478 validationDelay : 250,
25480 defaultAutoCreate : {tag: "input", type: "text", size: "20", autocomplete: "off"},
25482 fieldClass : "x-form-field",
25484 msgTarget : 'qtip',
25498 isFormField : true,
25507 initComponent : function(){
25508 Ext.form.Field.superclass.initComponent.call(this);
25526 getName: function(){
25527 return this.rendered && this.el.dom.name ? this.el.dom.name : (this.hiddenName || '');
25530 onRender : function(ct, position){
25531 Ext.form.Field.superclass.onRender.call(this, ct, position);
25533 var cfg = this.getAutoCreate();
25535 cfg.name = this.name || this.id;
25537 if(this.inputType){
25538 cfg.type = this.inputType;
25540 this.el = ct.createChild(cfg, position);
25542 var type = this.el.dom.type;
25544 if(type == 'password'){
25547 this.el.addClass('x-form-'+type);
25550 this.el.dom.readOnly = true;
25552 if(this.tabIndex !== undefined){
25553 this.el.dom.setAttribute('tabIndex', this.tabIndex);
25556 this.el.addClass([this.fieldClass, this.cls]);
25560 initValue : function(){
25561 if(this.value !== undefined){
25562 this.setValue(this.value);
25563 }else if(this.el.dom.value.length > 0){
25564 this.setValue(this.el.dom.value);
25569 isDirty : function() {
25570 if(this.disabled) {
25573 return String(this.getValue()) !== String(this.originalValue);
25576 afterRender : function(){
25577 Ext.form.Field.superclass.afterRender.call(this);
25581 fireKey : function(e){
25582 if(e.isSpecialKey()){
25583 this.fireEvent("specialkey", this, e);
25588 reset : function(){
25589 this.setValue(this.originalValue);
25590 this.clearInvalid();
25593 initEvents : function(){
25594 this.el.on(Ext.isIE ? "keydown" : "keypress", this.fireKey, this);
25595 this.el.on("focus", this.onFocus, this);
25596 this.el.on("blur", this.onBlur, this);
25598 this.originalValue = this.getValue();
25601 onFocus : function(){
25602 if(!Ext.isOpera && this.focusClass){ this.el.addClass(this.focusClass);
25604 if(!this.hasFocus){
25605 this.hasFocus = true;
25606 this.startValue = this.getValue();
25607 this.fireEvent("focus", this);
25611 beforeBlur : Ext.emptyFn,
25613 onBlur : function(){
25615 if(!Ext.isOpera && this.focusClass){ this.el.removeClass(this.focusClass);
25617 this.hasFocus = false;
25618 if(this.validationEvent !== false && this.validateOnBlur && this.validationEvent != "blur"){
25621 var v = this.getValue();
25622 if(String(v) !== String(this.startValue)){
25623 this.fireEvent('change', this, v, this.startValue);
25625 this.fireEvent("blur", this);
25629 isValid : function(preventMark){
25633 var restore = this.preventMark;
25634 this.preventMark = preventMark === true;
25635 var v = this.validateValue(this.processValue(this.getRawValue()));
25636 this.preventMark = restore;
25641 validate : function(){
25642 if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
25643 this.clearInvalid();
25649 processValue : function(value){
25653 validateValue : function(value){
25658 markInvalid : function(msg){
25659 if(!this.rendered || this.preventMark){ return;
25661 this.el.addClass(this.invalidClass);
25662 msg = msg || this.invalidText;
25663 switch(this.msgTarget){
25665 this.el.dom.qtip = msg;
25666 this.el.dom.qclass = 'x-form-invalid-tip';
25667 if(Ext.QuickTips){ Ext.QuickTips.enable();
25671 this.el.dom.title = msg;
25675 var elp = this.el.findParent('.x-form-element', 5, true);
25676 this.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
25677 this.errorEl.setWidth(elp.getWidth(true)-20);
25679 this.errorEl.update(msg);
25680 Ext.form.Field.msgFx[this.msgFx].show(this.errorEl, this);
25683 if(!this.errorIcon){
25684 var elp = this.el.findParent('.x-form-element', 5, true);
25685 this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
25687 this.alignErrorIcon();
25688 this.errorIcon.dom.qtip = msg;
25689 this.errorIcon.dom.qclass = 'x-form-invalid-tip';
25690 this.errorIcon.show();
25691 this.on('resize', this.alignErrorIcon, this);
25694 var t = Ext.getDom(this.msgTarget);
25696 t.style.display = this.msgDisplay;
25699 this.fireEvent('invalid', this, msg);
25702 alignErrorIcon : function(){
25703 this.errorIcon.alignTo(this.el, 'tl-tr', [2, 0]);
25707 clearInvalid : function(){
25708 if(!this.rendered || this.preventMark){ return;
25710 this.el.removeClass(this.invalidClass);
25711 switch(this.msgTarget){
25713 this.el.dom.qtip = '';
25716 this.el.dom.title = '';
25720 Ext.form.Field.msgFx[this.msgFx].hide(this.errorEl, this);
25724 if(this.errorIcon){
25725 this.errorIcon.dom.qtip = '';
25726 this.errorIcon.hide();
25727 this.un('resize', this.alignErrorIcon, this);
25731 var t = Ext.getDom(this.msgTarget);
25733 t.style.display = 'none';
25736 this.fireEvent('valid', this);
25740 getRawValue : function(){
25741 var v = this.rendered ? this.el.getValue() : Ext.value(this.value, '');
25742 if(v === this.emptyText){
25749 getValue : function(){
25750 if(!this.rendered) {
25753 var v = this.el.getValue();
25754 if(v === this.emptyText || v === undefined){
25761 setRawValue : function(v){
25762 return this.el.dom.value = (v === null || v === undefined ? '' : v);
25766 setValue : function(v){
25769 this.el.dom.value = (v === null || v === undefined ? '' : v);
25774 adjustSize : function(w, h){
25775 var s = Ext.form.Field.superclass.adjustSize.call(this, w, h);
25776 s.width = this.adjustWidth(this.el.dom.tagName, s.width);
25780 adjustWidth : function(tag, w){
25781 tag = tag.toLowerCase();
25782 if(typeof w == 'number' && !Ext.isSafari){
25783 if(Ext.isIE && (tag == 'input' || tag == 'textarea')){
25784 if(tag == 'input' && !Ext.isStrict){
25785 return this.inEditor ? w : w - 3;
25787 if(tag == 'input' && Ext.isStrict){
25788 return w - (Ext.isIE6 ? 4 : 1);
25790 if(tag = 'textarea' && Ext.isStrict){
25793 }else if(Ext.isOpera && Ext.isStrict){
25794 if(tag == 'input'){
25797 if(tag = 'textarea'){
25812 Ext.form.Field.msgFx = {
25814 show: function(msgEl, f){
25815 msgEl.setDisplayed('block');
25818 hide : function(msgEl, f){
25819 msgEl.setDisplayed(false).update('');
25824 show: function(msgEl, f){
25825 msgEl.slideIn('t', {stopFx:true});
25828 hide : function(msgEl, f){
25829 msgEl.slideOut('t', {stopFx:true,useDisplay:true});
25834 show: function(msgEl, f){
25835 msgEl.fixDisplay();
25836 msgEl.alignTo(f.el, 'tl-tr');
25837 msgEl.slideIn('l', {stopFx:true});
25840 hide : function(msgEl, f){
25841 msgEl.slideOut('l', {stopFx:true,useDisplay:true});
25845 Ext.reg('field', Ext.form.Field);
25848 Ext.form.TextField = Ext.extend(Ext.form.Field, {
25861 disableKeyFilter : false,
25867 maxLength : Number.MAX_VALUE,
25869 minLengthText : "The minimum length for this field is {0}",
25871 maxLengthText : "The maximum length for this field is {0}",
25873 selectOnFocus : false,
25875 blankText : "This field is required",
25885 emptyClass : 'x-form-empty-field',
25887 initComponent : function(){
25888 Ext.form.TextField.superclass.initComponent.call(this);
25895 initEvents : function(){
25896 Ext.form.TextField.superclass.initEvents.call(this);
25897 if(this.validationEvent == 'keyup'){
25898 this.validationTask = new Ext.util.DelayedTask(this.validate, this);
25899 this.el.on('keyup', this.filterValidation, this);
25901 else if(this.validationEvent !== false){
25902 this.el.on(this.validationEvent, this.validate, this, {buffer: this.validationDelay});
25904 if(this.selectOnFocus || this.emptyText){
25905 this.on("focus", this.preFocus, this);
25906 if(this.emptyText){
25907 this.on('blur', this.postBlur, this);
25908 this.applyEmptyText();
25911 if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Ext.form.VTypes[this.vtype+'Mask']))){
25912 this.el.on("keypress", this.filterKeys, this);
25915 this.el.on("keyup", this.onKeyUp, this, {buffer:50});
25916 this.el.on("click", this.autoSize, this);
25920 processValue : function(value){
25921 if(this.stripCharsRe){
25922 var newValue = value.replace(this.stripCharsRe, '');
25923 if(newValue !== value){
25924 this.setRawValue(newValue);
25931 filterValidation : function(e){
25932 if(!e.isNavKeyPress()){
25933 this.validationTask.delay(this.validationDelay);
25937 onKeyUp : function(e){
25938 if(!e.isNavKeyPress()){
25944 reset : function(){
25945 Ext.form.TextField.superclass.reset.call(this);
25946 this.applyEmptyText();
25949 applyEmptyText : function(){
25950 if(this.rendered && this.emptyText && this.getRawValue().length < 1){
25951 this.setRawValue(this.emptyText);
25952 this.el.addClass(this.emptyClass);
25956 preFocus : function(){
25957 if(this.emptyText){
25958 if(this.el.dom.value == this.emptyText){
25959 this.setRawValue('');
25961 this.el.removeClass(this.emptyClass);
25963 if(this.selectOnFocus){
25964 this.el.dom.select();
25968 postBlur : function(){
25969 this.applyEmptyText();
25972 filterKeys : function(e){
25973 var k = e.getKey();
25974 if(!Ext.isIE && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
25977 var c = e.getCharCode(), cc = String.fromCharCode(c);
25978 if(Ext.isIE && (e.isSpecialKey() || !cc)){
25981 if(!this.maskRe.test(cc)){
25986 setValue : function(v){
25987 if(this.emptyText && this.el && v !== undefined && v !== null && v !== ''){
25988 this.el.removeClass(this.emptyClass);
25990 Ext.form.TextField.superclass.setValue.apply(this, arguments);
25991 this.applyEmptyText();
25996 validateValue : function(value){
25997 if(value.length < 1 || value === this.emptyText){ if(this.allowBlank){
25998 this.clearInvalid();
26001 this.markInvalid(this.blankText);
26005 if(value.length < this.minLength){
26006 this.markInvalid(String.format(this.minLengthText, this.minLength));
26009 if(value.length > this.maxLength){
26010 this.markInvalid(String.format(this.maxLengthText, this.maxLength));
26014 var vt = Ext.form.VTypes;
26015 if(!vt[this.vtype](value, this)){
26016 this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
26020 if(typeof this.validator == "function"){
26021 var msg = this.validator(value);
26023 this.markInvalid(msg);
26027 if(this.regex && !this.regex.test(value)){
26028 this.markInvalid(this.regexText);
26035 selectText : function(start, end){
26036 var v = this.getRawValue();
26038 start = start === undefined ? 0 : start;
26039 end = end === undefined ? v.length : end;
26040 var d = this.el.dom;
26041 if(d.setSelectionRange){
26042 d.setSelectionRange(start, end);
26043 }else if(d.createTextRange){
26044 var range = d.createTextRange();
26045 range.moveStart("character", start);
26046 range.moveEnd("character", end-v.length);
26053 autoSize : function(){
26054 if(!this.grow || !this.rendered){
26058 this.metrics = Ext.util.TextMetrics.createInstance(this.el);
26061 var v = el.dom.value;
26062 var d = document.createElement('div');
26063 d.appendChild(document.createTextNode(v));
26067 var w = Math.min(this.growMax, Math.max(this.metrics.getWidth(v) + 10, this.growMin));
26068 this.el.setWidth(w);
26069 this.fireEvent("autosize", this, w);
26072 Ext.reg('textfield', Ext.form.TextField);
26075 Ext.form.TriggerField = Ext.extend(Ext.form.TextField, {
26078 defaultAutoCreate : {tag: "input", type: "text", size: "16", autocomplete: "off"},
26083 autoSize: Ext.emptyFn,
26085 deferHeight : true,
26088 onResize : function(w, h){
26089 Ext.form.TriggerField.superclass.onResize.call(this, w, h);
26090 if(typeof w == 'number'){
26091 this.el.setWidth(this.adjustWidth('input', w - this.trigger.getWidth()));
26093 this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
26096 adjustSize : Ext.BoxComponent.prototype.adjustSize,
26098 getResizeEl : function(){
26102 getPositionEl : function(){
26106 alignErrorIcon : function(){
26107 this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
26110 onRender : function(ct, position){
26111 Ext.form.TriggerField.superclass.onRender.call(this, ct, position);
26112 this.wrap = this.el.wrap({cls: "x-form-field-wrap"});
26113 this.trigger = this.wrap.createChild(this.triggerConfig ||
26114 {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.triggerClass});
26115 if(this.hideTrigger){
26116 this.trigger.setDisplayed(false);
26118 this.initTrigger();
26120 this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
26124 initTrigger : function(){
26125 this.trigger.on("click", this.onTriggerClick, this, {preventDefault:true});
26126 this.trigger.addClassOnOver('x-form-trigger-over');
26127 this.trigger.addClassOnClick('x-form-trigger-click');
26130 onDestroy : function(){
26132 this.trigger.removeAllListeners();
26133 this.trigger.remove();
26136 this.wrap.remove();
26138 Ext.form.TriggerField.superclass.onDestroy.call(this);
26141 onFocus : function(){
26142 Ext.form.TriggerField.superclass.onFocus.call(this);
26143 if(!this.mimicing){
26144 this.wrap.addClass('x-trigger-wrap-focus');
26145 this.mimicing = true;
26146 Ext.get(Ext.isIE ? document.body : document).on("mousedown", this.mimicBlur, this, {delay: 10});
26147 if(this.monitorTab){
26148 this.el.on("keydown", this.checkTab, this);
26153 checkTab : function(e){
26154 if(e.getKey() == e.TAB){
26155 this.triggerBlur();
26159 onBlur : function(){
26162 mimicBlur : function(e){
26163 if(!this.wrap.contains(e.target) && this.validateBlur(e)){
26164 this.triggerBlur();
26168 triggerBlur : function(){
26169 this.mimicing = false;
26170 Ext.get(Ext.isIE ? document.body : document).un("mousedown", this.mimicBlur);
26171 if(this.monitorTab){
26172 this.el.un("keydown", this.checkTab, this);
26175 this.wrap.removeClass('x-trigger-wrap-focus');
26176 Ext.form.TriggerField.superclass.onBlur.call(this);
26179 beforeBlur : Ext.emptyFn,
26181 validateBlur : function(e){
26185 onDisable : function(){
26186 Ext.form.TriggerField.superclass.onDisable.call(this);
26188 this.wrap.addClass('x-item-disabled');
26192 onEnable : function(){
26193 Ext.form.TriggerField.superclass.onEnable.call(this);
26195 this.wrap.removeClass('x-item-disabled');
26200 onShow : function(){
26202 this.wrap.dom.style.display = '';
26203 this.wrap.dom.style.visibility = 'visible';
26207 onHide : function(){
26208 this.wrap.dom.style.display = 'none';
26212 onTriggerClick : Ext.emptyFn
26219 Ext.form.TwinTriggerField = Ext.extend(Ext.form.TriggerField, {
26220 initComponent : function(){
26221 Ext.form.TwinTriggerField.superclass.initComponent.call(this);
26223 this.triggerConfig = {
26224 tag:'span', cls:'x-form-twin-triggers', cn:[
26225 {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger1Class},
26226 {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger2Class}
26230 getTrigger : function(index){
26231 return this.triggers[index];
26234 initTrigger : function(){
26235 var ts = this.trigger.select('.x-form-trigger', true);
26236 this.wrap.setStyle('overflow', 'hidden');
26237 var triggerField = this;
26238 ts.each(function(t, all, index){
26239 t.hide = function(){
26240 var w = triggerField.wrap.getWidth();
26241 this.dom.style.display = 'none';
26242 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
26244 t.show = function(){
26245 var w = triggerField.wrap.getWidth();
26246 this.dom.style.display = '';
26247 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
26249 var triggerIndex = 'Trigger'+(index+1);
26251 if(this['hide'+triggerIndex]){
26252 t.dom.style.display = 'none';
26254 t.on("click", this['on'+triggerIndex+'Click'], this, {preventDefault:true});
26255 t.addClassOnOver('x-form-trigger-over');
26256 t.addClassOnClick('x-form-trigger-click');
26258 this.triggers = ts.elements;
26261 onTrigger1Click : Ext.emptyFn,
26262 onTrigger2Click : Ext.emptyFn
26264 Ext.reg('trigger', Ext.form.TriggerField);
26266 Ext.form.TextArea = Ext.extend(Ext.form.TextField, {
26271 growAppend : ' \n ',
26274 enterIsSpecial : false,
26277 preventScrollbars: false,
26280 onRender : function(ct, position){
26282 this.defaultAutoCreate = {
26284 style:"width:100px;height:60px;",
26285 autocomplete: "off"
26288 Ext.form.TextArea.superclass.onRender.call(this, ct, position);
26290 this.textSizeEl = Ext.DomHelper.append(document.body, {
26291 tag: "pre", cls: "x-form-grow-sizer"
26293 if(this.preventScrollbars){
26294 this.el.setStyle("overflow", "hidden");
26296 this.el.setHeight(this.growMin);
26300 onDestroy : function(){
26301 if(this.textSizeEl){
26302 Ext.removeNode(this.textSizeEl);
26304 Ext.form.TextArea.superclass.onDestroy.call(this);
26307 fireKey : function(e){
26308 if(e.isSpecialKey() && (this.enterIsSpecial || (e.getKey() != e.ENTER || e.hasModifier()))){
26309 this.fireEvent("specialkey", this, e);
26313 onKeyUp : function(e){
26314 if(!e.isNavKeyPress() || e.getKey() == e.ENTER){
26320 autoSize : function(){
26321 if(!this.grow || !this.textSizeEl){
26325 var v = el.dom.value;
26326 var ts = this.textSizeEl;
26328 ts.appendChild(document.createTextNode(v));
26331 Ext.fly(ts).setWidth(this.el.getWidth());
26333 v = "  ";
26336 v = v.replace(/\n/g, '<p> </p>');
26338 v += this.growAppend;
26341 var h = Math.min(this.growMax, Math.max(ts.offsetHeight, this.growMin)+this.growPad);
26342 if(h != this.lastHeight){
26343 this.lastHeight = h;
26344 this.el.setHeight(h);
26345 this.fireEvent("autosize", this, h);
26349 Ext.reg('textarea', Ext.form.TextArea);
26351 Ext.form.NumberField = Ext.extend(Ext.form.TextField, {
26353 fieldClass: "x-form-field x-form-num-field",
26355 allowDecimals : true,
26357 decimalSeparator : ".",
26359 decimalPrecision : 2,
26361 allowNegative : true,
26363 minValue : Number.NEGATIVE_INFINITY,
26365 maxValue : Number.MAX_VALUE,
26367 minText : "The minimum value for this field is {0}",
26369 maxText : "The maximum value for this field is {0}",
26371 nanText : "{0} is not a valid number",
26373 baseChars : "0123456789",
26375 initEvents : function(){
26376 Ext.form.NumberField.superclass.initEvents.call(this);
26377 var allowed = this.baseChars+'';
26378 if(this.allowDecimals){
26379 allowed += this.decimalSeparator;
26381 if(this.allowNegative){
26384 this.stripCharsRe = new RegExp('[^'+allowed+']', 'gi');
26385 var keyPress = function(e){
26386 var k = e.getKey();
26387 if(!Ext.isIE && (e.isSpecialKey() || k == e.BACKSPACE || k == e.DELETE)){
26390 var c = e.getCharCode();
26391 if(allowed.indexOf(String.fromCharCode(c)) === -1){
26395 this.el.on("keypress", keyPress, this);
26398 validateValue : function(value){
26399 if(!Ext.form.NumberField.superclass.validateValue.call(this, value)){
26402 if(value.length < 1){ return true;
26404 value = String(value).replace(this.decimalSeparator, ".");
26406 this.markInvalid(String.format(this.nanText, value));
26409 var num = this.parseValue(value);
26410 if(num < this.minValue){
26411 this.markInvalid(String.format(this.minText, this.minValue));
26414 if(num > this.maxValue){
26415 this.markInvalid(String.format(this.maxText, this.maxValue));
26421 getValue : function(){
26422 return this.fixPrecision(this.parseValue(Ext.form.NumberField.superclass.getValue.call(this)));
26425 setValue : function(v){
26427 v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator);
26428 Ext.form.NumberField.superclass.setValue.call(this, v);
26431 parseValue : function(value){
26432 value = parseFloat(String(value).replace(this.decimalSeparator, "."));
26433 return isNaN(value) ? '' : value;
26436 fixPrecision : function(value){
26437 var nan = isNaN(value);
26438 if(!this.allowDecimals || this.decimalPrecision == -1 || nan || !value){
26439 return nan ? '' : value;
26441 return parseFloat(parseFloat(value).toFixed(this.decimalPrecision));
26444 beforeBlur : function(){
26445 var v = this.parseValue(this.getRawValue());
26447 this.setValue(this.fixPrecision(v));
26451 Ext.reg('numberfield', Ext.form.NumberField);
26453 Ext.form.DateField = Ext.extend(Ext.form.TriggerField, {
26457 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",
26459 disabledDays : null,
26461 disabledDaysText : "Disabled",
26463 disabledDates : null,
26465 disabledDatesText : "Disabled",
26471 minText : "The date in this field must be equal to or after {0}",
26473 maxText : "The date in this field must be equal to or before {0}",
26475 invalidText : "{0} is not a valid date - it must be in the format {1}",
26477 triggerClass : 'x-form-date-trigger',
26480 defaultAutoCreate : {tag: "input", type: "text", size: "10", autocomplete: "off"},
26482 initComponent : function(){
26483 Ext.form.DateField.superclass.initComponent.call(this);
26484 if(typeof this.minValue == "string"){
26485 this.minValue = this.parseDate(this.minValue);
26487 if(typeof this.maxValue == "string"){
26488 this.maxValue = this.parseDate(this.maxValue);
26490 this.ddMatch = null;
26491 if(this.disabledDates){
26492 var dd = this.disabledDates;
26494 for(var i = 0; i < dd.length; i++){
26496 if(i != dd.length-1) re += "|";
26498 this.ddMatch = new RegExp(re + ")");
26502 validateValue : function(value){
26503 value = this.formatDate(value);
26504 if(!Ext.form.DateField.superclass.validateValue.call(this, value)){
26507 if(value.length < 1){ return true;
26509 var svalue = value;
26510 value = this.parseDate(value);
26512 this.markInvalid(String.format(this.invalidText, svalue, this.format));
26515 var time = value.getTime();
26516 if(this.minValue && time < this.minValue.getTime()){
26517 this.markInvalid(String.format(this.minText, this.formatDate(this.minValue)));
26520 if(this.maxValue && time > this.maxValue.getTime()){
26521 this.markInvalid(String.format(this.maxText, this.formatDate(this.maxValue)));
26524 if(this.disabledDays){
26525 var day = value.getDay();
26526 for(var i = 0; i < this.disabledDays.length; i++) {
26527 if(day === this.disabledDays[i]){
26528 this.markInvalid(this.disabledDaysText);
26533 var fvalue = this.formatDate(value);
26534 if(this.ddMatch && this.ddMatch.test(fvalue)){
26535 this.markInvalid(String.format(this.disabledDatesText, fvalue));
26541 validateBlur : function(){
26542 return !this.menu || !this.menu.isVisible();
26546 getValue : function(){
26547 return this.parseDate(Ext.form.DateField.superclass.getValue.call(this)) || "";
26551 setValue : function(date){
26552 Ext.form.DateField.superclass.setValue.call(this, this.formatDate(this.parseDate(date)));
26555 parseDate : function(value){
26556 if(!value || Ext.isDate(value)){
26559 var v = Date.parseDate(value, this.format);
26560 if(!v && this.altFormats){
26561 if(!this.altFormatsArray){
26562 this.altFormatsArray = this.altFormats.split("|");
26564 for(var i = 0, len = this.altFormatsArray.length; i < len && !v; i++){
26565 v = Date.parseDate(value, this.altFormatsArray[i]);
26571 onDestroy : function(){
26573 this.menu.destroy();
26576 this.wrap.remove();
26578 Ext.form.DateField.superclass.onDestroy.call(this);
26581 formatDate : function(date){
26582 return Ext.isDate(date) ? date.dateFormat(this.format) : date;
26586 select: function(m, d){
26589 show : function(){ this.onFocus();
26592 this.focus.defer(10, this);
26593 var ml = this.menuListeners;
26594 this.menu.un("select", ml.select, this);
26595 this.menu.un("show", ml.show, this);
26596 this.menu.un("hide", ml.hide, this);
26600 onTriggerClick : function(){
26604 if(this.menu == null){
26605 this.menu = new Ext.menu.DateMenu();
26607 Ext.apply(this.menu.picker, {
26608 minDate : this.minValue,
26609 maxDate : this.maxValue,
26610 disabledDatesRE : this.ddMatch,
26611 disabledDatesText : this.disabledDatesText,
26612 disabledDays : this.disabledDays,
26613 disabledDaysText : this.disabledDaysText,
26614 format : this.format,
26615 minText : String.format(this.minText, this.formatDate(this.minValue)),
26616 maxText : String.format(this.maxText, this.formatDate(this.maxValue))
26618 this.menu.on(Ext.apply({}, this.menuListeners, {
26621 this.menu.picker.setValue(this.getValue() || new Date());
26622 this.menu.show(this.el, "tl-bl?");
26625 beforeBlur : function(){
26626 var v = this.parseDate(this.getRawValue());
26637 Ext.reg('datefield', Ext.form.DateField);
26639 Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
26646 defaultAutoCreate : {tag: "input", type: "text", size: "24", autocomplete: "off"},
26655 selectedClass: 'x-combo-selected',
26657 triggerClass : 'x-form-arrow-trigger',
26661 listAlign: 'tl-bl?',
26667 triggerAction: 'query',
26677 selectOnFocus:false,
26679 queryParam: 'query',
26681 loadingText: 'Loading...',
26695 forceSelection:false,
26697 typeAheadDelay : 250,
26703 initComponent : function(){
26704 Ext.form.ComboBox.superclass.initComponent.call(this);
26717 if(this.transform){
26718 this.allowDomMove = false;
26719 var s = Ext.getDom(this.transform);
26720 if(!this.hiddenName){
26721 this.hiddenName = s.name;
26724 this.mode = 'local';
26725 var d = [], opts = s.options;
26726 for(var i = 0, len = opts.length;i < len; i++){
26728 var value = (Ext.isIE ? o.getAttributeNode('value').specified : o.hasAttribute('value')) ? o.value : o.text;
26730 this.value = value;
26732 d.push([value, o.text]);
26734 this.store = new Ext.data.SimpleStore({
26736 fields: ['value', 'text'],
26739 this.valueField = 'value';
26740 this.displayField = 'text';
26742 s.name = Ext.id(); if(!this.lazyRender){
26743 this.target = true;
26744 this.el = Ext.DomHelper.insertBefore(s, this.autoCreate || this.defaultAutoCreate);
26745 Ext.removeNode(s); this.render(this.el.parentNode);
26747 Ext.removeNode(s); }
26750 this.selectedIndex = -1;
26751 if(this.mode == 'local'){
26752 if(this.initialConfig.queryDelay === undefined){
26753 this.queryDelay = 10;
26755 if(this.initialConfig.minChars === undefined){
26761 onRender : function(ct, position){
26762 Ext.form.ComboBox.superclass.onRender.call(this, ct, position);
26763 if(this.hiddenName){
26764 this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName, id: (this.hiddenId||this.hiddenName)},
26766 this.hiddenField.value =
26767 this.hiddenValue !== undefined ? this.hiddenValue :
26768 this.value !== undefined ? this.value : '';
26770 this.el.dom.removeAttribute('name');
26773 this.el.dom.setAttribute('autocomplete', 'off');
26776 if(!this.lazyInit){
26779 this.on('focus', this.initList, this, {single: true});
26782 if(!this.editable){
26783 this.editable = true;
26784 this.setEditable(false);
26788 initList : function(){
26790 var cls = 'x-combo-list';
26792 this.list = new Ext.Layer({
26793 shadow: this.shadow, cls: [cls, this.listClass].join(' '), constrain:false
26796 var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
26797 this.list.setWidth(lw);
26798 this.list.swallowEvent('mousewheel');
26799 this.assetHeight = 0;
26802 this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
26803 this.assetHeight += this.header.getHeight();
26806 this.innerList = this.list.createChild({cls:cls+'-inner'});
26807 this.innerList.on('mouseover', this.onViewOver, this);
26808 this.innerList.on('mousemove', this.onViewMove, this);
26809 this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
26812 this.footer = this.list.createChild({cls:cls+'-ft'});
26813 this.pageTb = new Ext.PagingToolbar({
26815 pageSize: this.pageSize,
26816 renderTo:this.footer
26818 this.assetHeight += this.footer.getHeight();
26823 this.tpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';
26827 this.view = new Ext.DataView({
26828 applyTo: this.innerList,
26830 singleSelect: true,
26831 selectedClass: this.selectedClass,
26832 itemSelector: this.itemSelector || '.' + cls + '-item'
26835 this.view.on('click', this.onViewClick, this);
26837 this.bindStore(this.store, true);
26839 if(this.resizable){
26840 this.resizer = new Ext.Resizable(this.list, {
26841 pinned:true, handles:'se'
26843 this.resizer.on('resize', function(r, w, h){
26844 this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
26845 this.listWidth = w;
26846 this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
26847 this.restrictHeight();
26849 this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
26855 bindStore : function(store, initial){
26856 if(this.store && !initial){
26857 this.store.un('beforeload', this.onBeforeLoad, this);
26858 this.store.un('load', this.onLoad, this);
26859 this.store.un('loadexception', this.collapse, this);
26863 this.view.setStore(null);
26868 this.store = Ext.StoreMgr.lookup(store);
26870 this.store.on('beforeload', this.onBeforeLoad, this);
26871 this.store.on('load', this.onLoad, this);
26872 this.store.on('loadexception', this.collapse, this);
26875 this.view.setStore(store);
26880 initEvents : function(){
26881 Ext.form.ComboBox.superclass.initEvents.call(this);
26883 this.keyNav = new Ext.KeyNav(this.el, {
26884 "up" : function(e){
26885 this.inKeyMode = true;
26889 "down" : function(e){
26890 if(!this.isExpanded()){
26891 this.onTriggerClick();
26893 this.inKeyMode = true;
26898 "enter" : function(e){
26899 this.onViewClick();
26900 this.delayedCheck = true;
26901 this.unsetDelayCheck.defer(10, this);
26904 "esc" : function(e){
26908 "tab" : function(e){
26909 this.onViewClick(false);
26915 doRelay : function(foo, bar, hname){
26916 if(hname == 'down' || this.scope.isExpanded()){
26917 return Ext.KeyNav.prototype.doRelay.apply(this, arguments);
26922 forceKeyDown : true
26924 this.queryDelay = Math.max(this.queryDelay || 10,
26925 this.mode == 'local' ? 10 : 250);
26926 this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);
26927 if(this.typeAhead){
26928 this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
26930 if(this.editable !== false){
26931 this.el.on("keyup", this.onKeyUp, this);
26933 if(this.forceSelection){
26934 this.on('blur', this.doForce, this);
26938 onDestroy : function(){
26940 this.view.el.removeAllListeners();
26941 this.view.el.remove();
26942 this.view.purgeListeners();
26945 this.list.destroy();
26947 this.bindStore(null);
26948 Ext.form.ComboBox.superclass.onDestroy.call(this);
26951 unsetDelayCheck : function(){
26952 delete this.delayedCheck;
26954 fireKey : function(e){
26955 if(e.isNavKeyPress() && !this.isExpanded() && !this.delayedCheck){
26956 this.fireEvent("specialkey", this, e);
26960 onResize: function(w, h){
26961 Ext.form.ComboBox.superclass.onResize.apply(this, arguments);
26962 if(this.list && this.listWidth === undefined){
26963 var lw = Math.max(w, this.minListWidth);
26964 this.list.setWidth(lw);
26965 this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
26969 onEnable: function(){
26970 Ext.form.ComboBox.superclass.onEnable.apply(this, arguments);
26971 if(this.hiddenField){
26972 this.hiddenField.disabled = false;
26976 onDisable: function(){
26977 Ext.form.ComboBox.superclass.onDisable.apply(this, arguments);
26978 if(this.hiddenField){
26979 this.hiddenField.disabled = true;
26984 setEditable : function(value){
26985 if(value == this.editable){
26988 this.editable = value;
26990 this.el.dom.setAttribute('readOnly', true);
26991 this.el.on('mousedown', this.onTriggerClick, this);
26992 this.el.addClass('x-combo-noedit');
26994 this.el.dom.setAttribute('readOnly', false);
26995 this.el.un('mousedown', this.onTriggerClick, this);
26996 this.el.removeClass('x-combo-noedit');
27000 onBeforeLoad : function(){
27001 if(!this.hasFocus){
27004 this.innerList.update(this.loadingText ?
27005 '<div class="loading-indicator">'+this.loadingText+'</div>' : '');
27006 this.restrictHeight();
27007 this.selectedIndex = -1;
27010 onLoad : function(){
27011 if(!this.hasFocus){
27014 if(this.store.getCount() > 0){
27016 this.restrictHeight();
27017 if(this.lastQuery == this.allQuery){
27019 this.el.dom.select();
27021 if(!this.selectByValue(this.value, true)){
27022 this.select(0, true);
27026 if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){
27027 this.taTask.delay(this.typeAheadDelay);
27031 this.onEmptyResults();
27035 onTypeAhead : function(){
27036 if(this.store.getCount() > 0){
27037 var r = this.store.getAt(0);
27038 var newValue = r.data[this.displayField];
27039 var len = newValue.length;
27040 var selStart = this.getRawValue().length;
27041 if(selStart != len){
27042 this.setRawValue(newValue);
27043 this.selectText(selStart, newValue.length);
27048 onSelect : function(record, index){
27049 if(this.fireEvent('beforeselect', this, record, index) !== false){
27050 this.setValue(record.data[this.valueField || this.displayField]);
27052 this.fireEvent('select', this, record, index);
27057 getValue : function(){
27058 if(this.valueField){
27059 return typeof this.value != 'undefined' ? this.value : '';
27061 return Ext.form.ComboBox.superclass.getValue.call(this);
27066 clearValue : function(){
27067 if(this.hiddenField){
27068 this.hiddenField.value = '';
27070 this.setRawValue('');
27071 this.lastSelectionText = '';
27072 this.applyEmptyText();
27077 setValue : function(v){
27079 if(this.valueField){
27080 var r = this.findRecord(this.valueField, v);
27082 text = r.data[this.displayField];
27083 }else if(this.valueNotFoundText !== undefined){
27084 text = this.valueNotFoundText;
27087 this.lastSelectionText = text;
27088 if(this.hiddenField){
27089 this.hiddenField.value = v;
27091 Ext.form.ComboBox.superclass.setValue.call(this, text);
27095 findRecord : function(prop, value){
27097 if(this.store.getCount() > 0){
27098 this.store.each(function(r){
27099 if(r.data[prop] == value){
27108 onViewMove : function(e, t){
27109 this.inKeyMode = false;
27112 onViewOver : function(e, t){
27113 if(this.inKeyMode){ return;
27115 var item = this.view.findItemFromChild(t);
27117 var index = this.view.indexOf(item);
27118 this.select(index, false);
27122 onViewClick : function(doFocus){
27123 var index = this.view.getSelectedIndexes()[0];
27124 var r = this.store.getAt(index);
27126 this.onSelect(r, index);
27128 if(doFocus !== false){
27133 restrictHeight : function(){
27134 this.innerList.dom.style.height = '';
27135 var inner = this.innerList.dom;
27136 var pad = this.list.getFrameWidth('tb')+(this.resizable?this.handleHeight:0)+this.assetHeight;
27137 var h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight);
27138 var ha = this.getPosition()[1]-Ext.getBody().getScroll().top;
27139 var hb = Ext.lib.Dom.getViewHeight()-ha-this.getSize().height;
27140 var space = Math.max(ha, hb, this.minHeight || 0)-this.list.shadow.offset-pad-2;
27141 h = Math.min(h, space, this.maxHeight);
27143 this.innerList.setHeight(h);
27144 this.list.beginUpdate();
27145 this.list.setHeight(h+pad);
27146 this.list.alignTo(this.el, this.listAlign);
27147 this.list.endUpdate();
27150 onEmptyResults : function(){
27155 isExpanded : function(){
27156 return this.list && this.list.isVisible();
27160 selectByValue : function(v, scrollIntoView){
27161 if(v !== undefined && v !== null){
27162 var r = this.findRecord(this.valueField || this.displayField, v);
27164 this.select(this.store.indexOf(r), scrollIntoView);
27172 select : function(index, scrollIntoView){
27173 this.selectedIndex = index;
27174 this.view.select(index);
27175 if(scrollIntoView !== false){
27176 var el = this.view.getNode(index);
27178 this.innerList.scrollChildIntoView(el, false);
27183 selectNext : function(){
27184 var ct = this.store.getCount();
27186 if(this.selectedIndex == -1){
27188 }else if(this.selectedIndex < ct-1){
27189 this.select(this.selectedIndex+1);
27194 selectPrev : function(){
27195 var ct = this.store.getCount();
27197 if(this.selectedIndex == -1){
27199 }else if(this.selectedIndex != 0){
27200 this.select(this.selectedIndex-1);
27205 onKeyUp : function(e){
27206 if(this.editable !== false && !e.isSpecialKey()){
27207 this.lastKey = e.getKey();
27208 this.dqTask.delay(this.queryDelay);
27212 validateBlur : function(){
27213 return !this.list || !this.list.isVisible();
27216 initQuery : function(){
27217 this.doQuery(this.getRawValue());
27220 doForce : function(){
27221 if(this.el.dom.value.length > 0){
27222 this.el.dom.value =
27223 this.lastSelectionText === undefined ? '' : this.lastSelectionText;
27224 this.applyEmptyText();
27229 doQuery : function(q, forceAll){
27230 if(q === undefined || q === null){
27235 forceAll: forceAll,
27239 if(this.fireEvent('beforequery', qe)===false || qe.cancel){
27243 forceAll = qe.forceAll;
27244 if(forceAll === true || (q.length >= this.minChars)){
27245 if(this.lastQuery !== q){
27246 this.lastQuery = q;
27247 if(this.mode == 'local'){
27248 this.selectedIndex = -1;
27250 this.store.clearFilter();
27252 this.store.filter(this.displayField, q);
27256 this.store.baseParams[this.queryParam] = q;
27258 params: this.getParams(q)
27263 this.selectedIndex = -1;
27269 getParams : function(q){
27273 p.limit = this.pageSize;
27279 collapse : function(){
27280 if(!this.isExpanded()){
27284 Ext.getDoc().un('mousewheel', this.collapseIf, this);
27285 Ext.getDoc().un('mousedown', this.collapseIf, this);
27286 this.fireEvent('collapse', this);
27289 collapseIf : function(e){
27290 if(!e.within(this.wrap) && !e.within(this.list)){
27296 expand : function(){
27297 if(this.isExpanded() || !this.hasFocus){
27300 this.list.alignTo(this.wrap, this.listAlign);
27302 this.innerList.setOverflow('auto'); Ext.getDoc().on('mousewheel', this.collapseIf, this);
27303 Ext.getDoc().on('mousedown', this.collapseIf, this);
27304 this.fireEvent('expand', this);
27307 onTriggerClick : function(){
27311 if(this.isExpanded()){
27316 if(this.triggerAction == 'all') {
27317 this.doQuery(this.allQuery, true);
27319 this.doQuery(this.getRawValue());
27331 Ext.reg('combo', Ext.form.ComboBox);
27333 Ext.form.Checkbox = Ext.extend(Ext.form.Field, {
27335 focusClass : undefined,
27337 fieldClass: "x-form-field",
27341 defaultAutoCreate : { tag: "input", type: 'checkbox', autocomplete: "off"},
27345 initComponent : function(){
27346 Ext.form.Checkbox.superclass.initComponent.call(this);
27353 onResize : function(){
27354 Ext.form.Checkbox.superclass.onResize.apply(this, arguments);
27355 if(!this.boxLabel){
27356 this.el.alignTo(this.wrap, 'c-c');
27360 initEvents : function(){
27361 Ext.form.Checkbox.superclass.initEvents.call(this);
27362 this.el.on("click", this.onClick, this);
27363 this.el.on("change", this.onClick, this);
27366 getResizeEl : function(){
27370 getPositionEl : function(){
27375 markInvalid : Ext.emptyFn,
27377 clearInvalid : Ext.emptyFn,
27379 onRender : function(ct, position){
27380 Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
27381 if(this.inputValue !== undefined){
27382 this.el.dom.value = this.inputValue;
27384 this.wrap = this.el.wrap({cls: "x-form-check-wrap"});
27386 this.wrap.createChild({tag: 'label', htmlFor: this.el.id, cls: 'x-form-cb-label', html: this.boxLabel});
27389 this.setValue(true);
27391 this.checked = this.el.dom.checked;
27395 onDestroy : function(){
27397 this.wrap.remove();
27399 Ext.form.Checkbox.superclass.onDestroy.call(this);
27402 initValue : Ext.emptyFn,
27405 getValue : function(){
27407 return this.el.dom.checked;
27412 onClick : function(){
27413 if(this.el.dom.checked != this.checked){
27414 this.setValue(this.el.dom.checked);
27419 setValue : function(v){
27420 this.checked = (v === true || v === 'true' || v == '1' || String(v).toLowerCase() == 'on');
27421 if(this.el && this.el.dom){
27422 this.el.dom.checked = this.checked;
27423 this.el.dom.defaultChecked = this.checked;
27425 this.fireEvent("check", this, this.checked);
27428 Ext.reg('checkbox', Ext.form.Checkbox);
27430 Ext.form.Radio = Ext.extend(Ext.form.Checkbox, {
27431 inputType: 'radio',
27434 markInvalid : Ext.emptyFn,
27436 clearInvalid : Ext.emptyFn,
27439 getGroupValue : function(){
27440 var p = this.el.up('form') || Ext.getBody();
27441 var c = p.child('input[name='+this.el.dom.name+']:checked', true);
27442 return c ? c.value : null;
27445 onClick : function(){
27446 if(this.el.dom.checked != this.checked){
27447 var p = this.el.up('form') || Ext.getBody();
27448 var els = p.select('input[name='+this.el.dom.name+']');
27449 els.each(function(el){
27450 if(el.dom.id == this.id){
27451 this.setValue(true);
27453 Ext.getCmp(el.dom.id).setValue(false);
27460 setValue : function(v){
27461 if (typeof v == 'boolean') {
27462 Ext.form.Radio.superclass.setValue.call(this, v);
27464 var r = this.el.up('form').child('input[name='+this.el.dom.name+'][value='+v+']', true);
27471 Ext.reg('radio', Ext.form.Radio);
27473 Ext.form.Hidden = Ext.extend(Ext.form.Field, {
27475 inputType : 'hidden',
27478 onRender : function(){
27479 Ext.form.Hidden.superclass.onRender.apply(this, arguments);
27483 initEvents : function(){
27484 this.originalValue = this.getValue();
27488 setSize : Ext.emptyFn,
27489 setWidth : Ext.emptyFn,
27490 setHeight : Ext.emptyFn,
27491 setPosition : Ext.emptyFn,
27492 setPagePosition : Ext.emptyFn,
27493 markInvalid : Ext.emptyFn,
27494 clearInvalid : Ext.emptyFn
27496 Ext.reg('hidden', Ext.form.Hidden);
27498 Ext.form.BasicForm = function(el, config){
27499 Ext.apply(this, config);
27501 this.items = new Ext.util.MixedCollection(false, function(o){
27502 return o.id || (o.id = Ext.id());
27516 Ext.form.BasicForm.superclass.constructor.call(this);
27519 Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
27529 activeAction : null,
27532 trackResetOnLoad : false,
27537 initEl : function(el){
27538 this.el = Ext.get(el);
27539 this.id = this.el.id || Ext.id();
27540 if(!this.standardSubmit){
27541 this.el.on('submit', this.onSubmit, this);
27543 this.el.addClass('x-form');
27551 onSubmit : function(e){
27555 destroy: function() {
27556 this.items.each(function(f){
27560 this.el.removeAllListeners();
27563 this.purgeListeners();
27567 isValid : function(){
27569 this.items.each(function(f){
27578 isDirty : function(){
27580 this.items.each(function(f){
27590 doAction : function(action, options){
27591 if(typeof action == 'string'){
27592 action = new Ext.form.Action.ACTION_TYPES[action](this, options);
27594 if(this.fireEvent('beforeaction', this, action) !== false){
27595 this.beforeAction(action);
27596 action.run.defer(100, action);
27602 submit : function(options){
27603 if(this.standardSubmit){
27604 var v = this.isValid();
27606 this.el.dom.submit();
27610 this.doAction('submit', options);
27615 load : function(options){
27616 this.doAction('load', options);
27621 updateRecord : function(record){
27622 record.beginEdit();
27623 var fs = record.fields;
27624 fs.each(function(f){
27625 var field = this.findField(f.name);
27627 record.set(f.name, field.getValue());
27635 loadRecord : function(record){
27636 this.setValues(record.data);
27640 beforeAction : function(action){
27641 var o = action.options;
27643 if(this.waitMsgTarget === true){
27644 this.el.mask(o.waitMsg, 'x-mask-loading');
27645 }else if(this.waitMsgTarget){
27646 this.waitMsgTarget = Ext.get(this.waitMsgTarget);
27647 this.waitMsgTarget.mask(o.waitMsg, 'x-mask-loading');
27649 Ext.MessageBox.wait(o.waitMsg, o.waitTitle || this.waitTitle || 'Please Wait...');
27654 afterAction : function(action, success){
27655 this.activeAction = null;
27656 var o = action.options;
27658 if(this.waitMsgTarget === true){
27660 }else if(this.waitMsgTarget){
27661 this.waitMsgTarget.unmask();
27663 Ext.MessageBox.updateProgress(1);
27664 Ext.MessageBox.hide();
27671 Ext.callback(o.success, o.scope, [this, action]);
27672 this.fireEvent('actioncomplete', this, action);
27674 Ext.callback(o.failure, o.scope, [this, action]);
27675 this.fireEvent('actionfailed', this, action);
27680 findField : function(id){
27681 var field = this.items.get(id);
27683 this.items.each(function(f){
27684 if(f.isFormField && (f.dataIndex == id || f.id == id || f.getName() == id)){
27690 return field || null;
27695 markInvalid : function(errors){
27696 if(Ext.isArray(errors)){
27697 for(var i = 0, len = errors.length; i < len; i++){
27698 var fieldError = errors[i];
27699 var f = this.findField(fieldError.id);
27701 f.markInvalid(fieldError.msg);
27707 if(typeof errors[id] != 'function' && (field = this.findField(id))){
27708 field.markInvalid(errors[id]);
27716 setValues : function(values){
27717 if(Ext.isArray(values)){ for(var i = 0, len = values.length; i < len; i++){
27719 var f = this.findField(v.id);
27721 f.setValue(v.value);
27722 if(this.trackResetOnLoad){
27723 f.originalValue = f.getValue();
27727 }else{ var field, id;
27729 if(typeof values[id] != 'function' && (field = this.findField(id))){
27730 field.setValue(values[id]);
27731 if(this.trackResetOnLoad){
27732 field.originalValue = field.getValue();
27741 getValues : function(asString){
27742 var fs = Ext.lib.Ajax.serializeForm(this.el.dom);
27743 if(asString === true){
27746 return Ext.urlDecode(fs);
27750 clearInvalid : function(){
27751 this.items.each(function(f){
27758 reset : function(){
27759 this.items.each(function(f){
27767 this.items.addAll(Array.prototype.slice.call(arguments, 0));
27773 remove : function(field){
27774 this.items.remove(field);
27779 render : function(){
27780 this.items.each(function(f){
27781 if(f.isFormField && !f.rendered && document.getElementById(f.id)){ f.applyToMarkup(f.id);
27788 applyToFields : function(o){
27789 this.items.each(function(f){
27796 applyIfToFields : function(o){
27797 this.items.each(function(f){
27804 Ext.BasicForm = Ext.form.BasicForm;
27806 Ext.FormPanel = Ext.extend(Ext.Panel, {
27811 buttonAlign:'center',
27820 monitorValid : false,
27828 initComponent :function(){
27829 this.form = this.createForm();
27831 Ext.FormPanel.superclass.initComponent.call(this);
27838 this.relayEvents(this.form, ['beforeaction', 'actionfailed', 'actioncomplete']);
27841 createForm: function(){
27842 delete this.initialConfig.listeners;
27843 return new Ext.form.BasicForm(null, this.initialConfig);
27846 initFields : function(){
27848 var formPanel = this;
27849 var fn = function(c){
27850 if(c.doLayout && c != formPanel){
27852 labelAlign: c.ownerCt.labelAlign,
27853 labelWidth: c.ownerCt.labelWidth,
27854 itemCls: c.ownerCt.itemCls
27859 }else if(c.isFormField){
27863 this.items.each(fn);
27866 getLayoutTarget : function(){
27867 return this.form.el;
27871 getForm : function(){
27875 onRender : function(ct, position){
27878 Ext.FormPanel.superclass.onRender.call(this, ct, position);
27881 method : this.method || 'POST',
27882 id : this.formId || Ext.id()
27884 if(this.fileUpload) {
27885 o.enctype = 'multipart/form-data';
27887 this.form.initEl(this.body.createChild(o));
27890 beforeDestroy: function(){
27891 Ext.FormPanel.superclass.beforeDestroy.call(this);
27892 Ext.destroy(this.form);
27895 initEvents : function(){
27896 Ext.FormPanel.superclass.initEvents.call(this);
27897 this.items.on('remove', this.onRemove, this);
27898 this.items.on('add', this.onAdd, this);
27899 if(this.monitorValid){ this.startMonitoring();
27903 onAdd : function(ct, c) {
27904 if (c.isFormField) {
27909 onRemove : function(c) {
27910 if (c.isFormField) {
27911 Ext.destroy(c.container.up('.x-form-item'));
27912 this.form.remove(c);
27917 startMonitoring : function(){
27920 Ext.TaskMgr.start({
27921 run : this.bindHandler,
27922 interval : this.monitorPoll || 200,
27929 stopMonitoring : function(){
27930 this.bound = false;
27935 this.form.load.apply(this.form, arguments);
27938 onDisable : function(){
27939 Ext.FormPanel.superclass.onDisable.call(this);
27941 this.form.items.each(function(){
27947 onEnable : function(){
27948 Ext.FormPanel.superclass.onEnable.call(this);
27950 this.form.items.each(function(){
27956 bindHandler : function(){
27960 this.form.items.each(function(f){
27961 if(!f.isValid(true)){
27967 for(var i = 0, len = this.buttons.length; i < len; i++){
27968 var btn = this.buttons[i];
27969 if(btn.formBind === true && btn.disabled === valid){
27970 btn.setDisabled(!valid);
27974 this.fireEvent('clientvalidation', this, valid);
27977 Ext.reg('form', Ext.FormPanel);
27979 Ext.form.FormPanel = Ext.FormPanel;
27983 Ext.form.FieldSet = Ext.extend(Ext.Panel, {
27989 baseCls:'x-fieldset',
27994 onRender : function(ct, position){
27996 this.el = document.createElement('fieldset');
27997 this.el.id = this.id;
27998 if (this.title || this.header || this.checkboxToggle) {
27999 this.el.appendChild(document.createElement('legend')).className = 'x-fieldset-header';
28003 Ext.form.FieldSet.superclass.onRender.call(this, ct, position);
28005 if(this.checkboxToggle){
28006 var o = typeof this.checkboxToggle == 'object' ?
28007 this.checkboxToggle :
28008 {tag: 'input', type: 'checkbox', name: this.checkboxName || this.id+'-checkbox'};
28009 this.checkbox = this.header.insertFirst(o);
28010 this.checkbox.dom.checked = !this.collapsed;
28011 this.checkbox.on('click', this.onCheckClick, this);
28016 onCollapse : function(doAnim, animArg){
28018 this.checkbox.dom.checked = false;
28020 this.afterCollapse();
28025 onExpand : function(doAnim, animArg){
28027 this.checkbox.dom.checked = true;
28029 this.afterExpand();
28033 onCheckClick : function(){
28034 this[this.checkbox.dom.checked ? 'expand' : 'collapse']();
28075 Ext.reg('fieldset', Ext.form.FieldSet);
28080 Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
28082 enableFormat : true,
28084 enableFontSize : true,
28086 enableColors : true,
28088 enableAlignments : true,
28090 enableLists : true,
28092 enableSourceEdit : true,
28094 enableLinks : true,
28098 createLinkText : 'Please enter the URL for the link:',
28100 defaultLinkValue : 'http:/'+'/',
28109 defaultFont: 'tahoma',
28112 validationEvent : false,
28114 initialized : false,
28116 sourceEditMode : false,
28117 onFocus : Ext.emptyFn,
28119 hideMode:'offsets',
28120 defaultAutoCreate : {
28122 style:"width:500px;height:300px;",
28123 autocomplete: "off"
28127 initComponent : function(){
28146 createFontOptions : function(){
28147 var buf = [], fs = this.fontFamilies, ff, lc;
28148 for(var i = 0, len = fs.length; i< len; i++){
28150 lc = ff.toLowerCase();
28152 '<option value="',lc,'" style="font-family:',ff,';"',
28153 (this.defaultFont == lc ? ' selected="true">' : '>'),
28158 return buf.join('');
28161 createToolbar : function(editor){
28163 function btn(id, toggle, handler){
28166 cls : 'x-btn-icon x-edit-'+id,
28167 enableToggle:toggle !== false,
28169 handler:handler||editor.relayBtnCmd,
28170 clickEvent:'mousedown',
28171 tooltip: editor.buttonTips[id] || undefined,
28177 var tb = new Ext.Toolbar({
28178 renderTo:this.wrap.dom.firstChild
28182 tb.el.on('click', function(e){
28183 e.preventDefault();
28186 if(this.enableFont && !Ext.isSafari){
28187 this.fontSelect = tb.el.createChild({
28189 cls:'x-font-select',
28190 html: this.createFontOptions()
28192 this.fontSelect.on('change', function(){
28193 var font = this.fontSelect.dom.value;
28194 this.relayCmd('fontname', font);
28198 this.fontSelect.dom,
28203 if(this.enableFormat){
28211 if(this.enableFontSize){
28214 btn('increasefontsize', false, this.adjustFont),
28215 btn('decreasefontsize', false, this.adjustFont)
28219 if(this.enableColors){
28222 itemId:'forecolor',
28223 cls:'x-btn-icon x-edit-forecolor',
28224 clickEvent:'mousedown',
28225 tooltip: editor.buttonTips['forecolor'] || undefined,
28227 menu : new Ext.menu.ColorMenu({
28228 allowReselect: true,
28229 focus: Ext.emptyFn,
28232 selectHandler: function(cp, color){
28233 this.execCmd('forecolor', Ext.isSafari || Ext.isIE ? '#'+color : color);
28237 clickEvent:'mousedown'
28240 itemId:'backcolor',
28241 cls:'x-btn-icon x-edit-backcolor',
28242 clickEvent:'mousedown',
28243 tooltip: editor.buttonTips['backcolor'] || undefined,
28245 menu : new Ext.menu.ColorMenu({
28246 focus: Ext.emptyFn,
28249 allowReselect: true,
28250 selectHandler: function(cp, color){
28252 this.execCmd('useCSS', false);
28253 this.execCmd('hilitecolor', color);
28254 this.execCmd('useCSS', true);
28257 this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isSafari || Ext.isIE ? '#'+color : color);
28262 clickEvent:'mousedown'
28268 if(this.enableAlignments){
28271 btn('justifyleft'),
28272 btn('justifycenter'),
28273 btn('justifyright')
28278 if(this.enableLinks){
28281 btn('createlink', false, this.createLink)
28285 if(this.enableLists){
28288 btn('insertorderedlist'),
28289 btn('insertunorderedlist')
28292 if(this.enableSourceEdit){
28295 btn('sourceedit', true, function(btn){
28296 this.toggleSourceEdit(btn.pressed);
28306 getDocMarkup : function(){
28307 return '<html><head><style type="text/css">body{border:0;margin:0;padding:3px;height:98%;cursor:text;}</style></head><body></body></html>';
28310 getEditorBody : function(){
28311 return this.doc.body || this.doc.documentElement;
28315 onRender : function(ct, position){
28316 Ext.form.HtmlEditor.superclass.onRender.call(this, ct, position);
28317 this.el.dom.style.border = '0 none';
28318 this.el.dom.setAttribute('tabIndex', -1);
28319 this.el.addClass('x-hidden');
28321 this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;')
28323 this.wrap = this.el.wrap({
28324 cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
28327 this.createToolbar(this);
28329 this.tb.items.each(function(item){
28330 if(item.itemId != 'sourceedit'){
28335 var iframe = document.createElement('iframe');
28336 iframe.name = Ext.id();
28337 iframe.frameBorder = 'no';
28339 iframe.src=(Ext.SSL_SECURE_URL || "javascript:false");
28341 this.wrap.dom.appendChild(iframe);
28343 this.iframe = iframe;
28346 iframe.contentWindow.document.designMode = 'on';
28347 this.doc = iframe.contentWindow.document;
28348 this.win = iframe.contentWindow;
28350 this.doc = (iframe.contentDocument || window.frames[iframe.name].document);
28351 this.win = window.frames[iframe.name];
28352 this.doc.designMode = 'on';
28355 this.doc.write(this.getDocMarkup())
28360 if(this.doc.body || this.doc.readyState == 'complete'){
28361 Ext.TaskMgr.stop(task);
28362 this.doc.designMode="on";
28363 this.initEditor.defer(10, this);
28370 Ext.TaskMgr.start(task);
28373 this.setSize(this.el.getSize());
28378 onResize : function(w, h){
28379 Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments);
28380 if(this.el && this.iframe){
28381 if(typeof w == 'number'){
28382 var aw = w - this.wrap.getFrameWidth('lr');
28383 this.el.setWidth(this.adjustWidth('textarea', aw));
28384 this.iframe.style.width = aw + 'px';
28386 if(typeof h == 'number'){
28387 var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight();
28388 this.el.setHeight(this.adjustWidth('textarea', ah));
28389 this.iframe.style.height = ah + 'px';
28391 this.getEditorBody().style.height = (ah - (this.iframePad*2)) + 'px';
28398 toggleSourceEdit : function(sourceEditMode){
28399 if(sourceEditMode === undefined){
28400 sourceEditMode = !this.sourceEditMode;
28402 this.sourceEditMode = sourceEditMode === true;
28403 var btn = this.tb.items.get('sourceedit');
28404 if(btn.pressed !== this.sourceEditMode){
28405 btn.toggle(this.sourceEditMode);
28408 if(this.sourceEditMode){
28409 this.tb.items.each(function(item){
28410 if(item.itemId != 'sourceedit'){
28415 this.iframe.className = 'x-hidden';
28416 this.el.removeClass('x-hidden');
28417 this.el.dom.removeAttribute('tabIndex');
28420 if(this.initialized){
28421 this.tb.items.each(function(item){
28426 this.iframe.className = '';
28427 this.el.addClass('x-hidden');
28428 this.el.dom.setAttribute('tabIndex', -1);
28431 var lastSize = this.lastSize;
28433 delete this.lastSize;
28434 this.setSize(lastSize);
28436 this.fireEvent('editmodechange', this, this.sourceEditMode);
28440 createLink : function(){
28441 var url = prompt(this.createLinkText, this.defaultLinkValue);
28442 if(url && url != 'http:/'+'/'){
28443 this.relayCmd('createlink', url);
28448 adjustSize : Ext.BoxComponent.prototype.adjustSize,
28451 getResizeEl : function(){
28456 getPositionEl : function(){
28461 initEvents : function(){
28462 this.originalValue = this.getValue();
28466 markInvalid : Ext.emptyFn,
28468 clearInvalid : Ext.emptyFn,
28470 setValue : function(v){
28471 Ext.form.HtmlEditor.superclass.setValue.call(this, v);
28476 cleanHtml : function(html){
28477 html = String(html);
28478 if(html.length > 5){
28480 html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');
28483 if(html == ' '){
28490 syncValue : function(){
28491 if(this.initialized){
28492 var bd = this.getEditorBody();
28493 var html = bd.innerHTML;
28495 var bs = bd.getAttribute('style');
28496 var m = bs.match(/text-align:(.*?);/i);
28498 html = '<div style="'+m[0]+'">' + html + '</div>';
28501 html = this.cleanHtml(html);
28502 if(this.fireEvent('beforesync', this, html) !== false){
28503 this.el.dom.value = html;
28504 this.fireEvent('sync', this, html);
28510 pushValue : function(){
28511 if(this.initialized){
28512 var v = this.el.dom.value;
28513 if(!this.activated && v.length < 1){
28516 if(this.fireEvent('beforepush', this, v) !== false){
28517 this.getEditorBody().innerHTML = v;
28518 this.fireEvent('push', this, v);
28524 deferFocus : function(){
28525 this.focus.defer(10, this);
28529 focus : function(){
28530 if(this.win && !this.sourceEditMode){
28538 initEditor : function(){
28539 var dbody = this.getEditorBody();
28540 var ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat');
28541 ss['background-attachment'] = 'fixed';
28542 dbody.bgProperties = 'fixed';
28543 Ext.DomHelper.applyStyles(dbody, ss);
28544 Ext.EventManager.on(this.doc, {
28545 'mousedown': this.onEditorEvent,
28546 'dblclick': this.onEditorEvent,
28547 'click': this.onEditorEvent,
28548 'keyup': this.onEditorEvent,
28553 Ext.EventManager.on(this.doc, 'keypress', this.applyCommand, this);
28555 if(Ext.isIE || Ext.isSafari || Ext.isOpera){
28556 Ext.EventManager.on(this.doc, 'keydown', this.fixKeys, this);
28558 this.initialized = true;
28560 this.fireEvent('initialize', this);
28565 onDestroy : function(){
28567 this.tb.items.each(function(item){
28569 item.menu.removeAll();
28571 item.menu.el.destroy();
28576 this.wrap.dom.innerHTML = '';
28577 this.wrap.remove();
28582 onFirstFocus : function(){
28583 this.activated = true;
28584 this.tb.items.each(function(item){
28589 var s = this.win.getSelection();
28590 if(!s.focusNode || s.focusNode.nodeType != 3){
28591 var r = s.getRangeAt(0);
28592 r.selectNodeContents(this.getEditorBody());
28597 this.execCmd('useCSS', true);
28598 this.execCmd('styleWithCSS', false);
28601 this.fireEvent('activate', this);
28605 adjustFont: function(btn){
28606 var adjust = btn.itemId == 'increasefontsize' ? 1 : -1;
28608 var v = parseInt(this.doc.queryCommandValue('FontSize') || 2, 10);
28609 if(Ext.isSafari3 || Ext.isAir){
28625 v = v.constrain(1, 6);
28630 v = Math.max(1, v+adjust) + (Ext.isSafari ? 'px' : 0);
28632 this.execCmd('FontSize', v);
28635 onEditorEvent : function(e){
28636 this.updateToolbar();
28641 updateToolbar: function(){
28643 if(!this.activated){
28644 this.onFirstFocus();
28648 var btns = this.tb.items.map, doc = this.doc;
28650 if(this.enableFont && !Ext.isSafari){
28651 var name = (this.doc.queryCommandValue('FontName')||this.defaultFont).toLowerCase();
28652 if(name != this.fontSelect.dom.value){
28653 this.fontSelect.dom.value = name;
28656 if(this.enableFormat){
28657 btns.bold.toggle(doc.queryCommandState('bold'));
28658 btns.italic.toggle(doc.queryCommandState('italic'));
28659 btns.underline.toggle(doc.queryCommandState('underline'));
28661 if(this.enableAlignments){
28662 btns.justifyleft.toggle(doc.queryCommandState('justifyleft'));
28663 btns.justifycenter.toggle(doc.queryCommandState('justifycenter'));
28664 btns.justifyright.toggle(doc.queryCommandState('justifyright'));
28666 if(!Ext.isSafari && this.enableLists){
28667 btns.insertorderedlist.toggle(doc.queryCommandState('insertorderedlist'));
28668 btns.insertunorderedlist.toggle(doc.queryCommandState('insertunorderedlist'));
28671 Ext.menu.MenuMgr.hideAll();
28677 relayBtnCmd : function(btn){
28678 this.relayCmd(btn.itemId);
28682 relayCmd : function(cmd, value){
28684 this.execCmd(cmd, value);
28685 this.updateToolbar();
28690 execCmd : function(cmd, value){
28691 this.doc.execCommand(cmd, false, value === undefined ? null : value);
28696 applyCommand : function(e){
28698 var c = e.getCharCode(), cmd;
28700 c = String.fromCharCode(c);
28716 e.preventDefault();
28723 insertAtCursor : function(text){
28724 if(!this.activated){
28729 var r = this.doc.selection.createRange();
28736 }else if(Ext.isGecko || Ext.isOpera){
28738 this.execCmd('InsertHTML', text);
28740 }else if(Ext.isSafari){
28741 this.execCmd('InsertText', text);
28747 fixKeys : function(){
28749 return function(e){
28750 var k = e.getKey(), r;
28753 r = this.doc.selection.createRange();
28756 r.pasteHTML(' ');
28759 }else if(k == e.ENTER){
28760 r = this.doc.selection.createRange();
28762 var target = r.parentElement();
28763 if(!target || target.tagName.toLowerCase() != 'li'){
28765 r.pasteHTML('<br />');
28772 }else if(Ext.isOpera){
28773 return function(e){
28774 var k = e.getKey();
28778 this.execCmd('InsertHTML',' ');
28782 }else if(Ext.isSafari){
28783 return function(e){
28784 var k = e.getKey();
28787 this.execCmd('InsertText','\t');
28795 getToolbar : function(){
28802 title: 'Bold (Ctrl+B)',
28803 text: 'Make the selected text bold.',
28804 cls: 'x-html-editor-tip'
28807 title: 'Italic (Ctrl+I)',
28808 text: 'Make the selected text italic.',
28809 cls: 'x-html-editor-tip'
28812 title: 'Underline (Ctrl+U)',
28813 text: 'Underline the selected text.',
28814 cls: 'x-html-editor-tip'
28816 increasefontsize : {
28817 title: 'Grow Text',
28818 text: 'Increase the font size.',
28819 cls: 'x-html-editor-tip'
28821 decreasefontsize : {
28822 title: 'Shrink Text',
28823 text: 'Decrease the font size.',
28824 cls: 'x-html-editor-tip'
28827 title: 'Text Highlight Color',
28828 text: 'Change the background color of the selected text.',
28829 cls: 'x-html-editor-tip'
28832 title: 'Font Color',
28833 text: 'Change the color of the selected text.',
28834 cls: 'x-html-editor-tip'
28837 title: 'Align Text Left',
28838 text: 'Align text to the left.',
28839 cls: 'x-html-editor-tip'
28842 title: 'Center Text',
28843 text: 'Center text in the editor.',
28844 cls: 'x-html-editor-tip'
28847 title: 'Align Text Right',
28848 text: 'Align text to the right.',
28849 cls: 'x-html-editor-tip'
28851 insertunorderedlist : {
28852 title: 'Bullet List',
28853 text: 'Start a bulleted list.',
28854 cls: 'x-html-editor-tip'
28856 insertorderedlist : {
28857 title: 'Numbered List',
28858 text: 'Start a numbered list.',
28859 cls: 'x-html-editor-tip'
28862 title: 'Hyperlink',
28863 text: 'Make the selected text a hyperlink.',
28864 cls: 'x-html-editor-tip'
28867 title: 'Source Edit',
28868 text: 'Switch to source editing mode.',
28869 cls: 'x-html-editor-tip'
28907 Ext.reg('htmleditor', Ext.form.HtmlEditor);
28909 Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {
28915 minText : "The time in this field must be equal to or after {0}",
28917 maxText : "The time in this field must be equal to or before {0}",
28919 invalidText : "{0} is not a valid time",
28923 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",
28930 triggerAction: 'all',
28935 initComponent : function(){
28936 Ext.form.TimeField.superclass.initComponent.call(this);
28938 if(typeof this.minValue == "string"){
28939 this.minValue = this.parseDate(this.minValue);
28941 if(typeof this.maxValue == "string"){
28942 this.maxValue = this.parseDate(this.maxValue);
28946 var min = this.parseDate(this.minValue);
28948 min = new Date().clearTime();
28950 var max = this.parseDate(this.maxValue);
28952 max = new Date().clearTime().add('mi', (24 * 60) - 1);
28956 times.push([min.dateFormat(this.format)]);
28957 min = min.add('mi', this.increment);
28959 this.store = new Ext.data.SimpleStore({
28963 this.displayField = 'text';
28968 getValue : function(){
28969 var v = Ext.form.TimeField.superclass.getValue.call(this);
28970 return this.formatDate(this.parseDate(v)) || '';
28974 setValue : function(value){
28975 Ext.form.TimeField.superclass.setValue.call(this, this.formatDate(this.parseDate(value)));
28979 validateValue : Ext.form.DateField.prototype.validateValue,
28980 parseDate : Ext.form.DateField.prototype.parseDate,
28981 formatDate : Ext.form.DateField.prototype.formatDate,
28984 beforeBlur : function(){
28985 var v = this.parseDate(this.getRawValue());
28987 this.setValue(v.dateFormat(this.format));
28996 Ext.reg('timefield', Ext.form.TimeField);
28997 Ext.form.Label = Ext.extend(Ext.BoxComponent, {
28998 onRender : function(ct, position){
29000 this.el = document.createElement('label');
29001 this.el.innerHTML = this.text ? Ext.util.Format.htmlEncode(this.text) : (this.html || '');
29003 this.el.setAttribute('htmlFor', this.forId);
29006 Ext.form.Label.superclass.onRender.call(this, ct, position);
29010 Ext.reg('label', Ext.form.Label);
29012 Ext.form.Action = function(form, options){
29014 this.options = options || {};
29018 Ext.form.Action.CLIENT_INVALID = 'client';
29020 Ext.form.Action.SERVER_INVALID = 'server';
29022 Ext.form.Action.CONNECT_FAILURE = 'connect';
29024 Ext.form.Action.LOAD_FAILURE = 'load';
29026 Ext.form.Action.prototype = {
29040 run : function(options){
29044 success : function(response){
29048 handleResponse : function(response){
29052 failure : function(response){
29053 this.response = response;
29054 this.failureType = Ext.form.Action.CONNECT_FAILURE;
29055 this.form.afterAction(this, false);
29058 processResponse : function(response){
29059 this.response = response;
29060 if(!response.responseText){
29063 this.result = this.handleResponse(response);
29064 return this.result;
29067 getUrl : function(appendParams){
29068 var url = this.options.url || this.form.url || this.form.el.dom.action;
29070 var p = this.getParams();
29072 url += (url.indexOf('?') != -1 ? '&' : '?') + p;
29078 getMethod : function(){
29079 return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();
29082 getParams : function(){
29083 var bp = this.form.baseParams;
29084 var p = this.options.params;
29086 if(typeof p == "object"){
29087 p = Ext.urlEncode(Ext.applyIf(p, bp));
29088 }else if(typeof p == 'string' && bp){
29089 p += '&' + Ext.urlEncode(bp);
29092 p = Ext.urlEncode(bp);
29097 createCallback : function(opts){
29098 var opts = opts || {};
29100 success: this.success,
29101 failure: this.failure,
29103 timeout: (opts.timeout*1000) || (this.form.timeout*1000),
29104 upload: this.form.fileUpload ? this.success : undefined
29110 Ext.form.Action.Submit = function(form, options){
29111 Ext.form.Action.Submit.superclass.constructor.call(this, form, options);
29114 Ext.extend(Ext.form.Action.Submit, Ext.form.Action, {
29119 var o = this.options;
29120 var method = this.getMethod();
29121 var isPost = method == 'POST';
29122 if(o.clientValidation === false || this.form.isValid()){
29123 Ext.Ajax.request(Ext.apply(this.createCallback(o), {
29124 form:this.form.el.dom,
29125 url:this.getUrl(!isPost),
29127 params:isPost ? this.getParams() : null,
29128 isUpload: this.form.fileUpload
29131 }else if (o.clientValidation !== false){ this.failureType = Ext.form.Action.CLIENT_INVALID;
29132 this.form.afterAction(this, false);
29136 success : function(response){
29137 var result = this.processResponse(response);
29138 if(result === true || result.success){
29139 this.form.afterAction(this, true);
29143 this.form.markInvalid(result.errors);
29144 this.failureType = Ext.form.Action.SERVER_INVALID;
29146 this.form.afterAction(this, false);
29149 handleResponse : function(response){
29150 if(this.form.errorReader){
29151 var rs = this.form.errorReader.read(response);
29154 for(var i = 0, len = rs.records.length; i < len; i++) {
29155 var r = rs.records[i];
29156 errors[i] = r.data;
29159 if(errors.length < 1){
29163 success : rs.success,
29167 return Ext.decode(response.responseText);
29173 Ext.form.Action.Load = function(form, options){
29174 Ext.form.Action.Load.superclass.constructor.call(this, form, options);
29175 this.reader = this.form.reader;
29178 Ext.extend(Ext.form.Action.Load, Ext.form.Action, {
29182 Ext.Ajax.request(Ext.apply(
29183 this.createCallback(this.options), {
29184 method:this.getMethod(),
29185 url:this.getUrl(false),
29186 params:this.getParams()
29190 success : function(response){
29191 var result = this.processResponse(response);
29192 if(result === true || !result.success || !result.data){
29193 this.failureType = Ext.form.Action.LOAD_FAILURE;
29194 this.form.afterAction(this, false);
29197 this.form.clearInvalid();
29198 this.form.setValues(result.data);
29199 this.form.afterAction(this, true);
29202 handleResponse : function(response){
29203 if(this.form.reader){
29204 var rs = this.form.reader.read(response);
29205 var data = rs.records && rs.records[0] ? rs.records[0].data : null;
29207 success : rs.success,
29211 return Ext.decode(response.responseText);
29215 Ext.form.Action.ACTION_TYPES = {
29216 'load' : Ext.form.Action.Load,
29217 'submit' : Ext.form.Action.Submit
29221 Ext.form.VTypes = function(){
29222 var alpha = /^[a-zA-Z_]+$/;
29223 var alphanum = /^[a-zA-Z0-9_]+$/;
29224 var email = /^([\w]+)(.[\w]+)*@([\w-]+\.){1,5}([A-Za-z]){2,4}$/;
29225 var url = /(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
29229 'email' : function(v){
29230 return email.test(v);
29233 'emailText' : 'This field should be an e-mail address in the format "user@domain.com"',
29235 'emailMask' : /[a-z0-9_\.\-@]/i,
29238 'url' : function(v){
29239 return url.test(v);
29242 'urlText' : 'This field should be a URL in the format "http:/'+'/www.domain.com"',
29245 'alpha' : function(v){
29246 return alpha.test(v);
29249 'alphaText' : 'This field should only contain letters and _',
29251 'alphaMask' : /[a-z_]/i,
29254 'alphanum' : function(v){
29255 return alphanum.test(v);
29258 'alphanumText' : 'This field should only contain letters, numbers and _',
29260 'alphanumMask' : /[a-z0-9_]/i
29264 Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
29278 ddText : "{0} selected row{1}",
29280 minColumnWidth : 25,
29282 trackMouseOver : true,
29284 enableDragDrop : false,
29286 enableColumnMove : true,
29288 enableColumnHide : true,
29290 enableHdMenu : true,
29292 stripeRows : false,
29294 autoExpandColumn : false,
29296 autoExpandMin : 50,
29298 autoExpandMax : 1000,
29309 stateEvents: ["columnmove", "columnresize", "sortchange"],
29312 initComponent : function(){
29313 Ext.grid.GridPanel.superclass.initComponent.call(this);
29317 this.autoScroll = false;
29318 this.autoWidth = false;
29320 if(Ext.isArray(this.columns)){
29321 this.colModel = new Ext.grid.ColumnModel(this.columns);
29322 delete this.columns;
29327 this.store = this.ds;
29331 this.colModel = this.cm;
29335 this.selModel = this.sm;
29338 this.store = Ext.StoreMgr.lookup(this.store);
29386 "headercontextmenu",
29399 onRender : function(ct, position){
29400 Ext.grid.GridPanel.superclass.onRender.apply(this, arguments);
29404 this.el.addClass('x-grid-panel');
29406 var view = this.getView();
29409 c.on("mousedown", this.onMouseDown, this);
29410 c.on("click", this.onClick, this);
29411 c.on("dblclick", this.onDblClick, this);
29412 c.on("contextmenu", this.onContextMenu, this);
29413 c.on("keydown", this.onKeyDown, this);
29415 this.relayEvents(c, ["mousedown","mouseup","mouseover","mouseout","keypress"]);
29417 this.getSelectionModel().init(this);
29418 this.view.render();
29422 initEvents : function(){
29423 Ext.grid.GridPanel.superclass.initEvents.call(this);
29426 this.loadMask = new Ext.LoadMask(this.bwrap,
29427 Ext.apply({store:this.store}, this.loadMask));
29431 initStateEvents : function(){
29432 Ext.grid.GridPanel.superclass.initStateEvents.call(this);
29433 this.colModel.on('hiddenchange', this.saveState, this, {delay: 100});
29436 applyState : function(state){
29437 var cm = this.colModel;
29438 var cs = state.columns;
29440 for(var i = 0, len = cs.length; i < len; i++){
29442 var c = cm.getColumnById(s.id);
29444 c.hidden = s.hidden;
29446 var oldIndex = cm.getIndexById(s.id);
29448 cm.moveColumn(oldIndex, i);
29454 this.store[this.store.remoteSort ? 'setDefaultSort' : 'sort'](state.sort.field, state.sort.direction);
29458 getState : function(){
29459 var o = {columns: []};
29460 for(var i = 0, c; c = this.colModel.config[i]; i++){
29466 o.columns[i].hidden = true;
29469 var ss = this.store.getSortState();
29477 afterRender : function(){
29478 Ext.grid.GridPanel.superclass.afterRender.call(this);
29479 this.view.layout();
29480 this.viewReady = true;
29484 reconfigure : function(store, colModel){
29486 this.loadMask.destroy();
29487 this.loadMask = new Ext.LoadMask(this.bwrap,
29488 Ext.apply({store:store}, this.initialConfig.loadMask));
29490 this.view.bind(store, colModel);
29491 this.store = store;
29492 this.colModel = colModel;
29494 this.view.refresh(true);
29499 onKeyDown : function(e){
29500 this.fireEvent("keydown", e);
29504 onDestroy : function(){
29507 this.loadMask.destroy();
29510 c.removeAllListeners();
29511 this.view.destroy();
29514 this.colModel.purgeListeners();
29515 Ext.grid.GridPanel.superclass.onDestroy.call(this);
29519 processEvent : function(name, e){
29520 this.fireEvent(name, e);
29521 var t = e.getTarget();
29523 var header = v.findHeaderIndex(t);
29524 if(header !== false){
29525 this.fireEvent("header" + name, this, header, e);
29527 var row = v.findRowIndex(t);
29528 var cell = v.findCellIndex(t);
29530 this.fireEvent("row" + name, this, row, e);
29531 if(cell !== false){
29532 this.fireEvent("cell" + name, this, row, cell, e);
29539 onClick : function(e){
29540 this.processEvent("click", e);
29544 onMouseDown : function(e){
29545 this.processEvent("mousedown", e);
29549 onContextMenu : function(e, t){
29550 this.processEvent("contextmenu", e);
29554 onDblClick : function(e){
29555 this.processEvent("dblclick", e);
29559 walkCells : function(row, col, step, fn, scope){
29560 var cm = this.colModel, clen = cm.getColumnCount();
29561 var ds = this.store, rlen = ds.getCount(), first = true;
29573 if(fn.call(scope || this, row, col, cm) === true){
29591 if(fn.call(scope || this, row, col, cm) === true){
29603 getSelections : function(){
29604 return this.selModel.getSelections();
29608 onResize : function(){
29609 Ext.grid.GridPanel.superclass.onResize.apply(this, arguments);
29610 if(this.viewReady){
29611 this.view.layout();
29616 getGridEl : function(){
29621 stopEditing : function(){},
29624 getSelectionModel : function(){
29625 if(!this.selModel){
29626 this.selModel = new Ext.grid.RowSelectionModel(
29627 this.disableSelection ? {selectRow: Ext.emptyFn} : null);
29629 return this.selModel;
29633 getStore : function(){
29638 getColumnModel : function(){
29639 return this.colModel;
29643 getView : function(){
29645 this.view = new Ext.grid.GridView(this.viewConfig);
29650 getDragDropText : function(){
29651 var count = this.selModel.getCount();
29652 return String.format(this.ddText, count, count == 1 ? '' : 's');
29705 Ext.reg('grid', Ext.grid.GridPanel);
29707 Ext.grid.GridView = function(config){
29708 Ext.apply(this, config);
29711 "beforerowremoved",
29713 "beforerowsinserted",
29725 Ext.grid.GridView.superclass.constructor.call(this);
29728 Ext.extend(Ext.grid.GridView, Ext.util.Observable, {
29739 sortClasses : ["sort-asc", "sort-desc"],
29741 sortAscText : "Sort Ascending",
29743 sortDescText : "Sort Descending",
29745 columnsText : "Columns",
29751 initTemplates : function(){
29752 var ts = this.templates || {};
29754 ts.master = new Ext.Template(
29755 '<div class="x-grid3" hidefocus="true">',
29756 '<div class="x-grid3-viewport">',
29757 '<div class="x-grid3-header"><div class="x-grid3-header-inner"><div class="x-grid3-header-offset">{header}</div></div><div class="x-clear"></div></div>',
29758 '<div class="x-grid3-scroller"><div class="x-grid3-body">{body}</div><a href="#" class="x-grid3-focus" tabIndex="-1"></a></div>',
29760 '<div class="x-grid3-resize-marker"> </div>',
29761 '<div class="x-grid3-resize-proxy"> </div>',
29767 ts.header = new Ext.Template(
29768 '<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
29769 '<thead><tr class="x-grid3-hd-row">{cells}</tr></thead>',
29775 ts.hcell = new Ext.Template(
29776 '<td class="x-grid3-hd x-grid3-cell x-grid3-td-{id}" 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>' : '',
29777 '{value}<img class="x-grid3-sort-icon" src="', Ext.BLANK_IMAGE_URL, '" />',
29783 ts.body = new Ext.Template('{rows}');
29787 ts.row = new Ext.Template(
29788 '<div class="x-grid3-row {alt}" style="{tstyle}"><table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
29789 '<tbody><tr>{cells}</tr>',
29790 (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>' : ''),
29791 '</tbody></table></div>'
29796 ts.cell = new Ext.Template(
29797 '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}" tabIndex="0" {cellAttr}>',
29798 '<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr}>{value}</div>',
29805 if(t && typeof t.compile == 'function' && !t.compiled){
29806 t.disableFormats = true;
29811 this.templates = ts;
29813 this.tdClass = 'x-grid3-cell';
29814 this.cellSelector = 'td.x-grid3-cell';
29815 this.hdCls = 'x-grid3-hd';
29816 this.rowSelector = 'div.x-grid3-row';
29817 this.colRe = new RegExp("x-grid3-td-([^\\s]+)", "");
29820 fly : function(el){
29821 if(!this._flyweight){
29822 this._flyweight = new Ext.Element.Flyweight(document.body);
29824 this._flyweight.dom = el;
29825 return this._flyweight;
29828 getEditorParent : function(ed){
29829 return this.scroller.dom;
29832 initElements : function(){
29833 var E = Ext.Element;
29835 var el = this.grid.getGridEl().dom.firstChild;
29836 var cs = el.childNodes;
29838 this.el = new E(el);
29840 this.mainWrap = new E(cs[0]);
29841 this.mainHd = new E(this.mainWrap.dom.firstChild);
29843 if(this.grid.hideHeaders){
29844 this.mainHd.setDisplayed(false);
29847 this.innerHd = this.mainHd.dom.firstChild;
29848 this.scroller = new E(this.mainWrap.dom.childNodes[1]);
29850 this.scroller.setStyle('overflow-x', 'hidden');
29852 this.mainBody = new E(this.scroller.dom.firstChild);
29854 this.focusEl = new E(this.scroller.dom.childNodes[1]);
29855 this.focusEl.swallowEvent("click", true);
29857 this.resizeMarker = new E(cs[1]);
29858 this.resizeProxy = new E(cs[2]);
29861 getRows : function(){
29862 return this.hasRows() ? this.mainBody.dom.childNodes : [];
29866 findCell : function(el){
29870 return this.fly(el).findParent(this.cellSelector, 3);
29873 findCellIndex : function(el, requiredCls){
29874 var cell = this.findCell(el);
29875 if(cell && (!requiredCls || this.fly(cell).hasClass(requiredCls))){
29876 return this.getCellIndex(cell);
29881 getCellIndex : function(el){
29883 var m = el.className.match(this.colRe);
29885 return this.cm.getIndexById(m[1]);
29891 findHeaderCell : function(el){
29892 var cell = this.findCell(el);
29893 return cell && this.fly(cell).hasClass(this.hdCls) ? cell : null;
29896 findHeaderIndex : function(el){
29897 return this.findCellIndex(el, this.hdCls);
29900 findRow : function(el){
29904 return this.fly(el).findParent(this.rowSelector, 10);
29907 findRowIndex : function(el){
29908 var r = this.findRow(el);
29909 return r ? r.rowIndex : false;
29914 getRow : function(row){
29915 return this.getRows()[row];
29919 getCell : function(row, col){
29920 return this.getRow(row).getElementsByTagName('td')[col];
29924 getHeaderCell : function(index){
29925 return this.mainHd.dom.getElementsByTagName('td')[index];
29929 addRowClass : function(row, cls){
29930 var r = this.getRow(row);
29932 this.fly(r).addClass(cls);
29936 removeRowClass : function(row, cls){
29937 var r = this.getRow(row);
29939 this.fly(r).removeClass(cls);
29943 removeRow : function(row){
29944 Ext.removeNode(this.getRow(row));
29947 removeRows : function(firstRow, lastRow){
29948 var bd = this.mainBody.dom;
29949 for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
29950 Ext.removeNode(bd.childNodes[firstRow]);
29955 getScrollState : function(){
29956 var sb = this.scroller.dom;
29957 return {left: sb.scrollLeft, top: sb.scrollTop};
29960 restoreScroll : function(state){
29961 var sb = this.scroller.dom;
29962 sb.scrollLeft = state.left;
29963 sb.scrollTop = state.top;
29967 scrollToTop : function(){
29968 this.scroller.dom.scrollTop = 0;
29969 this.scroller.dom.scrollLeft = 0;
29972 syncScroll : function(){
29973 this.syncHeaderScroll();
29974 var mb = this.scroller.dom;
29975 this.grid.fireEvent("bodyscroll", mb.scrollLeft, mb.scrollTop);
29978 syncHeaderScroll : function(){
29979 var mb = this.scroller.dom;
29980 this.innerHd.scrollLeft = mb.scrollLeft;
29981 this.innerHd.scrollLeft = mb.scrollLeft; },
29983 updateSortIcon : function(col, dir){
29984 var sc = this.sortClasses;
29985 var hds = this.mainHd.select('td').removeClass(sc);
29986 hds.item(col).addClass(sc[dir == "DESC" ? 1 : 0]);
29989 updateAllColumnWidths : function(){
29990 var tw = this.getTotalWidth();
29991 var clen = this.cm.getColumnCount();
29993 for(var i = 0; i < clen; i++){
29994 ws[i] = this.getColumnWidth(i);
29997 this.innerHd.firstChild.firstChild.style.width = tw;
29999 for(var i = 0; i < clen; i++){
30000 var hd = this.getHeaderCell(i);
30001 hd.style.width = ws[i];
30004 var ns = this.getRows();
30005 for(var i = 0, len = ns.length; i < len; i++){
30006 ns[i].style.width = tw;
30007 ns[i].firstChild.style.width = tw;
30008 var row = ns[i].firstChild.rows[0];
30009 for(var j = 0; j < clen; j++){
30010 row.childNodes[j].style.width = ws[j];
30014 this.onAllColumnWidthsUpdated(ws, tw);
30017 updateColumnWidth : function(col, width){
30018 var w = this.getColumnWidth(col);
30019 var tw = this.getTotalWidth();
30021 this.innerHd.firstChild.firstChild.style.width = tw;
30022 var hd = this.getHeaderCell(col);
30023 hd.style.width = w;
30025 var ns = this.getRows();
30026 for(var i = 0, len = ns.length; i < len; i++){
30027 ns[i].style.width = tw;
30028 ns[i].firstChild.style.width = tw;
30029 ns[i].firstChild.rows[0].childNodes[col].style.width = w;
30032 this.onColumnWidthUpdated(col, w, tw);
30035 updateColumnHidden : function(col, hidden){
30036 var tw = this.getTotalWidth();
30038 this.innerHd.firstChild.firstChild.style.width = tw;
30040 var display = hidden ? 'none' : '';
30042 var hd = this.getHeaderCell(col);
30043 hd.style.display = display;
30045 var ns = this.getRows();
30046 for(var i = 0, len = ns.length; i < len; i++){
30047 ns[i].style.width = tw;
30048 ns[i].firstChild.style.width = tw;
30049 ns[i].firstChild.rows[0].childNodes[col].style.display = display;
30052 this.onColumnHiddenUpdated(col, hidden, tw);
30054 delete this.lastViewWidth; this.layout();
30057 doRender : function(cs, rs, ds, startRow, colCount, stripe){
30058 var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount-1;
30059 var tstyle = 'width:'+this.getTotalWidth()+';';
30060 var buf = [], cb, c, p = {}, rp = {tstyle: tstyle}, r;
30061 for(var j = 0, len = rs.length; j < len; j++){
30062 r = rs[j]; cb = [];
30063 var rowIndex = (j+startRow);
30064 for(var i = 0; i < colCount; i++){
30067 p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
30068 p.attr = p.cellAttr = "";
30069 p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
30071 if(p.value == undefined || p.value === "") p.value = " ";
30072 if(r.dirty && typeof r.modified[c.name] !== 'undefined'){
30073 p.css += ' x-grid3-dirty-cell';
30075 cb[cb.length] = ct.apply(p);
30078 if(stripe && ((rowIndex+1) % 2 == 0)){
30079 alt[0] = "x-grid3-row-alt";
30082 alt[1] = " x-grid3-dirty-row";
30084 rp.cols = colCount;
30085 if(this.getRowClass){
30086 alt[2] = this.getRowClass(r, rowIndex, rp, ds);
30088 rp.alt = alt.join(" ");
30089 rp.cells = cb.join("");
30090 buf[buf.length] = rt.apply(rp);
30092 return buf.join("");
30095 processRows : function(startRow, skipStripe){
30096 if(this.ds.getCount() < 1){
30099 skipStripe = skipStripe || !this.grid.stripeRows;
30100 startRow = startRow || 0;
30101 var rows = this.getRows();
30102 var cls = ' x-grid3-row-alt ';
30103 for(var i = startRow, len = rows.length; i < len; i++){
30107 var isAlt = ((i+1) % 2 == 0);
30108 var hasAlt = (' '+row.className + ' ').indexOf(cls) != -1;
30109 if(isAlt == hasAlt){
30113 row.className += " x-grid3-row-alt";
30115 row.className = row.className.replace("x-grid3-row-alt", "");
30121 renderUI : function(){
30123 var header = this.renderHeaders();
30124 var body = this.templates.body.apply({rows:''});
30127 var html = this.templates.master.apply({
30134 g.getGridEl().dom.innerHTML = html;
30136 this.initElements();
30139 this.mainBody.dom.innerHTML = this.renderRows();
30140 this.processRows(0, true);
30143 Ext.fly(this.innerHd).on("click", this.handleHdDown, this);
30144 this.mainHd.on("mouseover", this.handleHdOver, this);
30145 this.mainHd.on("mouseout", this.handleHdOut, this);
30146 this.mainHd.on("mousemove", this.handleHdMove, this);
30148 this.scroller.on('scroll', this.syncScroll, this);
30149 if(g.enableColumnResize !== false){
30150 this.splitone = new Ext.grid.GridView.SplitDragZone(g, this.mainHd.dom);
30153 if(g.enableColumnMove){
30154 this.columnDrag = new Ext.grid.GridView.ColumnDragZone(g, this.innerHd);
30155 this.columnDrop = new Ext.grid.HeaderDropZone(g, this.mainHd.dom);
30158 if(g.enableHdMenu !== false){
30159 if(g.enableColumnHide !== false){
30160 this.colMenu = new Ext.menu.Menu({id:g.id + "-hcols-menu"});
30161 this.colMenu.on("beforeshow", this.beforeColMenuShow, this);
30162 this.colMenu.on("itemclick", this.handleHdMenuClick, this);
30164 this.hmenu = new Ext.menu.Menu({id: g.id + "-hctx"});
30166 {id:"asc", text: this.sortAscText, cls: "xg-hmenu-sort-asc"},
30167 {id:"desc", text: this.sortDescText, cls: "xg-hmenu-sort-desc"}
30169 if(g.enableColumnHide !== false){
30170 this.hmenu.add('-',
30171 {id:"columns", text: this.columnsText, menu: this.colMenu, iconCls: 'x-cols-icon'}
30174 this.hmenu.on("itemclick", this.handleHdMenuClick, this);
30178 if(g.enableDragDrop || g.enableDrag){
30179 var dd = new Ext.grid.GridDragZone(g, {
30180 ddGroup : g.ddGroup || 'GridDD'
30184 this.updateHeaderSortState();
30188 layout : function(){
30189 if(!this.mainBody){
30192 var c = g.getGridEl(), cm = this.cm,
30193 expandCol = g.autoExpandColumn,
30196 var csize = c.getSize(true);
30197 var vw = csize.width;
30199 if(vw < 20 || csize.height < 20){ return;
30203 this.scroller.dom.style.overflow = 'visible';
30205 this.el.setSize(csize.width, csize.height);
30207 var hdHeight = this.mainHd.getHeight();
30208 var vh = csize.height - (hdHeight);
30210 this.scroller.setSize(vw, vh);
30212 this.innerHd.style.width = (vw)+'px';
30216 if(this.lastViewWidth != vw){
30217 this.fitColumns(false, false);
30218 this.lastViewWidth = vw;
30222 this.syncHeaderScroll();
30224 this.onLayout(vw, vh);
30227 onLayout : function(vw, vh){
30230 onColumnWidthUpdated : function(col, w, tw){
30233 onAllColumnWidthsUpdated : function(ws, tw){
30236 onColumnHiddenUpdated : function(col, hidden, tw){
30239 updateColumnText : function(col, text){
30242 afterMove : function(colIndex){
30246 init: function(grid){
30249 this.initTemplates();
30250 this.initData(grid.store, grid.colModel);
30254 getColumnId : function(index){
30255 return this.cm.getColumnId(index);
30258 renderHeaders : function(){
30259 var cm = this.cm, ts = this.templates;
30262 var cb = [], sb = [], p = {};
30264 for(var i = 0, len = cm.getColumnCount(); i < len; i++){
30265 p.id = cm.getColumnId(i);
30266 p.value = cm.getColumnHeader(i) || "";
30267 p.style = this.getColumnStyle(i, true);
30268 p.tooltip = this.getColumnTooltip(i);
30269 if(cm.config[i].align == 'right'){
30270 p.istyle = 'padding-right:16px';
30274 cb[cb.length] = ct.apply(p);
30276 return ts.header.apply({cells: cb.join(""), tstyle:'width:'+this.getTotalWidth()+';'});
30279 getColumnTooltip : function(i){
30280 var tt = this.cm.getColumnTooltip(i);
30282 if(Ext.QuickTips.isEnabled()){
30283 return 'ext:qtip="'+tt+'"';
30285 return 'title="'+tt+'"';
30291 beforeUpdate : function(){
30292 this.grid.stopEditing(true);
30295 updateHeaders : function(){
30296 this.innerHd.firstChild.innerHTML = this.renderHeaders();
30300 focusRow : function(row){
30301 this.focusCell(row, 0, false);
30305 focusCell : function(row, col, hscroll){
30306 var xy = this.ensureVisible(row, col, hscroll);
30307 this.focusEl.setXY(xy);
30309 this.focusEl.focus();
30311 this.focusEl.focus.defer(1, this.focusEl);
30315 ensureVisible : function(row, col, hscroll){
30316 if(typeof row != "number"){
30317 row = row.rowIndex;
30322 if(row < 0 || row >= this.ds.getCount()){
30325 col = (col !== undefined ? col : 0);
30327 var rowEl = this.getRow(row), cellEl;
30328 if(!(hscroll === false && col === 0)){
30329 while(this.cm.isHidden(col)){
30332 cellEl = this.getCell(row, col);
30338 var c = this.scroller.dom;
30341 var p = rowEl, stop = this.el.dom;
30342 while(p && p != stop){
30343 ctop += p.offsetTop;
30344 p = p.offsetParent;
30346 ctop -= this.mainHd.dom.offsetHeight;
30348 var cbot = ctop + rowEl.offsetHeight;
30350 var ch = c.clientHeight;
30351 var stop = parseInt(c.scrollTop, 10);
30352 var sbot = stop + ch;
30355 c.scrollTop = ctop;
30356 }else if(cbot > sbot){
30357 c.scrollTop = cbot-ch;
30360 if(hscroll !== false){
30361 var cleft = parseInt(cellEl.offsetLeft, 10);
30362 var cright = cleft + cellEl.offsetWidth;
30364 var sleft = parseInt(c.scrollLeft, 10);
30365 var sright = sleft + c.clientWidth;
30367 c.scrollLeft = cleft;
30368 }else if(cright > sright){
30369 c.scrollLeft = cright-c.clientWidth;
30372 return cellEl ? Ext.fly(cellEl).getXY() : [c.scrollLeft, Ext.fly(rowEl).getY()];
30375 insertRows : function(dm, firstRow, lastRow, isUpdate){
30376 if(!isUpdate && firstRow === 0 && lastRow == dm.getCount()-1){
30380 this.fireEvent("beforerowsinserted", this, firstRow, lastRow);
30382 var html = this.renderRows(firstRow, lastRow);
30383 var before = this.getRow(firstRow);
30385 Ext.DomHelper.insertHtml('beforeBegin', before, html);
30387 Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html);
30390 this.fireEvent("rowsinserted", this, firstRow, lastRow);
30391 this.processRows(firstRow);
30396 deleteRows : function(dm, firstRow, lastRow){
30397 if(dm.getRowCount()<1){
30400 this.fireEvent("beforerowsdeleted", this, firstRow, lastRow);
30402 this.removeRows(firstRow, lastRow);
30404 this.processRows(firstRow);
30405 this.fireEvent("rowsdeleted", this, firstRow, lastRow);
30409 getColumnStyle : function(col, isHeader){
30410 var style = !isHeader ? (this.cm.config[col].css || '') : '';
30411 style += 'width:'+this.getColumnWidth(col)+';';
30412 if(this.cm.isHidden(col)){
30413 style += 'display:none;';
30415 var align = this.cm.config[col].align;
30417 style += 'text-align:'+align+';';
30422 getColumnWidth : function(col){
30423 var w = this.cm.getColumnWidth(col);
30424 if(typeof w == 'number'){
30425 return (Ext.isBorderBox ? w : (w-this.borderWidth > 0 ? w-this.borderWidth:0)) + 'px';
30430 getTotalWidth : function(){
30431 return this.cm.getTotalWidth()+'px';
30434 fitColumns : function(preventRefresh, onlyExpand, omitColumn){
30435 var cm = this.cm, leftOver, dist, i;
30436 var tw = cm.getTotalWidth(false);
30437 var aw = this.grid.getGridEl().getWidth(true)-this.scrollOffset;
30439 if(aw < 20){ return;
30441 var extra = aw - tw;
30447 var vc = cm.getColumnCount(true);
30448 var ac = vc-(typeof omitColumn == 'number' ? 1 : 0);
30451 omitColumn = undefined;
30453 var colCount = cm.getColumnCount();
30458 for (i = 0; i < colCount; i++){
30459 if(!cm.isHidden(i) && !cm.isFixed(i) && i !== omitColumn){
30460 w = cm.getColumnWidth(i);
30467 var frac = (aw - cm.getTotalWidth())/width;
30468 while (cols.length){
30471 cm.setColumnWidth(i, Math.max(this.grid.minColumnWidth, Math.floor(w + w*frac)), true);
30474 if((tw = cm.getTotalWidth(false)) > aw){
30475 var adjustCol = ac != vc ? omitColumn : extraCol;
30476 cm.setColumnWidth(adjustCol, Math.max(1,
30477 cm.getColumnWidth(adjustCol)- (tw-aw)), true);
30480 if(preventRefresh !== true){
30481 this.updateAllColumnWidths();
30488 autoExpand : function(preventUpdate){
30489 var g = this.grid, cm = this.cm;
30490 if(!this.userResized && g.autoExpandColumn){
30491 var tw = cm.getTotalWidth(false);
30492 var aw = this.grid.getGridEl().getWidth(true)-this.scrollOffset;
30494 var ci = cm.getIndexById(g.autoExpandColumn);
30495 var currentWidth = cm.getColumnWidth(ci);
30496 var cw = Math.min(Math.max(((aw-tw)+currentWidth), g.autoExpandMin), g.autoExpandMax);
30497 if(cw != currentWidth){
30498 cm.setColumnWidth(ci, cw, true);
30499 if(preventUpdate !== true){
30500 this.updateColumnWidth(ci, cw);
30507 getColumnData : function(){
30508 var cs = [], cm = this.cm, colCount = cm.getColumnCount();
30509 for(var i = 0; i < colCount; i++){
30510 var name = cm.getDataIndex(i);
30512 name : (typeof name == 'undefined' ? this.ds.fields.get(i).name : name),
30513 renderer : cm.getRenderer(i),
30514 id : cm.getColumnId(i),
30515 style : this.getColumnStyle(i)
30521 renderRows : function(startRow, endRow){
30522 var g = this.grid, cm = g.colModel, ds = g.store, stripe = g.stripeRows;
30523 var colCount = cm.getColumnCount();
30525 if(ds.getCount() < 1){
30529 var cs = this.getColumnData();
30531 startRow = startRow || 0;
30532 endRow = typeof endRow == "undefined"? ds.getCount()-1 : endRow;
30534 var rs = ds.getRange(startRow, endRow);
30536 return this.doRender(cs, rs, ds, startRow, colCount, stripe);
30539 renderBody : function(){
30540 var markup = this.renderRows();
30541 return this.templates.body.apply({rows: markup});
30544 refreshRow : function(record){
30545 var ds = this.ds, index;
30546 if(typeof record == 'number'){
30548 record = ds.getAt(index);
30550 index = ds.indexOf(record);
30553 this.insertRows(ds, index, index, true);
30554 this.getRow(index).rowIndex = index;
30555 this.onRemove(ds, record, index+1, true);
30556 this.fireEvent("rowupdated", this, index, record);
30560 refresh : function(headersToo){
30561 this.fireEvent("beforerefresh", this);
30562 this.grid.stopEditing(true);
30564 var result = this.renderBody();
30565 this.mainBody.update(result);
30567 if(headersToo === true){
30568 this.updateHeaders();
30569 this.updateHeaderSortState();
30571 this.processRows(0, true);
30573 this.applyEmptyText();
30574 this.fireEvent("refresh", this);
30577 applyEmptyText : function(){
30578 if(this.emptyText && !this.hasRows()){
30579 this.mainBody.update('<div class="x-grid-empty">' + this.emptyText + '</div>');
30583 updateHeaderSortState : function(){
30584 var state = this.ds.getSortState();
30588 if(!this.sortState || (this.sortState.field != state.field || this.sortState.direction != state.direction)){
30589 this.grid.fireEvent('sortchange', this.grid, state);
30591 this.sortState = state;
30592 var sortColumn = this.cm.findColumnIndex(state.field);
30593 if(sortColumn != -1){
30594 var sortDir = state.direction;
30595 this.updateSortIcon(sortColumn, sortDir);
30599 destroy : function(){
30601 this.colMenu.removeAll();
30602 Ext.menu.MenuMgr.unregister(this.colMenu);
30603 this.colMenu.getEl().remove();
30604 delete this.colMenu;
30607 this.hmenu.removeAll();
30608 Ext.menu.MenuMgr.unregister(this.hmenu);
30609 this.hmenu.getEl().remove();
30612 if(this.grid.enableColumnMove){
30613 var dds = Ext.dd.DDM.ids['gridHeader' + this.grid.getGridEl().id];
30615 for(var dd in dds){
30616 if(!dds[dd].config.isTarget && dds[dd].dragElId){
30617 var elid = dds[dd].dragElId;
30619 Ext.get(elid).remove();
30620 } else if(dds[dd].config.isTarget){
30621 dds[dd].proxyTop.remove();
30622 dds[dd].proxyBottom.remove();
30625 if(Ext.dd.DDM.locationCache[dd]){
30626 delete Ext.dd.DDM.locationCache[dd];
30629 delete Ext.dd.DDM.ids['gridHeader' + this.grid.getGridEl().id];
30633 Ext.destroy(this.resizeMarker, this.resizeProxy);
30635 this.initData(null, null);
30636 Ext.EventManager.removeResizeListener(this.onWindowResize, this);
30639 onDenyColumnHide : function(){
30643 render : function(){
30646 var colCount = cm.getColumnCount();
30649 this.fitColumns(true, true);
30650 }else if(this.forceFit){
30651 this.fitColumns(true, false);
30652 }else if(this.grid.autoExpandColumn){
30653 this.autoExpand(true);
30660 initData : function(ds, cm){
30662 this.ds.un("load", this.onLoad, this);
30663 this.ds.un("datachanged", this.onDataChange, this);
30664 this.ds.un("add", this.onAdd, this);
30665 this.ds.un("remove", this.onRemove, this);
30666 this.ds.un("update", this.onUpdate, this);
30667 this.ds.un("clear", this.onClear, this);
30670 ds.on("load", this.onLoad, this);
30671 ds.on("datachanged", this.onDataChange, this);
30672 ds.on("add", this.onAdd, this);
30673 ds.on("remove", this.onRemove, this);
30674 ds.on("update", this.onUpdate, this);
30675 ds.on("clear", this.onClear, this);
30680 this.cm.un("configchange", this.onColConfigChange, this);
30681 this.cm.un("widthchange", this.onColWidthChange, this);
30682 this.cm.un("headerchange", this.onHeaderChange, this);
30683 this.cm.un("hiddenchange", this.onHiddenChange, this);
30684 this.cm.un("columnmoved", this.onColumnMove, this);
30685 this.cm.un("columnlockchange", this.onColumnLock, this);
30688 cm.on("configchange", this.onColConfigChange, this);
30689 cm.on("widthchange", this.onColWidthChange, this);
30690 cm.on("headerchange", this.onHeaderChange, this);
30691 cm.on("hiddenchange", this.onHiddenChange, this);
30692 cm.on("columnmoved", this.onColumnMove, this);
30693 cm.on("columnlockchange", this.onColumnLock, this);
30698 onDataChange : function(){
30700 this.updateHeaderSortState();
30703 onClear : function(){
30707 onUpdate : function(ds, record){
30708 this.refreshRow(record);
30711 onAdd : function(ds, records, index){
30712 this.insertRows(ds, index, index + (records.length-1));
30715 onRemove : function(ds, record, index, isUpdate){
30716 if(isUpdate !== true){
30717 this.fireEvent("beforerowremoved", this, index, record);
30719 this.removeRow(index);
30720 if(isUpdate !== true){
30721 this.processRows(index);
30722 this.applyEmptyText();
30723 this.fireEvent("rowremoved", this, index, record);
30727 onLoad : function(){
30728 this.scrollToTop();
30731 onColWidthChange : function(cm, col, width){
30732 this.updateColumnWidth(col, width);
30735 onHeaderChange : function(cm, col, text){
30736 this.updateHeaders();
30739 onHiddenChange : function(cm, col, hidden){
30740 this.updateColumnHidden(col, hidden);
30743 onColumnMove : function(cm, oldIndex, newIndex){
30744 this.indexMap = null;
30745 var s = this.getScrollState();
30746 this.refresh(true);
30747 this.restoreScroll(s);
30748 this.afterMove(newIndex);
30751 onColConfigChange : function(){
30752 delete this.lastViewWidth;
30753 this.indexMap = null;
30754 this.refresh(true);
30758 initUI : function(grid){
30759 grid.on("headerclick", this.onHeaderClick, this);
30761 if(grid.trackMouseOver){
30762 grid.on("mouseover", this.onRowOver, this);
30763 grid.on("mouseout", this.onRowOut, this);
30767 initEvents : function(){
30771 onHeaderClick : function(g, index){
30772 if(this.headersDisabled || !this.cm.isSortable(index)){
30775 g.stopEditing(true);
30776 g.store.sort(this.cm.getDataIndex(index));
30779 onRowOver : function(e, t){
30781 if((row = this.findRowIndex(t)) !== false){
30782 this.addRowClass(row, "x-grid3-row-over");
30786 onRowOut : function(e, t){
30788 if((row = this.findRowIndex(t)) !== false && row !== this.findRowIndex(e.getRelatedTarget())){
30789 this.removeRowClass(row, "x-grid3-row-over");
30793 handleWheel : function(e){
30794 e.stopPropagation();
30797 onRowSelect : function(row){
30798 this.addRowClass(row, "x-grid3-row-selected");
30801 onRowDeselect : function(row){
30802 this.removeRowClass(row, "x-grid3-row-selected");
30805 onCellSelect : function(row, col){
30806 var cell = this.getCell(row, col);
30808 this.fly(cell).addClass("x-grid3-cell-selected");
30812 onCellDeselect : function(row, col){
30813 var cell = this.getCell(row, col);
30815 this.fly(cell).removeClass("x-grid3-cell-selected");
30819 onColumnSplitterMoved : function(i, w){
30820 this.userResized = true;
30821 var cm = this.grid.colModel;
30822 cm.setColumnWidth(i, w, true);
30825 this.fitColumns(true, false, i);
30826 this.updateAllColumnWidths();
30828 this.updateColumnWidth(i, w);
30831 this.grid.fireEvent("columnresize", i, w);
30834 handleHdMenuClick : function(item){
30835 var index = this.hdCtxIndex;
30836 var cm = this.cm, ds = this.ds;
30839 ds.sort(cm.getDataIndex(index), "ASC");
30842 ds.sort(cm.getDataIndex(index), "DESC");
30845 index = cm.getIndexById(item.id.substr(4));
30847 if(item.checked && cm.getColumnsBy(this.isHideableColumn, this).length <= 1){
30848 this.onDenyColumnHide();
30851 cm.setHidden(index, item.checked);
30857 isHideableColumn : function(c){
30858 return !c.hidden && !c.fixed;
30861 beforeColMenuShow : function(){
30862 var cm = this.cm, colCount = cm.getColumnCount();
30863 this.colMenu.removeAll();
30864 for(var i = 0; i < colCount; i++){
30865 if(cm.config[i].fixed !== true && cm.config[i].hideable !== false){
30866 this.colMenu.add(new Ext.menu.CheckItem({
30867 id: "col-"+cm.getColumnId(i),
30868 text: cm.getColumnHeader(i),
30869 checked: !cm.isHidden(i),
30871 disabled: cm.config[i].hideable === false
30877 handleHdDown : function(e, t){
30878 if(Ext.fly(t).hasClass('x-grid3-hd-btn')){
30880 var hd = this.findHeaderCell(t);
30881 Ext.fly(hd).addClass('x-grid3-hd-menu-open');
30882 var index = this.getCellIndex(hd);
30883 this.hdCtxIndex = index;
30884 var ms = this.hmenu.items, cm = this.cm;
30885 ms.get("asc").setDisabled(!cm.isSortable(index));
30886 ms.get("desc").setDisabled(!cm.isSortable(index));
30887 this.hmenu.on("hide", function(){
30888 Ext.fly(hd).removeClass('x-grid3-hd-menu-open');
30889 }, this, {single:true});
30890 this.hmenu.show(t, "tl-bl?");
30894 handleHdOver : function(e, t){
30895 var hd = this.findHeaderCell(t);
30896 if(hd && !this.headersDisabled){
30897 this.activeHd = hd;
30898 this.activeHdIndex = this.getCellIndex(hd);
30899 var fly = this.fly(hd);
30900 this.activeHdRegion = fly.getRegion();
30901 if(!this.cm.isMenuDisabled(this.activeHdIndex)){
30902 fly.addClass("x-grid3-hd-over");
30903 this.activeHdBtn = fly.child('.x-grid3-hd-btn');
30904 if(this.activeHdBtn){
30905 this.activeHdBtn.dom.style.height = (hd.firstChild.offsetHeight-1)+'px';
30911 handleHdMove : function(e, t){
30912 if(this.activeHd && !this.headersDisabled){
30913 var hw = this.splitHandleWidth || 5;
30914 var r = this.activeHdRegion;
30915 var x = e.getPageX();
30916 var ss = this.activeHd.style;
30917 if(x - r.left <= hw && this.cm.isResizable(this.activeHdIndex-1)){
30918 ss.cursor = Ext.isAir ? 'move' : Ext.isSafari ? 'e-resize' : 'col-resize'; }else if(r.right - x <= (!this.activeHdBtn ? hw : 2) && this.cm.isResizable(this.activeHdIndex)){
30919 ss.cursor = Ext.isAir ? 'move' : Ext.isSafari ? 'w-resize' : 'col-resize';
30926 handleHdOut : function(e, t){
30927 var hd = this.findHeaderCell(t);
30928 if(hd && (!Ext.isIE || !e.within(hd, true))){
30929 this.activeHd = null;
30930 this.fly(hd).removeClass("x-grid3-hd-over");
30931 hd.style.cursor = '';
30935 hasRows : function(){
30936 var fc = this.mainBody.dom.firstChild;
30937 return fc && fc.className != 'x-grid-empty';
30940 bind : function(d, c){
30941 this.initData(d, c);
30946 Ext.grid.GridView.SplitDragZone = function(grid, hd){
30948 this.view = grid.getView();
30949 this.marker = this.view.resizeMarker;
30950 this.proxy = this.view.resizeProxy;
30951 Ext.grid.GridView.SplitDragZone.superclass.constructor.call(this, hd,
30952 "gridSplitters" + this.grid.getGridEl().id, {
30953 dragElId : Ext.id(this.proxy.dom), resizeFrame:false
30955 this.scroll = false;
30956 this.hw = this.view.splitHandleWidth || 5;
30958 Ext.extend(Ext.grid.GridView.SplitDragZone, Ext.dd.DDProxy, {
30960 b4StartDrag : function(x, y){
30961 this.view.headersDisabled = true;
30962 var h = this.view.mainWrap.getHeight();
30963 this.marker.setHeight(h);
30964 this.marker.show();
30965 this.marker.alignTo(this.view.getHeaderCell(this.cellIndex), 'tl-tl', [-2, 0]);
30966 this.proxy.setHeight(h);
30967 var w = this.cm.getColumnWidth(this.cellIndex);
30968 var minw = Math.max(w-this.grid.minColumnWidth, 0);
30969 this.resetConstraints();
30970 this.setXConstraint(minw, 1000);
30971 this.setYConstraint(0, 0);
30972 this.minX = x - minw;
30973 this.maxX = x + 1000;
30975 Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
30979 handleMouseDown : function(e){
30980 var t = this.view.findHeaderCell(e.getTarget());
30982 var xy = this.view.fly(t).getXY(), x = xy[0], y = xy[1];
30983 var exy = e.getXY(), ex = exy[0], ey = exy[1];
30984 var w = t.offsetWidth, adjust = false;
30985 if((ex - x) <= this.hw){
30987 }else if((x+w) - ex <= this.hw){
30990 if(adjust !== false){
30991 this.cm = this.grid.colModel;
30992 var ci = this.view.getCellIndex(t);
30994 if (ci + adjust < 0) {
30997 while(this.cm.isHidden(ci+adjust)){
31004 this.cellIndex = ci+adjust;
31005 this.split = t.dom;
31006 if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
31007 Ext.grid.GridView.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
31009 }else if(this.view.columnDrag){
31010 this.view.columnDrag.callHandleMouseDown(e);
31015 endDrag : function(e){
31016 this.marker.hide();
31018 var endX = Math.max(this.minX, e.getPageX());
31019 var diff = endX - this.startPos;
31020 v.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
31021 setTimeout(function(){
31022 v.headersDisabled = false;
31026 autoOffset : function(){
31027 this.setDelta(0,0);
31032 Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
31034 hideGroupedColumn:false,
31036 showGroupName:true,
31038 startCollapsed:false,
31040 enableGrouping:true,
31042 enableGroupingMenu:true,
31044 enableNoGroups:true,
31046 emptyGroupText : '(None)',
31050 groupTextTpl : '{text}',
31058 initTemplates : function(){
31059 Ext.grid.GroupingView.superclass.initTemplates.call(this);
31062 var sm = this.grid.getSelectionModel();
31063 sm.on(sm.selectRow ? 'beforerowselect' : 'beforecellselect',
31064 this.onBeforeRowSelect, this);
31066 if(!this.startGroup){
31067 this.startGroup = new Ext.XTemplate(
31068 '<div id="{groupId}" class="x-grid-group {cls}">',
31069 '<div id="{groupId}-hd" class="x-grid-group-hd" style="{style}"><div>', this.groupTextTpl ,'</div></div>',
31070 '<div id="{groupId}-bd" class="x-grid-group-body">'
31073 this.startGroup.compile();
31074 this.endGroup = '</div></div>';
31078 findGroup : function(el){
31079 return Ext.fly(el).up('.x-grid-group', this.mainBody.dom);
31083 getGroups : function(){
31084 return this.hasRows() ? this.mainBody.dom.childNodes : [];
31088 onAdd : function(){
31089 if(this.enableGrouping && !this.ignoreAdd){
31090 var ss = this.getScrollState();
31092 this.restoreScroll(ss);
31093 }else if(!this.enableGrouping){
31094 Ext.grid.GroupingView.superclass.onAdd.apply(this, arguments);
31099 onRemove : function(ds, record, index, isUpdate){
31100 Ext.grid.GroupingView.superclass.onRemove.apply(this, arguments);
31101 var g = document.getElementById(record._groupId);
31102 if(g && g.childNodes[1].childNodes.length < 1){
31105 this.applyEmptyText();
31109 refreshRow : function(record){
31110 if(this.ds.getCount()==1){
31113 this.isUpdating = true;
31114 Ext.grid.GroupingView.superclass.refreshRow.apply(this, arguments);
31115 this.isUpdating = false;
31120 beforeMenuShow : function(){
31121 var field = this.getGroupField();
31122 var g = this.hmenu.items.get('groupBy');
31124 g.setDisabled(this.cm.config[this.hdCtxIndex].groupable === false);
31126 var s = this.hmenu.items.get('showGroups');
31129 s.setDisabled(this.cm.config[this.hdCtxIndex].groupable === false)
31131 s.setChecked(!!field);
31136 renderUI : function(){
31137 Ext.grid.GroupingView.superclass.renderUI.call(this);
31138 this.mainBody.on('mousedown', this.interceptMouse, this);
31140 if(this.enableGroupingMenu && this.hmenu){
31141 this.hmenu.add('-',{
31143 text: this.groupByText,
31144 handler: this.onGroupByClick,
31146 iconCls:'x-group-by-icon'
31148 if(this.enableNoGroups){
31151 text: this.showGroupsText,
31153 checkHandler: this.onShowGroupsClick,
31157 this.hmenu.on('beforeshow', this.beforeMenuShow, this);
31162 onGroupByClick : function(){
31163 this.grid.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex));
31164 this.beforeMenuShow();
31168 onShowGroupsClick : function(mi, checked){
31170 this.onGroupByClick();
31172 this.grid.store.clearGrouping();
31177 toggleGroup : function(group, expanded){
31178 this.grid.stopEditing(true);
31179 group = Ext.getDom(group);
31180 var gel = Ext.fly(group);
31181 expanded = expanded !== undefined ?
31182 expanded : gel.hasClass('x-grid-group-collapsed');
31184 this.state[gel.dom.id] = expanded;
31185 gel[expanded ? 'removeClass' : 'addClass']('x-grid-group-collapsed');
31189 toggleAllGroups : function(expanded){
31190 var groups = this.getGroups();
31191 for(var i = 0, len = groups.length; i < len; i++){
31192 this.toggleGroup(groups[i], expanded);
31197 expandAllGroups : function(){
31198 this.toggleAllGroups(true);
31202 collapseAllGroups : function(){
31203 this.toggleAllGroups(false);
31207 interceptMouse : function(e){
31208 var hd = e.getTarget('.x-grid-group-hd', this.mainBody);
31211 this.toggleGroup(hd.parentNode);
31216 getGroup : function(v, r, groupRenderer, rowIndex, colIndex, ds){
31217 var g = groupRenderer ? groupRenderer(v, {}, r, rowIndex, colIndex, ds) : String(v);
31219 g = this.cm.config[colIndex].emptyGroupText || this.emptyGroupText;
31225 getGroupField : function(){
31226 return this.grid.store.getGroupState();
31230 renderRows : function(){
31231 var groupField = this.getGroupField();
31232 var eg = !!groupField;
31234 if(this.hideGroupedColumn) {
31235 var colIndex = this.cm.findColumnIndex(groupField);
31236 if(!eg && this.lastGroupField !== undefined) {
31237 this.mainBody.update('');
31238 this.cm.setHidden(this.cm.findColumnIndex(this.lastGroupField), false);
31239 delete this.lastGroupField;
31240 }else if (eg && this.lastGroupField === undefined) {
31241 this.lastGroupField = groupField;
31242 this.cm.setHidden(colIndex, true);
31243 }else if (eg && this.lastGroupField !== undefined && groupField !== this.lastGroupField) {
31244 this.mainBody.update('');
31245 var oldIndex = this.cm.findColumnIndex(this.lastGroupField);
31246 this.cm.setHidden(oldIndex, false);
31247 this.lastGroupField = groupField;
31248 this.cm.setHidden(colIndex, true);
31251 return Ext.grid.GroupingView.superclass.renderRows.apply(
31256 doRender : function(cs, rs, ds, startRow, colCount, stripe){
31260 var groupField = this.getGroupField();
31261 var colIndex = this.cm.findColumnIndex(groupField);
31263 this.enableGrouping = !!groupField;
31265 if(!this.enableGrouping || this.isUpdating){
31266 return Ext.grid.GroupingView.superclass.doRender.apply(
31269 var gstyle = 'width:'+this.getTotalWidth()+';';
31271 var gidPrefix = this.grid.getGridEl().id;
31272 var cfg = this.cm.config[colIndex];
31273 var groupRenderer = cfg.groupRenderer || cfg.renderer;
31274 var prefix = this.showGroupName ?
31275 (cfg.groupName || cfg.header)+': ' : '';
31277 var groups = [], curGroup, i, len, gid;
31278 for(i = 0, len = rs.length; i < len; i++){
31279 var rowIndex = startRow + i;
31281 gvalue = r.data[groupField],
31282 g = this.getGroup(gvalue, r, groupRenderer, rowIndex, colIndex, ds);
31283 if(!curGroup || curGroup.group != g){
31284 gid = gidPrefix + '-gp-' + groupField + '-' + Ext.util.Format.htmlEncode(g);
31287 var isCollapsed = typeof this.state[gid] !== 'undefined' ? !this.state[gid] : this.startCollapsed;
31288 var gcls = isCollapsed ? 'x-grid-group-collapsed' : '';
31294 startRow: rowIndex,
31299 groups.push(curGroup);
31301 curGroup.rs.push(r);
31307 for(i = 0, len = groups.length; i < len; i++){
31309 this.doGroupStart(buf, g, cs, ds, colCount);
31310 buf[buf.length] = Ext.grid.GroupingView.superclass.doRender.call(
31311 this, cs, g.rs, ds, g.startRow, colCount, stripe);
31313 this.doGroupEnd(buf, g, cs, ds, colCount);
31315 return buf.join('');
31319 getGroupId : function(value){
31320 var gidPrefix = this.grid.getGridEl().id;
31321 var groupField = this.getGroupField();
31322 var colIndex = this.cm.findColumnIndex(groupField);
31323 var cfg = this.cm.config[colIndex];
31324 var groupRenderer = cfg.groupRenderer || cfg.renderer;
31325 var gtext = this.getGroup(value, {data:{}}, groupRenderer, 0, colIndex, this.ds);
31326 return gidPrefix + '-gp-' + groupField + '-' + Ext.util.Format.htmlEncode(value);
31330 doGroupStart : function(buf, g, cs, ds, colCount){
31331 buf[buf.length] = this.startGroup.apply(g);
31335 doGroupEnd : function(buf, g, cs, ds, colCount){
31336 buf[buf.length] = this.endGroup;
31340 getRows : function(){
31341 if(!this.enableGrouping){
31342 return Ext.grid.GroupingView.superclass.getRows.call(this);
31345 var g, gs = this.getGroups();
31346 for(var i = 0, len = gs.length; i < len; i++){
31347 g = gs[i].childNodes[1].childNodes;
31348 for(var j = 0, jlen = g.length; j < jlen; j++){
31349 r[r.length] = g[j];
31356 updateGroupWidths : function(){
31357 if(!this.enableGrouping || !this.hasRows()){
31360 var tw = Math.max(this.cm.getTotalWidth(), this.el.dom.offsetWidth-this.scrollOffset) +'px';
31361 var gs = this.getGroups();
31362 for(var i = 0, len = gs.length; i < len; i++){
31363 gs[i].firstChild.style.width = tw;
31368 onColumnWidthUpdated : function(col, w, tw){
31369 this.updateGroupWidths();
31373 onAllColumnWidthsUpdated : function(ws, tw){
31374 this.updateGroupWidths();
31378 onColumnHiddenUpdated : function(col, hidden, tw){
31379 this.updateGroupWidths();
31383 onLayout : function(){
31384 this.updateGroupWidths();
31388 onBeforeRowSelect : function(sm, rowIndex){
31389 if(!this.enableGrouping){
31392 var row = this.getRow(rowIndex);
31393 if(row && !row.offsetParent){
31394 var g = this.findGroup(row);
31395 this.toggleGroup(g, true);
31400 groupByText: 'Group By This Field',
31402 showGroupsText: 'Show in Groups'
31405 Ext.grid.GroupingView.GROUP_ID = 1000;
31408 Ext.grid.HeaderDragZone = function(grid, hd, hd2){
31410 this.view = grid.getView();
31411 this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
31412 Ext.grid.HeaderDragZone.superclass.constructor.call(this, hd);
31414 this.setHandleElId(Ext.id(hd));
31415 this.setOuterHandleElId(Ext.id(hd2));
31417 this.scroll = false;
31419 Ext.extend(Ext.grid.HeaderDragZone, Ext.dd.DragZone, {
31421 getDragData : function(e){
31422 var t = Ext.lib.Event.getTarget(e);
31423 var h = this.view.findHeaderCell(t);
31425 return {ddel: h.firstChild, header:h};
31430 onInitDrag : function(e){
31431 this.view.headersDisabled = true;
31432 var clone = this.dragData.ddel.cloneNode(true);
31433 clone.id = Ext.id();
31434 clone.style.width = Math.min(this.dragData.header.offsetWidth,this.maxDragWidth) + "px";
31435 this.proxy.update(clone);
31439 afterValidDrop : function(){
31441 setTimeout(function(){
31442 v.headersDisabled = false;
31446 afterInvalidDrop : function(){
31448 setTimeout(function(){
31449 v.headersDisabled = false;
31456 Ext.grid.HeaderDropZone = function(grid, hd, hd2){
31458 this.view = grid.getView();
31460 this.proxyTop = Ext.DomHelper.append(document.body, {
31461 cls:"col-move-top", html:" "
31463 this.proxyBottom = Ext.DomHelper.append(document.body, {
31464 cls:"col-move-bottom", html:" "
31466 this.proxyTop.hide = this.proxyBottom.hide = function(){
31467 this.setLeftTop(-100,-100);
31468 this.setStyle("visibility", "hidden");
31470 this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
31473 Ext.grid.HeaderDropZone.superclass.constructor.call(this, grid.getGridEl().dom);
31475 Ext.extend(Ext.grid.HeaderDropZone, Ext.dd.DropZone, {
31476 proxyOffsets : [-4, -9],
31477 fly: Ext.Element.fly,
31479 getTargetFromEvent : function(e){
31480 var t = Ext.lib.Event.getTarget(e);
31481 var cindex = this.view.findCellIndex(t);
31482 if(cindex !== false){
31483 return this.view.getHeaderCell(cindex);
31487 nextVisible : function(h){
31488 var v = this.view, cm = this.grid.colModel;
31491 if(!cm.isHidden(v.getCellIndex(h))){
31499 prevVisible : function(h){
31500 var v = this.view, cm = this.grid.colModel;
31503 if(!cm.isHidden(v.getCellIndex(h))){
31511 positionIndicator : function(h, n, e){
31512 var x = Ext.lib.Event.getPageX(e);
31513 var r = Ext.lib.Dom.getRegion(n.firstChild);
31514 var px, pt, py = r.top + this.proxyOffsets[1];
31515 if((r.right - x) <= (r.right-r.left)/2){
31516 px = r.right+this.view.borderWidth;
31522 var oldIndex = this.view.getCellIndex(h);
31523 var newIndex = this.view.getCellIndex(n);
31525 if(this.grid.colModel.isFixed(newIndex)){
31529 var locked = this.grid.colModel.isLocked(newIndex);
31534 if(oldIndex < newIndex){
31537 if(oldIndex == newIndex && (locked == this.grid.colModel.isLocked(oldIndex))){
31540 px += this.proxyOffsets[0];
31541 this.proxyTop.setLeftTop(px, py);
31542 this.proxyTop.show();
31543 if(!this.bottomOffset){
31544 this.bottomOffset = this.view.mainHd.getHeight();
31546 this.proxyBottom.setLeftTop(px, py+this.proxyTop.dom.offsetHeight+this.bottomOffset);
31547 this.proxyBottom.show();
31551 onNodeEnter : function(n, dd, e, data){
31552 if(data.header != n){
31553 this.positionIndicator(data.header, n, e);
31557 onNodeOver : function(n, dd, e, data){
31558 var result = false;
31559 if(data.header != n){
31560 result = this.positionIndicator(data.header, n, e);
31563 this.proxyTop.hide();
31564 this.proxyBottom.hide();
31566 return result ? this.dropAllowed : this.dropNotAllowed;
31569 onNodeOut : function(n, dd, e, data){
31570 this.proxyTop.hide();
31571 this.proxyBottom.hide();
31574 onNodeDrop : function(n, dd, e, data){
31575 var h = data.header;
31577 var cm = this.grid.colModel;
31578 var x = Ext.lib.Event.getPageX(e);
31579 var r = Ext.lib.Dom.getRegion(n.firstChild);
31580 var pt = (r.right - x) <= ((r.right-r.left)/2) ? "after" : "before";
31581 var oldIndex = this.view.getCellIndex(h);
31582 var newIndex = this.view.getCellIndex(n);
31583 var locked = cm.isLocked(newIndex);
31587 if(oldIndex < newIndex){
31590 if(oldIndex == newIndex && (locked == cm.isLocked(oldIndex))){
31593 cm.setLocked(oldIndex, locked, true);
31594 cm.moveColumn(oldIndex, newIndex);
31595 this.grid.fireEvent("columnmove", oldIndex, newIndex);
31603 Ext.grid.GridView.ColumnDragZone = function(grid, hd){
31604 Ext.grid.GridView.ColumnDragZone.superclass.constructor.call(this, grid, hd, null);
31605 this.proxy.el.addClass('x-grid3-col-dd');
31608 Ext.extend(Ext.grid.GridView.ColumnDragZone, Ext.grid.HeaderDragZone, {
31609 handleMouseDown : function(e){
31613 callHandleMouseDown : function(e){
31614 Ext.grid.GridView.ColumnDragZone.superclass.handleMouseDown.call(this, e);
31617 Ext.grid.SplitDragZone = function(grid, hd, hd2){
31619 this.view = grid.getView();
31620 this.proxy = this.view.resizeProxy;
31621 Ext.grid.SplitDragZone.superclass.constructor.call(this, hd,
31622 "gridSplitters" + this.grid.getGridEl().id, {
31623 dragElId : Ext.id(this.proxy.dom), resizeFrame:false
31625 this.setHandleElId(Ext.id(hd));
31626 this.setOuterHandleElId(Ext.id(hd2));
31627 this.scroll = false;
31629 Ext.extend(Ext.grid.SplitDragZone, Ext.dd.DDProxy, {
31630 fly: Ext.Element.fly,
31632 b4StartDrag : function(x, y){
31633 this.view.headersDisabled = true;
31634 this.proxy.setHeight(this.view.mainWrap.getHeight());
31635 var w = this.cm.getColumnWidth(this.cellIndex);
31636 var minw = Math.max(w-this.grid.minColumnWidth, 0);
31637 this.resetConstraints();
31638 this.setXConstraint(minw, 1000);
31639 this.setYConstraint(0, 0);
31640 this.minX = x - minw;
31641 this.maxX = x + 1000;
31643 Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
31647 handleMouseDown : function(e){
31648 ev = Ext.EventObject.setEvent(e);
31649 var t = this.fly(ev.getTarget());
31650 if(t.hasClass("x-grid-split")){
31651 this.cellIndex = this.view.getCellIndex(t.dom);
31652 this.split = t.dom;
31653 this.cm = this.grid.colModel;
31654 if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
31655 Ext.grid.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
31660 endDrag : function(e){
31661 this.view.headersDisabled = false;
31662 var endX = Math.max(this.minX, Ext.lib.Event.getPageX(e));
31663 var diff = endX - this.startPos;
31664 this.view.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
31667 autoOffset : function(){
31668 this.setDelta(0,0);
31671 Ext.grid.GridDragZone = function(grid, config){
31672 this.view = grid.getView();
31673 Ext.grid.GridDragZone.superclass.constructor.call(this, this.view.mainBody.dom, config);
31674 if(this.view.lockedBody){
31675 this.setHandleElId(Ext.id(this.view.mainBody.dom));
31676 this.setOuterHandleElId(Ext.id(this.view.lockedBody.dom));
31678 this.scroll = false;
31680 this.ddel = document.createElement('div');
31681 this.ddel.className = 'x-grid-dd-wrap';
31684 Ext.extend(Ext.grid.GridDragZone, Ext.dd.DragZone, {
31685 ddGroup : "GridDD",
31687 getDragData : function(e){
31688 var t = Ext.lib.Event.getTarget(e);
31689 var rowIndex = this.view.findRowIndex(t);
31690 if(rowIndex !== false){
31691 var sm = this.grid.selModel;
31692 if(!sm.isSelected(rowIndex) || e.hasModifier()){
31693 sm.handleMouseDown(this.grid, rowIndex, e);
31695 return {grid: this.grid, ddel: this.ddel, rowIndex: rowIndex, selections:sm.getSelections()};
31700 onInitDrag : function(e){
31701 var data = this.dragData;
31702 this.ddel.innerHTML = this.grid.getDragDropText();
31703 this.proxy.update(this.ddel);
31706 afterRepair : function(){
31707 this.dragging = false;
31710 getRepairXY : function(e, data){
31714 onEndDrag : function(data, e){
31717 onValidDrop : function(dd, e, id){
31721 beforeInvalidDrop : function(e, id){
31727 Ext.grid.ColumnModel = function(config){
31729 this.defaultWidth = 100;
31732 this.defaultSortable = false;
31735 if(config.columns){
31736 Ext.apply(this, config);
31737 this.setConfig(config.columns, true);
31739 this.setConfig(config, true);
31751 "columnlockchange",
31755 Ext.grid.ColumnModel.superclass.constructor.call(this);
31757 Ext.extend(Ext.grid.ColumnModel, Ext.util.Observable, {
31775 getColumnId : function(index){
31776 return this.config[index].id;
31780 setConfig : function(config, initial){
31782 delete this.totalWidth;
31783 for(var i = 0, len = this.config.length; i < len; i++){
31784 var c = this.config[i];
31786 c.editor.destroy();
31790 this.config = config;
31793 for(var i = 0, len = config.length; i < len; i++){
31795 if(typeof c.renderer == "string"){
31796 c.renderer = Ext.util.Format[c.renderer];
31798 if(typeof c.id == "undefined"){
31801 if(c.editor && c.editor.isFormField){
31802 c.editor = new Ext.grid.GridEditor(c.editor);
31804 this.lookup[c.id] = c;
31807 this.fireEvent('configchange', this);
31812 getColumnById : function(id){
31813 return this.lookup[id];
31817 getIndexById : function(id){
31818 for(var i = 0, len = this.config.length; i < len; i++){
31819 if(this.config[i].id == id){
31827 moveColumn : function(oldIndex, newIndex){
31828 var c = this.config[oldIndex];
31829 this.config.splice(oldIndex, 1);
31830 this.config.splice(newIndex, 0, c);
31831 this.dataMap = null;
31832 this.fireEvent("columnmoved", this, oldIndex, newIndex);
31836 isLocked : function(colIndex){
31837 return this.config[colIndex].locked === true;
31841 setLocked : function(colIndex, value, suppressEvent){
31842 if(this.isLocked(colIndex) == value){
31845 this.config[colIndex].locked = value;
31846 if(!suppressEvent){
31847 this.fireEvent("columnlockchange", this, colIndex, value);
31852 getTotalLockedWidth : function(){
31853 var totalWidth = 0;
31854 for(var i = 0; i < this.config.length; i++){
31855 if(this.isLocked(i) && !this.isHidden(i)){
31856 this.totalWidth += this.getColumnWidth(i);
31863 getLockedCount : function(){
31864 for(var i = 0, len = this.config.length; i < len; i++){
31865 if(!this.isLocked(i)){
31872 getColumnCount : function(visibleOnly){
31873 if(visibleOnly === true){
31875 for(var i = 0, len = this.config.length; i < len; i++){
31876 if(!this.isHidden(i)){
31882 return this.config.length;
31886 getColumnsBy : function(fn, scope){
31888 for(var i = 0, len = this.config.length; i < len; i++){
31889 var c = this.config[i];
31890 if(fn.call(scope||this, c, i) === true){
31898 isSortable : function(col){
31899 if(typeof this.config[col].sortable == "undefined"){
31900 return this.defaultSortable;
31902 return this.config[col].sortable;
31906 isMenuDisabled : function(col){
31907 return !!this.config[col].menuDisabled;
31911 getRenderer : function(col){
31912 if(!this.config[col].renderer){
31913 return Ext.grid.ColumnModel.defaultRenderer;
31915 return this.config[col].renderer;
31919 setRenderer : function(col, fn){
31920 this.config[col].renderer = fn;
31924 getColumnWidth : function(col){
31925 return this.config[col].width || this.defaultWidth;
31929 setColumnWidth : function(col, width, suppressEvent){
31930 this.config[col].width = width;
31931 this.totalWidth = null;
31932 if(!suppressEvent){
31933 this.fireEvent("widthchange", this, col, width);
31938 getTotalWidth : function(includeHidden){
31939 if(!this.totalWidth){
31940 this.totalWidth = 0;
31941 for(var i = 0, len = this.config.length; i < len; i++){
31942 if(includeHidden || !this.isHidden(i)){
31943 this.totalWidth += this.getColumnWidth(i);
31947 return this.totalWidth;
31951 getColumnHeader : function(col){
31952 return this.config[col].header;
31956 setColumnHeader : function(col, header){
31957 this.config[col].header = header;
31958 this.fireEvent("headerchange", this, col, header);
31962 getColumnTooltip : function(col){
31963 return this.config[col].tooltip;
31966 setColumnTooltip : function(col, tooltip){
31967 this.config[col].tooltip = tooltip;
31971 getDataIndex : function(col){
31972 return this.config[col].dataIndex;
31976 setDataIndex : function(col, dataIndex){
31977 this.config[col].dataIndex = dataIndex;
31980 findColumnIndex : function(dataIndex){
31981 var c = this.config;
31982 for(var i = 0, len = c.length; i < len; i++){
31983 if(c[i].dataIndex == dataIndex){
31991 isCellEditable : function(colIndex, rowIndex){
31992 return (this.config[colIndex].editable || (typeof this.config[colIndex].editable == "undefined" && this.config[colIndex].editor)) ? true : false;
31996 getCellEditor : function(colIndex, rowIndex){
31997 return this.config[colIndex].editor;
32001 setEditable : function(col, editable){
32002 this.config[col].editable = editable;
32007 isHidden : function(colIndex){
32008 return this.config[colIndex].hidden;
32013 isFixed : function(colIndex){
32014 return this.config[colIndex].fixed;
32018 isResizable : function(colIndex){
32019 return colIndex >= 0 && this.config[colIndex].resizable !== false && this.config[colIndex].fixed !== true;
32022 setHidden : function(colIndex, hidden){
32023 var c = this.config[colIndex];
32024 if(c.hidden !== hidden){
32026 this.totalWidth = null;
32027 this.fireEvent("hiddenchange", this, colIndex, hidden);
32032 setEditor : function(col, editor){
32033 this.config[col].editor = editor;
32038 Ext.grid.ColumnModel.defaultRenderer = function(value){
32039 if(typeof value == "string" && value.length < 1){
32046 Ext.grid.DefaultColumnModel = Ext.grid.ColumnModel;
32049 Ext.grid.AbstractSelectionModel = function(){
32050 this.locked = false;
32051 Ext.grid.AbstractSelectionModel.superclass.constructor.call(this);
32054 Ext.extend(Ext.grid.AbstractSelectionModel, Ext.util.Observable, {
32056 init : function(grid){
32063 this.locked = true;
32067 unlock : function(){
32068 this.locked = false;
32072 isLocked : function(){
32073 return this.locked;
32077 Ext.grid.RowSelectionModel = function(config){
32078 Ext.apply(this, config);
32079 this.selections = new Ext.util.MixedCollection(false, function(o){
32084 this.lastActive = false;
32097 Ext.grid.RowSelectionModel.superclass.constructor.call(this);
32100 Ext.extend(Ext.grid.RowSelectionModel, Ext.grid.AbstractSelectionModel, {
32102 singleSelect : false,
32105 initEvents : function(){
32107 if(!this.grid.enableDragDrop && !this.grid.enableDrag){
32108 this.grid.on("rowmousedown", this.handleMouseDown, this);
32109 }else{ this.grid.on("rowclick", function(grid, rowIndex, e) {
32110 if(e.button === 0 && !e.shiftKey && !e.ctrlKey) {
32111 this.selectRow(rowIndex, false);
32112 grid.view.focusRow(rowIndex);
32117 this.rowNav = new Ext.KeyNav(this.grid.getGridEl(), {
32118 "up" : function(e){
32120 this.selectPrevious(e.shiftKey);
32121 }else if(this.last !== false && this.lastActive !== false){
32122 var last = this.last;
32123 this.selectRange(this.last, this.lastActive-1);
32124 this.grid.getView().focusRow(this.lastActive);
32125 if(last !== false){
32129 this.selectFirstRow();
32132 "down" : function(e){
32134 this.selectNext(e.shiftKey);
32135 }else if(this.last !== false && this.lastActive !== false){
32136 var last = this.last;
32137 this.selectRange(this.last, this.lastActive+1);
32138 this.grid.getView().focusRow(this.lastActive);
32139 if(last !== false){
32143 this.selectFirstRow();
32149 var view = this.grid.view;
32150 view.on("refresh", this.onRefresh, this);
32151 view.on("rowupdated", this.onRowUpdated, this);
32152 view.on("rowremoved", this.onRemove, this);
32155 onRefresh : function(){
32156 var ds = this.grid.store, index;
32157 var s = this.getSelections();
32158 this.clearSelections(true);
32159 for(var i = 0, len = s.length; i < len; i++){
32161 if((index = ds.indexOfId(r.id)) != -1){
32162 this.selectRow(index, true);
32165 if(s.length != this.selections.getCount()){
32166 this.fireEvent("selectionchange", this);
32170 onRemove : function(v, index, r){
32171 if(this.selections.remove(r) !== false){
32172 this.fireEvent('selectionchange', this);
32176 onRowUpdated : function(v, index, r){
32177 if(this.isSelected(r)){
32178 v.onRowSelect(index);
32183 selectRecords : function(records, keepExisting){
32185 this.clearSelections();
32187 var ds = this.grid.store;
32188 for(var i = 0, len = records.length; i < len; i++){
32189 this.selectRow(ds.indexOf(records[i]), true);
32194 getCount : function(){
32195 return this.selections.length;
32199 selectFirstRow : function(){
32204 selectLastRow : function(keepExisting){
32205 this.selectRow(this.grid.store.getCount() - 1, keepExisting);
32209 selectNext : function(keepExisting){
32210 if(this.hasNext()){
32211 this.selectRow(this.last+1, keepExisting);
32212 this.grid.getView().focusRow(this.last);
32219 selectPrevious : function(keepExisting){
32220 if(this.hasPrevious()){
32221 this.selectRow(this.last-1, keepExisting);
32222 this.grid.getView().focusRow(this.last);
32229 hasNext : function(){
32230 return this.last !== false && (this.last+1) < this.grid.store.getCount();
32234 hasPrevious : function(){
32235 return !!this.last;
32240 getSelections : function(){
32241 return [].concat(this.selections.items);
32245 getSelected : function(){
32246 return this.selections.itemAt(0);
32250 each : function(fn, scope){
32251 var s = this.getSelections();
32252 for(var i = 0, len = s.length; i < len; i++){
32253 if(fn.call(scope || this, s[i], i) === false){
32261 clearSelections : function(fast){
32262 if(this.locked) return;
32264 var ds = this.grid.store;
32265 var s = this.selections;
32266 s.each(function(r){
32267 this.deselectRow(ds.indexOfId(r.id));
32271 this.selections.clear();
32278 selectAll : function(){
32279 if(this.locked) return;
32280 this.selections.clear();
32281 for(var i = 0, len = this.grid.store.getCount(); i < len; i++){
32282 this.selectRow(i, true);
32287 hasSelection : function(){
32288 return this.selections.length > 0;
32292 isSelected : function(index){
32293 var r = typeof index == "number" ? this.grid.store.getAt(index) : index;
32294 return (r && this.selections.key(r.id) ? true : false);
32298 isIdSelected : function(id){
32299 return (this.selections.key(id) ? true : false);
32302 handleMouseDown : function(g, rowIndex, e){
32303 if(e.button !== 0 || this.isLocked()){
32306 var view = this.grid.getView();
32307 if(e.shiftKey && this.last !== false){
32308 var last = this.last;
32309 this.selectRange(last, rowIndex, e.ctrlKey);
32310 this.last = last; view.focusRow(rowIndex);
32312 var isSelected = this.isSelected(rowIndex);
32313 if(e.ctrlKey && isSelected){
32314 this.deselectRow(rowIndex);
32315 }else if(!isSelected || this.getCount() > 1){
32316 this.selectRow(rowIndex, e.ctrlKey || e.shiftKey);
32317 view.focusRow(rowIndex);
32323 selectRows : function(rows, keepExisting){
32325 this.clearSelections();
32327 for(var i = 0, len = rows.length; i < len; i++){
32328 this.selectRow(rows[i], true);
32333 selectRange : function(startRow, endRow, keepExisting){
32334 if(this.locked) return;
32336 this.clearSelections();
32338 if(startRow <= endRow){
32339 for(var i = startRow; i <= endRow; i++){
32340 this.selectRow(i, true);
32343 for(var i = startRow; i >= endRow; i--){
32344 this.selectRow(i, true);
32350 deselectRange : function(startRow, endRow, preventViewNotify){
32351 if(this.locked) return;
32352 for(var i = startRow; i <= endRow; i++){
32353 this.deselectRow(i, preventViewNotify);
32358 selectRow : function(index, keepExisting, preventViewNotify){
32359 if(this.locked || (index < 0 || index >= this.grid.store.getCount())) return;
32360 var r = this.grid.store.getAt(index);
32361 if(r && this.fireEvent("beforerowselect", this, index, keepExisting, r) !== false){
32362 if(!keepExisting || this.singleSelect){
32363 this.clearSelections();
32365 this.selections.add(r);
32366 this.last = this.lastActive = index;
32367 if(!preventViewNotify){
32368 this.grid.getView().onRowSelect(index);
32370 this.fireEvent("rowselect", this, index, r);
32371 this.fireEvent("selectionchange", this);
32376 deselectRow : function(index, preventViewNotify){
32377 if(this.locked) return;
32378 if(this.last == index){
32381 if(this.lastActive == index){
32382 this.lastActive = false;
32384 var r = this.grid.store.getAt(index);
32386 this.selections.remove(r);
32387 if(!preventViewNotify){
32388 this.grid.getView().onRowDeselect(index);
32390 this.fireEvent("rowdeselect", this, index, r);
32391 this.fireEvent("selectionchange", this);
32395 restoreLast : function(){
32397 this.last = this._last;
32401 acceptsNav : function(row, col, cm){
32402 return !cm.isHidden(col) && cm.isCellEditable(col, row);
32405 onEditorKey : function(field, e){
32406 var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor;
32407 var shift = e.shiftKey;
32412 newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
32414 newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
32416 }else if(k == e.ENTER){
32419 if(this.moveEditorOnEnter !== false){
32421 newCell = g.walkCells(ed.row - 1, ed.col, -1, this.acceptsNav, this);
32423 newCell = g.walkCells(ed.row + 1, ed.col, 1, this.acceptsNav, this);
32426 }else if(k == e.ESC){
32430 g.startEditing(newCell[0], newCell[1]);
32435 Ext.grid.CellSelectionModel = function(config){
32436 Ext.apply(this, config);
32438 this.selection = null;
32442 "beforecellselect",
32449 Ext.grid.CellSelectionModel.superclass.constructor.call(this);
32452 Ext.extend(Ext.grid.CellSelectionModel, Ext.grid.AbstractSelectionModel, {
32455 initEvents : function(){
32456 this.grid.on("cellmousedown", this.handleMouseDown, this);
32457 this.grid.getGridEl().on(Ext.isIE ? "keydown" : "keypress", this.handleKeyDown, this);
32458 var view = this.grid.view;
32459 view.on("refresh", this.onViewChange, this);
32460 view.on("rowupdated", this.onRowUpdated, this);
32461 view.on("beforerowremoved", this.clearSelections, this);
32462 view.on("beforerowsinserted", this.clearSelections, this);
32463 if(this.grid.isEditor){
32464 this.grid.on("beforeedit", this.beforeEdit, this);
32468 beforeEdit : function(e){
32469 this.select(e.row, e.column, false, true, e.record);
32472 onRowUpdated : function(v, index, r){
32473 if(this.selection && this.selection.record == r){
32474 v.onCellSelect(index, this.selection.cell[1]);
32478 onViewChange : function(){
32479 this.clearSelections(true);
32483 getSelectedCell : function(){
32484 return this.selection ? this.selection.cell : null;
32488 clearSelections : function(preventNotify){
32489 var s = this.selection;
32491 if(preventNotify !== true){
32492 this.grid.view.onCellDeselect(s.cell[0], s.cell[1]);
32494 this.selection = null;
32495 this.fireEvent("selectionchange", this, null);
32500 hasSelection : function(){
32501 return this.selection ? true : false;
32505 handleMouseDown : function(g, row, cell, e){
32506 if(e.button !== 0 || this.isLocked()){
32509 this.select(row, cell);
32513 select : function(rowIndex, colIndex, preventViewNotify, preventFocus, r){
32514 if(this.fireEvent("beforecellselect", this, rowIndex, colIndex) !== false){
32515 this.clearSelections();
32516 r = r || this.grid.store.getAt(rowIndex);
32519 cell : [rowIndex, colIndex]
32521 if(!preventViewNotify){
32522 var v = this.grid.getView();
32523 v.onCellSelect(rowIndex, colIndex);
32524 if(preventFocus !== true){
32525 v.focusCell(rowIndex, colIndex);
32528 this.fireEvent("cellselect", this, rowIndex, colIndex);
32529 this.fireEvent("selectionchange", this, this.selection);
32533 isSelectable : function(rowIndex, colIndex, cm){
32534 return !cm.isHidden(colIndex);
32538 handleKeyDown : function(e){
32539 if(!e.isNavKeyPress()){
32542 var g = this.grid, s = this.selection;
32545 var cell = g.walkCells(0, 0, 1, this.isSelectable, this);
32547 this.select(cell[0], cell[1]);
32552 var walk = function(row, col, step){
32553 return g.walkCells(row, col, step, sm.isSelectable, sm);
32555 var k = e.getKey(), r = s.cell[0], c = s.cell[1];
32561 newCell = walk(r, c-1, -1);
32563 newCell = walk(r, c+1, 1);
32567 newCell = walk(r+1, c, 1);
32570 newCell = walk(r-1, c, -1);
32573 newCell = walk(r, c+1, 1);
32576 newCell = walk(r, c-1, -1);
32579 if(g.isEditor && !g.editing){
32580 g.startEditing(r, c);
32587 this.select(newCell[0], newCell[1]);
32592 acceptsNav : function(row, col, cm){
32593 return !cm.isHidden(col) && cm.isCellEditable(col, row);
32596 onEditorKey : function(field, e){
32597 var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor;
32600 newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
32602 newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
32605 }else if(k == e.ENTER){
32608 }else if(k == e.ESC){
32613 g.startEditing(newCell[0], newCell[1]);
32618 Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, {
32628 autoEncode : false,
32632 trackMouseOver: false,
32635 initComponent : function(){
32636 Ext.grid.EditorGridPanel.superclass.initComponent.call(this);
32638 if(!this.selModel){
32639 this.selModel = new Ext.grid.CellSelectionModel();
32642 this.activeEditor = null;
32655 initEvents : function(){
32656 Ext.grid.EditorGridPanel.superclass.initEvents.call(this);
32658 this.on("bodyscroll", this.stopEditing, this, [true]);
32660 if(this.clicksToEdit == 1){
32661 this.on("cellclick", this.onCellDblClick, this);
32663 if(this.clicksToEdit == 'auto' && this.view.mainBody){
32664 this.view.mainBody.on("mousedown", this.onAutoEditClick, this);
32666 this.on("celldblclick", this.onCellDblClick, this);
32668 this.getGridEl().addClass("xedit-grid");
32672 onCellDblClick : function(g, row, col){
32673 this.startEditing(row, col);
32677 onAutoEditClick : function(e, t){
32678 if(e.button !== 0){
32681 var row = this.view.findRowIndex(t);
32682 var col = this.view.findCellIndex(t);
32683 if(row !== false && col !== false){
32684 this.stopEditing();
32685 if(this.selModel.getSelectedCell){
32686 var sc = this.selModel.getSelectedCell();
32687 if(sc && sc.cell[0] === row && sc.cell[1] === col){
32688 this.startEditing(row, col);
32691 if(this.selModel.isSelected(row)){
32692 this.startEditing(row, col);
32699 onEditComplete : function(ed, value, startValue){
32700 this.editing = false;
32701 this.activeEditor = null;
32702 ed.un("specialkey", this.selModel.onEditorKey, this.selModel);
32704 var field = this.colModel.getDataIndex(ed.col);
32705 value = this.postEditValue(value, startValue, r, field);
32706 if(String(value) !== String(startValue)){
32711 originalValue: startValue,
32717 if(this.fireEvent("validateedit", e) !== false && !e.cancel){
32718 r.set(field, e.value);
32720 this.fireEvent("afteredit", e);
32723 this.view.focusCell(ed.row, ed.col);
32727 startEditing : function(row, col){
32728 this.stopEditing();
32729 if(this.colModel.isCellEditable(col, row)){
32730 this.view.ensureVisible(row, col, true);
32731 var r = this.store.getAt(row);
32732 var field = this.colModel.getDataIndex(col);
32737 value: r.data[field],
32742 if(this.fireEvent("beforeedit", e) !== false && !e.cancel){
32743 this.editing = true;
32744 var ed = this.colModel.getCellEditor(col, row);
32746 ed.render(this.view.getEditorParent(ed));
32752 ed.on("complete", this.onEditComplete, this, {single: true});
32753 ed.on("specialkey", this.selModel.onEditorKey, this.selModel);
32754 this.activeEditor = ed;
32755 var v = this.preEditValue(r, field);
32756 ed.startEdit(this.view.getCell(row, col), v);
32757 }).defer(50, this);
32762 preEditValue : function(r, field){
32763 return this.autoEncode && typeof value == 'string' ? Ext.util.Format.htmlDecode(r.data[field]) : r.data[field];
32766 postEditValue : function(value, originalValue, r, field){
32767 return this.autoEncode && typeof value == 'string' ? Ext.util.Format.htmlEncode(value) : value;
32771 stopEditing : function(cancel){
32772 if(this.activeEditor){
32773 this.activeEditor[cancel === true ? 'cancelEdit' : 'completeEdit']();
32775 this.activeEditor = null;
32778 Ext.reg('editorgrid', Ext.grid.EditorGridPanel);
32779 Ext.grid.GridEditor = function(field, config){
32780 Ext.grid.GridEditor.superclass.constructor.call(this, field, config);
32781 field.monitorTab = false;
32784 Ext.extend(Ext.grid.GridEditor, Ext.Editor, {
32785 alignment: "tl-tl",
32788 cls: "x-small-editor x-grid-editor",
32793 Ext.grid.PropertyRecord = Ext.data.Record.create([
32794 {name:'name',type:'string'}, 'value'
32798 Ext.grid.PropertyStore = function(grid, source){
32800 this.store = new Ext.data.Store({
32801 recordType : Ext.grid.PropertyRecord
32803 this.store.on('update', this.onUpdate, this);
32805 this.setSource(source);
32807 Ext.grid.PropertyStore.superclass.constructor.call(this);
32809 Ext.extend(Ext.grid.PropertyStore, Ext.util.Observable, {
32810 setSource : function(o){
32812 this.store.removeAll();
32815 if(this.isEditableValue(o[k])){
32816 data.push(new Ext.grid.PropertyRecord({name: k, value: o[k]}, k));
32819 this.store.loadRecords({records: data}, {}, true);
32822 onUpdate : function(ds, record, type){
32823 if(type == Ext.data.Record.EDIT){
32824 var v = record.data['value'];
32825 var oldValue = record.modified['value'];
32826 if(this.grid.fireEvent('beforepropertychange', this.source, record.id, v, oldValue) !== false){
32827 this.source[record.id] = v;
32829 this.grid.fireEvent('propertychange', this.source, record.id, v, oldValue);
32836 getProperty : function(row){
32837 return this.store.getAt(row);
32840 isEditableValue: function(val){
32841 if(Ext.isDate(val)){
32843 }else if(typeof val == 'object' || typeof val == 'function'){
32849 setValue : function(prop, value){
32850 this.source[prop] = value;
32851 this.store.getById(prop).set('value', value);
32854 getSource : function(){
32855 return this.source;
32860 Ext.grid.PropertyColumnModel = function(grid, store){
32863 g.PropertyColumnModel.superclass.constructor.call(this, [
32864 {header: this.nameText, width:50, sortable: true, dataIndex:'name', id: 'name', menuDisabled:true},
32865 {header: this.valueText, width:50, resizable:false, dataIndex: 'value', id: 'value', menuDisabled:true}
32867 this.store = store;
32868 this.bselect = Ext.DomHelper.append(document.body, {
32869 tag: 'select', cls: 'x-grid-editor x-hide-display', children: [
32870 {tag: 'option', value: 'true', html: 'true'},
32871 {tag: 'option', value: 'false', html: 'false'}
32876 var bfield = new f.Field({
32878 bselect : this.bselect,
32880 getValue : function(){
32881 return this.bselect.value == 'true';
32885 'date' : new g.GridEditor(new f.DateField({selectOnFocus:true})),
32886 'string' : new g.GridEditor(new f.TextField({selectOnFocus:true})),
32887 'number' : new g.GridEditor(new f.NumberField({selectOnFocus:true, style:'text-align:left;'})),
32888 'boolean' : new g.GridEditor(bfield)
32890 this.renderCellDelegate = this.renderCell.createDelegate(this);
32891 this.renderPropDelegate = this.renderProp.createDelegate(this);
32894 Ext.extend(Ext.grid.PropertyColumnModel, Ext.grid.ColumnModel, {
32896 valueText : 'Value',
32897 dateFormat : 'm/j/Y',
32899 renderDate : function(dateVal){
32900 return dateVal.dateFormat(this.dateFormat);
32903 renderBool : function(bVal){
32904 return bVal ? 'true' : 'false';
32907 isCellEditable : function(colIndex, rowIndex){
32908 return colIndex == 1;
32911 getRenderer : function(col){
32913 this.renderCellDelegate : this.renderPropDelegate;
32916 renderProp : function(v){
32917 return this.getPropertyName(v);
32920 renderCell : function(val){
32922 if(Ext.isDate(val)){
32923 rv = this.renderDate(val);
32924 }else if(typeof val == 'boolean'){
32925 rv = this.renderBool(val);
32927 return Ext.util.Format.htmlEncode(rv);
32930 getPropertyName : function(name){
32931 var pn = this.grid.propertyNames;
32932 return pn && pn[name] ? pn[name] : name;
32935 getCellEditor : function(colIndex, rowIndex){
32936 var p = this.store.getProperty(rowIndex);
32937 var n = p.data['name'], val = p.data['value'];
32938 if(this.grid.customEditors[n]){
32939 return this.grid.customEditors[n];
32941 if(Ext.isDate(val)){
32942 return this.editors['date'];
32943 }else if(typeof val == 'number'){
32944 return this.editors['number'];
32945 }else if(typeof val == 'boolean'){
32946 return this.editors['boolean'];
32948 return this.editors['string'];
32954 Ext.grid.PropertyGrid = Ext.extend(Ext.grid.EditorGridPanel, {
32958 enableColumnMove:false,
32960 trackMouseOver: false,
32962 enableHdMenu : false,
32967 initComponent : function(){
32968 this.customEditors = this.customEditors || {};
32969 this.lastEditRow = null;
32970 var store = new Ext.grid.PropertyStore(this);
32971 this.propStore = store;
32972 var cm = new Ext.grid.PropertyColumnModel(this, store);
32973 store.store.sort('name', 'ASC');
32976 'beforepropertychange',
32981 this.ds = store.store;
32982 Ext.grid.PropertyGrid.superclass.initComponent.call(this);
32984 this.selModel.on('beforecellselect', function(sm, rowIndex, colIndex){
32985 if(colIndex === 0){
32986 this.startEditing.defer(200, this, [rowIndex, 1]);
32992 onRender : function(){
32993 Ext.grid.PropertyGrid.superclass.onRender.apply(this, arguments);
32995 this.getGridEl().addClass('x-props-grid');
32998 afterRender: function(){
32999 Ext.grid.PropertyGrid.superclass.afterRender.apply(this, arguments);
33001 this.setSource(this.source);
33006 setSource : function(source){
33007 this.propStore.setSource(source);
33011 getSource : function(){
33012 return this.propStore.getSource();
33016 Ext.grid.RowNumberer = function(config){
33017 Ext.apply(this, config);
33019 this.renderer = this.renderer.createDelegate(this);
33023 Ext.grid.RowNumberer.prototype = {
33036 rowspan: undefined,
33039 renderer : function(v, p, record, rowIndex){
33041 p.cellAttr = 'rowspan="'+this.rowspan+'"';
33047 Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, {
33049 header: '<div class="x-grid3-hd-checker"> </div>',
33062 initEvents : function(){
33063 Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this);
33064 this.grid.on('render', function(){
33065 var view = this.grid.getView();
33066 view.mainBody.on('mousedown', this.onMouseDown, this);
33067 Ext.fly(view.innerHd).on('mousedown', this.onHdMouseDown, this);
33073 onMouseDown : function(e, t){
33074 if(e.button === 0 && t.className == 'x-grid3-row-checker'){
33076 var row = e.getTarget('.x-grid3-row');
33078 var index = row.rowIndex;
33079 if(this.isSelected(index)){
33080 this.deselectRow(index);
33082 this.selectRow(index, true);
33089 onHdMouseDown : function(e, t){
33090 if(t.className == 'x-grid3-hd-checker'){
33092 var hd = Ext.fly(t.parentNode);
33093 var isChecked = hd.hasClass('x-grid3-hd-checker-on');
33095 hd.removeClass('x-grid3-hd-checker-on');
33096 this.clearSelections();
33098 hd.addClass('x-grid3-hd-checker-on');
33105 renderer : function(v, p, record){
33106 return '<div class="x-grid3-row-checker"> </div>';
33110 Ext.LoadMask = function(el, config){
33111 this.el = Ext.get(el);
33112 Ext.apply(this, config);
33114 this.store.on('beforeload', this.onBeforeLoad, this);
33115 this.store.on('load', this.onLoad, this);
33116 this.store.on('loadexception', this.onLoad, this);
33117 this.removeMask = Ext.value(this.removeMask, false);
33119 var um = this.el.getUpdater();
33120 um.showLoadIndicator = false; um.on('beforeupdate', this.onBeforeLoad, this);
33121 um.on('update', this.onLoad, this);
33122 um.on('failure', this.onLoad, this);
33123 this.removeMask = Ext.value(this.removeMask, true);
33127 Ext.LoadMask.prototype = {
33131 msg : 'Loading...',
33133 msgCls : 'x-mask-loading',
33139 disable : function(){
33140 this.disabled = true;
33144 enable : function(){
33145 this.disabled = false;
33148 onLoad : function(){
33149 this.el.unmask(this.removeMask);
33152 onBeforeLoad : function(){
33153 if(!this.disabled){
33154 this.el.mask(this.msg, this.msgCls);
33160 this.onBeforeLoad();
33168 destroy : function(){
33170 this.store.un('beforeload', this.onBeforeLoad, this);
33171 this.store.un('load', this.onLoad, this);
33172 this.store.un('loadexception', this.onLoad, this);
33174 var um = this.el.getUpdater();
33175 um.un('beforeupdate', this.onBeforeLoad, this);
33176 um.un('update', this.onLoad, this);
33177 um.un('failure', this.onLoad, this);
33182 Ext.ProgressBar = Ext.extend(Ext.BoxComponent, {
33184 baseCls : 'x-progress',
33190 initComponent : function(){
33191 Ext.ProgressBar.superclass.initComponent.call(this);
33199 onRender : function(ct, position){
33200 Ext.ProgressBar.superclass.onRender.call(this, ct, position);
33202 var tpl = new Ext.Template(
33203 '<div class="{cls}-wrap">',
33204 '<div class="{cls}-inner">',
33205 '<div class="{cls}-bar">',
33206 '<div class="{cls}-text">',
33207 '<div> </div>',
33210 '<div class="{cls}-text {cls}-text-back">',
33211 '<div> </div>',
33218 this.el = tpl.insertBefore(position, {cls: this.baseCls}, true);
33220 this.el = tpl.append(ct, {cls: this.baseCls}, true);
33223 this.el.dom.id = this.id;
33225 var inner = this.el.dom.firstChild;
33226 this.progressBar = Ext.get(inner.firstChild);
33230 this.textEl = Ext.get(this.textEl);
33231 delete this.textTopEl;
33234 this.textTopEl = Ext.get(this.progressBar.dom.firstChild);
33235 var textBackEl = Ext.get(inner.childNodes[1]);
33236 this.textTopEl.setStyle("z-index", 99).addClass('x-hidden');
33237 this.textEl = new Ext.CompositeElement([this.textTopEl.dom.firstChild, textBackEl.dom.firstChild]);
33238 this.textEl.setWidth(inner.offsetWidth);
33241 this.updateProgress(this.value, this.text);
33243 this.updateText(this.text);
33245 this.setSize(this.width || 'auto', 'auto');
33246 this.progressBar.setHeight(inner.offsetHeight);
33250 updateProgress : function(value, text){
33251 this.value = value || 0;
33253 this.updateText(text);
33255 var w = Math.floor(value*this.el.dom.firstChild.offsetWidth);
33256 this.progressBar.setWidth(w);
33257 if(this.textTopEl){
33259 this.textTopEl.removeClass('x-hidden').setWidth(w);
33261 this.fireEvent('update', this, value, text);
33266 wait : function(o){
33267 if(!this.waitTimer){
33270 this.waitTimer = Ext.TaskMgr.start({
33272 var inc = o.increment || 10;
33273 this.updateProgress(((((i+inc)%inc)+1)*(100/inc))*.01);
33275 interval: o.interval || 1000,
33276 duration: o.duration,
33277 onStop: function(){
33279 o.fn.apply(o.scope || this);
33290 isWaiting : function(){
33291 return this.waitTimer != null;
33295 updateText : function(text){
33296 this.text = text || ' ';
33297 this.textEl.update(this.text);
33302 setSize : function(w, h){
33303 Ext.ProgressBar.superclass.setSize.call(this, w, h);
33304 if(this.textTopEl){
33305 var inner = this.el.dom.firstChild;
33306 this.textEl.setSize(inner.offsetWidth, inner.offsetHeight);
33312 reset : function(hide){
33313 this.updateProgress(0);
33314 if(this.textTopEl){
33315 this.textTopEl.addClass('x-hidden');
33317 if(this.waitTimer){
33318 this.waitTimer.onStop = null;
33319 Ext.TaskMgr.stop(this.waitTimer);
33320 this.waitTimer = null;
33328 Ext.reg('progress', Ext.ProgressBar);
33335 function createConsole(){
33337 var scriptPanel = new Ext.debug.ScriptsPanel();
33338 var logView = new Ext.debug.LogPanel();
33339 var tree = new Ext.debug.DomTree();
33341 var tabs = new Ext.TabPanel({
33344 tabPosition: 'bottom',
33346 title: 'Debug Console',
33348 items: [logView, scriptPanel]
33350 title: 'DOM Inspector',
33356 cp = new Ext.Panel({
33357 id: 'x-debug-browser',
33360 animCollapse: false,
33361 style: 'position:absolute;left:0;bottom:0;',
33368 handler: function(){
33371 Ext.EventManager.removeResizeListener(handleResize);
33378 cp.render(document.body);
33380 cp.resizer = new Ext.Resizable(cp.el, {
33385 resizeElement : function(){
33386 var box = this.proxy.getBox();
33388 cp.setHeight(box.height);
33393 function handleResize(){
33394 cp.setWidth(Ext.getBody().getViewSize().width);
33396 Ext.EventManager.onWindowResize(handleResize);
33407 cp.logView.log.apply(cp.logView, arguments);
33410 logf : function(format, arg1, arg2, etc){
33411 Ext.log(String.format.apply(String, arguments));
33414 dump : function(o){
33415 if(typeof o == 'string' || typeof o == 'number' || typeof o == 'undefined' || Ext.isDate(o)){
33419 }else if(typeof o != "object"){
33420 Ext.log('Unknown return type');
33421 }else if(Ext.isArray(o)){
33422 Ext.log('['+o.join(',')+']');
33426 var to = typeof o[key];
33427 if(to != "function" && to != "object"){
33428 b.push(String.format(" {0}: {1},\n", key, o[key]));
33431 var s = b.join("");
33433 s = s.substr(0, s.length-2);
33435 Ext.log(s + "\n}");
33441 time : function(name){
33442 name = name || "def";
33443 Ext._timers[name] = new Date().getTime();
33446 timeEnd : function(name, printResults){
33447 var t = new Date().getTime();
33448 name = name || "def";
33449 var v = String.format("{0} ms", t-Ext._timers[name]);
33450 Ext._timers[name] = new Date().getTime();
33451 if(printResults !== false){
33452 Ext.log('Timer ' + (name == "def" ? v : name + ": " + v));
33461 Ext.debug.ScriptsPanel = Ext.extend(Ext.Panel, {
33462 id:'x-debug-scripts',
33469 style:'border-width:0 0 0 1px;',
33471 initComponent : function(){
33473 this.scriptField = new Ext.form.TextArea({
33474 anchor: '100% -26',
33475 style:'border-width:0;'
33478 this.trapBox = new Ext.form.Checkbox({
33479 id: 'console-trap',
33480 boxLabel: 'Trap Errors',
33484 this.toolbar = new Ext.Toolbar([{
33487 handler: this.evalScript
33491 handler: this.clear
33498 this.items = [this.toolbar, this.scriptField];
33500 Ext.debug.ScriptsPanel.superclass.initComponent.call(this);
33503 evalScript : function(){
33504 var s = this.scriptField.getValue();
33505 if(this.trapBox.getValue()){
33508 Ext.dump(rt === undefined? '(no return)' : rt);
33510 Ext.log(e.message || e.descript);
33514 Ext.dump(rt === undefined? '(no return)' : rt);
33518 clear : function(){
33519 this.scriptField.setValue('');
33520 this.scriptField.focus();
33525 Ext.debug.LogPanel = Ext.extend(Ext.Panel, {
33529 style:'border-width:0 1px 0 0',
33532 var markup = [ '<div style="padding:5px !important;border-bottom:1px solid #ccc;">',
33533 Ext.util.Format.htmlEncode(Array.prototype.join.call(arguments, ', ')).replace(/\n/g, '<br />').replace(/\s/g, ' '),
33534 '</div>'].join('');
33536 this.body.insertHtml('beforeend', markup);
33537 this.body.scrollTo('top', 100000);
33540 clear : function(){
33541 this.body.update('');
33542 this.body.dom.scrollTop = 0;
33546 Ext.debug.DomTree = Ext.extend(Ext.tree.TreePanel, {
33556 initComponent : function(){
33559 Ext.debug.DomTree.superclass.initComponent.call(this);
33561 var styles = false, hnode;
33562 var nonSpace = /^\s*$/;
33563 var html = Ext.util.Format.htmlEncode;
33564 var ellipsis = Ext.util.Format.ellipsis;
33565 var styleRe = /\s?([a-z\-]*)\:([^;]*)(?:[;\s\n\r]*)/gi;
33567 function findNode(n){
33568 if(!n || n.nodeType != 1 || n == document.body || n == document){
33571 var pn = [n], p = n;
33572 while((p = p.parentNode) && p.nodeType == 1 && p.tagName.toUpperCase() != 'HTML'){
33576 for(var i = 0, len = pn.length; i < len; i++){
33578 cn = cn.findChild('htmlNode', pn[i]);
33579 if(!cn){ return false;
33583 var a = cn.ui.anchor;
33584 treeEl.dom.scrollTop = Math.max(0 ,a.offsetTop-10);
33589 function nodeTitle(n){
33593 }else if(n.className){
33594 s += '.'+n.className;
33599 function onNodeSelect(t, n, last){
33601 if(last && last.unframe){
33605 if(n && n.htmlNode){
33606 if(frameEl.pressed){
33613 reload.setDisabled(n.leaf);
33614 var dom = n.htmlNode;
33615 stylePanel.setTitle(nodeTitle(dom));
33616 if(styles && !showAll.pressed){
33617 var s = dom.style ? dom.style.cssText : '';
33620 while ((m = styleRe.exec(s)) != null){
33621 props[m[1].toLowerCase()] = m[2];
33625 var cl = Ext.debug.cssList;
33626 var s = dom.style, fly = Ext.fly(dom);
33628 for(var i = 0, len = cl.length; i<len; i++){
33630 var v = s[st] || fly.getStyle(st);
33631 if(v != undefined && v !== null && v !== ''){
33639 if((isNaN(a+10)) && v != undefined && v !== null && v !== '' && !(Ext.isGecko && a[0] == a[0].toUpperCase())){
33648 addStyle.disable();
33651 stylesGrid.setSource(props);
33652 stylesGrid.treeNode = n;
33653 stylesGrid.view.fitColumns();
33656 this.loader = new Ext.tree.TreeLoader();
33657 this.loader.load = function(n, cb){
33658 var isBody = n.htmlNode == document.body;
33659 var cn = n.htmlNode.childNodes;
33660 for(var i = 0, c; c = cn[i]; i++){
33661 if(isBody && c.id == 'x-debug-browser'){
33664 if(c.nodeType == 1){
33665 n.appendChild(new Ext.debug.HtmlNode(c));
33666 }else if(c.nodeType == 3 && !nonSpace.test(c.nodeValue)){
33667 n.appendChild(new Ext.tree.TreeNode({
33668 text:'<em>' + ellipsis(html(String(c.nodeValue)), 35) + '</em>',
33669 cls: 'x-tree-noicon'
33677 this.root = this.setRootNode(new Ext.tree.TreeNode('Ext'));
33679 hnode = this.root.appendChild(new Ext.debug.HtmlNode(
33680 document.getElementsByTagName('html')[0]
33687 Ext.debug.HtmlNode = function(){
33688 var html = Ext.util.Format.htmlEncode;
33689 var ellipsis = Ext.util.Format.ellipsis;
33690 var nonSpace = /^\s*$/;
33693 {n: 'id', v: 'id'},
33694 {n: 'className', v: 'class'},
33695 {n: 'name', v: 'name'},
33696 {n: 'type', v: 'type'},
33697 {n: 'src', v: 'src'},
33698 {n: 'href', v: 'href'}
33701 function hasChild(n){
33702 for(var i = 0, c; c = n.childNodes[i]; i++){
33703 if(c.nodeType == 1){
33710 function renderNode(n, leaf){
33711 var tag = n.tagName.toLowerCase();
33712 var s = '<' + tag;
33713 for(var i = 0, len = attrs.length; i < len; i++){
33716 if(v && !nonSpace.test(v)){
33717 s += ' ' + a.v + '="<i>' + html(v) +'</i>"';
33720 var style = n.style ? n.style.cssText : '';
33722 s += ' style="<i>' + html(style.toLowerCase()) +'</i>"';
33724 if(leaf && n.childNodes.length > 0){
33725 s+='><em>' + ellipsis(html(String(n.innerHTML)), 35) + '</em></'+tag+'>';
33734 var HtmlNode = function(n){
33735 var leaf = !hasChild(n);
33737 this.tagName = n.tagName.toLowerCase();
33739 text : renderNode(n, leaf),
33741 cls: 'x-tree-noicon'
33743 HtmlNode.superclass.constructor.call(this, attr);
33744 this.attributes.htmlNode = n; if(!leaf){
33745 this.on('expand', this.onExpand, this);
33746 this.on('collapse', this.onCollapse, this);
33751 Ext.extend(HtmlNode, Ext.tree.AsyncTreeNode, {
33752 cls: 'x-tree-noicon',
33753 preventHScroll: true,
33754 refresh : function(highlight){
33755 var leaf = !hasChild(this.htmlNode);
33756 this.setText(renderNode(this.htmlNode, leaf));
33758 Ext.fly(this.ui.textNode).highlight();
33762 onExpand : function(){
33763 if(!this.closeNode && this.parentNode){
33764 this.closeNode = this.parentNode.insertBefore(new Ext.tree.TreeNode({
33765 text:'</' + this.tagName + '>',
33766 cls: 'x-tree-noicon'
33767 }), this.nextSibling);
33768 }else if(this.closeNode){
33769 this.closeNode.ui.show();
33773 onCollapse : function(){
33774 if(this.closeNode){
33775 this.closeNode.ui.hide();
33779 render : function(bulkRender){
33780 HtmlNode.superclass.render.call(this, bulkRender);
33783 highlightNode : function(){
33786 highlight : function(){
33789 frame : function(){
33790 this.htmlNode.style.border = '1px solid #0000ff';
33793 unframe : function(){
33794 this.htmlNode.style.border = '';