view onlypaths/js/ext/ext-all-debug.js @ 46:26c2b3ad21c7 laserkard

[svn r47] saving progresswww.cinemassacre.com/new/?page_id=30
author rlm
date Sun, 31 Jan 2010 12:33:33 -0500
parents
children
line wrap: on
line source
1 /*
2 * Ext JS Library 2.1
3 * Copyright(c) 2006-2008, Ext JS, LLC.
4 * licensing@extjs.com
5 *
6 * http://extjs.com/license
7 */
10 Ext.DomHelper = function(){
11 var tempTableEl = null;
12 var emptyTags = /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i;
13 var tableRe = /^table|tbody|tr|td$/i;
15 var createHtml = function(o){
16 if(typeof o == 'string'){
17 return o;
18 }
19 var b = "";
20 if (Ext.isArray(o)) {
21 for (var i = 0, l = o.length; i < l; i++) {
22 b += createHtml(o[i]);
23 }
24 return b;
25 }
26 if(!o.tag){
27 o.tag = "div";
28 }
29 b += "<" + o.tag;
30 for(var attr in o){
31 if(attr == "tag" || attr == "children" || attr == "cn" || attr == "html" || typeof o[attr] == "function") continue;
32 if(attr == "style"){
33 var s = o["style"];
34 if(typeof s == "function"){
35 s = s.call();
36 }
37 if(typeof s == "string"){
38 b += ' style="' + s + '"';
39 }else if(typeof s == "object"){
40 b += ' style="';
41 for(var key in s){
42 if(typeof s[key] != "function"){
43 b += key + ":" + s[key] + ";";
44 }
45 }
46 b += '"';
47 }
48 }else{
49 if(attr == "cls"){
50 b += ' class="' + o["cls"] + '"';
51 }else if(attr == "htmlFor"){
52 b += ' for="' + o["htmlFor"] + '"';
53 }else{
54 b += " " + attr + '="' + o[attr] + '"';
55 }
56 }
57 }
58 if(emptyTags.test(o.tag)){
59 b += "/>";
60 }else{
61 b += ">";
62 var cn = o.children || o.cn;
63 if(cn){
64 b += createHtml(cn);
65 } else if(o.html){
66 b += o.html;
67 }
68 b += "</" + o.tag + ">";
69 }
70 return b;
71 };
74 var createDom = function(o, parentNode){
75 var el;
76 if (Ext.isArray(o)) { el = document.createDocumentFragment(); for(var i = 0, l = o.length; i < l; i++) {
77 createDom(o[i], el);
78 }
79 } else if (typeof o == "string") { el = document.createTextNode(o);
80 } else {
81 el = document.createElement(o.tag||'div');
82 var useSet = !!el.setAttribute; for(var attr in o){
83 if(attr == "tag" || attr == "children" || attr == "cn" || attr == "html" || attr == "style" || typeof o[attr] == "function") continue;
84 if(attr=="cls"){
85 el.className = o["cls"];
86 }else{
87 if(useSet) el.setAttribute(attr, o[attr]);
88 else el[attr] = o[attr];
89 }
90 }
91 Ext.DomHelper.applyStyles(el, o.style);
92 var cn = o.children || o.cn;
93 if(cn){
94 createDom(cn, el);
95 } else if(o.html){
96 el.innerHTML = o.html;
97 }
98 }
99 if(parentNode){
100 parentNode.appendChild(el);
101 }
102 return el;
103 };
105 var ieTable = function(depth, s, h, e){
106 tempTableEl.innerHTML = [s, h, e].join('');
107 var i = -1, el = tempTableEl;
108 while(++i < depth){
109 el = el.firstChild;
110 }
111 return el;
112 };
114 var ts = '<table>',
115 te = '</table>',
116 tbs = ts+'<tbody>',
117 tbe = '</tbody>'+te,
118 trs = tbs + '<tr>',
119 tre = '</tr>'+tbe;
122 var insertIntoTable = function(tag, where, el, html){
123 if(!tempTableEl){
124 tempTableEl = document.createElement('div');
125 }
126 var node;
127 var before = null;
128 if(tag == 'td'){
129 if(where == 'afterbegin' || where == 'beforeend'){ return;
130 }
131 if(where == 'beforebegin'){
132 before = el;
133 el = el.parentNode;
134 } else{
135 before = el.nextSibling;
136 el = el.parentNode;
137 }
138 node = ieTable(4, trs, html, tre);
139 }
140 else if(tag == 'tr'){
141 if(where == 'beforebegin'){
142 before = el;
143 el = el.parentNode;
144 node = ieTable(3, tbs, html, tbe);
145 } else if(where == 'afterend'){
146 before = el.nextSibling;
147 el = el.parentNode;
148 node = ieTable(3, tbs, html, tbe);
149 } else{ if(where == 'afterbegin'){
150 before = el.firstChild;
151 }
152 node = ieTable(4, trs, html, tre);
153 }
154 } else if(tag == 'tbody'){
155 if(where == 'beforebegin'){
156 before = el;
157 el = el.parentNode;
158 node = ieTable(2, ts, html, te);
159 } else if(where == 'afterend'){
160 before = el.nextSibling;
161 el = el.parentNode;
162 node = ieTable(2, ts, html, te);
163 } else{
164 if(where == 'afterbegin'){
165 before = el.firstChild;
166 }
167 node = ieTable(3, tbs, html, tbe);
168 }
169 } else{ if(where == 'beforebegin' || where == 'afterend'){ return;
170 }
171 if(where == 'afterbegin'){
172 before = el.firstChild;
173 }
174 node = ieTable(2, ts, html, te);
175 }
176 el.insertBefore(node, before);
177 return node;
178 };
181 return {
183 useDom : false,
186 markup : function(o){
187 return createHtml(o);
188 },
191 applyStyles : function(el, styles){
192 if(styles){
193 el = Ext.fly(el);
194 if(typeof styles == "string"){
195 var re = /\s?([a-z\-]*)\:\s?([^;]*);?/gi;
196 var matches;
197 while ((matches = re.exec(styles)) != null){
198 el.setStyle(matches[1], matches[2]);
199 }
200 }else if (typeof styles == "object"){
201 for (var style in styles){
202 el.setStyle(style, styles[style]);
203 }
204 }else if (typeof styles == "function"){
205 Ext.DomHelper.applyStyles(el, styles.call());
206 }
207 }
208 },
211 insertHtml : function(where, el, html){
212 where = where.toLowerCase();
213 if(el.insertAdjacentHTML){
214 if(tableRe.test(el.tagName)){
215 var rs;
216 if(rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html)){
217 return rs;
218 }
219 }
220 switch(where){
221 case "beforebegin":
222 el.insertAdjacentHTML('BeforeBegin', html);
223 return el.previousSibling;
224 case "afterbegin":
225 el.insertAdjacentHTML('AfterBegin', html);
226 return el.firstChild;
227 case "beforeend":
228 el.insertAdjacentHTML('BeforeEnd', html);
229 return el.lastChild;
230 case "afterend":
231 el.insertAdjacentHTML('AfterEnd', html);
232 return el.nextSibling;
233 }
234 throw 'Illegal insertion point -> "' + where + '"';
235 }
236 var range = el.ownerDocument.createRange();
237 var frag;
238 switch(where){
239 case "beforebegin":
240 range.setStartBefore(el);
241 frag = range.createContextualFragment(html);
242 el.parentNode.insertBefore(frag, el);
243 return el.previousSibling;
244 case "afterbegin":
245 if(el.firstChild){
246 range.setStartBefore(el.firstChild);
247 frag = range.createContextualFragment(html);
248 el.insertBefore(frag, el.firstChild);
249 return el.firstChild;
250 }else{
251 el.innerHTML = html;
252 return el.firstChild;
253 }
254 case "beforeend":
255 if(el.lastChild){
256 range.setStartAfter(el.lastChild);
257 frag = range.createContextualFragment(html);
258 el.appendChild(frag);
259 return el.lastChild;
260 }else{
261 el.innerHTML = html;
262 return el.lastChild;
263 }
264 case "afterend":
265 range.setStartAfter(el);
266 frag = range.createContextualFragment(html);
267 el.parentNode.insertBefore(frag, el.nextSibling);
268 return el.nextSibling;
269 }
270 throw 'Illegal insertion point -> "' + where + '"';
271 },
274 insertBefore : function(el, o, returnElement){
275 return this.doInsert(el, o, returnElement, "beforeBegin");
276 },
279 insertAfter : function(el, o, returnElement){
280 return this.doInsert(el, o, returnElement, "afterEnd", "nextSibling");
281 },
284 insertFirst : function(el, o, returnElement){
285 return this.doInsert(el, o, returnElement, "afterBegin", "firstChild");
286 },
288 doInsert : function(el, o, returnElement, pos, sibling){
289 el = Ext.getDom(el);
290 var newNode;
291 if(this.useDom){
292 newNode = createDom(o, null);
293 (sibling === "firstChild" ? el : el.parentNode).insertBefore(newNode, sibling ? el[sibling] : el);
294 }else{
295 var html = createHtml(o);
296 newNode = this.insertHtml(pos, el, html);
297 }
298 return returnElement ? Ext.get(newNode, true) : newNode;
299 },
302 append : function(el, o, returnElement){
303 el = Ext.getDom(el);
304 var newNode;
305 if(this.useDom){
306 newNode = createDom(o, null);
307 el.appendChild(newNode);
308 }else{
309 var html = createHtml(o);
310 newNode = this.insertHtml("beforeEnd", el, html);
311 }
312 return returnElement ? Ext.get(newNode, true) : newNode;
313 },
316 overwrite : function(el, o, returnElement){
317 el = Ext.getDom(el);
318 el.innerHTML = createHtml(o);
319 return returnElement ? Ext.get(el.firstChild, true) : el.firstChild;
320 },
323 createTemplate : function(o){
324 var html = createHtml(o);
325 return new Ext.Template(html);
326 }
327 };
328 }();
331 Ext.Template = function(html){
332 var a = arguments;
333 if(Ext.isArray(html)){
334 html = html.join("");
335 }else if(a.length > 1){
336 var buf = [];
337 for(var i = 0, len = a.length; i < len; i++){
338 if(typeof a[i] == 'object'){
339 Ext.apply(this, a[i]);
340 }else{
341 buf[buf.length] = a[i];
342 }
343 }
344 html = buf.join('');
345 }
347 this.html = html;
348 if(this.compiled){
349 this.compile();
350 }
351 };
352 Ext.Template.prototype = {
354 applyTemplate : function(values){
355 if(this.compiled){
356 return this.compiled(values);
357 }
358 var useF = this.disableFormats !== true;
359 var fm = Ext.util.Format, tpl = this;
360 var fn = function(m, name, format, args){
361 if(format && useF){
362 if(format.substr(0, 5) == "this."){
363 return tpl.call(format.substr(5), values[name], values);
364 }else{
365 if(args){
366 var re = /^\s*['"](.*)["']\s*$/;
367 args = args.split(',');
368 for(var i = 0, len = args.length; i < len; i++){
369 args[i] = args[i].replace(re, "$1");
370 }
371 args = [values[name]].concat(args);
372 }else{
373 args = [values[name]];
374 }
375 return fm[format].apply(fm, args);
376 }
377 }else{
378 return values[name] !== undefined ? values[name] : "";
379 }
380 };
381 return this.html.replace(this.re, fn);
382 },
385 set : function(html, compile){
386 this.html = html;
387 this.compiled = null;
388 if(compile){
389 this.compile();
390 }
391 return this;
392 },
395 disableFormats : false,
398 re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
401 compile : function(){
402 var fm = Ext.util.Format;
403 var useF = this.disableFormats !== true;
404 var sep = Ext.isGecko ? "+" : ",";
405 var fn = function(m, name, format, args){
406 if(format && useF){
407 args = args ? ',' + args : "";
408 if(format.substr(0, 5) != "this."){
409 format = "fm." + format + '(';
410 }else{
411 format = 'this.call("'+ format.substr(5) + '", ';
412 args = ", values";
413 }
414 }else{
415 args= ''; format = "(values['" + name + "'] == undefined ? '' : ";
416 }
417 return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'";
418 };
419 var body;
420 if(Ext.isGecko){
421 body = "this.compiled = function(values){ return '" +
422 this.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) +
423 "';};";
424 }else{
425 body = ["this.compiled = function(values){ return ['"];
426 body.push(this.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn));
427 body.push("'].join('');};");
428 body = body.join('');
429 }
430 eval(body);
431 return this;
432 },
434 call : function(fnName, value, allValues){
435 return this[fnName](value, allValues);
436 },
439 insertFirst: function(el, values, returnElement){
440 return this.doInsert('afterBegin', el, values, returnElement);
441 },
444 insertBefore: function(el, values, returnElement){
445 return this.doInsert('beforeBegin', el, values, returnElement);
446 },
449 insertAfter : function(el, values, returnElement){
450 return this.doInsert('afterEnd', el, values, returnElement);
451 },
454 append : function(el, values, returnElement){
455 return this.doInsert('beforeEnd', el, values, returnElement);
456 },
458 doInsert : function(where, el, values, returnEl){
459 el = Ext.getDom(el);
460 var newNode = Ext.DomHelper.insertHtml(where, el, this.applyTemplate(values));
461 return returnEl ? Ext.get(newNode, true) : newNode;
462 },
465 overwrite : function(el, values, returnElement){
466 el = Ext.getDom(el);
467 el.innerHTML = this.applyTemplate(values);
468 return returnElement ? Ext.get(el.firstChild, true) : el.firstChild;
469 }
470 };
472 Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;
474 Ext.DomHelper.Template = Ext.Template;
477 Ext.Template.from = function(el, config){
478 el = Ext.getDom(el);
479 return new Ext.Template(el.value || el.innerHTML, config || '');
480 };
483 Ext.DomQuery = function(){
484 var cache = {}, simpleCache = {}, valueCache = {};
485 var nonSpace = /\S/;
486 var trimRe = /^\s+|\s+$/g;
487 var tplRe = /\{(\d+)\}/g;
488 var modeRe = /^(\s?[\/>+~]\s?|\s|$)/;
489 var tagTokenRe = /^(#)?([\w-\*]+)/;
490 var nthRe = /(\d*)n\+?(\d*)/, nthRe2 = /\D/;
492 function child(p, index){
493 var i = 0;
494 var n = p.firstChild;
495 while(n){
496 if(n.nodeType == 1){
497 if(++i == index){
498 return n;
499 }
500 }
501 n = n.nextSibling;
502 }
503 return null;
504 };
506 function next(n){
507 while((n = n.nextSibling) && n.nodeType != 1);
508 return n;
509 };
511 function prev(n){
512 while((n = n.previousSibling) && n.nodeType != 1);
513 return n;
514 };
516 function children(d){
517 var n = d.firstChild, ni = -1;
518 while(n){
519 var nx = n.nextSibling;
520 if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){
521 d.removeChild(n);
522 }else{
523 n.nodeIndex = ++ni;
524 }
525 n = nx;
526 }
527 return this;
528 };
530 function byClassName(c, a, v){
531 if(!v){
532 return c;
533 }
534 var r = [], ri = -1, cn;
535 for(var i = 0, ci; ci = c[i]; i++){
536 if((' '+ci.className+' ').indexOf(v) != -1){
537 r[++ri] = ci;
538 }
539 }
540 return r;
541 };
543 function attrValue(n, attr){
544 if(!n.tagName && typeof n.length != "undefined"){
545 n = n[0];
546 }
547 if(!n){
548 return null;
549 }
550 if(attr == "for"){
551 return n.htmlFor;
552 }
553 if(attr == "class" || attr == "className"){
554 return n.className;
555 }
556 return n.getAttribute(attr) || n[attr];
558 };
560 function getNodes(ns, mode, tagName){
561 var result = [], ri = -1, cs;
562 if(!ns){
563 return result;
564 }
565 tagName = tagName || "*";
566 if(typeof ns.getElementsByTagName != "undefined"){
567 ns = [ns];
568 }
569 if(!mode){
570 for(var i = 0, ni; ni = ns[i]; i++){
571 cs = ni.getElementsByTagName(tagName);
572 for(var j = 0, ci; ci = cs[j]; j++){
573 result[++ri] = ci;
574 }
575 }
576 }else if(mode == "/" || mode == ">"){
577 var utag = tagName.toUpperCase();
578 for(var i = 0, ni, cn; ni = ns[i]; i++){
579 cn = ni.children || ni.childNodes;
580 for(var j = 0, cj; cj = cn[j]; j++){
581 if(cj.nodeName == utag || cj.nodeName == tagName || tagName == '*'){
582 result[++ri] = cj;
583 }
584 }
585 }
586 }else if(mode == "+"){
587 var utag = tagName.toUpperCase();
588 for(var i = 0, n; n = ns[i]; i++){
589 while((n = n.nextSibling) && n.nodeType != 1);
590 if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){
591 result[++ri] = n;
592 }
593 }
594 }else if(mode == "~"){
595 for(var i = 0, n; n = ns[i]; i++){
596 while((n = n.nextSibling) && (n.nodeType != 1 || (tagName == '*' || n.tagName.toLowerCase()!=tagName)));
597 if(n){
598 result[++ri] = n;
599 }
600 }
601 }
602 return result;
603 };
605 function concat(a, b){
606 if(b.slice){
607 return a.concat(b);
608 }
609 for(var i = 0, l = b.length; i < l; i++){
610 a[a.length] = b[i];
611 }
612 return a;
613 }
615 function byTag(cs, tagName){
616 if(cs.tagName || cs == document){
617 cs = [cs];
618 }
619 if(!tagName){
620 return cs;
621 }
622 var r = [], ri = -1;
623 tagName = tagName.toLowerCase();
624 for(var i = 0, ci; ci = cs[i]; i++){
625 if(ci.nodeType == 1 && ci.tagName.toLowerCase()==tagName){
626 r[++ri] = ci;
627 }
628 }
629 return r;
630 };
632 function byId(cs, attr, id){
633 if(cs.tagName || cs == document){
634 cs = [cs];
635 }
636 if(!id){
637 return cs;
638 }
639 var r = [], ri = -1;
640 for(var i = 0,ci; ci = cs[i]; i++){
641 if(ci && ci.id == id){
642 r[++ri] = ci;
643 return r;
644 }
645 }
646 return r;
647 };
649 function byAttribute(cs, attr, value, op, custom){
650 var r = [], ri = -1, st = custom=="{";
651 var f = Ext.DomQuery.operators[op];
652 for(var i = 0, ci; ci = cs[i]; i++){
653 var a;
654 if(st){
655 a = Ext.DomQuery.getStyle(ci, attr);
656 }
657 else if(attr == "class" || attr == "className"){
658 a = ci.className;
659 }else if(attr == "for"){
660 a = ci.htmlFor;
661 }else if(attr == "href"){
662 a = ci.getAttribute("href", 2);
663 }else{
664 a = ci.getAttribute(attr);
665 }
666 if((f && f(a, value)) || (!f && a)){
667 r[++ri] = ci;
668 }
669 }
670 return r;
671 };
673 function byPseudo(cs, name, value){
674 return Ext.DomQuery.pseudos[name](cs, value);
675 };
680 var isIE = window.ActiveXObject ? true : false;
684 eval("var batch = 30803;");
686 var key = 30803;
688 function nodupIEXml(cs){
689 var d = ++key;
690 cs[0].setAttribute("_nodup", d);
691 var r = [cs[0]];
692 for(var i = 1, len = cs.length; i < len; i++){
693 var c = cs[i];
694 if(!c.getAttribute("_nodup") != d){
695 c.setAttribute("_nodup", d);
696 r[r.length] = c;
697 }
698 }
699 for(var i = 0, len = cs.length; i < len; i++){
700 cs[i].removeAttribute("_nodup");
701 }
702 return r;
703 }
705 function nodup(cs){
706 if(!cs){
707 return [];
708 }
709 var len = cs.length, c, i, r = cs, cj, ri = -1;
710 if(!len || typeof cs.nodeType != "undefined" || len == 1){
711 return cs;
712 }
713 if(isIE && typeof cs[0].selectSingleNode != "undefined"){
714 return nodupIEXml(cs);
715 }
716 var d = ++key;
717 cs[0]._nodup = d;
718 for(i = 1; c = cs[i]; i++){
719 if(c._nodup != d){
720 c._nodup = d;
721 }else{
722 r = [];
723 for(var j = 0; j < i; j++){
724 r[++ri] = cs[j];
725 }
726 for(j = i+1; cj = cs[j]; j++){
727 if(cj._nodup != d){
728 cj._nodup = d;
729 r[++ri] = cj;
730 }
731 }
732 return r;
733 }
734 }
735 return r;
736 }
738 function quickDiffIEXml(c1, c2){
739 var d = ++key;
740 for(var i = 0, len = c1.length; i < len; i++){
741 c1[i].setAttribute("_qdiff", d);
742 }
743 var r = [];
744 for(var i = 0, len = c2.length; i < len; i++){
745 if(c2[i].getAttribute("_qdiff") != d){
746 r[r.length] = c2[i];
747 }
748 }
749 for(var i = 0, len = c1.length; i < len; i++){
750 c1[i].removeAttribute("_qdiff");
751 }
752 return r;
753 }
755 function quickDiff(c1, c2){
756 var len1 = c1.length;
757 if(!len1){
758 return c2;
759 }
760 if(isIE && c1[0].selectSingleNode){
761 return quickDiffIEXml(c1, c2);
762 }
763 var d = ++key;
764 for(var i = 0; i < len1; i++){
765 c1[i]._qdiff = d;
766 }
767 var r = [];
768 for(var i = 0, len = c2.length; i < len; i++){
769 if(c2[i]._qdiff != d){
770 r[r.length] = c2[i];
771 }
772 }
773 return r;
774 }
776 function quickId(ns, mode, root, id){
777 if(ns == root){
778 var d = root.ownerDocument || root;
779 return d.getElementById(id);
780 }
781 ns = getNodes(ns, mode, "*");
782 return byId(ns, null, id);
783 }
785 return {
786 getStyle : function(el, name){
787 return Ext.fly(el).getStyle(name);
788 },
790 compile : function(path, type){
791 type = type || "select";
793 var fn = ["var f = function(root){\n var mode; ++batch; var n = root || document;\n"];
794 var q = path, mode, lq;
795 var tk = Ext.DomQuery.matchers;
796 var tklen = tk.length;
797 var mm;
800 var lmode = q.match(modeRe);
801 if(lmode && lmode[1]){
802 fn[fn.length] = 'mode="'+lmode[1].replace(trimRe, "")+'";';
803 q = q.replace(lmode[1], "");
804 }
806 while(path.substr(0, 1)=="/"){
807 path = path.substr(1);
808 }
810 while(q && lq != q){
811 lq = q;
812 var tm = q.match(tagTokenRe);
813 if(type == "select"){
814 if(tm){
815 if(tm[1] == "#"){
816 fn[fn.length] = 'n = quickId(n, mode, root, "'+tm[2]+'");';
817 }else{
818 fn[fn.length] = 'n = getNodes(n, mode, "'+tm[2]+'");';
819 }
820 q = q.replace(tm[0], "");
821 }else if(q.substr(0, 1) != '@'){
822 fn[fn.length] = 'n = getNodes(n, mode, "*");';
823 }
824 }else{
825 if(tm){
826 if(tm[1] == "#"){
827 fn[fn.length] = 'n = byId(n, null, "'+tm[2]+'");';
828 }else{
829 fn[fn.length] = 'n = byTag(n, "'+tm[2]+'");';
830 }
831 q = q.replace(tm[0], "");
832 }
833 }
834 while(!(mm = q.match(modeRe))){
835 var matched = false;
836 for(var j = 0; j < tklen; j++){
837 var t = tk[j];
838 var m = q.match(t.re);
839 if(m){
840 fn[fn.length] = t.select.replace(tplRe, function(x, i){
841 return m[i];
842 });
843 q = q.replace(m[0], "");
844 matched = true;
845 break;
846 }
847 }
849 if(!matched){
850 throw 'Error parsing selector, parsing failed at "' + q + '"';
851 }
852 }
853 if(mm[1]){
854 fn[fn.length] = 'mode="'+mm[1].replace(trimRe, "")+'";';
855 q = q.replace(mm[1], "");
856 }
857 }
858 fn[fn.length] = "return nodup(n);\n}";
859 eval(fn.join(""));
860 return f;
861 },
864 select : function(path, root, type){
865 if(!root || root == document){
866 root = document;
867 }
868 if(typeof root == "string"){
869 root = document.getElementById(root);
870 }
871 var paths = path.split(",");
872 var results = [];
873 for(var i = 0, len = paths.length; i < len; i++){
874 var p = paths[i].replace(trimRe, "");
875 if(!cache[p]){
876 cache[p] = Ext.DomQuery.compile(p);
877 if(!cache[p]){
878 throw p + " is not a valid selector";
879 }
880 }
881 var result = cache[p](root);
882 if(result && result != document){
883 results = results.concat(result);
884 }
885 }
886 if(paths.length > 1){
887 return nodup(results);
888 }
889 return results;
890 },
893 selectNode : function(path, root){
894 return Ext.DomQuery.select(path, root)[0];
895 },
898 selectValue : function(path, root, defaultValue){
899 path = path.replace(trimRe, "");
900 if(!valueCache[path]){
901 valueCache[path] = Ext.DomQuery.compile(path, "select");
902 }
903 var n = valueCache[path](root);
904 n = n[0] ? n[0] : n;
905 var v = (n && n.firstChild ? n.firstChild.nodeValue : null);
906 return ((v === null||v === undefined||v==='') ? defaultValue : v);
907 },
910 selectNumber : function(path, root, defaultValue){
911 var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0);
912 return parseFloat(v);
913 },
916 is : function(el, ss){
917 if(typeof el == "string"){
918 el = document.getElementById(el);
919 }
920 var isArray = Ext.isArray(el);
921 var result = Ext.DomQuery.filter(isArray ? el : [el], ss);
922 return isArray ? (result.length == el.length) : (result.length > 0);
923 },
926 filter : function(els, ss, nonMatches){
927 ss = ss.replace(trimRe, "");
928 if(!simpleCache[ss]){
929 simpleCache[ss] = Ext.DomQuery.compile(ss, "simple");
930 }
931 var result = simpleCache[ss](els);
932 return nonMatches ? quickDiff(result, els) : result;
933 },
936 matchers : [{
937 re: /^\.([\w-]+)/,
938 select: 'n = byClassName(n, null, " {1} ");'
939 }, {
940 re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,
941 select: 'n = byPseudo(n, "{1}", "{2}");'
942 },{
943 re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,
944 select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'
945 }, {
946 re: /^#([\w-]+)/,
947 select: 'n = byId(n, null, "{1}");'
948 },{
949 re: /^@([\w-]+)/,
950 select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
951 }
952 ],
955 operators : {
956 "=" : function(a, v){
957 return a == v;
958 },
959 "!=" : function(a, v){
960 return a != v;
961 },
962 "^=" : function(a, v){
963 return a && a.substr(0, v.length) == v;
964 },
965 "$=" : function(a, v){
966 return a && a.substr(a.length-v.length) == v;
967 },
968 "*=" : function(a, v){
969 return a && a.indexOf(v) !== -1;
970 },
971 "%=" : function(a, v){
972 return (a % v) == 0;
973 },
974 "|=" : function(a, v){
975 return a && (a == v || a.substr(0, v.length+1) == v+'-');
976 },
977 "~=" : function(a, v){
978 return a && (' '+a+' ').indexOf(' '+v+' ') != -1;
979 }
980 },
983 pseudos : {
984 "first-child" : function(c){
985 var r = [], ri = -1, n;
986 for(var i = 0, ci; ci = n = c[i]; i++){
987 while((n = n.previousSibling) && n.nodeType != 1);
988 if(!n){
989 r[++ri] = ci;
990 }
991 }
992 return r;
993 },
995 "last-child" : function(c){
996 var r = [], ri = -1, n;
997 for(var i = 0, ci; ci = n = c[i]; i++){
998 while((n = n.nextSibling) && n.nodeType != 1);
999 if(!n){
1000 r[++ri] = ci;
1003 return r;
1004 },
1006 "nth-child" : function(c, a) {
1007 var r = [], ri = -1;
1008 var m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a);
1009 var f = (m[1] || 1) - 0, l = m[2] - 0;
1010 for(var i = 0, n; n = c[i]; i++){
1011 var pn = n.parentNode;
1012 if (batch != pn._batch) {
1013 var j = 0;
1014 for(var cn = pn.firstChild; cn; cn = cn.nextSibling){
1015 if(cn.nodeType == 1){
1016 cn.nodeIndex = ++j;
1019 pn._batch = batch;
1021 if (f == 1) {
1022 if (l == 0 || n.nodeIndex == l){
1023 r[++ri] = n;
1025 } else if ((n.nodeIndex + l) % f == 0){
1026 r[++ri] = n;
1030 return r;
1031 },
1033 "only-child" : function(c){
1034 var r = [], ri = -1;;
1035 for(var i = 0, ci; ci = c[i]; i++){
1036 if(!prev(ci) && !next(ci)){
1037 r[++ri] = ci;
1040 return r;
1041 },
1043 "empty" : function(c){
1044 var r = [], ri = -1;
1045 for(var i = 0, ci; ci = c[i]; i++){
1046 var cns = ci.childNodes, j = 0, cn, empty = true;
1047 while(cn = cns[j]){
1048 ++j;
1049 if(cn.nodeType == 1 || cn.nodeType == 3){
1050 empty = false;
1051 break;
1054 if(empty){
1055 r[++ri] = ci;
1058 return r;
1059 },
1061 "contains" : function(c, v){
1062 var r = [], ri = -1;
1063 for(var i = 0, ci; ci = c[i]; i++){
1064 if((ci.textContent||ci.innerText||'').indexOf(v) != -1){
1065 r[++ri] = ci;
1068 return r;
1069 },
1071 "nodeValue" : function(c, v){
1072 var r = [], ri = -1;
1073 for(var i = 0, ci; ci = c[i]; i++){
1074 if(ci.firstChild && ci.firstChild.nodeValue == v){
1075 r[++ri] = ci;
1078 return r;
1079 },
1081 "checked" : function(c){
1082 var r = [], ri = -1;
1083 for(var i = 0, ci; ci = c[i]; i++){
1084 if(ci.checked == true){
1085 r[++ri] = ci;
1088 return r;
1089 },
1091 "not" : function(c, ss){
1092 return Ext.DomQuery.filter(c, ss, true);
1093 },
1095 "any" : function(c, selectors){
1096 var ss = selectors.split('|');
1097 var r = [], ri = -1, s;
1098 for(var i = 0, ci; ci = c[i]; i++){
1099 for(var j = 0; s = ss[j]; j++){
1100 if(Ext.DomQuery.is(ci, s)){
1101 r[++ri] = ci;
1102 break;
1106 return r;
1107 },
1109 "odd" : function(c){
1110 return this["nth-child"](c, "odd");
1111 },
1113 "even" : function(c){
1114 return this["nth-child"](c, "even");
1115 },
1117 "nth" : function(c, a){
1118 return c[a-1] || [];
1119 },
1121 "first" : function(c){
1122 return c[0] || [];
1123 },
1125 "last" : function(c){
1126 return c[c.length-1] || [];
1127 },
1129 "has" : function(c, ss){
1130 var s = Ext.DomQuery.select;
1131 var r = [], ri = -1;
1132 for(var i = 0, ci; ci = c[i]; i++){
1133 if(s(ss, ci).length > 0){
1134 r[++ri] = ci;
1137 return r;
1138 },
1140 "next" : function(c, ss){
1141 var is = Ext.DomQuery.is;
1142 var r = [], ri = -1;
1143 for(var i = 0, ci; ci = c[i]; i++){
1144 var n = next(ci);
1145 if(n && is(n, ss)){
1146 r[++ri] = ci;
1149 return r;
1150 },
1152 "prev" : function(c, ss){
1153 var is = Ext.DomQuery.is;
1154 var r = [], ri = -1;
1155 for(var i = 0, ci; ci = c[i]; i++){
1156 var n = prev(ci);
1157 if(n && is(n, ss)){
1158 r[++ri] = ci;
1161 return r;
1164 };
1165 }();
1168 Ext.query = Ext.DomQuery.select;
1171 Ext.util.Observable = function(){
1173 if(this.listeners){
1174 this.on(this.listeners);
1175 delete this.listeners;
1177 };
1178 Ext.util.Observable.prototype = {
1180 fireEvent : function(){
1181 if(this.eventsSuspended !== true){
1182 var ce = this.events[arguments[0].toLowerCase()];
1183 if(typeof ce == "object"){
1184 return ce.fire.apply(ce, Array.prototype.slice.call(arguments, 1));
1187 return true;
1188 },
1190 filterOptRe : /^(?:scope|delay|buffer|single)$/,
1193 addListener : function(eventName, fn, scope, o){
1194 if(typeof eventName == "object"){
1195 o = eventName;
1196 for(var e in o){
1197 if(this.filterOptRe.test(e)){
1198 continue;
1200 if(typeof o[e] == "function"){
1201 this.addListener(e, o[e], o.scope, o);
1202 }else{
1203 this.addListener(e, o[e].fn, o[e].scope, o[e]);
1206 return;
1208 o = (!o || typeof o == "boolean") ? {} : o;
1209 eventName = eventName.toLowerCase();
1210 var ce = this.events[eventName] || true;
1211 if(typeof ce == "boolean"){
1212 ce = new Ext.util.Event(this, eventName);
1213 this.events[eventName] = ce;
1215 ce.addListener(fn, scope, o);
1216 },
1219 removeListener : function(eventName, fn, scope){
1220 var ce = this.events[eventName.toLowerCase()];
1221 if(typeof ce == "object"){
1222 ce.removeListener(fn, scope);
1224 },
1227 purgeListeners : function(){
1228 for(var evt in this.events){
1229 if(typeof this.events[evt] == "object"){
1230 this.events[evt].clearListeners();
1233 },
1236 relayEvents : function(o, events){
1237 var createHandler = function(ename){
1238 return function(){
1239 return this.fireEvent.apply(this, Ext.combine(ename, Array.prototype.slice.call(arguments, 0)));
1240 };
1241 };
1242 for(var i = 0, len = events.length; i < len; i++){
1243 var ename = events[i];
1244 if(!this.events[ename]){ this.events[ename] = true; };
1245 o.on(ename, createHandler(ename), this);
1247 },
1250 addEvents : function(o){
1251 if(!this.events){
1252 this.events = {};
1254 if(typeof o == 'string'){
1255 for(var i = 0, a = arguments, v; v = a[i]; i++){
1256 if(!this.events[a[i]]){
1257 this.events[a[i]] = true;
1260 }else{
1261 Ext.applyIf(this.events, o);
1263 },
1266 hasListener : function(eventName){
1267 var e = this.events[eventName];
1268 return typeof e == "object" && e.listeners.length > 0;
1269 },
1272 suspendEvents : function(){
1273 this.eventsSuspended = true;
1274 },
1277 resumeEvents : function(){
1278 this.eventsSuspended = false;
1279 },
1281 getMethodEvent : function(method){
1282 if(!this.methodEvents){
1283 this.methodEvents = {};
1285 var e = this.methodEvents[method];
1286 if(!e){
1287 e = {};
1288 this.methodEvents[method] = e;
1290 e.originalFn = this[method];
1291 e.methodName = method;
1292 e.before = [];
1293 e.after = [];
1296 var returnValue, v, cancel;
1297 var obj = this;
1299 var makeCall = function(fn, scope, args){
1300 if((v = fn.apply(scope || obj, args)) !== undefined){
1301 if(typeof v === 'object'){
1302 if(v.returnValue !== undefined){
1303 returnValue = v.returnValue;
1304 }else{
1305 returnValue = v;
1307 if(v.cancel === true){
1308 cancel = true;
1310 }else if(v === false){
1311 cancel = true;
1312 }else {
1313 returnValue = v;
1318 this[method] = function(){
1319 returnValue = v = undefined; cancel = false;
1320 var args = Array.prototype.slice.call(arguments, 0);
1321 for(var i = 0, len = e.before.length; i < len; i++){
1322 makeCall(e.before[i].fn, e.before[i].scope, args);
1323 if(cancel){
1324 return returnValue;
1328 if((v = e.originalFn.apply(obj, args)) !== undefined){
1329 returnValue = v;
1332 for(var i = 0, len = e.after.length; i < len; i++){
1333 makeCall(e.after[i].fn, e.after[i].scope, args);
1334 if(cancel){
1335 return returnValue;
1338 return returnValue;
1339 };
1341 return e;
1342 },
1344 beforeMethod : function(method, fn, scope){
1345 var e = this.getMethodEvent(method);
1346 e.before.push({fn: fn, scope: scope});
1347 },
1349 afterMethod : function(method, fn, scope){
1350 var e = this.getMethodEvent(method);
1351 e.after.push({fn: fn, scope: scope});
1352 },
1354 removeMethodListener : function(method, fn, scope){
1355 var e = this.getMethodEvent(method);
1356 for(var i = 0, len = e.before.length; i < len; i++){
1357 if(e.before[i].fn == fn && e.before[i].scope == scope){
1358 e.before.splice(i, 1);
1359 return;
1362 for(var i = 0, len = e.after.length; i < len; i++){
1363 if(e.after[i].fn == fn && e.after[i].scope == scope){
1364 e.after.splice(i, 1);
1365 return;
1369 };
1371 Ext.util.Observable.prototype.on = Ext.util.Observable.prototype.addListener;
1373 Ext.util.Observable.prototype.un = Ext.util.Observable.prototype.removeListener;
1376 Ext.util.Observable.capture = function(o, fn, scope){
1377 o.fireEvent = o.fireEvent.createInterceptor(fn, scope);
1378 };
1381 Ext.util.Observable.releaseCapture = function(o){
1382 o.fireEvent = Ext.util.Observable.prototype.fireEvent;
1383 };
1385 (function(){
1387 var createBuffered = function(h, o, scope){
1388 var task = new Ext.util.DelayedTask();
1389 return function(){
1390 task.delay(o.buffer, h, scope, Array.prototype.slice.call(arguments, 0));
1391 };
1392 };
1394 var createSingle = function(h, e, fn, scope){
1395 return function(){
1396 e.removeListener(fn, scope);
1397 return h.apply(scope, arguments);
1398 };
1399 };
1401 var createDelayed = function(h, o, scope){
1402 return function(){
1403 var args = Array.prototype.slice.call(arguments, 0);
1404 setTimeout(function(){
1405 h.apply(scope, args);
1406 }, o.delay || 10);
1407 };
1408 };
1410 Ext.util.Event = function(obj, name){
1411 this.name = name;
1412 this.obj = obj;
1413 this.listeners = [];
1414 };
1416 Ext.util.Event.prototype = {
1417 addListener : function(fn, scope, options){
1418 scope = scope || this.obj;
1419 if(!this.isListening(fn, scope)){
1420 var l = this.createListener(fn, scope, options);
1421 if(!this.firing){
1422 this.listeners.push(l);
1423 }else{ this.listeners = this.listeners.slice(0);
1424 this.listeners.push(l);
1427 },
1429 createListener : function(fn, scope, o){
1430 o = o || {};
1431 scope = scope || this.obj;
1432 var l = {fn: fn, scope: scope, options: o};
1433 var h = fn;
1434 if(o.delay){
1435 h = createDelayed(h, o, scope);
1437 if(o.single){
1438 h = createSingle(h, this, fn, scope);
1440 if(o.buffer){
1441 h = createBuffered(h, o, scope);
1443 l.fireFn = h;
1444 return l;
1445 },
1447 findListener : function(fn, scope){
1448 scope = scope || this.obj;
1449 var ls = this.listeners;
1450 for(var i = 0, len = ls.length; i < len; i++){
1451 var l = ls[i];
1452 if(l.fn == fn && l.scope == scope){
1453 return i;
1456 return -1;
1457 },
1459 isListening : function(fn, scope){
1460 return this.findListener(fn, scope) != -1;
1461 },
1463 removeListener : function(fn, scope){
1464 var index;
1465 if((index = this.findListener(fn, scope)) != -1){
1466 if(!this.firing){
1467 this.listeners.splice(index, 1);
1468 }else{
1469 this.listeners = this.listeners.slice(0);
1470 this.listeners.splice(index, 1);
1472 return true;
1474 return false;
1475 },
1477 clearListeners : function(){
1478 this.listeners = [];
1479 },
1481 fire : function(){
1482 var ls = this.listeners, scope, len = ls.length;
1483 if(len > 0){
1484 this.firing = true;
1485 var args = Array.prototype.slice.call(arguments, 0);
1486 for(var i = 0; i < len; i++){
1487 var l = ls[i];
1488 if(l.fireFn.apply(l.scope||this.obj||window, arguments) === false){
1489 this.firing = false;
1490 return false;
1493 this.firing = false;
1495 return true;
1497 };
1498 })();
1500 Ext.EventManager = function(){
1501 var docReadyEvent, docReadyProcId, docReadyState = false;
1502 var resizeEvent, resizeTask, textEvent, textSize;
1503 var E = Ext.lib.Event;
1504 var D = Ext.lib.Dom;
1507 var fireDocReady = function(){
1508 if(!docReadyState){
1509 docReadyState = true;
1510 Ext.isReady = true;
1511 if(docReadyProcId){
1512 clearInterval(docReadyProcId);
1514 if(Ext.isGecko || Ext.isOpera) {
1515 document.removeEventListener("DOMContentLoaded", fireDocReady, false);
1517 if(Ext.isIE){
1518 var defer = document.getElementById("ie-deferred-loader");
1519 if(defer){
1520 defer.onreadystatechange = null;
1521 defer.parentNode.removeChild(defer);
1524 if(docReadyEvent){
1525 docReadyEvent.fire();
1526 docReadyEvent.clearListeners();
1529 };
1531 var initDocReady = function(){
1532 docReadyEvent = new Ext.util.Event();
1533 if(Ext.isGecko || Ext.isOpera) {
1534 document.addEventListener("DOMContentLoaded", fireDocReady, false);
1535 }else if(Ext.isIE){
1536 document.write("<s"+'cript id="ie-deferred-loader" defer="defer" src="/'+'/:"></s'+"cript>");
1537 var defer = document.getElementById("ie-deferred-loader");
1538 defer.onreadystatechange = function(){
1539 if(this.readyState == "complete"){
1540 fireDocReady();
1542 };
1543 }else if(Ext.isSafari){
1544 docReadyProcId = setInterval(function(){
1545 var rs = document.readyState;
1546 if(rs == "complete") {
1547 fireDocReady();
1549 }, 10);
1552 E.on(window, "load", fireDocReady);
1553 };
1555 var createBuffered = function(h, o){
1556 var task = new Ext.util.DelayedTask(h);
1557 return function(e){
1559 e = new Ext.EventObjectImpl(e);
1560 task.delay(o.buffer, h, null, [e]);
1561 };
1562 };
1564 var createSingle = function(h, el, ename, fn){
1565 return function(e){
1566 Ext.EventManager.removeListener(el, ename, fn);
1567 h(e);
1568 };
1569 };
1571 var createDelayed = function(h, o){
1572 return function(e){
1574 e = new Ext.EventObjectImpl(e);
1575 setTimeout(function(){
1576 h(e);
1577 }, o.delay || 10);
1578 };
1579 };
1581 var listen = function(element, ename, opt, fn, scope){
1582 var o = (!opt || typeof opt == "boolean") ? {} : opt;
1583 fn = fn || o.fn; scope = scope || o.scope;
1584 var el = Ext.getDom(element);
1585 if(!el){
1586 throw "Error listening for \"" + ename + '\". Element "' + element + '" doesn\'t exist.';
1588 var h = function(e){
1589 e = Ext.EventObject.setEvent(e);
1590 var t;
1591 if(o.delegate){
1592 t = e.getTarget(o.delegate, el);
1593 if(!t){
1594 return;
1596 }else{
1597 t = e.target;
1599 if(o.stopEvent === true){
1600 e.stopEvent();
1602 if(o.preventDefault === true){
1603 e.preventDefault();
1605 if(o.stopPropagation === true){
1606 e.stopPropagation();
1609 if(o.normalized === false){
1610 e = e.browserEvent;
1613 fn.call(scope || el, e, t, o);
1614 };
1615 if(o.delay){
1616 h = createDelayed(h, o);
1618 if(o.single){
1619 h = createSingle(h, el, ename, fn);
1621 if(o.buffer){
1622 h = createBuffered(h, o);
1624 fn._handlers = fn._handlers || [];
1625 fn._handlers.push([Ext.id(el), ename, h]);
1627 E.on(el, ename, h);
1628 if(ename == "mousewheel" && el.addEventListener){
1629 el.addEventListener("DOMMouseScroll", h, false);
1630 E.on(window, 'unload', function(){
1631 el.removeEventListener("DOMMouseScroll", h, false);
1632 });
1634 if(ename == "mousedown" && el == document){
1635 Ext.EventManager.stoppedMouseDownEvent.addListener(h);
1637 return h;
1638 };
1640 var stopListening = function(el, ename, fn){
1641 var id = Ext.id(el), hds = fn._handlers, hd = fn;
1642 if(hds){
1643 for(var i = 0, len = hds.length; i < len; i++){
1644 var h = hds[i];
1645 if(h[0] == id && h[1] == ename){
1646 hd = h[2];
1647 hds.splice(i, 1);
1648 break;
1652 E.un(el, ename, hd);
1653 el = Ext.getDom(el);
1654 if(ename == "mousewheel" && el.addEventListener){
1655 el.removeEventListener("DOMMouseScroll", hd, false);
1657 if(ename == "mousedown" && el == document){
1658 Ext.EventManager.stoppedMouseDownEvent.removeListener(hd);
1660 };
1662 var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
1663 var pub = {
1666 addListener : function(element, eventName, fn, scope, options){
1667 if(typeof eventName == "object"){
1668 var o = eventName;
1669 for(var e in o){
1670 if(propRe.test(e)){
1671 continue;
1673 if(typeof o[e] == "function"){
1675 listen(element, e, o, o[e], o.scope);
1676 }else{
1678 listen(element, e, o[e]);
1681 return;
1683 return listen(element, eventName, options, fn, scope);
1684 },
1687 removeListener : function(element, eventName, fn){
1688 return stopListening(element, eventName, fn);
1689 },
1692 onDocumentReady : function(fn, scope, options){
1693 if(docReadyState){
1694 docReadyEvent.addListener(fn, scope, options);
1695 docReadyEvent.fire();
1696 docReadyEvent.clearListeners();
1697 return;
1699 if(!docReadyEvent){
1700 initDocReady();
1702 docReadyEvent.addListener(fn, scope, options);
1703 },
1706 onWindowResize : function(fn, scope, options){
1707 if(!resizeEvent){
1708 resizeEvent = new Ext.util.Event();
1709 resizeTask = new Ext.util.DelayedTask(function(){
1710 resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
1711 });
1712 E.on(window, "resize", this.fireWindowResize, this);
1714 resizeEvent.addListener(fn, scope, options);
1715 },
1718 fireWindowResize : function(){
1719 if(resizeEvent){
1720 if((Ext.isIE||Ext.isAir) && resizeTask){
1721 resizeTask.delay(50);
1722 }else{
1723 resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
1726 },
1729 onTextResize : function(fn, scope, options){
1730 if(!textEvent){
1731 textEvent = new Ext.util.Event();
1732 var textEl = new Ext.Element(document.createElement('div'));
1733 textEl.dom.className = 'x-text-resize';
1734 textEl.dom.innerHTML = 'X';
1735 textEl.appendTo(document.body);
1736 textSize = textEl.dom.offsetHeight;
1737 setInterval(function(){
1738 if(textEl.dom.offsetHeight != textSize){
1739 textEvent.fire(textSize, textSize = textEl.dom.offsetHeight);
1741 }, this.textResizeInterval);
1743 textEvent.addListener(fn, scope, options);
1744 },
1747 removeResizeListener : function(fn, scope){
1748 if(resizeEvent){
1749 resizeEvent.removeListener(fn, scope);
1751 },
1754 fireResize : function(){
1755 if(resizeEvent){
1756 resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
1758 },
1760 ieDeferSrc : false,
1762 textResizeInterval : 50
1763 };
1765 pub.on = pub.addListener;
1767 pub.un = pub.removeListener;
1769 pub.stoppedMouseDownEvent = new Ext.util.Event();
1770 return pub;
1771 }();
1773 Ext.onReady = Ext.EventManager.onDocumentReady;
1775 Ext.onReady(function(){
1776 var bd = Ext.getBody();
1777 if(!bd){ return; }
1779 var cls = [
1780 Ext.isIE ? "ext-ie " + (Ext.isIE6 ? 'ext-ie6' : 'ext-ie7')
1781 : Ext.isGecko ? "ext-gecko"
1782 : Ext.isOpera ? "ext-opera"
1783 : Ext.isSafari ? "ext-safari" : ""];
1785 if(Ext.isMac){
1786 cls.push("ext-mac");
1788 if(Ext.isLinux){
1789 cls.push("ext-linux");
1791 if(Ext.isBorderBox){
1792 cls.push('ext-border-box');
1794 if(Ext.isStrict){
1795 var p = bd.dom.parentNode;
1796 if(p){
1797 p.className += ' ext-strict';
1800 bd.addClass(cls.join(' '));
1801 });
1804 Ext.EventObject = function(){
1806 var E = Ext.lib.Event;
1809 var safariKeys = {
1810 63234 : 37,
1811 63235 : 39,
1812 63232 : 38,
1813 63233 : 40,
1814 63276 : 33,
1815 63277 : 34,
1816 63272 : 46,
1817 63273 : 36,
1818 63275 : 35
1819 };
1822 var btnMap = Ext.isIE ? {1:0,4:1,2:2} :
1823 (Ext.isSafari ? {1:0,2:1,3:2} : {0:0,1:1,2:2});
1825 Ext.EventObjectImpl = function(e){
1826 if(e){
1827 this.setEvent(e.browserEvent || e);
1829 };
1830 Ext.EventObjectImpl.prototype = {
1832 browserEvent : null,
1834 button : -1,
1836 shiftKey : false,
1838 ctrlKey : false,
1840 altKey : false,
1843 BACKSPACE : 8,
1845 TAB : 9,
1847 RETURN : 13,
1849 ENTER : 13,
1851 SHIFT : 16,
1853 CONTROL : 17,
1855 ESC : 27,
1857 SPACE : 32,
1859 PAGEUP : 33,
1861 PAGEDOWN : 34,
1863 END : 35,
1865 HOME : 36,
1867 LEFT : 37,
1869 UP : 38,
1871 RIGHT : 39,
1873 DOWN : 40,
1875 DELETE : 46,
1877 F5 : 116,
1880 setEvent : function(e){
1881 if(e == this || (e && e.browserEvent)){
1882 return e;
1884 this.browserEvent = e;
1885 if(e){
1887 this.button = e.button ? btnMap[e.button] : (e.which ? e.which-1 : -1);
1888 if(e.type == 'click' && this.button == -1){
1889 this.button = 0;
1891 this.type = e.type;
1892 this.shiftKey = e.shiftKey;
1894 this.ctrlKey = e.ctrlKey || e.metaKey;
1895 this.altKey = e.altKey;
1897 this.keyCode = e.keyCode;
1898 this.charCode = e.charCode;
1900 this.target = E.getTarget(e);
1902 this.xy = E.getXY(e);
1903 }else{
1904 this.button = -1;
1905 this.shiftKey = false;
1906 this.ctrlKey = false;
1907 this.altKey = false;
1908 this.keyCode = 0;
1909 this.charCode =0;
1910 this.target = null;
1911 this.xy = [0, 0];
1913 return this;
1914 },
1917 stopEvent : function(){
1918 if(this.browserEvent){
1919 if(this.browserEvent.type == 'mousedown'){
1920 Ext.EventManager.stoppedMouseDownEvent.fire(this);
1922 E.stopEvent(this.browserEvent);
1924 },
1927 preventDefault : function(){
1928 if(this.browserEvent){
1929 E.preventDefault(this.browserEvent);
1931 },
1934 isNavKeyPress : function(){
1935 var k = this.keyCode;
1936 k = Ext.isSafari ? (safariKeys[k] || k) : k;
1937 return (k >= 33 && k <= 40) || k == this.RETURN || k == this.TAB || k == this.ESC;
1938 },
1940 isSpecialKey : function(){
1941 var k = this.keyCode;
1942 return (this.type == 'keypress' && this.ctrlKey) || k == 9 || k == 13 || k == 40 || k == 27 ||
1943 (k == 16) || (k == 17) ||
1944 (k >= 18 && k <= 20) ||
1945 (k >= 33 && k <= 35) ||
1946 (k >= 36 && k <= 39) ||
1947 (k >= 44 && k <= 45);
1948 },
1950 stopPropagation : function(){
1951 if(this.browserEvent){
1952 if(this.browserEvent.type == 'mousedown'){
1953 Ext.EventManager.stoppedMouseDownEvent.fire(this);
1955 E.stopPropagation(this.browserEvent);
1957 },
1960 getCharCode : function(){
1961 return this.charCode || this.keyCode;
1962 },
1965 getKey : function(){
1966 var k = this.keyCode || this.charCode;
1967 return Ext.isSafari ? (safariKeys[k] || k) : k;
1968 },
1971 getPageX : function(){
1972 return this.xy[0];
1973 },
1976 getPageY : function(){
1977 return this.xy[1];
1978 },
1981 getTime : function(){
1982 if(this.browserEvent){
1983 return E.getTime(this.browserEvent);
1985 return null;
1986 },
1989 getXY : function(){
1990 return this.xy;
1991 },
1994 getTarget : function(selector, maxDepth, returnEl){
1995 return selector ? Ext.fly(this.target).findParent(selector, maxDepth, returnEl) : (returnEl ? Ext.get(this.target) : this.target);
1996 },
1999 getRelatedTarget : function(){
2000 if(this.browserEvent){
2001 return E.getRelatedTarget(this.browserEvent);
2003 return null;
2004 },
2007 getWheelDelta : function(){
2008 var e = this.browserEvent;
2009 var delta = 0;
2010 if(e.wheelDelta){
2011 delta = e.wheelDelta/120;
2012 }else if(e.detail){
2013 delta = -e.detail/3;
2015 return delta;
2016 },
2019 hasModifier : function(){
2020 return ((this.ctrlKey || this.altKey) || this.shiftKey) ? true : false;
2021 },
2024 within : function(el, related){
2025 var t = this[related ? "getRelatedTarget" : "getTarget"]();
2026 return t && Ext.fly(el).contains(t);
2027 },
2029 getPoint : function(){
2030 return new Ext.lib.Point(this.xy[0], this.xy[1]);
2032 };
2034 return new Ext.EventObjectImpl();
2035 }();
2037 (function(){
2038 var D = Ext.lib.Dom;
2039 var E = Ext.lib.Event;
2040 var A = Ext.lib.Anim;
2042 var propCache = {};
2043 var camelRe = /(-[a-z])/gi;
2044 var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };
2045 var view = document.defaultView;
2047 Ext.Element = function(element, forceNew){
2048 var dom = typeof element == "string" ?
2049 document.getElementById(element) : element;
2050 if(!dom){ return null;
2052 var id = dom.id;
2053 if(forceNew !== true && id && Ext.Element.cache[id]){ return Ext.Element.cache[id];
2057 this.dom = dom;
2060 this.id = id || Ext.id(dom);
2061 };
2063 var El = Ext.Element;
2065 El.prototype = {
2067 originalDisplay : "",
2069 visibilityMode : 1,
2071 defaultUnit : "px",
2073 setVisibilityMode : function(visMode){
2074 this.visibilityMode = visMode;
2075 return this;
2076 },
2078 enableDisplayMode : function(display){
2079 this.setVisibilityMode(El.DISPLAY);
2080 if(typeof display != "undefined") this.originalDisplay = display;
2081 return this;
2082 },
2085 findParent : function(simpleSelector, maxDepth, returnEl){
2086 var p = this.dom, b = document.body, depth = 0, dq = Ext.DomQuery, stopEl;
2087 maxDepth = maxDepth || 50;
2088 if(typeof maxDepth != "number"){
2089 stopEl = Ext.getDom(maxDepth);
2090 maxDepth = 10;
2092 while(p && p.nodeType == 1 && depth < maxDepth && p != b && p != stopEl){
2093 if(dq.is(p, simpleSelector)){
2094 return returnEl ? Ext.get(p) : p;
2096 depth++;
2097 p = p.parentNode;
2099 return null;
2100 },
2104 findParentNode : function(simpleSelector, maxDepth, returnEl){
2105 var p = Ext.fly(this.dom.parentNode, '_internal');
2106 return p ? p.findParent(simpleSelector, maxDepth, returnEl) : null;
2107 },
2110 up : function(simpleSelector, maxDepth){
2111 return this.findParentNode(simpleSelector, maxDepth, true);
2112 },
2117 is : function(simpleSelector){
2118 return Ext.DomQuery.is(this.dom, simpleSelector);
2119 },
2122 animate : function(args, duration, onComplete, easing, animType){
2123 this.anim(args, {duration: duration, callback: onComplete, easing: easing}, animType);
2124 return this;
2125 },
2128 anim : function(args, opt, animType, defaultDur, defaultEase, cb){
2129 animType = animType || 'run';
2130 opt = opt || {};
2131 var anim = Ext.lib.Anim[animType](
2132 this.dom, args,
2133 (opt.duration || defaultDur) || .35,
2134 (opt.easing || defaultEase) || 'easeOut',
2135 function(){
2136 Ext.callback(cb, this);
2137 Ext.callback(opt.callback, opt.scope || this, [this, opt]);
2138 },
2139 this
2140 );
2141 opt.anim = anim;
2142 return anim;
2143 },
2145 preanim : function(a, i){
2146 return !a[i] ? false : (typeof a[i] == "object" ? a[i]: {duration: a[i+1], callback: a[i+2], easing: a[i+3]});
2147 },
2150 clean : function(forceReclean){
2151 if(this.isCleaned && forceReclean !== true){
2152 return this;
2154 var ns = /\S/;
2155 var d = this.dom, n = d.firstChild, ni = -1;
2156 while(n){
2157 var nx = n.nextSibling;
2158 if(n.nodeType == 3 && !ns.test(n.nodeValue)){
2159 d.removeChild(n);
2160 }else{
2161 n.nodeIndex = ++ni;
2163 n = nx;
2165 this.isCleaned = true;
2166 return this;
2167 },
2170 scrollIntoView : function(container, hscroll){
2171 var c = Ext.getDom(container) || Ext.getBody().dom;
2172 var el = this.dom;
2174 var o = this.getOffsetsTo(c),
2175 l = o[0] + c.scrollLeft,
2176 t = o[1] + c.scrollTop,
2177 b = t+el.offsetHeight,
2178 r = l+el.offsetWidth;
2180 var ch = c.clientHeight;
2181 var ct = parseInt(c.scrollTop, 10);
2182 var cl = parseInt(c.scrollLeft, 10);
2183 var cb = ct + ch;
2184 var cr = cl + c.clientWidth;
2186 if(el.offsetHeight > ch || t < ct){
2187 c.scrollTop = t;
2188 }else if(b > cb){
2189 c.scrollTop = b-ch;
2191 c.scrollTop = c.scrollTop;
2192 if(hscroll !== false){
2193 if(el.offsetWidth > c.clientWidth || l < cl){
2194 c.scrollLeft = l;
2195 }else if(r > cr){
2196 c.scrollLeft = r-c.clientWidth;
2198 c.scrollLeft = c.scrollLeft;
2200 return this;
2201 },
2203 scrollChildIntoView : function(child, hscroll){
2204 Ext.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll);
2205 },
2208 autoHeight : function(animate, duration, onComplete, easing){
2209 var oldHeight = this.getHeight();
2210 this.clip();
2211 this.setHeight(1); setTimeout(function(){
2212 var height = parseInt(this.dom.scrollHeight, 10); if(!animate){
2213 this.setHeight(height);
2214 this.unclip();
2215 if(typeof onComplete == "function"){
2216 onComplete();
2218 }else{
2219 this.setHeight(oldHeight); this.setHeight(height, animate, duration, function(){
2220 this.unclip();
2221 if(typeof onComplete == "function") onComplete();
2222 }.createDelegate(this), easing);
2224 }.createDelegate(this), 0);
2225 return this;
2226 },
2229 contains : function(el){
2230 if(!el){return false;}
2231 return D.isAncestor(this.dom, el.dom ? el.dom : el);
2232 },
2235 isVisible : function(deep) {
2236 var vis = !(this.getStyle("visibility") == "hidden" || this.getStyle("display") == "none");
2237 if(deep !== true || !vis){
2238 return vis;
2240 var p = this.dom.parentNode;
2241 while(p && p.tagName.toLowerCase() != "body"){
2242 if(!Ext.fly(p, '_isVisible').isVisible()){
2243 return false;
2245 p = p.parentNode;
2247 return true;
2248 },
2251 select : function(selector, unique){
2252 return El.select(selector, unique, this.dom);
2253 },
2256 query : function(selector, unique){
2257 return Ext.DomQuery.select(selector, this.dom);
2258 },
2261 child : function(selector, returnDom){
2262 var n = Ext.DomQuery.selectNode(selector, this.dom);
2263 return returnDom ? n : Ext.get(n);
2264 },
2267 down : function(selector, returnDom){
2268 var n = Ext.DomQuery.selectNode(" > " + selector, this.dom);
2269 return returnDom ? n : Ext.get(n);
2270 },
2273 initDD : function(group, config, overrides){
2274 var dd = new Ext.dd.DD(Ext.id(this.dom), group, config);
2275 return Ext.apply(dd, overrides);
2276 },
2279 initDDProxy : function(group, config, overrides){
2280 var dd = new Ext.dd.DDProxy(Ext.id(this.dom), group, config);
2281 return Ext.apply(dd, overrides);
2282 },
2285 initDDTarget : function(group, config, overrides){
2286 var dd = new Ext.dd.DDTarget(Ext.id(this.dom), group, config);
2287 return Ext.apply(dd, overrides);
2288 },
2291 setVisible : function(visible, animate){
2292 if(!animate || !A){
2293 if(this.visibilityMode == El.DISPLAY){
2294 this.setDisplayed(visible);
2295 }else{
2296 this.fixDisplay();
2297 this.dom.style.visibility = visible ? "visible" : "hidden";
2299 }else{
2300 var dom = this.dom;
2301 var visMode = this.visibilityMode;
2302 if(visible){
2303 this.setOpacity(.01);
2304 this.setVisible(true);
2306 this.anim({opacity: { to: (visible?1:0) }},
2307 this.preanim(arguments, 1),
2308 null, .35, 'easeIn', function(){
2309 if(!visible){
2310 if(visMode == El.DISPLAY){
2311 dom.style.display = "none";
2312 }else{
2313 dom.style.visibility = "hidden";
2315 Ext.get(dom).setOpacity(1);
2317 });
2319 return this;
2320 },
2323 isDisplayed : function() {
2324 return this.getStyle("display") != "none";
2325 },
2328 toggle : function(animate){
2329 this.setVisible(!this.isVisible(), this.preanim(arguments, 0));
2330 return this;
2331 },
2334 setDisplayed : function(value) {
2335 if(typeof value == "boolean"){
2336 value = value ? this.originalDisplay : "none";
2338 this.setStyle("display", value);
2339 return this;
2340 },
2343 focus : function() {
2344 try{
2345 this.dom.focus();
2346 }catch(e){}
2347 return this;
2348 },
2351 blur : function() {
2352 try{
2353 this.dom.blur();
2354 }catch(e){}
2355 return this;
2356 },
2359 addClass : function(className){
2360 if(Ext.isArray(className)){
2361 for(var i = 0, len = className.length; i < len; i++) {
2362 this.addClass(className[i]);
2364 }else{
2365 if(className && !this.hasClass(className)){
2366 this.dom.className = this.dom.className + " " + className;
2369 return this;
2370 },
2373 radioClass : function(className){
2374 var siblings = this.dom.parentNode.childNodes;
2375 for(var i = 0; i < siblings.length; i++) {
2376 var s = siblings[i];
2377 if(s.nodeType == 1){
2378 Ext.get(s).removeClass(className);
2381 this.addClass(className);
2382 return this;
2383 },
2386 removeClass : function(className){
2387 if(!className || !this.dom.className){
2388 return this;
2390 if(Ext.isArray(className)){
2391 for(var i = 0, len = className.length; i < len; i++) {
2392 this.removeClass(className[i]);
2394 }else{
2395 if(this.hasClass(className)){
2396 var re = this.classReCache[className];
2397 if (!re) {
2398 re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)', "g");
2399 this.classReCache[className] = re;
2401 this.dom.className =
2402 this.dom.className.replace(re, " ");
2405 return this;
2406 },
2408 classReCache: {},
2411 toggleClass : function(className){
2412 if(this.hasClass(className)){
2413 this.removeClass(className);
2414 }else{
2415 this.addClass(className);
2417 return this;
2418 },
2421 hasClass : function(className){
2422 return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1;
2423 },
2426 replaceClass : function(oldClassName, newClassName){
2427 this.removeClass(oldClassName);
2428 this.addClass(newClassName);
2429 return this;
2430 },
2433 getStyles : function(){
2434 var a = arguments, len = a.length, r = {};
2435 for(var i = 0; i < len; i++){
2436 r[a[i]] = this.getStyle(a[i]);
2438 return r;
2439 },
2442 getStyle : function(){
2443 return view && view.getComputedStyle ?
2444 function(prop){
2445 var el = this.dom, v, cs, camel;
2446 if(prop == 'float'){
2447 prop = "cssFloat";
2449 if(v = el.style[prop]){
2450 return v;
2452 if(cs = view.getComputedStyle(el, "")){
2453 if(!(camel = propCache[prop])){
2454 camel = propCache[prop] = prop.replace(camelRe, camelFn);
2456 return cs[camel];
2458 return null;
2459 } :
2460 function(prop){
2461 var el = this.dom, v, cs, camel;
2462 if(prop == 'opacity'){
2463 if(typeof el.style.filter == 'string'){
2464 var m = el.style.filter.match(/alpha\(opacity=(.*)\)/i);
2465 if(m){
2466 var fv = parseFloat(m[1]);
2467 if(!isNaN(fv)){
2468 return fv ? fv / 100 : 0;
2472 return 1;
2473 }else if(prop == 'float'){
2474 prop = "styleFloat";
2476 if(!(camel = propCache[prop])){
2477 camel = propCache[prop] = prop.replace(camelRe, camelFn);
2479 if(v = el.style[camel]){
2480 return v;
2482 if(cs = el.currentStyle){
2483 return cs[camel];
2485 return null;
2486 };
2487 }(),
2490 setStyle : function(prop, value){
2491 if(typeof prop == "string"){
2492 var camel;
2493 if(!(camel = propCache[prop])){
2494 camel = propCache[prop] = prop.replace(camelRe, camelFn);
2496 if(camel == 'opacity') {
2497 this.setOpacity(value);
2498 }else{
2499 this.dom.style[camel] = value;
2501 }else{
2502 for(var style in prop){
2503 if(typeof prop[style] != "function"){
2504 this.setStyle(style, prop[style]);
2508 return this;
2509 },
2512 applyStyles : function(style){
2513 Ext.DomHelper.applyStyles(this.dom, style);
2514 return this;
2515 },
2518 getX : function(){
2519 return D.getX(this.dom);
2520 },
2523 getY : function(){
2524 return D.getY(this.dom);
2525 },
2528 getXY : function(){
2529 return D.getXY(this.dom);
2530 },
2533 getOffsetsTo : function(el){
2534 var o = this.getXY();
2535 var e = Ext.fly(el, '_internal').getXY();
2536 return [o[0]-e[0],o[1]-e[1]];
2537 },
2540 setX : function(x, animate){
2541 if(!animate || !A){
2542 D.setX(this.dom, x);
2543 }else{
2544 this.setXY([x, this.getY()], this.preanim(arguments, 1));
2546 return this;
2547 },
2550 setY : function(y, animate){
2551 if(!animate || !A){
2552 D.setY(this.dom, y);
2553 }else{
2554 this.setXY([this.getX(), y], this.preanim(arguments, 1));
2556 return this;
2557 },
2560 setLeft : function(left){
2561 this.setStyle("left", this.addUnits(left));
2562 return this;
2563 },
2566 setTop : function(top){
2567 this.setStyle("top", this.addUnits(top));
2568 return this;
2569 },
2572 setRight : function(right){
2573 this.setStyle("right", this.addUnits(right));
2574 return this;
2575 },
2578 setBottom : function(bottom){
2579 this.setStyle("bottom", this.addUnits(bottom));
2580 return this;
2581 },
2584 setXY : function(pos, animate){
2585 if(!animate || !A){
2586 D.setXY(this.dom, pos);
2587 }else{
2588 this.anim({points: {to: pos}}, this.preanim(arguments, 1), 'motion');
2590 return this;
2591 },
2594 setLocation : function(x, y, animate){
2595 this.setXY([x, y], this.preanim(arguments, 2));
2596 return this;
2597 },
2600 moveTo : function(x, y, animate){
2601 this.setXY([x, y], this.preanim(arguments, 2));
2602 return this;
2603 },
2606 getRegion : function(){
2607 return D.getRegion(this.dom);
2608 },
2611 getHeight : function(contentHeight){
2612 var h = this.dom.offsetHeight || 0;
2613 h = contentHeight !== true ? h : h-this.getBorderWidth("tb")-this.getPadding("tb");
2614 return h < 0 ? 0 : h;
2615 },
2618 getWidth : function(contentWidth){
2619 var w = this.dom.offsetWidth || 0;
2620 w = contentWidth !== true ? w : w-this.getBorderWidth("lr")-this.getPadding("lr");
2621 return w < 0 ? 0 : w;
2622 },
2625 getComputedHeight : function(){
2626 var h = Math.max(this.dom.offsetHeight, this.dom.clientHeight);
2627 if(!h){
2628 h = parseInt(this.getStyle('height'), 10) || 0;
2629 if(!this.isBorderBox()){
2630 h += this.getFrameWidth('tb');
2633 return h;
2634 },
2637 getComputedWidth : function(){
2638 var w = Math.max(this.dom.offsetWidth, this.dom.clientWidth);
2639 if(!w){
2640 w = parseInt(this.getStyle('width'), 10) || 0;
2641 if(!this.isBorderBox()){
2642 w += this.getFrameWidth('lr');
2645 return w;
2646 },
2649 getSize : function(contentSize){
2650 return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)};
2651 },
2653 getStyleSize : function(){
2654 var w, h, d = this.dom, s = d.style;
2655 if(s.width && s.width != 'auto'){
2656 w = parseInt(s.width, 10);
2657 if(Ext.isBorderBox){
2658 w -= this.getFrameWidth('lr');
2661 if(s.height && s.height != 'auto'){
2662 h = parseInt(s.height, 10);
2663 if(Ext.isBorderBox){
2664 h -= this.getFrameWidth('tb');
2667 return {width: w || this.getWidth(true), height: h || this.getHeight(true)};
2669 },
2672 getViewSize : function(){
2673 var d = this.dom, doc = document, aw = 0, ah = 0;
2674 if(d == doc || d == doc.body){
2675 return {width : D.getViewWidth(), height: D.getViewHeight()};
2676 }else{
2677 return {
2678 width : d.clientWidth,
2679 height: d.clientHeight
2680 };
2682 },
2685 getValue : function(asNumber){
2686 return asNumber ? parseInt(this.dom.value, 10) : this.dom.value;
2687 },
2689 adjustWidth : function(width){
2690 if(typeof width == "number"){
2691 if(this.autoBoxAdjust && !this.isBorderBox()){
2692 width -= (this.getBorderWidth("lr") + this.getPadding("lr"));
2694 if(width < 0){
2695 width = 0;
2698 return width;
2699 },
2701 adjustHeight : function(height){
2702 if(typeof height == "number"){
2703 if(this.autoBoxAdjust && !this.isBorderBox()){
2704 height -= (this.getBorderWidth("tb") + this.getPadding("tb"));
2706 if(height < 0){
2707 height = 0;
2710 return height;
2711 },
2714 setWidth : function(width, animate){
2715 width = this.adjustWidth(width);
2716 if(!animate || !A){
2717 this.dom.style.width = this.addUnits(width);
2718 }else{
2719 this.anim({width: {to: width}}, this.preanim(arguments, 1));
2721 return this;
2722 },
2725 setHeight : function(height, animate){
2726 height = this.adjustHeight(height);
2727 if(!animate || !A){
2728 this.dom.style.height = this.addUnits(height);
2729 }else{
2730 this.anim({height: {to: height}}, this.preanim(arguments, 1));
2732 return this;
2733 },
2736 setSize : function(width, height, animate){
2737 if(typeof width == "object"){ height = width.height; width = width.width;
2739 width = this.adjustWidth(width); height = this.adjustHeight(height);
2740 if(!animate || !A){
2741 this.dom.style.width = this.addUnits(width);
2742 this.dom.style.height = this.addUnits(height);
2743 }else{
2744 this.anim({width: {to: width}, height: {to: height}}, this.preanim(arguments, 2));
2746 return this;
2747 },
2750 setBounds : function(x, y, width, height, animate){
2751 if(!animate || !A){
2752 this.setSize(width, height);
2753 this.setLocation(x, y);
2754 }else{
2755 width = this.adjustWidth(width); height = this.adjustHeight(height);
2756 this.anim({points: {to: [x, y]}, width: {to: width}, height: {to: height}},
2757 this.preanim(arguments, 4), 'motion');
2759 return this;
2760 },
2763 setRegion : function(region, animate){
2764 this.setBounds(region.left, region.top, region.right-region.left, region.bottom-region.top, this.preanim(arguments, 1));
2765 return this;
2766 },
2769 addListener : function(eventName, fn, scope, options){
2770 Ext.EventManager.on(this.dom, eventName, fn, scope || this, options);
2771 },
2774 removeListener : function(eventName, fn){
2775 Ext.EventManager.removeListener(this.dom, eventName, fn);
2776 return this;
2777 },
2780 removeAllListeners : function(){
2781 E.purgeElement(this.dom);
2782 return this;
2783 },
2786 relayEvent : function(eventName, observable){
2787 this.on(eventName, function(e){
2788 observable.fireEvent(eventName, e);
2789 });
2790 },
2793 setOpacity : function(opacity, animate){
2794 if(!animate || !A){
2795 var s = this.dom.style;
2796 if(Ext.isIE){
2797 s.zoom = 1;
2798 s.filter = (s.filter || '').replace(/alpha\([^\)]*\)/gi,"") +
2799 (opacity == 1 ? "" : " alpha(opacity=" + opacity * 100 + ")");
2800 }else{
2801 s.opacity = opacity;
2803 }else{
2804 this.anim({opacity: {to: opacity}}, this.preanim(arguments, 1), null, .35, 'easeIn');
2806 return this;
2807 },
2810 getLeft : function(local){
2811 if(!local){
2812 return this.getX();
2813 }else{
2814 return parseInt(this.getStyle("left"), 10) || 0;
2816 },
2819 getRight : function(local){
2820 if(!local){
2821 return this.getX() + this.getWidth();
2822 }else{
2823 return (this.getLeft(true) + this.getWidth()) || 0;
2825 },
2828 getTop : function(local) {
2829 if(!local){
2830 return this.getY();
2831 }else{
2832 return parseInt(this.getStyle("top"), 10) || 0;
2834 },
2837 getBottom : function(local){
2838 if(!local){
2839 return this.getY() + this.getHeight();
2840 }else{
2841 return (this.getTop(true) + this.getHeight()) || 0;
2843 },
2846 position : function(pos, zIndex, x, y){
2847 if(!pos){
2848 if(this.getStyle('position') == 'static'){
2849 this.setStyle('position', 'relative');
2851 }else{
2852 this.setStyle("position", pos);
2854 if(zIndex){
2855 this.setStyle("z-index", zIndex);
2857 if(x !== undefined && y !== undefined){
2858 this.setXY([x, y]);
2859 }else if(x !== undefined){
2860 this.setX(x);
2861 }else if(y !== undefined){
2862 this.setY(y);
2864 },
2867 clearPositioning : function(value){
2868 value = value ||'';
2869 this.setStyle({
2870 "left": value,
2871 "right": value,
2872 "top": value,
2873 "bottom": value,
2874 "z-index": "",
2875 "position" : "static"
2876 });
2877 return this;
2878 },
2881 getPositioning : function(){
2882 var l = this.getStyle("left");
2883 var t = this.getStyle("top");
2884 return {
2885 "position" : this.getStyle("position"),
2886 "left" : l,
2887 "right" : l ? "" : this.getStyle("right"),
2888 "top" : t,
2889 "bottom" : t ? "" : this.getStyle("bottom"),
2890 "z-index" : this.getStyle("z-index")
2891 };
2892 },
2895 getBorderWidth : function(side){
2896 return this.addStyles(side, El.borders);
2897 },
2900 getPadding : function(side){
2901 return this.addStyles(side, El.paddings);
2902 },
2905 setPositioning : function(pc){
2906 this.applyStyles(pc);
2907 if(pc.right == "auto"){
2908 this.dom.style.right = "";
2910 if(pc.bottom == "auto"){
2911 this.dom.style.bottom = "";
2913 return this;
2914 },
2916 fixDisplay : function(){
2917 if(this.getStyle("display") == "none"){
2918 this.setStyle("visibility", "hidden");
2919 this.setStyle("display", this.originalDisplay); if(this.getStyle("display") == "none"){ this.setStyle("display", "block");
2922 },
2924 setOverflow : function(v){
2925 if(v=='auto' && Ext.isMac && Ext.isGecko){ this.dom.style.overflow = 'hidden';
2926 (function(){this.dom.style.overflow = 'auto';}).defer(1, this);
2927 }else{
2928 this.dom.style.overflow = v;
2930 },
2933 setLeftTop : function(left, top){
2934 this.dom.style.left = this.addUnits(left);
2935 this.dom.style.top = this.addUnits(top);
2936 return this;
2937 },
2940 move : function(direction, distance, animate){
2941 var xy = this.getXY();
2942 direction = direction.toLowerCase();
2943 switch(direction){
2944 case "l":
2945 case "left":
2946 this.moveTo(xy[0]-distance, xy[1], this.preanim(arguments, 2));
2947 break;
2948 case "r":
2949 case "right":
2950 this.moveTo(xy[0]+distance, xy[1], this.preanim(arguments, 2));
2951 break;
2952 case "t":
2953 case "top":
2954 case "up":
2955 this.moveTo(xy[0], xy[1]-distance, this.preanim(arguments, 2));
2956 break;
2957 case "b":
2958 case "bottom":
2959 case "down":
2960 this.moveTo(xy[0], xy[1]+distance, this.preanim(arguments, 2));
2961 break;
2963 return this;
2964 },
2967 clip : function(){
2968 if(!this.isClipped){
2969 this.isClipped = true;
2970 this.originalClip = {
2971 "o": this.getStyle("overflow"),
2972 "x": this.getStyle("overflow-x"),
2973 "y": this.getStyle("overflow-y")
2974 };
2975 this.setStyle("overflow", "hidden");
2976 this.setStyle("overflow-x", "hidden");
2977 this.setStyle("overflow-y", "hidden");
2979 return this;
2980 },
2983 unclip : function(){
2984 if(this.isClipped){
2985 this.isClipped = false;
2986 var o = this.originalClip;
2987 if(o.o){this.setStyle("overflow", o.o);}
2988 if(o.x){this.setStyle("overflow-x", o.x);}
2989 if(o.y){this.setStyle("overflow-y", o.y);}
2991 return this;
2992 },
2996 getAnchorXY : function(anchor, local, s){
2998 var w, h, vp = false;
2999 if(!s){
3000 var d = this.dom;
3001 if(d == document.body || d == document){
3002 vp = true;
3003 w = D.getViewWidth(); h = D.getViewHeight();
3004 }else{
3005 w = this.getWidth(); h = this.getHeight();
3007 }else{
3008 w = s.width; h = s.height;
3010 var x = 0, y = 0, r = Math.round;
3011 switch((anchor || "tl").toLowerCase()){
3012 case "c":
3013 x = r(w*.5);
3014 y = r(h*.5);
3015 break;
3016 case "t":
3017 x = r(w*.5);
3018 y = 0;
3019 break;
3020 case "l":
3021 x = 0;
3022 y = r(h*.5);
3023 break;
3024 case "r":
3025 x = w;
3026 y = r(h*.5);
3027 break;
3028 case "b":
3029 x = r(w*.5);
3030 y = h;
3031 break;
3032 case "tl":
3033 x = 0;
3034 y = 0;
3035 break;
3036 case "bl":
3037 x = 0;
3038 y = h;
3039 break;
3040 case "br":
3041 x = w;
3042 y = h;
3043 break;
3044 case "tr":
3045 x = w;
3046 y = 0;
3047 break;
3049 if(local === true){
3050 return [x, y];
3052 if(vp){
3053 var sc = this.getScroll();
3054 return [x + sc.left, y + sc.top];
3056 var o = this.getXY();
3057 return [x+o[0], y+o[1]];
3058 },
3061 getAlignToXY : function(el, p, o){
3062 el = Ext.get(el);
3063 if(!el || !el.dom){
3064 throw "Element.alignToXY with an element that doesn't exist";
3066 var d = this.dom;
3067 var c = false; var p1 = "", p2 = "";
3068 o = o || [0,0];
3070 if(!p){
3071 p = "tl-bl";
3072 }else if(p == "?"){
3073 p = "tl-bl?";
3074 }else if(p.indexOf("-") == -1){
3075 p = "tl-" + p;
3077 p = p.toLowerCase();
3078 var m = p.match(/^([a-z]+)-([a-z]+)(\?)?$/);
3079 if(!m){
3080 throw "Element.alignTo with an invalid alignment " + p;
3082 p1 = m[1]; p2 = m[2]; c = !!m[3];
3084 var a1 = this.getAnchorXY(p1, true);
3085 var a2 = el.getAnchorXY(p2, false);
3087 var x = a2[0] - a1[0] + o[0];
3088 var y = a2[1] - a1[1] + o[1];
3090 if(c){
3091 var w = this.getWidth(), h = this.getHeight(), r = el.getRegion();
3092 var dw = D.getViewWidth()-5, dh = D.getViewHeight()-5;
3094 var p1y = p1.charAt(0), p1x = p1.charAt(p1.length-1);
3095 var p2y = p2.charAt(0), p2x = p2.charAt(p2.length-1);
3096 var swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t"));
3097 var swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r"));
3099 var doc = document;
3100 var scrollX = (doc.documentElement.scrollLeft || doc.body.scrollLeft || 0)+5;
3101 var scrollY = (doc.documentElement.scrollTop || doc.body.scrollTop || 0)+5;
3103 if((x+w) > dw + scrollX){
3104 x = swapX ? r.left-w : dw+scrollX-w;
3106 if(x < scrollX){
3107 x = swapX ? r.right : scrollX;
3109 if((y+h) > dh + scrollY){
3110 y = swapY ? r.top-h : dh+scrollY-h;
3112 if (y < scrollY){
3113 y = swapY ? r.bottom : scrollY;
3116 return [x,y];
3117 },
3119 getConstrainToXY : function(){
3120 var os = {top:0, left:0, bottom:0, right: 0};
3122 return function(el, local, offsets, proposedXY){
3123 el = Ext.get(el);
3124 offsets = offsets ? Ext.applyIf(offsets, os) : os;
3126 var vw, vh, vx = 0, vy = 0;
3127 if(el.dom == document.body || el.dom == document){
3128 vw = Ext.lib.Dom.getViewWidth();
3129 vh = Ext.lib.Dom.getViewHeight();
3130 }else{
3131 vw = el.dom.clientWidth;
3132 vh = el.dom.clientHeight;
3133 if(!local){
3134 var vxy = el.getXY();
3135 vx = vxy[0];
3136 vy = vxy[1];
3140 var s = el.getScroll();
3142 vx += offsets.left + s.left;
3143 vy += offsets.top + s.top;
3145 vw -= offsets.right;
3146 vh -= offsets.bottom;
3148 var vr = vx+vw;
3149 var vb = vy+vh;
3151 var xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]);
3152 var x = xy[0], y = xy[1];
3153 var w = this.dom.offsetWidth, h = this.dom.offsetHeight;
3155 var moved = false;
3157 if((x + w) > vr){
3158 x = vr - w;
3159 moved = true;
3161 if((y + h) > vb){
3162 y = vb - h;
3163 moved = true;
3165 if(x < vx){
3166 x = vx;
3167 moved = true;
3169 if(y < vy){
3170 y = vy;
3171 moved = true;
3173 return moved ? [x, y] : false;
3174 };
3175 }(),
3177 adjustForConstraints : function(xy, parent, offsets){
3178 return this.getConstrainToXY(parent || document, false, offsets, xy) || xy;
3179 },
3182 alignTo : function(element, position, offsets, animate){
3183 var xy = this.getAlignToXY(element, position, offsets);
3184 this.setXY(xy, this.preanim(arguments, 3));
3185 return this;
3186 },
3189 anchorTo : function(el, alignment, offsets, animate, monitorScroll, callback){
3190 var action = function(){
3191 this.alignTo(el, alignment, offsets, animate);
3192 Ext.callback(callback, this);
3193 };
3194 Ext.EventManager.onWindowResize(action, this);
3195 var tm = typeof monitorScroll;
3196 if(tm != 'undefined'){
3197 Ext.EventManager.on(window, 'scroll', action, this,
3198 {buffer: tm == 'number' ? monitorScroll : 50});
3200 action.call(this); return this;
3201 },
3203 clearOpacity : function(){
3204 if (window.ActiveXObject) {
3205 if(typeof this.dom.style.filter == 'string' && (/alpha/i).test(this.dom.style.filter)){
3206 this.dom.style.filter = "";
3208 } else {
3209 this.dom.style.opacity = "";
3210 this.dom.style["-moz-opacity"] = "";
3211 this.dom.style["-khtml-opacity"] = "";
3213 return this;
3214 },
3217 hide : function(animate){
3218 this.setVisible(false, this.preanim(arguments, 0));
3219 return this;
3220 },
3223 show : function(animate){
3224 this.setVisible(true, this.preanim(arguments, 0));
3225 return this;
3226 },
3229 addUnits : function(size){
3230 return Ext.Element.addUnits(size, this.defaultUnit);
3231 },
3234 update : function(html, loadScripts, callback){
3235 if(typeof html == "undefined"){
3236 html = "";
3238 if(loadScripts !== true){
3239 this.dom.innerHTML = html;
3240 if(typeof callback == "function"){
3241 callback();
3243 return this;
3245 var id = Ext.id();
3246 var dom = this.dom;
3248 html += '<span id="' + id + '"></span>';
3250 E.onAvailable(id, function(){
3251 var hd = document.getElementsByTagName("head")[0];
3252 var re = /(?:<script([^>]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig;
3253 var srcRe = /\ssrc=([\'\"])(.*?)\1/i;
3254 var typeRe = /\stype=([\'\"])(.*?)\1/i;
3256 var match;
3257 while(match = re.exec(html)){
3258 var attrs = match[1];
3259 var srcMatch = attrs ? attrs.match(srcRe) : false;
3260 if(srcMatch && srcMatch[2]){
3261 var s = document.createElement("script");
3262 s.src = srcMatch[2];
3263 var typeMatch = attrs.match(typeRe);
3264 if(typeMatch && typeMatch[2]){
3265 s.type = typeMatch[2];
3267 hd.appendChild(s);
3268 }else if(match[2] && match[2].length > 0){
3269 if(window.execScript) {
3270 window.execScript(match[2]);
3271 } else {
3272 window.eval(match[2]);
3276 var el = document.getElementById(id);
3277 if(el){Ext.removeNode(el);}
3278 if(typeof callback == "function"){
3279 callback();
3281 });
3282 dom.innerHTML = html.replace(/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig, "");
3283 return this;
3284 },
3287 load : function(){
3288 var um = this.getUpdater();
3289 um.update.apply(um, arguments);
3290 return this;
3291 },
3294 getUpdater : function(){
3295 if(!this.updateManager){
3296 this.updateManager = new Ext.Updater(this);
3298 return this.updateManager;
3299 },
3302 unselectable : function(){
3303 this.dom.unselectable = "on";
3304 this.swallowEvent("selectstart", true);
3305 this.applyStyles("-moz-user-select:none;-khtml-user-select:none;");
3306 this.addClass("x-unselectable");
3307 return this;
3308 },
3311 getCenterXY : function(){
3312 return this.getAlignToXY(document, 'c-c');
3313 },
3316 center : function(centerIn){
3317 this.alignTo(centerIn || document, 'c-c');
3318 return this;
3319 },
3322 isBorderBox : function(){
3323 return noBoxAdjust[this.dom.tagName.toLowerCase()] || Ext.isBorderBox;
3324 },
3327 getBox : function(contentBox, local){
3328 var xy;
3329 if(!local){
3330 xy = this.getXY();
3331 }else{
3332 var left = parseInt(this.getStyle("left"), 10) || 0;
3333 var top = parseInt(this.getStyle("top"), 10) || 0;
3334 xy = [left, top];
3336 var el = this.dom, w = el.offsetWidth, h = el.offsetHeight, bx;
3337 if(!contentBox){
3338 bx = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: w, height: h};
3339 }else{
3340 var l = this.getBorderWidth("l")+this.getPadding("l");
3341 var r = this.getBorderWidth("r")+this.getPadding("r");
3342 var t = this.getBorderWidth("t")+this.getPadding("t");
3343 var b = this.getBorderWidth("b")+this.getPadding("b");
3344 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)};
3346 bx.right = bx.x + bx.width;
3347 bx.bottom = bx.y + bx.height;
3348 return bx;
3349 },
3352 getFrameWidth : function(sides, onlyContentBox){
3353 return onlyContentBox && Ext.isBorderBox ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides));
3354 },
3357 setBox : function(box, adjust, animate){
3358 var w = box.width, h = box.height;
3359 if((adjust && !this.autoBoxAdjust) && !this.isBorderBox()){
3360 w -= (this.getBorderWidth("lr") + this.getPadding("lr"));
3361 h -= (this.getBorderWidth("tb") + this.getPadding("tb"));
3363 this.setBounds(box.x, box.y, w, h, this.preanim(arguments, 2));
3364 return this;
3365 },
3368 repaint : function(){
3369 var dom = this.dom;
3370 this.addClass("x-repaint");
3371 setTimeout(function(){
3372 Ext.get(dom).removeClass("x-repaint");
3373 }, 1);
3374 return this;
3375 },
3378 getMargins : function(side){
3379 if(!side){
3380 return {
3381 top: parseInt(this.getStyle("margin-top"), 10) || 0,
3382 left: parseInt(this.getStyle("margin-left"), 10) || 0,
3383 bottom: parseInt(this.getStyle("margin-bottom"), 10) || 0,
3384 right: parseInt(this.getStyle("margin-right"), 10) || 0
3385 };
3386 }else{
3387 return this.addStyles(side, El.margins);
3389 },
3391 addStyles : function(sides, styles){
3392 var val = 0, v, w;
3393 for(var i = 0, len = sides.length; i < len; i++){
3394 v = this.getStyle(styles[sides.charAt(i)]);
3395 if(v){
3396 w = parseInt(v, 10);
3397 if(w){ val += (w >= 0 ? w : -1 * w); }
3400 return val;
3401 },
3404 createProxy : function(config, renderTo, matchBox){
3405 config = typeof config == "object" ?
3406 config : {tag : "div", cls: config};
3408 var proxy;
3409 if(renderTo){
3410 proxy = Ext.DomHelper.append(renderTo, config, true);
3411 }else {
3412 proxy = Ext.DomHelper.insertBefore(this.dom, config, true);
3414 if(matchBox){
3415 proxy.setBox(this.getBox());
3417 return proxy;
3418 },
3421 mask : function(msg, msgCls){
3422 if(this.getStyle("position") == "static"){
3423 this.setStyle("position", "relative");
3425 if(this._maskMsg){
3426 this._maskMsg.remove();
3428 if(this._mask){
3429 this._mask.remove();
3432 this._mask = Ext.DomHelper.append(this.dom, {cls:"ext-el-mask"}, true);
3434 this.addClass("x-masked");
3435 this._mask.setDisplayed(true);
3436 if(typeof msg == 'string'){
3437 this._maskMsg = Ext.DomHelper.append(this.dom, {cls:"ext-el-mask-msg", cn:{tag:'div'}}, true);
3438 var mm = this._maskMsg;
3439 mm.dom.className = msgCls ? "ext-el-mask-msg " + msgCls : "ext-el-mask-msg";
3440 mm.dom.firstChild.innerHTML = msg;
3441 mm.setDisplayed(true);
3442 mm.center(this);
3444 if(Ext.isIE && !(Ext.isIE7 && Ext.isStrict) && this.getStyle('height') == 'auto'){ this._mask.setSize(this.dom.clientWidth, this.getHeight());
3446 return this._mask;
3447 },
3450 unmask : function(){
3451 if(this._mask){
3452 if(this._maskMsg){
3453 this._maskMsg.remove();
3454 delete this._maskMsg;
3456 this._mask.remove();
3457 delete this._mask;
3459 this.removeClass("x-masked");
3460 },
3463 isMasked : function(){
3464 return this._mask && this._mask.isVisible();
3465 },
3468 createShim : function(){
3469 var el = document.createElement('iframe');
3470 el.frameBorder = 'no';
3471 el.className = 'ext-shim';
3472 if(Ext.isIE && Ext.isSecure){
3473 el.src = Ext.SSL_SECURE_URL;
3475 var shim = Ext.get(this.dom.parentNode.insertBefore(el, this.dom));
3476 shim.autoBoxAdjust = false;
3477 return shim;
3478 },
3481 remove : function(){
3482 Ext.removeNode(this.dom);
3483 delete El.cache[this.dom.id];
3484 },
3487 hover : function(overFn, outFn, scope){
3488 var preOverFn = function(e){
3489 if(!e.within(this, true)){
3490 overFn.apply(scope || this, arguments);
3492 };
3493 var preOutFn = function(e){
3494 if(!e.within(this, true)){
3495 outFn.apply(scope || this, arguments);
3497 };
3498 this.on("mouseover", preOverFn, this.dom);
3499 this.on("mouseout", preOutFn, this.dom);
3500 return this;
3501 },
3504 addClassOnOver : function(className){
3505 this.hover(
3506 function(){
3507 Ext.fly(this, '_internal').addClass(className);
3508 },
3509 function(){
3510 Ext.fly(this, '_internal').removeClass(className);
3512 );
3513 return this;
3514 },
3517 addClassOnFocus : function(className){
3518 this.on("focus", function(){
3519 Ext.fly(this, '_internal').addClass(className);
3520 }, this.dom);
3521 this.on("blur", function(){
3522 Ext.fly(this, '_internal').removeClass(className);
3523 }, this.dom);
3524 return this;
3525 },
3527 addClassOnClick : function(className){
3528 var dom = this.dom;
3529 this.on("mousedown", function(){
3530 Ext.fly(dom, '_internal').addClass(className);
3531 var d = Ext.getDoc();
3532 var fn = function(){
3533 Ext.fly(dom, '_internal').removeClass(className);
3534 d.removeListener("mouseup", fn);
3535 };
3536 d.on("mouseup", fn);
3537 });
3538 return this;
3539 },
3542 swallowEvent : function(eventName, preventDefault){
3543 var fn = function(e){
3544 e.stopPropagation();
3545 if(preventDefault){
3546 e.preventDefault();
3548 };
3549 if(Ext.isArray(eventName)){
3550 for(var i = 0, len = eventName.length; i < len; i++){
3551 this.on(eventName[i], fn);
3553 return this;
3555 this.on(eventName, fn);
3556 return this;
3557 },
3560 parent : function(selector, returnDom){
3561 return this.matchNode('parentNode', 'parentNode', selector, returnDom);
3562 },
3565 next : function(selector, returnDom){
3566 return this.matchNode('nextSibling', 'nextSibling', selector, returnDom);
3567 },
3570 prev : function(selector, returnDom){
3571 return this.matchNode('previousSibling', 'previousSibling', selector, returnDom);
3572 },
3576 first : function(selector, returnDom){
3577 return this.matchNode('nextSibling', 'firstChild', selector, returnDom);
3578 },
3581 last : function(selector, returnDom){
3582 return this.matchNode('previousSibling', 'lastChild', selector, returnDom);
3583 },
3585 matchNode : function(dir, start, selector, returnDom){
3586 var n = this.dom[start];
3587 while(n){
3588 if(n.nodeType == 1 && (!selector || Ext.DomQuery.is(n, selector))){
3589 return !returnDom ? Ext.get(n) : n;
3591 n = n[dir];
3593 return null;
3594 },
3597 appendChild: function(el){
3598 el = Ext.get(el);
3599 el.appendTo(this);
3600 return this;
3601 },
3604 createChild: function(config, insertBefore, returnDom){
3605 config = config || {tag:'div'};
3606 if(insertBefore){
3607 return Ext.DomHelper.insertBefore(insertBefore, config, returnDom !== true);
3609 return Ext.DomHelper[!this.dom.firstChild ? 'overwrite' : 'append'](this.dom, config, returnDom !== true);
3610 },
3613 appendTo: function(el){
3614 el = Ext.getDom(el);
3615 el.appendChild(this.dom);
3616 return this;
3617 },
3620 insertBefore: function(el){
3621 el = Ext.getDom(el);
3622 el.parentNode.insertBefore(this.dom, el);
3623 return this;
3624 },
3627 insertAfter: function(el){
3628 el = Ext.getDom(el);
3629 el.parentNode.insertBefore(this.dom, el.nextSibling);
3630 return this;
3631 },
3634 insertFirst: function(el, returnDom){
3635 el = el || {};
3636 if(typeof el == 'object' && !el.nodeType && !el.dom){ return this.createChild(el, this.dom.firstChild, returnDom);
3637 }else{
3638 el = Ext.getDom(el);
3639 this.dom.insertBefore(el, this.dom.firstChild);
3640 return !returnDom ? Ext.get(el) : el;
3642 },
3645 insertSibling: function(el, where, returnDom){
3646 var rt;
3647 if(Ext.isArray(el)){
3648 for(var i = 0, len = el.length; i < len; i++){
3649 rt = this.insertSibling(el[i], where, returnDom);
3651 return rt;
3653 where = where ? where.toLowerCase() : 'before';
3654 el = el || {};
3655 var refNode = where == 'before' ? this.dom : this.dom.nextSibling;
3657 if(typeof el == 'object' && !el.nodeType && !el.dom){ if(where == 'after' && !this.dom.nextSibling){
3658 rt = Ext.DomHelper.append(this.dom.parentNode, el, !returnDom);
3659 }else{
3660 rt = Ext.DomHelper[where == 'after' ? 'insertAfter' : 'insertBefore'](this.dom, el, !returnDom);
3663 }else{
3664 rt = this.dom.parentNode.insertBefore(Ext.getDom(el), refNode);
3665 if(!returnDom){
3666 rt = Ext.get(rt);
3669 return rt;
3670 },
3673 wrap: function(config, returnDom){
3674 if(!config){
3675 config = {tag: "div"};
3677 var newEl = Ext.DomHelper.insertBefore(this.dom, config, !returnDom);
3678 newEl.dom ? newEl.dom.appendChild(this.dom) : newEl.appendChild(this.dom);
3679 return newEl;
3680 },
3683 replace: function(el){
3684 el = Ext.get(el);
3685 this.insertBefore(el);
3686 el.remove();
3687 return this;
3688 },
3691 replaceWith: function(el){
3692 if(typeof el == 'object' && !el.nodeType && !el.dom){ el = this.insertSibling(el, 'before');
3693 }else{
3694 el = Ext.getDom(el);
3695 this.dom.parentNode.insertBefore(el, this.dom);
3697 El.uncache(this.id);
3698 this.dom.parentNode.removeChild(this.dom);
3699 this.dom = el;
3700 this.id = Ext.id(el);
3701 El.cache[this.id] = this;
3702 return this;
3703 },
3706 insertHtml : function(where, html, returnEl){
3707 var el = Ext.DomHelper.insertHtml(where, this.dom, html);
3708 return returnEl ? Ext.get(el) : el;
3709 },
3712 set : function(o, useSet){
3713 var el = this.dom;
3714 useSet = typeof useSet == 'undefined' ? (el.setAttribute ? true : false) : useSet;
3715 for(var attr in o){
3716 if(attr == "style" || typeof o[attr] == "function") continue;
3717 if(attr=="cls"){
3718 el.className = o["cls"];
3719 }else if(o.hasOwnProperty(attr)){
3720 if(useSet) el.setAttribute(attr, o[attr]);
3721 else el[attr] = o[attr];
3724 if(o.style){
3725 Ext.DomHelper.applyStyles(el, o.style);
3727 return this;
3728 },
3731 addKeyListener : function(key, fn, scope){
3732 var config;
3733 if(typeof key != "object" || Ext.isArray(key)){
3734 config = {
3735 key: key,
3736 fn: fn,
3737 scope: scope
3738 };
3739 }else{
3740 config = {
3741 key : key.key,
3742 shift : key.shift,
3743 ctrl : key.ctrl,
3744 alt : key.alt,
3745 fn: fn,
3746 scope: scope
3747 };
3749 return new Ext.KeyMap(this, config);
3750 },
3753 addKeyMap : function(config){
3754 return new Ext.KeyMap(this, config);
3755 },
3758 isScrollable : function(){
3759 var dom = this.dom;
3760 return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth;
3761 },
3764 scrollTo : function(side, value, animate){
3765 var prop = side.toLowerCase() == "left" ? "scrollLeft" : "scrollTop";
3766 if(!animate || !A){
3767 this.dom[prop] = value;
3768 }else{
3769 var to = prop == "scrollLeft" ? [value, this.dom.scrollTop] : [this.dom.scrollLeft, value];
3770 this.anim({scroll: {"to": to}}, this.preanim(arguments, 2), 'scroll');
3772 return this;
3773 },
3776 scroll : function(direction, distance, animate){
3777 if(!this.isScrollable()){
3778 return;
3780 var el = this.dom;
3781 var l = el.scrollLeft, t = el.scrollTop;
3782 var w = el.scrollWidth, h = el.scrollHeight;
3783 var cw = el.clientWidth, ch = el.clientHeight;
3784 direction = direction.toLowerCase();
3785 var scrolled = false;
3786 var a = this.preanim(arguments, 2);
3787 switch(direction){
3788 case "l":
3789 case "left":
3790 if(w - l > cw){
3791 var v = Math.min(l + distance, w-cw);
3792 this.scrollTo("left", v, a);
3793 scrolled = true;
3795 break;
3796 case "r":
3797 case "right":
3798 if(l > 0){
3799 var v = Math.max(l - distance, 0);
3800 this.scrollTo("left", v, a);
3801 scrolled = true;
3803 break;
3804 case "t":
3805 case "top":
3806 case "up":
3807 if(t > 0){
3808 var v = Math.max(t - distance, 0);
3809 this.scrollTo("top", v, a);
3810 scrolled = true;
3812 break;
3813 case "b":
3814 case "bottom":
3815 case "down":
3816 if(h - t > ch){
3817 var v = Math.min(t + distance, h-ch);
3818 this.scrollTo("top", v, a);
3819 scrolled = true;
3821 break;
3823 return scrolled;
3824 },
3827 translatePoints : function(x, y){
3828 if(typeof x == 'object' || Ext.isArray(x)){
3829 y = x[1]; x = x[0];
3831 var p = this.getStyle('position');
3832 var o = this.getXY();
3834 var l = parseInt(this.getStyle('left'), 10);
3835 var t = parseInt(this.getStyle('top'), 10);
3837 if(isNaN(l)){
3838 l = (p == "relative") ? 0 : this.dom.offsetLeft;
3840 if(isNaN(t)){
3841 t = (p == "relative") ? 0 : this.dom.offsetTop;
3844 return {left: (x - o[0] + l), top: (y - o[1] + t)};
3845 },
3848 getScroll : function(){
3849 var d = this.dom, doc = document;
3850 if(d == doc || d == doc.body){
3851 var l, t;
3852 if(Ext.isIE && Ext.isStrict){
3853 l = doc.documentElement.scrollLeft || (doc.body.scrollLeft || 0);
3854 t = doc.documentElement.scrollTop || (doc.body.scrollTop || 0);
3855 }else{
3856 l = window.pageXOffset || (doc.body.scrollLeft || 0);
3857 t = window.pageYOffset || (doc.body.scrollTop || 0);
3859 return {left: l, top: t};
3860 }else{
3861 return {left: d.scrollLeft, top: d.scrollTop};
3863 },
3866 getColor : function(attr, defaultValue, prefix){
3867 var v = this.getStyle(attr);
3868 if(!v || v == "transparent" || v == "inherit") {
3869 return defaultValue;
3871 var color = typeof prefix == "undefined" ? "#" : prefix;
3872 if(v.substr(0, 4) == "rgb("){
3873 var rvs = v.slice(4, v.length -1).split(",");
3874 for(var i = 0; i < 3; i++){
3875 var h = parseInt(rvs[i]);
3876 var s = h.toString(16);
3877 if(h < 16){
3878 s = "0" + s;
3880 color += s;
3882 } else {
3883 if(v.substr(0, 1) == "#"){
3884 if(v.length == 4) {
3885 for(var i = 1; i < 4; i++){
3886 var c = v.charAt(i);
3887 color += c + c;
3889 }else if(v.length == 7){
3890 color += v.substr(1);
3894 return(color.length > 5 ? color.toLowerCase() : defaultValue);
3895 },
3898 boxWrap : function(cls){
3899 cls = cls || 'x-box';
3900 var el = Ext.get(this.insertHtml('beforeBegin', String.format('<div class="{0}">'+El.boxMarkup+'</div>', cls)));
3901 el.child('.'+cls+'-mc').dom.appendChild(this.dom);
3902 return el;
3903 },
3906 getAttributeNS : Ext.isIE ? function(ns, name){
3907 var d = this.dom;
3908 var type = typeof d[ns+":"+name];
3909 if(type != 'undefined' && type != 'unknown'){
3910 return d[ns+":"+name];
3912 return d[name];
3913 } : function(ns, name){
3914 var d = this.dom;
3915 return d.getAttributeNS(ns, name) || d.getAttribute(ns+":"+name) || d.getAttribute(name) || d[name];
3916 },
3918 getTextWidth : function(text, min, max){
3919 return (Ext.util.TextMetrics.measure(this.dom, Ext.value(text, this.dom.innerHTML, true)).width).constrain(min || 0, max || 1000000);
3921 };
3923 var ep = El.prototype;
3926 ep.on = ep.addListener;
3927 ep.mon = ep.addListener;
3929 ep.getUpdateManager = ep.getUpdater;
3932 ep.un = ep.removeListener;
3935 ep.autoBoxAdjust = true;
3937 El.unitPattern = /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i;
3939 El.addUnits = function(v, defaultUnit){
3940 if(v === "" || v == "auto"){
3941 return v;
3943 if(v === undefined){
3944 return '';
3946 if(typeof v == "number" || !El.unitPattern.test(v)){
3947 return v + (defaultUnit || 'px');
3949 return v;
3950 };
3952 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>';
3954 El.VISIBILITY = 1;
3956 El.DISPLAY = 2;
3958 El.borders = {l: "border-left-width", r: "border-right-width", t: "border-top-width", b: "border-bottom-width"};
3959 El.paddings = {l: "padding-left", r: "padding-right", t: "padding-top", b: "padding-bottom"};
3960 El.margins = {l: "margin-left", r: "margin-right", t: "margin-top", b: "margin-bottom"};
3965 El.cache = {};
3967 var docEl;
3970 El.get = function(el){
3971 var ex, elm, id;
3972 if(!el){ return null; }
3973 if(typeof el == "string"){ if(!(elm = document.getElementById(el))){
3974 return null;
3976 if(ex = El.cache[el]){
3977 ex.dom = elm;
3978 }else{
3979 ex = El.cache[el] = new El(elm);
3981 return ex;
3982 }else if(el.tagName){ if(!(id = el.id)){
3983 id = Ext.id(el);
3985 if(ex = El.cache[id]){
3986 ex.dom = el;
3987 }else{
3988 ex = El.cache[id] = new El(el);
3990 return ex;
3991 }else if(el instanceof El){
3992 if(el != docEl){
3993 el.dom = document.getElementById(el.id) || el.dom; El.cache[el.id] = el; }
3994 return el;
3995 }else if(el.isComposite){
3996 return el;
3997 }else if(Ext.isArray(el)){
3998 return El.select(el);
3999 }else if(el == document){
4000 if(!docEl){
4001 var f = function(){};
4002 f.prototype = El.prototype;
4003 docEl = new f();
4004 docEl.dom = document;
4006 return docEl;
4008 return null;
4009 };
4011 El.uncache = function(el){
4012 for(var i = 0, a = arguments, len = a.length; i < len; i++) {
4013 if(a[i]){
4014 delete El.cache[a[i].id || a[i]];
4017 };
4019 El.garbageCollect = function(){
4020 if(!Ext.enableGarbageCollector){
4021 clearInterval(El.collectorThread);
4022 return;
4024 for(var eid in El.cache){
4025 var el = El.cache[eid], d = el.dom;
4026 if(!d || !d.parentNode || (!d.offsetParent && !document.getElementById(eid))){
4027 delete El.cache[eid];
4028 if(d && Ext.enableListenerCollection){
4029 E.purgeElement(d);
4034 El.collectorThreadId = setInterval(El.garbageCollect, 30000);
4036 var flyFn = function(){};
4037 flyFn.prototype = El.prototype;
4038 var _cls = new flyFn();
4040 El.Flyweight = function(dom){
4041 this.dom = dom;
4042 };
4044 El.Flyweight.prototype = _cls;
4045 El.Flyweight.prototype.isFlyweight = true;
4047 El._flyweights = {};
4049 El.fly = function(el, named){
4050 named = named || '_global';
4051 el = Ext.getDom(el);
4052 if(!el){
4053 return null;
4055 if(!El._flyweights[named]){
4056 El._flyweights[named] = new El.Flyweight();
4058 El._flyweights[named].dom = el;
4059 return El._flyweights[named];
4060 };
4063 Ext.get = El.get;
4065 Ext.fly = El.fly;
4067 var noBoxAdjust = Ext.isStrict ? {
4068 select:1
4069 } : {
4070 input:1, select:1, textarea:1
4071 };
4072 if(Ext.isIE || Ext.isGecko){
4073 noBoxAdjust['button'] = 1;
4077 Ext.EventManager.on(window, 'unload', function(){
4078 delete El.cache;
4079 delete El._flyweights;
4080 });
4081 })();
4083 Ext.enableFx = true;
4086 Ext.Fx = {
4088 slideIn : function(anchor, o){
4089 var el = this.getFxEl();
4090 o = o || {};
4092 el.queueFx(o, function(){
4094 anchor = anchor || "t";
4096 this.fixDisplay();
4098 var r = this.getFxRestore();
4099 var b = this.getBox();
4100 this.setSize(b);
4102 var wrap = this.fxWrap(r.pos, o, "hidden");
4104 var st = this.dom.style;
4105 st.visibility = "visible";
4106 st.position = "absolute";
4108 var after = function(){
4109 el.fxUnwrap(wrap, r.pos, o);
4110 st.width = r.width;
4111 st.height = r.height;
4112 el.afterFx(o);
4113 };
4114 var a, pt = {to: [b.x, b.y]}, bw = {to: b.width}, bh = {to: b.height};
4116 switch(anchor.toLowerCase()){
4117 case "t":
4118 wrap.setSize(b.width, 0);
4119 st.left = st.bottom = "0";
4120 a = {height: bh};
4121 break;
4122 case "l":
4123 wrap.setSize(0, b.height);
4124 st.right = st.top = "0";
4125 a = {width: bw};
4126 break;
4127 case "r":
4128 wrap.setSize(0, b.height);
4129 wrap.setX(b.right);
4130 st.left = st.top = "0";
4131 a = {width: bw, points: pt};
4132 break;
4133 case "b":
4134 wrap.setSize(b.width, 0);
4135 wrap.setY(b.bottom);
4136 st.left = st.top = "0";
4137 a = {height: bh, points: pt};
4138 break;
4139 case "tl":
4140 wrap.setSize(0, 0);
4141 st.right = st.bottom = "0";
4142 a = {width: bw, height: bh};
4143 break;
4144 case "bl":
4145 wrap.setSize(0, 0);
4146 wrap.setY(b.y+b.height);
4147 st.right = st.top = "0";
4148 a = {width: bw, height: bh, points: pt};
4149 break;
4150 case "br":
4151 wrap.setSize(0, 0);
4152 wrap.setXY([b.right, b.bottom]);
4153 st.left = st.top = "0";
4154 a = {width: bw, height: bh, points: pt};
4155 break;
4156 case "tr":
4157 wrap.setSize(0, 0);
4158 wrap.setX(b.x+b.width);
4159 st.left = st.bottom = "0";
4160 a = {width: bw, height: bh, points: pt};
4161 break;
4163 this.dom.style.visibility = "visible";
4164 wrap.show();
4166 arguments.callee.anim = wrap.fxanim(a,
4167 o,
4168 'motion',
4169 .5,
4170 'easeOut', after);
4171 });
4172 return this;
4173 },
4176 slideOut : function(anchor, o){
4177 var el = this.getFxEl();
4178 o = o || {};
4180 el.queueFx(o, function(){
4182 anchor = anchor || "t";
4184 var r = this.getFxRestore();
4186 var b = this.getBox();
4187 this.setSize(b);
4189 var wrap = this.fxWrap(r.pos, o, "visible");
4191 var st = this.dom.style;
4192 st.visibility = "visible";
4193 st.position = "absolute";
4195 wrap.setSize(b);
4197 var after = function(){
4198 if(o.useDisplay){
4199 el.setDisplayed(false);
4200 }else{
4201 el.hide();
4204 el.fxUnwrap(wrap, r.pos, o);
4206 st.width = r.width;
4207 st.height = r.height;
4209 el.afterFx(o);
4210 };
4212 var a, zero = {to: 0};
4213 switch(anchor.toLowerCase()){
4214 case "t":
4215 st.left = st.bottom = "0";
4216 a = {height: zero};
4217 break;
4218 case "l":
4219 st.right = st.top = "0";
4220 a = {width: zero};
4221 break;
4222 case "r":
4223 st.left = st.top = "0";
4224 a = {width: zero, points: {to:[b.right, b.y]}};
4225 break;
4226 case "b":
4227 st.left = st.top = "0";
4228 a = {height: zero, points: {to:[b.x, b.bottom]}};
4229 break;
4230 case "tl":
4231 st.right = st.bottom = "0";
4232 a = {width: zero, height: zero};
4233 break;
4234 case "bl":
4235 st.right = st.top = "0";
4236 a = {width: zero, height: zero, points: {to:[b.x, b.bottom]}};
4237 break;
4238 case "br":
4239 st.left = st.top = "0";
4240 a = {width: zero, height: zero, points: {to:[b.x+b.width, b.bottom]}};
4241 break;
4242 case "tr":
4243 st.left = st.bottom = "0";
4244 a = {width: zero, height: zero, points: {to:[b.right, b.y]}};
4245 break;
4248 arguments.callee.anim = wrap.fxanim(a,
4249 o,
4250 'motion',
4251 .5,
4252 "easeOut", after);
4253 });
4254 return this;
4255 },
4258 puff : function(o){
4259 var el = this.getFxEl();
4260 o = o || {};
4262 el.queueFx(o, function(){
4263 this.clearOpacity();
4264 this.show();
4266 var r = this.getFxRestore();
4267 var st = this.dom.style;
4269 var after = function(){
4270 if(o.useDisplay){
4271 el.setDisplayed(false);
4272 }else{
4273 el.hide();
4276 el.clearOpacity();
4278 el.setPositioning(r.pos);
4279 st.width = r.width;
4280 st.height = r.height;
4281 st.fontSize = '';
4282 el.afterFx(o);
4283 };
4285 var width = this.getWidth();
4286 var height = this.getHeight();
4288 arguments.callee.anim = this.fxanim({
4289 width : {to: this.adjustWidth(width * 2)},
4290 height : {to: this.adjustHeight(height * 2)},
4291 points : {by: [-(width * .5), -(height * .5)]},
4292 opacity : {to: 0},
4293 fontSize: {to:200, unit: "%"}
4294 },
4295 o,
4296 'motion',
4297 .5,
4298 "easeOut", after);
4299 });
4300 return this;
4301 },
4304 switchOff : function(o){
4305 var el = this.getFxEl();
4306 o = o || {};
4308 el.queueFx(o, function(){
4309 this.clearOpacity();
4310 this.clip();
4312 var r = this.getFxRestore();
4313 var st = this.dom.style;
4315 var after = function(){
4316 if(o.useDisplay){
4317 el.setDisplayed(false);
4318 }else{
4319 el.hide();
4322 el.clearOpacity();
4323 el.setPositioning(r.pos);
4324 st.width = r.width;
4325 st.height = r.height;
4327 el.afterFx(o);
4328 };
4330 this.fxanim({opacity:{to:0.3}}, null, null, .1, null, function(){
4331 this.clearOpacity();
4332 (function(){
4333 this.fxanim({
4334 height:{to:1},
4335 points:{by:[0, this.getHeight() * .5]}
4336 }, o, 'motion', 0.3, 'easeIn', after);
4337 }).defer(100, this);
4338 });
4339 });
4340 return this;
4341 },
4344 highlight : function(color, o){
4345 var el = this.getFxEl();
4346 o = o || {};
4348 el.queueFx(o, function(){
4349 color = color || "ffff9c";
4350 var attr = o.attr || "backgroundColor";
4352 this.clearOpacity();
4353 this.show();
4355 var origColor = this.getColor(attr);
4356 var restoreColor = this.dom.style[attr];
4357 var endColor = (o.endColor || origColor) || "ffffff";
4359 var after = function(){
4360 el.dom.style[attr] = restoreColor;
4361 el.afterFx(o);
4362 };
4364 var a = {};
4365 a[attr] = {from: color, to: endColor};
4366 arguments.callee.anim = this.fxanim(a,
4367 o,
4368 'color',
4369 1,
4370 'easeIn', after);
4371 });
4372 return this;
4373 },
4376 frame : function(color, count, o){
4377 var el = this.getFxEl();
4378 o = o || {};
4380 el.queueFx(o, function(){
4381 color = color || "#C3DAF9";
4382 if(color.length == 6){
4383 color = "#" + color;
4385 count = count || 1;
4386 var duration = o.duration || 1;
4387 this.show();
4389 var b = this.getBox();
4390 var animFn = function(){
4391 var proxy = Ext.getBody().createChild({
4392 style:{
4393 visbility:"hidden",
4394 position:"absolute",
4395 "z-index":"35000", border:"0px solid " + color
4397 });
4398 var scale = Ext.isBorderBox ? 2 : 1;
4399 proxy.animate({
4400 top:{from:b.y, to:b.y - 20},
4401 left:{from:b.x, to:b.x - 20},
4402 borderWidth:{from:0, to:10},
4403 opacity:{from:1, to:0},
4404 height:{from:b.height, to:(b.height + (20*scale))},
4405 width:{from:b.width, to:(b.width + (20*scale))}
4406 }, duration, function(){
4407 proxy.remove();
4408 if(--count > 0){
4409 animFn();
4410 }else{
4411 el.afterFx(o);
4413 });
4414 };
4415 animFn.call(this);
4416 });
4417 return this;
4418 },
4421 pause : function(seconds){
4422 var el = this.getFxEl();
4423 var o = {};
4425 el.queueFx(o, function(){
4426 setTimeout(function(){
4427 el.afterFx(o);
4428 }, seconds * 1000);
4429 });
4430 return this;
4431 },
4434 fadeIn : function(o){
4435 var el = this.getFxEl();
4436 o = o || {};
4437 el.queueFx(o, function(){
4438 this.setOpacity(0);
4439 this.fixDisplay();
4440 this.dom.style.visibility = 'visible';
4441 var to = o.endOpacity || 1;
4442 arguments.callee.anim = this.fxanim({opacity:{to:to}},
4443 o, null, .5, "easeOut", function(){
4444 if(to == 1){
4445 this.clearOpacity();
4447 el.afterFx(o);
4448 });
4449 });
4450 return this;
4451 },
4454 fadeOut : function(o){
4455 var el = this.getFxEl();
4456 o = o || {};
4457 el.queueFx(o, function(){
4458 arguments.callee.anim = this.fxanim({opacity:{to:o.endOpacity || 0}},
4459 o, null, .5, "easeOut", function(){
4460 if(this.visibilityMode == Ext.Element.DISPLAY || o.useDisplay){
4461 this.dom.style.display = "none";
4462 }else{
4463 this.dom.style.visibility = "hidden";
4465 this.clearOpacity();
4466 el.afterFx(o);
4467 });
4468 });
4469 return this;
4470 },
4473 scale : function(w, h, o){
4474 this.shift(Ext.apply({}, o, {
4475 width: w,
4476 height: h
4477 }));
4478 return this;
4479 },
4482 shift : function(o){
4483 var el = this.getFxEl();
4484 o = o || {};
4485 el.queueFx(o, function(){
4486 var a = {}, w = o.width, h = o.height, x = o.x, y = o.y, op = o.opacity;
4487 if(w !== undefined){
4488 a.width = {to: this.adjustWidth(w)};
4490 if(h !== undefined){
4491 a.height = {to: this.adjustHeight(h)};
4493 if(o.left !== undefined){
4494 a.left = {to: o.left};
4496 if(o.top !== undefined){
4497 a.top = {to: o.top};
4499 if(o.right !== undefined){
4500 a.right = {to: o.right};
4502 if(o.bottom !== undefined){
4503 a.bottom = {to: o.bottom};
4505 if(x !== undefined || y !== undefined){
4506 a.points = {to: [
4507 x !== undefined ? x : this.getX(),
4508 y !== undefined ? y : this.getY()
4509 ]};
4511 if(op !== undefined){
4512 a.opacity = {to: op};
4514 if(o.xy !== undefined){
4515 a.points = {to: o.xy};
4517 arguments.callee.anim = this.fxanim(a,
4518 o, 'motion', .35, "easeOut", function(){
4519 el.afterFx(o);
4520 });
4521 });
4522 return this;
4523 },
4526 ghost : function(anchor, o){
4527 var el = this.getFxEl();
4528 o = o || {};
4530 el.queueFx(o, function(){
4531 anchor = anchor || "b";
4533 var r = this.getFxRestore();
4534 var w = this.getWidth(),
4535 h = this.getHeight();
4537 var st = this.dom.style;
4539 var after = function(){
4540 if(o.useDisplay){
4541 el.setDisplayed(false);
4542 }else{
4543 el.hide();
4546 el.clearOpacity();
4547 el.setPositioning(r.pos);
4548 st.width = r.width;
4549 st.height = r.height;
4551 el.afterFx(o);
4552 };
4554 var a = {opacity: {to: 0}, points: {}}, pt = a.points;
4555 switch(anchor.toLowerCase()){
4556 case "t":
4557 pt.by = [0, -h];
4558 break;
4559 case "l":
4560 pt.by = [-w, 0];
4561 break;
4562 case "r":
4563 pt.by = [w, 0];
4564 break;
4565 case "b":
4566 pt.by = [0, h];
4567 break;
4568 case "tl":
4569 pt.by = [-w, -h];
4570 break;
4571 case "bl":
4572 pt.by = [-w, h];
4573 break;
4574 case "br":
4575 pt.by = [w, h];
4576 break;
4577 case "tr":
4578 pt.by = [w, -h];
4579 break;
4582 arguments.callee.anim = this.fxanim(a,
4583 o,
4584 'motion',
4585 .5,
4586 "easeOut", after);
4587 });
4588 return this;
4589 },
4592 syncFx : function(){
4593 this.fxDefaults = Ext.apply(this.fxDefaults || {}, {
4594 block : false,
4595 concurrent : true,
4596 stopFx : false
4597 });
4598 return this;
4599 },
4602 sequenceFx : function(){
4603 this.fxDefaults = Ext.apply(this.fxDefaults || {}, {
4604 block : false,
4605 concurrent : false,
4606 stopFx : false
4607 });
4608 return this;
4609 },
4612 nextFx : function(){
4613 var ef = this.fxQueue[0];
4614 if(ef){
4615 ef.call(this);
4617 },
4620 hasActiveFx : function(){
4621 return this.fxQueue && this.fxQueue[0];
4622 },
4625 stopFx : function(){
4626 if(this.hasActiveFx()){
4627 var cur = this.fxQueue[0];
4628 if(cur && cur.anim && cur.anim.isAnimated()){
4629 this.fxQueue = [cur]; cur.anim.stop(true);
4632 return this;
4633 },
4636 beforeFx : function(o){
4637 if(this.hasActiveFx() && !o.concurrent){
4638 if(o.stopFx){
4639 this.stopFx();
4640 return true;
4642 return false;
4644 return true;
4645 },
4648 hasFxBlock : function(){
4649 var q = this.fxQueue;
4650 return q && q[0] && q[0].block;
4651 },
4654 queueFx : function(o, fn){
4655 if(!this.fxQueue){
4656 this.fxQueue = [];
4658 if(!this.hasFxBlock()){
4659 Ext.applyIf(o, this.fxDefaults);
4660 if(!o.concurrent){
4661 var run = this.beforeFx(o);
4662 fn.block = o.block;
4663 this.fxQueue.push(fn);
4664 if(run){
4665 this.nextFx();
4667 }else{
4668 fn.call(this);
4671 return this;
4672 },
4675 fxWrap : function(pos, o, vis){
4676 var wrap;
4677 if(!o.wrap || !(wrap = Ext.get(o.wrap))){
4678 var wrapXY;
4679 if(o.fixPosition){
4680 wrapXY = this.getXY();
4682 var div = document.createElement("div");
4683 div.style.visibility = vis;
4684 wrap = Ext.get(this.dom.parentNode.insertBefore(div, this.dom));
4685 wrap.setPositioning(pos);
4686 if(wrap.getStyle("position") == "static"){
4687 wrap.position("relative");
4689 this.clearPositioning('auto');
4690 wrap.clip();
4691 wrap.dom.appendChild(this.dom);
4692 if(wrapXY){
4693 wrap.setXY(wrapXY);
4696 return wrap;
4697 },
4700 fxUnwrap : function(wrap, pos, o){
4701 this.clearPositioning();
4702 this.setPositioning(pos);
4703 if(!o.wrap){
4704 wrap.dom.parentNode.insertBefore(this.dom, wrap.dom);
4705 wrap.remove();
4707 },
4710 getFxRestore : function(){
4711 var st = this.dom.style;
4712 return {pos: this.getPositioning(), width: st.width, height : st.height};
4713 },
4716 afterFx : function(o){
4717 if(o.afterStyle){
4718 this.applyStyles(o.afterStyle);
4720 if(o.afterCls){
4721 this.addClass(o.afterCls);
4723 if(o.remove === true){
4724 this.remove();
4726 Ext.callback(o.callback, o.scope, [this]);
4727 if(!o.concurrent){
4728 this.fxQueue.shift();
4729 this.nextFx();
4731 },
4734 getFxEl : function(){ return Ext.get(this.dom);
4735 },
4738 fxanim : function(args, opt, animType, defaultDur, defaultEase, cb){
4739 animType = animType || 'run';
4740 opt = opt || {};
4741 var anim = Ext.lib.Anim[animType](
4742 this.dom, args,
4743 (opt.duration || defaultDur) || .35,
4744 (opt.easing || defaultEase) || 'easeOut',
4745 function(){
4746 Ext.callback(cb, this);
4747 },
4748 this
4749 );
4750 opt.anim = anim;
4751 return anim;
4753 };
4755 Ext.Fx.resize = Ext.Fx.scale;
4757 Ext.apply(Ext.Element.prototype, Ext.Fx);
4760 Ext.CompositeElement = function(els){
4761 this.elements = [];
4762 this.addElements(els);
4763 };
4764 Ext.CompositeElement.prototype = {
4765 isComposite: true,
4766 addElements : function(els){
4767 if(!els) return this;
4768 if(typeof els == "string"){
4769 els = Ext.Element.selectorFunction(els);
4771 var yels = this.elements;
4772 var index = yels.length-1;
4773 for(var i = 0, len = els.length; i < len; i++) {
4774 yels[++index] = Ext.get(els[i]);
4776 return this;
4777 },
4780 fill : function(els){
4781 this.elements = [];
4782 this.add(els);
4783 return this;
4784 },
4787 filter : function(selector){
4788 var els = [];
4789 this.each(function(el){
4790 if(el.is(selector)){
4791 els[els.length] = el.dom;
4793 });
4794 this.fill(els);
4795 return this;
4796 },
4798 invoke : function(fn, args){
4799 var els = this.elements;
4800 for(var i = 0, len = els.length; i < len; i++) {
4801 Ext.Element.prototype[fn].apply(els[i], args);
4803 return this;
4804 },
4806 add : function(els){
4807 if(typeof els == "string"){
4808 this.addElements(Ext.Element.selectorFunction(els));
4809 }else if(els.length !== undefined){
4810 this.addElements(els);
4811 }else{
4812 this.addElements([els]);
4814 return this;
4815 },
4817 each : function(fn, scope){
4818 var els = this.elements;
4819 for(var i = 0, len = els.length; i < len; i++){
4820 if(fn.call(scope || els[i], els[i], this, i) === false) {
4821 break;
4824 return this;
4825 },
4828 item : function(index){
4829 return this.elements[index] || null;
4830 },
4833 first : function(){
4834 return this.item(0);
4835 },
4838 last : function(){
4839 return this.item(this.elements.length-1);
4840 },
4843 getCount : function(){
4844 return this.elements.length;
4845 },
4848 contains : function(el){
4849 return this.indexOf(el) !== -1;
4850 },
4853 indexOf : function(el){
4854 return this.elements.indexOf(Ext.get(el));
4855 },
4859 removeElement : function(el, removeDom){
4860 if(Ext.isArray(el)){
4861 for(var i = 0, len = el.length; i < len; i++){
4862 this.removeElement(el[i]);
4864 return this;
4866 var index = typeof el == 'number' ? el : this.indexOf(el);
4867 if(index !== -1 && this.elements[index]){
4868 if(removeDom){
4869 var d = this.elements[index];
4870 if(d.dom){
4871 d.remove();
4872 }else{
4873 Ext.removeNode(d);
4876 this.elements.splice(index, 1);
4878 return this;
4879 },
4882 replaceElement : function(el, replacement, domReplace){
4883 var index = typeof el == 'number' ? el : this.indexOf(el);
4884 if(index !== -1){
4885 if(domReplace){
4886 this.elements[index].replaceWith(replacement);
4887 }else{
4888 this.elements.splice(index, 1, Ext.get(replacement))
4891 return this;
4892 },
4895 clear : function(){
4896 this.elements = [];
4898 };
4899 (function(){
4900 Ext.CompositeElement.createCall = function(proto, fnName){
4901 if(!proto[fnName]){
4902 proto[fnName] = function(){
4903 return this.invoke(fnName, arguments);
4904 };
4906 };
4907 for(var fnName in Ext.Element.prototype){
4908 if(typeof Ext.Element.prototype[fnName] == "function"){
4909 Ext.CompositeElement.createCall(Ext.CompositeElement.prototype, fnName);
4911 };
4912 })();
4915 Ext.CompositeElementLite = function(els){
4916 Ext.CompositeElementLite.superclass.constructor.call(this, els);
4917 this.el = new Ext.Element.Flyweight();
4918 };
4919 Ext.extend(Ext.CompositeElementLite, Ext.CompositeElement, {
4920 addElements : function(els){
4921 if(els){
4922 if(Ext.isArray(els)){
4923 this.elements = this.elements.concat(els);
4924 }else{
4925 var yels = this.elements;
4926 var index = yels.length-1;
4927 for(var i = 0, len = els.length; i < len; i++) {
4928 yels[++index] = els[i];
4932 return this;
4933 },
4934 invoke : function(fn, args){
4935 var els = this.elements;
4936 var el = this.el;
4937 for(var i = 0, len = els.length; i < len; i++) {
4938 el.dom = els[i];
4939 Ext.Element.prototype[fn].apply(el, args);
4941 return this;
4942 },
4944 item : function(index){
4945 if(!this.elements[index]){
4946 return null;
4948 this.el.dom = this.elements[index];
4949 return this.el;
4950 },
4953 addListener : function(eventName, handler, scope, opt){
4954 var els = this.elements;
4955 for(var i = 0, len = els.length; i < len; i++) {
4956 Ext.EventManager.on(els[i], eventName, handler, scope || els[i], opt);
4958 return this;
4959 },
4962 each : function(fn, scope){
4963 var els = this.elements;
4964 var el = this.el;
4965 for(var i = 0, len = els.length; i < len; i++){
4966 el.dom = els[i];
4967 if(fn.call(scope || el, el, this, i) === false){
4968 break;
4971 return this;
4972 },
4974 indexOf : function(el){
4975 return this.elements.indexOf(Ext.getDom(el));
4976 },
4978 replaceElement : function(el, replacement, domReplace){
4979 var index = typeof el == 'number' ? el : this.indexOf(el);
4980 if(index !== -1){
4981 replacement = Ext.getDom(replacement);
4982 if(domReplace){
4983 var d = this.elements[index];
4984 d.parentNode.insertBefore(replacement, d);
4985 Ext.removeNode(d);
4987 this.elements.splice(index, 1, replacement);
4989 return this;
4991 });
4992 Ext.CompositeElementLite.prototype.on = Ext.CompositeElementLite.prototype.addListener;
4993 if(Ext.DomQuery){
4994 Ext.Element.selectorFunction = Ext.DomQuery.select;
4997 Ext.Element.select = function(selector, unique, root){
4998 var els;
4999 if(typeof selector == "string"){
5000 els = Ext.Element.selectorFunction(selector, root);
5001 }else if(selector.length !== undefined){
5002 els = selector;
5003 }else{
5004 throw "Invalid selector";
5006 if(unique === true){
5007 return new Ext.CompositeElement(els);
5008 }else{
5009 return new Ext.CompositeElementLite(els);
5011 };
5013 Ext.select = Ext.Element.select;
5015 Ext.data.Connection = function(config){
5016 Ext.apply(this, config);
5017 this.addEvents(
5019 "beforerequest",
5021 "requestcomplete",
5023 "requestexception"
5024 );
5025 Ext.data.Connection.superclass.constructor.call(this);
5026 };
5028 Ext.extend(Ext.data.Connection, Ext.util.Observable, {
5034 timeout : 30000,
5036 autoAbort:false,
5039 disableCaching: true,
5042 request : function(o){
5043 if(this.fireEvent("beforerequest", this, o) !== false){
5044 var p = o.params;
5046 if(typeof p == "function"){
5047 p = p.call(o.scope||window, o);
5049 if(typeof p == "object"){
5050 p = Ext.urlEncode(p);
5052 if(this.extraParams){
5053 var extras = Ext.urlEncode(this.extraParams);
5054 p = p ? (p + '&' + extras) : extras;
5057 var url = o.url || this.url;
5058 if(typeof url == 'function'){
5059 url = url.call(o.scope||window, o);
5062 if(o.form){
5063 var form = Ext.getDom(o.form);
5064 url = url || form.action;
5066 var enctype = form.getAttribute("enctype");
5067 if(o.isUpload || (enctype && enctype.toLowerCase() == 'multipart/form-data')){
5068 return this.doFormUpload(o, p, url);
5070 var f = Ext.lib.Ajax.serializeForm(form);
5071 p = p ? (p + '&' + f) : f;
5074 var hs = o.headers;
5075 if(this.defaultHeaders){
5076 hs = Ext.apply(hs || {}, this.defaultHeaders);
5077 if(!o.headers){
5078 o.headers = hs;
5082 var cb = {
5083 success: this.handleResponse,
5084 failure: this.handleFailure,
5085 scope: this,
5086 argument: {options: o},
5087 timeout : o.timeout || this.timeout
5088 };
5090 var method = o.method||this.method||(p ? "POST" : "GET");
5092 if(method == 'GET' && (this.disableCaching && o.disableCaching !== false) || o.disableCaching === true){
5093 url += (url.indexOf('?') != -1 ? '&' : '?') + '_dc=' + (new Date().getTime());
5096 if(typeof o.autoAbort == 'boolean'){ if(o.autoAbort){
5097 this.abort();
5099 }else if(this.autoAbort !== false){
5100 this.abort();
5102 if((method == 'GET' || o.xmlData || o.jsonData) && p){
5103 url += (url.indexOf('?') != -1 ? '&' : '?') + p;
5104 p = '';
5106 this.transId = Ext.lib.Ajax.request(method, url, cb, p, o);
5107 return this.transId;
5108 }else{
5109 Ext.callback(o.callback, o.scope, [o, null, null]);
5110 return null;
5112 },
5115 isLoading : function(transId){
5116 if(transId){
5117 return Ext.lib.Ajax.isCallInProgress(transId);
5118 }else{
5119 return this.transId ? true : false;
5121 },
5124 abort : function(transId){
5125 if(transId || this.isLoading()){
5126 Ext.lib.Ajax.abort(transId || this.transId);
5128 },
5130 handleResponse : function(response){
5131 this.transId = false;
5132 var options = response.argument.options;
5133 response.argument = options ? options.argument : null;
5134 this.fireEvent("requestcomplete", this, response, options);
5135 Ext.callback(options.success, options.scope, [response, options]);
5136 Ext.callback(options.callback, options.scope, [options, true, response]);
5137 },
5139 handleFailure : function(response, e){
5140 this.transId = false;
5141 var options = response.argument.options;
5142 response.argument = options ? options.argument : null;
5143 this.fireEvent("requestexception", this, response, options, e);
5144 Ext.callback(options.failure, options.scope, [response, options]);
5145 Ext.callback(options.callback, options.scope, [options, false, response]);
5146 },
5148 doFormUpload : function(o, ps, url){
5149 var id = Ext.id();
5150 var frame = document.createElement('iframe');
5151 frame.id = id;
5152 frame.name = id;
5153 frame.className = 'x-hidden';
5154 if(Ext.isIE){
5155 frame.src = Ext.SSL_SECURE_URL;
5157 document.body.appendChild(frame);
5159 if(Ext.isIE){
5160 document.frames[id].name = id;
5163 var form = Ext.getDom(o.form);
5164 form.target = id;
5165 form.method = 'POST';
5166 form.enctype = form.encoding = 'multipart/form-data';
5167 if(url){
5168 form.action = url;
5171 var hiddens, hd;
5172 if(ps){ hiddens = [];
5173 ps = Ext.urlDecode(ps, false);
5174 for(var k in ps){
5175 if(ps.hasOwnProperty(k)){
5176 hd = document.createElement('input');
5177 hd.type = 'hidden';
5178 hd.name = k;
5179 hd.value = ps[k];
5180 form.appendChild(hd);
5181 hiddens.push(hd);
5186 function cb(){
5187 var r = { responseText : '',
5188 responseXML : null
5189 };
5191 r.argument = o ? o.argument : null;
5193 try { var doc;
5194 if(Ext.isIE){
5195 doc = frame.contentWindow.document;
5196 }else {
5197 doc = (frame.contentDocument || window.frames[id].document);
5199 if(doc && doc.body){
5200 r.responseText = doc.body.innerHTML;
5202 if(doc && doc.XMLDocument){
5203 r.responseXML = doc.XMLDocument;
5204 }else {
5205 r.responseXML = doc;
5208 catch(e) {
5211 Ext.EventManager.removeListener(frame, 'load', cb, this);
5213 this.fireEvent("requestcomplete", this, r, o);
5215 Ext.callback(o.success, o.scope, [r, o]);
5216 Ext.callback(o.callback, o.scope, [o, true, r]);
5218 setTimeout(function(){Ext.removeNode(frame);}, 100);
5221 Ext.EventManager.on(frame, 'load', cb, this);
5222 form.submit();
5224 if(hiddens){ for(var i = 0, len = hiddens.length; i < len; i++){
5225 Ext.removeNode(hiddens[i]);
5229 });
5232 Ext.Ajax = new Ext.data.Connection({
5250 autoAbort : false,
5253 serializeForm : function(form){
5254 return Ext.lib.Ajax.serializeForm(form);
5256 });
5258 Ext.Updater = function(el, forceNew){
5259 el = Ext.get(el);
5260 if(!forceNew && el.updateManager){
5261 return el.updateManager;
5264 this.el = el;
5266 this.defaultUrl = null;
5268 this.addEvents(
5270 "beforeupdate",
5272 "update",
5274 "failure"
5275 );
5276 var d = Ext.Updater.defaults;
5278 this.sslBlankUrl = d.sslBlankUrl;
5280 this.disableCaching = d.disableCaching;
5282 this.indicatorText = d.indicatorText;
5284 this.showLoadIndicator = d.showLoadIndicator;
5286 this.timeout = d.timeout;
5288 this.loadScripts = d.loadScripts;
5290 this.transaction = null;
5292 this.refreshDelegate = this.refresh.createDelegate(this);
5294 this.updateDelegate = this.update.createDelegate(this);
5296 this.formUpdateDelegate = this.formUpdate.createDelegate(this);
5298 if(!this.renderer){
5300 this.renderer = new Ext.Updater.BasicRenderer();
5302 Ext.Updater.superclass.constructor.call(this);
5303 };
5305 Ext.extend(Ext.Updater, Ext.util.Observable, {
5307 getEl : function(){
5308 return this.el;
5309 },
5312 update : function(url, params, callback, discardUrl){
5313 if(this.fireEvent("beforeupdate", this.el, url, params) !== false){
5314 var cfg, callerScope;
5315 if(typeof url == "object"){
5316 cfg = url;
5317 url = cfg.url;
5318 params = params || cfg.params;
5319 callback = callback || cfg.callback;
5320 discardUrl = discardUrl || cfg.discardUrl;
5321 callerScope = cfg.scope;
5322 if(typeof cfg.nocache != "undefined"){this.disableCaching = cfg.nocache;};
5323 if(typeof cfg.text != "undefined"){this.indicatorText = '<div class="loading-indicator">'+cfg.text+"</div>";};
5324 if(typeof cfg.scripts != "undefined"){this.loadScripts = cfg.scripts;};
5325 if(typeof cfg.timeout != "undefined"){this.timeout = cfg.timeout;};
5327 this.showLoading();
5329 if(!discardUrl){
5330 this.defaultUrl = url;
5332 if(typeof url == "function"){
5333 url = url.call(this);
5336 var o = Ext.apply(cfg ||{}, {
5337 url : url,
5338 params: (typeof params == "function" && callerScope) ? params.createDelegate(callerScope) : params,
5339 success: this.processSuccess,
5340 failure: this.processFailure,
5341 scope: this,
5342 callback: undefined,
5343 timeout: (this.timeout*1000),
5344 disableCaching: this.disableCaching,
5345 argument: {
5346 "options": cfg,
5347 "url": url,
5348 "form": null,
5349 "callback": callback,
5350 "scope": callerScope || window,
5351 "params": params
5353 });
5355 this.transaction = Ext.Ajax.request(o);
5357 },
5360 formUpdate : function(form, url, reset, callback){
5361 if(this.fireEvent("beforeupdate", this.el, form, url) !== false){
5362 if(typeof url == "function"){
5363 url = url.call(this);
5365 form = Ext.getDom(form)
5366 this.transaction = Ext.Ajax.request({
5367 form: form,
5368 url:url,
5369 success: this.processSuccess,
5370 failure: this.processFailure,
5371 scope: this,
5372 timeout: (this.timeout*1000),
5373 argument: {
5374 "url": url,
5375 "form": form,
5376 "callback": callback,
5377 "reset": reset
5379 });
5380 this.showLoading.defer(1, this);
5382 },
5385 refresh : function(callback){
5386 if(this.defaultUrl == null){
5387 return;
5389 this.update(this.defaultUrl, null, callback, true);
5390 },
5393 startAutoRefresh : function(interval, url, params, callback, refreshNow){
5394 if(refreshNow){
5395 this.update(url || this.defaultUrl, params, callback, true);
5397 if(this.autoRefreshProcId){
5398 clearInterval(this.autoRefreshProcId);
5400 this.autoRefreshProcId = setInterval(this.update.createDelegate(this, [url || this.defaultUrl, params, callback, true]), interval*1000);
5401 },
5404 stopAutoRefresh : function(){
5405 if(this.autoRefreshProcId){
5406 clearInterval(this.autoRefreshProcId);
5407 delete this.autoRefreshProcId;
5409 },
5412 isAutoRefreshing : function(){
5413 return this.autoRefreshProcId ? true : false;
5414 },
5417 showLoading : function(){
5418 if(this.showLoadIndicator){
5419 this.el.update(this.indicatorText);
5421 },
5424 processSuccess : function(response){
5425 this.transaction = null;
5426 if(response.argument.form && response.argument.reset){
5427 try{
5428 response.argument.form.reset();
5429 }catch(e){}
5431 if(this.loadScripts){
5432 this.renderer.render(this.el, response, this,
5433 this.updateComplete.createDelegate(this, [response]));
5434 }else{
5435 this.renderer.render(this.el, response, this);
5436 this.updateComplete(response);
5438 },
5441 updateComplete : function(response){
5442 this.fireEvent("update", this.el, response);
5443 if(typeof response.argument.callback == "function"){
5444 response.argument.callback.call(response.argument.scope, this.el, true, response, response.argument.options);
5446 },
5449 processFailure : function(response){
5450 this.transaction = null;
5451 this.fireEvent("failure", this.el, response);
5452 if(typeof response.argument.callback == "function"){
5453 response.argument.callback.call(response.argument.scope, this.el, false, response, response.argument.options);
5455 },
5458 setRenderer : function(renderer){
5459 this.renderer = renderer;
5460 },
5463 getRenderer : function(){
5464 return this.renderer;
5465 },
5468 setDefaultUrl : function(defaultUrl){
5469 this.defaultUrl = defaultUrl;
5470 },
5473 abort : function(){
5474 if(this.transaction){
5475 Ext.Ajax.abort(this.transaction);
5477 },
5480 isUpdating : function(){
5481 if(this.transaction){
5482 return Ext.Ajax.isLoading(this.transaction);
5484 return false;
5486 });
5489 Ext.Updater.defaults = {
5491 timeout : 30,
5493 loadScripts : false,
5495 sslBlankUrl : (Ext.SSL_SECURE_URL || "javascript:false"),
5497 disableCaching : false,
5499 showLoadIndicator : true,
5501 indicatorText : '<div class="loading-indicator">Loading...</div>'
5502 };
5505 Ext.Updater.updateElement = function(el, url, params, options){
5506 var um = Ext.get(el).getUpdater();
5507 Ext.apply(um, options);
5508 um.update(url, params, options ? options.callback : null);
5509 };
5511 Ext.Updater.BasicRenderer = function(){};
5513 Ext.Updater.BasicRenderer.prototype = {
5515 render : function(el, response, updateManager, callback){
5516 el.update(response.responseText, updateManager.loadScripts, callback);
5518 };
5520 Ext.UpdateManager = Ext.Updater;
5526 Date.parseFunctions = {count:0};
5527 Date.parseRegexes = [];
5528 Date.formatFunctions = {count:0};
5530 Date.prototype.dateFormat = function(format) {
5531 if (Date.formatFunctions[format] == null) {
5532 Date.createNewFormat(format);
5534 var func = Date.formatFunctions[format];
5535 return this[func]();
5536 };
5540 Date.prototype.format = Date.prototype.dateFormat;
5542 Date.createNewFormat = function(format) {
5543 var funcName = "format" + Date.formatFunctions.count++;
5544 Date.formatFunctions[format] = funcName;
5545 var code = "Date.prototype." + funcName + " = function(){return ";
5546 var special = false;
5547 var ch = '';
5548 for (var i = 0; i < format.length; ++i) {
5549 ch = format.charAt(i);
5550 if (!special && ch == "\\") {
5551 special = true;
5553 else if (special) {
5554 special = false;
5555 code += "'" + String.escape(ch) + "' + ";
5557 else {
5558 code += Date.getFormatCode(ch) + " + ";
5561 eval(code.substring(0, code.length - 3) + ";}");
5562 };
5565 Date.formatCodes = {
5566 d: "String.leftPad(this.getDate(), 2, '0')",
5567 D: "Date.getShortDayName(this.getDay())", j: "this.getDate()",
5568 l: "Date.dayNames[this.getDay()]",
5569 N: "(this.getDay() ? this.getDay() : 7)",
5570 S: "this.getSuffix()",
5571 w: "this.getDay()",
5572 z: "this.getDayOfYear()",
5573 W: "String.leftPad(this.getWeekOfYear(), 2, '0')",
5574 F: "Date.monthNames[this.getMonth()]",
5575 m: "String.leftPad(this.getMonth() + 1, 2, '0')",
5576 M: "Date.getShortMonthName(this.getMonth())", n: "(this.getMonth() + 1)",
5577 t: "this.getDaysInMonth()",
5578 L: "(this.isLeapYear() ? 1 : 0)",
5579 o: "(this.getFullYear() + (this.getWeekOfYear() == 1 && this.getMonth() > 0 ? +1 : (this.getWeekOfYear() >= 52 && this.getMonth() < 11 ? -1 : 0)))",
5580 Y: "this.getFullYear()",
5581 y: "('' + this.getFullYear()).substring(2, 4)",
5582 a: "(this.getHours() < 12 ? 'am' : 'pm')",
5583 A: "(this.getHours() < 12 ? 'AM' : 'PM')",
5584 g: "((this.getHours() % 12) ? this.getHours() % 12 : 12)",
5585 G: "this.getHours()",
5586 h: "String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0')",
5587 H: "String.leftPad(this.getHours(), 2, '0')",
5588 i: "String.leftPad(this.getMinutes(), 2, '0')",
5589 s: "String.leftPad(this.getSeconds(), 2, '0')",
5590 u: "String.leftPad(this.getMilliseconds(), 3, '0')",
5591 O: "this.getGMTOffset()",
5592 P: "this.getGMTOffset(true)",
5593 T: "this.getTimezone()",
5594 Z: "(this.getTimezoneOffset() * -60)",
5595 c: function() { for (var c = "Y-m-dTH:i:sP", code = [], i = 0, l = c.length; i < l; ++i) {
5596 var e = c.charAt(i);
5597 code.push(e == "T" ? "'T'" : Date.getFormatCode(e)); }
5598 return code.join(" + ");
5599 },
5601 U: "Math.round(this.getTime() / 1000)"
5604 Date.getFormatCode = function(character) {
5605 var f = Date.formatCodes[character];
5607 if (f) {
5608 f = Ext.type(f) == 'function'? f() : f;
5609 Date.formatCodes[character] = f; }
5611 return f || ("'" + String.escape(character) + "'");
5612 };
5615 Date.parseDate = function(input, format) {
5616 if (Date.parseFunctions[format] == null) {
5617 Date.createParser(format);
5619 var func = Date.parseFunctions[format];
5620 return Date[func](input);
5621 };
5623 Date.createParser = function(format) {
5624 var funcName = "parse" + Date.parseFunctions.count++;
5625 var regexNum = Date.parseRegexes.length;
5626 var currentGroup = 1;
5627 Date.parseFunctions[format] = funcName;
5629 var code = "Date." + funcName + " = function(input){\n"
5630 + "var y = -1, m = -1, d = -1, h = -1, i = -1, s = -1, ms = -1, o, z, u, v;\n"
5631 + "input = String(input);var d = new Date();\n"
5632 + "y = d.getFullYear();\n"
5633 + "m = d.getMonth();\n"
5634 + "d = d.getDate();\n"
5635 + "var results = input.match(Date.parseRegexes[" + regexNum + "]);\n"
5636 + "if (results && results.length > 0) {";
5637 var regex = "";
5639 var special = false;
5640 var ch = '';
5641 for (var i = 0; i < format.length; ++i) {
5642 ch = format.charAt(i);
5643 if (!special && ch == "\\") {
5644 special = true;
5646 else if (special) {
5647 special = false;
5648 regex += String.escape(ch);
5650 else {
5651 var obj = Date.formatCodeToRegex(ch, currentGroup);
5652 currentGroup += obj.g;
5653 regex += obj.s;
5654 if (obj.g && obj.c) {
5655 code += obj.c;
5660 code += "if (u){\n"
5661 + "v = new Date(u * 1000);\n" + "}else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0 && ms >= 0){\n"
5662 + "v = new Date(y, m, d, h, i, s, ms);\n"
5663 + "}else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0){\n"
5664 + "v = new Date(y, m, d, h, i, s);\n"
5665 + "}else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0){\n"
5666 + "v = new Date(y, m, d, h, i);\n"
5667 + "}else if (y >= 0 && m >= 0 && d > 0 && h >= 0){\n"
5668 + "v = new Date(y, m, d, h);\n"
5669 + "}else if (y >= 0 && m >= 0 && d > 0){\n"
5670 + "v = new Date(y, m, d);\n"
5671 + "}else if (y >= 0 && m >= 0){\n"
5672 + "v = new Date(y, m);\n"
5673 + "}else if (y >= 0){\n"
5674 + "v = new Date(y);\n"
5675 + "}\n}\nreturn (v && Ext.type(z || o) == 'number')?" + " (Ext.type(z) == 'number' ? v.add(Date.SECOND, (v.getTimezoneOffset() * 60) + z) :" + " v.add(Date.HOUR, (v.getGMTOffset() / 100) + (o / -100))) : v;\n" + "}";
5677 Date.parseRegexes[regexNum] = new RegExp("^" + regex + "$", "i");
5678 eval(code);
5679 };
5681 Date.parseCodes = {
5683 d: {
5684 g:1,
5685 c:"d = parseInt(results[{0}], 10);\n",
5686 s:"(\\d{2})" },
5687 j: function() {
5688 return Ext.applyIf({
5689 s:"(\\d{1,2})" }, Date.parseCodes["d"]);
5690 },
5691 D: function() {
5692 for (var a = [], i = 0; i < 7; a.push(Date.getShortDayName(i)), ++i); return {
5693 g:0,
5694 c:null,
5695 s:"(?:" + a.join("|") +")"
5697 },
5698 l: function() {
5699 return {
5700 g:0,
5701 c:null,
5702 s:"(?:" + Date.dayNames.join("|") + ")"
5704 },
5705 N: {
5706 g:0,
5707 c:null,
5708 s:"[1-7]" },
5709 S: {
5710 g:0,
5711 c:null,
5712 s:"(?:st|nd|rd|th)"
5713 },
5714 w: {
5715 g:0,
5716 c:null,
5717 s:"[0-6]" },
5718 z: {
5719 g:0,
5720 c:null,
5721 s:"(?:\\d{1,3}" },
5722 W: {
5723 g:0,
5724 c:null,
5725 s:"(?:\\d{2})" },
5726 F: function() {
5727 return {
5728 g:1,
5729 c:"m = parseInt(Date.getMonthNumber(results[{0}]), 10);\n", s:"(" + Date.monthNames.join("|") + ")"
5731 },
5732 M: function() {
5733 for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i); return Ext.applyIf({
5734 s:"(" + a.join("|") + ")"
5735 }, Date.parseCodes["F"]);
5736 },
5737 m: {
5738 g:1,
5739 c:"m = parseInt(results[{0}], 10) - 1;\n",
5740 s:"(\\d{2})" },
5741 n: function() {
5742 return Ext.applyIf({
5743 s:"(\\d{1,2})" }, Date.parseCodes["m"]);
5744 },
5745 t: {
5746 g:0,
5747 c:null,
5748 s:"(?:\\d{2})" },
5749 L: {
5750 g:0,
5751 c:null,
5752 s:"(?:1|0)"
5753 },
5754 o: function() {
5755 return Date.parseCodes["Y"];
5756 },
5757 Y: {
5758 g:1,
5759 c:"y = parseInt(results[{0}], 10);\n",
5760 s:"(\\d{4})" },
5761 y: {
5762 g:1,
5763 c:"var ty = parseInt(results[{0}], 10);\n"
5764 + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n", s:"(\\d{1,2})"
5765 },
5766 a: {
5767 g:1,
5768 c:"if (results[{0}] == 'am') {\n"
5769 + "if (h == 12) { h = 0; }\n"
5770 + "} else { if (h < 12) { h += 12; }}",
5771 s:"(am|pm)"
5772 },
5773 A: {
5774 g:1,
5775 c:"if (results[{0}] == 'AM') {\n"
5776 + "if (h == 12) { h = 0; }\n"
5777 + "} else { if (h < 12) { h += 12; }}",
5778 s:"(AM|PM)"
5779 },
5780 g: function() {
5781 return Date.parseCodes["G"];
5782 },
5783 G: {
5784 g:1,
5785 c:"h = parseInt(results[{0}], 10);\n",
5786 s:"(\\d{1,2})" },
5787 h: function() {
5788 return Date.parseCodes["H"];
5789 },
5790 H: {
5791 g:1,
5792 c:"h = parseInt(results[{0}], 10);\n",
5793 s:"(\\d{2})" },
5794 i: {
5795 g:1,
5796 c:"i = parseInt(results[{0}], 10);\n",
5797 s:"(\\d{2})" },
5798 s: {
5799 g:1,
5800 c:"s = parseInt(results[{0}], 10);\n",
5801 s:"(\\d{2})" },
5802 u: {
5803 g:1,
5804 c:"ms = parseInt(results[{0}], 10);\n",
5805 s:"(\\d{3})" },
5806 O: {
5807 g:1,
5808 c:[
5809 "o = results[{0}];",
5810 "var sn = o.substring(0,1);", "var hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60);", "var mn = o.substring(3,5) % 60;", "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n" ].join("\n"),
5811 s: "([+\-]\\d{4})" },
5812 P: function() {
5813 return Ext.applyIf({
5814 s: "([+\-]\\d{2}:\\d{2})" }, Date.parseCodes["O"]);
5815 },
5816 T: {
5817 g:0,
5818 c:null,
5819 s:"[A-Z]{1,4}" },
5820 Z: {
5821 g:1,
5822 c:"z = results[{0}] * 1;\n" + "z = (-43200 <= z && z <= 50400)? z : null;\n",
5823 s:"([+\-]?\\d{1,5})" },
5824 c: function() {
5825 var df = Date.formatCodeToRegex, calc = [];
5826 var arr = [
5827 df("Y", 1),
5828 df("m", 2),
5829 df("d", 3),
5830 df("h", 4),
5831 df("i", 5),
5832 df("s", 6),
5833 {c:"if(results[7] == 'Z'){\no = 0;\n}else{\n" + df("P", 7).c + "\n}"} ];
5834 for (var i = 0, l = arr.length; i < l; ++i) {
5835 calc.push(arr[i].c);
5838 return {
5839 g:1,
5840 c:calc.join(""),
5841 s:arr[0].s + "-" + arr[1].s + "-" + arr[2].s + "T" + arr[3].s + ":" + arr[4].s + ":" + arr[5].s + "(" + df("P", 7).s + "|Z)"
5843 },
5844 U: {
5845 g:1,
5846 c:"u = parseInt(results[{0}], 10);\n",
5847 s:"(-?\\d+)" }
5850 Date.formatCodeToRegex = function(character, currentGroup) {
5851 var p = Date.parseCodes[character];
5853 if (p) {
5854 p = Ext.type(p) == 'function'? p() : p;
5855 Date.parseCodes[character] = p;
5856 if (p.c) {
5857 p.c = String.format(p.c, currentGroup);
5861 return p || {
5862 g:0,
5863 c:null,
5864 s:Ext.escapeRe(character) }
5865 };
5868 Date.prototype.getTimezone = function() {
5869 return this.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, "");
5870 };
5873 Date.prototype.getGMTOffset = function(colon) {
5874 return (this.getTimezoneOffset() > 0 ? "-" : "+")
5875 + String.leftPad(Math.abs(Math.floor(this.getTimezoneOffset() / 60)), 2, "0")
5876 + (colon ? ":" : "")
5877 + String.leftPad(this.getTimezoneOffset() % 60, 2, "0");
5878 };
5881 Date.prototype.getDayOfYear = function() {
5882 var num = 0;
5883 Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
5884 for (var i = 0; i < this.getMonth(); ++i) {
5885 num += Date.daysInMonth[i];
5887 return num + this.getDate() - 1;
5888 };
5891 Date.prototype.getWeekOfYear = function() {
5892 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();
5893 return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
5894 };
5897 Date.prototype.isLeapYear = function() {
5898 var year = this.getFullYear();
5899 return !!((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
5900 };
5903 Date.prototype.getFirstDayOfMonth = function() {
5904 var day = (this.getDay() - (this.getDate() - 1)) % 7;
5905 return (day < 0) ? (day + 7) : day;
5906 };
5909 Date.prototype.getLastDayOfMonth = function() {
5910 var day = (this.getDay() + (Date.daysInMonth[this.getMonth()] - this.getDate())) % 7;
5911 return (day < 0) ? (day + 7) : day;
5912 };
5916 Date.prototype.getFirstDateOfMonth = function() {
5917 return new Date(this.getFullYear(), this.getMonth(), 1);
5918 };
5921 Date.prototype.getLastDateOfMonth = function() {
5922 return new Date(this.getFullYear(), this.getMonth(), this.getDaysInMonth());
5923 };
5925 Date.prototype.getDaysInMonth = function() {
5926 Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
5927 return Date.daysInMonth[this.getMonth()];
5928 };
5931 Date.prototype.getSuffix = function() {
5932 switch (this.getDate()) {
5933 case 1:
5934 case 21:
5935 case 31:
5936 return "st";
5937 case 2:
5938 case 22:
5939 return "nd";
5940 case 3:
5941 case 23:
5942 return "rd";
5943 default:
5944 return "th";
5946 };
5948 Date.daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31];
5951 Date.monthNames = [
5952 "January",
5953 "February",
5954 "March",
5955 "April",
5956 "May",
5957 "June",
5958 "July",
5959 "August",
5960 "September",
5961 "October",
5962 "November",
5963 "December"
5964 ];
5967 Date.getShortMonthName = function(month) {
5968 return Date.monthNames[month].substring(0, 3);
5972 Date.dayNames = [
5973 "Sunday",
5974 "Monday",
5975 "Tuesday",
5976 "Wednesday",
5977 "Thursday",
5978 "Friday",
5979 "Saturday"
5980 ];
5983 Date.getShortDayName = function(day) {
5984 return Date.dayNames[day].substring(0, 3);
5987 Date.y2kYear = 50;
5990 Date.monthNumbers = {
5991 Jan:0,
5992 Feb:1,
5993 Mar:2,
5994 Apr:3,
5995 May:4,
5996 Jun:5,
5997 Jul:6,
5998 Aug:7,
5999 Sep:8,
6000 Oct:9,
6001 Nov:10,
6002 Dec:11
6003 };
6006 Date.getMonthNumber = function(name) {
6007 return Date.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()];
6011 Date.prototype.clone = function() {
6012 return new Date(this.getTime());
6013 };
6016 Date.prototype.clearTime = function(clone){
6017 if(clone){
6018 return this.clone().clearTime();
6020 this.setHours(0);
6021 this.setMinutes(0);
6022 this.setSeconds(0);
6023 this.setMilliseconds(0);
6024 return this;
6025 };
6027 if(Ext.isSafari){
6028 Date.brokenSetMonth = Date.prototype.setMonth;
6029 Date.prototype.setMonth = function(num){
6030 if(num <= -1){
6031 var n = Math.ceil(-num);
6032 var back_year = Math.ceil(n/12);
6033 var month = (n % 12) ? 12 - n % 12 : 0 ;
6034 this.setFullYear(this.getFullYear() - back_year);
6035 return Date.brokenSetMonth.call(this, month);
6036 } else {
6037 return Date.brokenSetMonth.apply(this, arguments);
6039 };
6043 Date.MILLI = "ms";
6045 Date.SECOND = "s";
6047 Date.MINUTE = "mi";
6049 Date.HOUR = "h";
6051 Date.DAY = "d";
6053 Date.MONTH = "mo";
6055 Date.YEAR = "y";
6058 Date.prototype.add = function(interval, value){
6059 var d = this.clone();
6060 if (!interval || value === 0) return d;
6061 switch(interval.toLowerCase()){
6062 case Date.MILLI:
6063 d.setMilliseconds(this.getMilliseconds() + value);
6064 break;
6065 case Date.SECOND:
6066 d.setSeconds(this.getSeconds() + value);
6067 break;
6068 case Date.MINUTE:
6069 d.setMinutes(this.getMinutes() + value);
6070 break;
6071 case Date.HOUR:
6072 d.setHours(this.getHours() + value);
6073 break;
6074 case Date.DAY:
6075 d.setDate(this.getDate() + value);
6076 break;
6077 case Date.MONTH:
6078 var day = this.getDate();
6079 if(day > 28){
6080 day = Math.min(day, this.getFirstDateOfMonth().add('mo', value).getLastDateOfMonth().getDate());
6082 d.setDate(day);
6083 d.setMonth(this.getMonth() + value);
6084 break;
6085 case Date.YEAR:
6086 d.setFullYear(this.getFullYear() + value);
6087 break;
6089 return d;
6090 };
6093 Date.prototype.between = function(start, end){
6094 var t = this.getTime();
6095 return start.getTime() <= t && t <= end.getTime();
6098 Ext.util.DelayedTask = function(fn, scope, args){
6099 var id = null, d, t;
6101 var call = function(){
6102 var now = new Date().getTime();
6103 if(now - t >= d){
6104 clearInterval(id);
6105 id = null;
6106 fn.apply(scope, args || []);
6108 };
6110 this.delay = function(delay, newFn, newScope, newArgs){
6111 if(id && delay != d){
6112 this.cancel();
6114 d = delay;
6115 t = new Date().getTime();
6116 fn = newFn || fn;
6117 scope = newScope || scope;
6118 args = newArgs || args;
6119 if(!id){
6120 id = setInterval(call, d);
6122 };
6125 this.cancel = function(){
6126 if(id){
6127 clearInterval(id);
6128 id = null;
6130 };
6131 };
6133 Ext.util.TaskRunner = function(interval){
6134 interval = interval || 10;
6135 var tasks = [], removeQueue = [];
6136 var id = 0;
6137 var running = false;
6139 var stopThread = function(){
6140 running = false;
6141 clearInterval(id);
6142 id = 0;
6143 };
6145 var startThread = function(){
6146 if(!running){
6147 running = true;
6148 id = setInterval(runTasks, interval);
6150 };
6152 var removeTask = function(t){
6153 removeQueue.push(t);
6154 if(t.onStop){
6155 t.onStop.apply(t.scope || t);
6157 };
6159 var runTasks = function(){
6160 if(removeQueue.length > 0){
6161 for(var i = 0, len = removeQueue.length; i < len; i++){
6162 tasks.remove(removeQueue[i]);
6164 removeQueue = [];
6165 if(tasks.length < 1){
6166 stopThread();
6167 return;
6170 var now = new Date().getTime();
6171 for(var i = 0, len = tasks.length; i < len; ++i){
6172 var t = tasks[i];
6173 var itime = now - t.taskRunTime;
6174 if(t.interval <= itime){
6175 var rt = t.run.apply(t.scope || t, t.args || [++t.taskRunCount]);
6176 t.taskRunTime = now;
6177 if(rt === false || t.taskRunCount === t.repeat){
6178 removeTask(t);
6179 return;
6182 if(t.duration && t.duration <= (now - t.taskStartTime)){
6183 removeTask(t);
6186 };
6189 this.start = function(task){
6190 tasks.push(task);
6191 task.taskStartTime = new Date().getTime();
6192 task.taskRunTime = 0;
6193 task.taskRunCount = 0;
6194 startThread();
6195 return task;
6196 };
6199 this.stop = function(task){
6200 removeTask(task);
6201 return task;
6202 };
6205 this.stopAll = function(){
6206 stopThread();
6207 for(var i = 0, len = tasks.length; i < len; i++){
6208 if(tasks[i].onStop){
6209 tasks[i].onStop();
6212 tasks = [];
6213 removeQueue = [];
6214 };
6215 };
6218 Ext.TaskMgr = new Ext.util.TaskRunner();
6220 Ext.util.MixedCollection = function(allowFunctions, keyFn){
6221 this.items = [];
6222 this.map = {};
6223 this.keys = [];
6224 this.length = 0;
6225 this.addEvents(
6227 "clear",
6229 "add",
6231 "replace",
6233 "remove",
6234 "sort"
6235 );
6236 this.allowFunctions = allowFunctions === true;
6237 if(keyFn){
6238 this.getKey = keyFn;
6240 Ext.util.MixedCollection.superclass.constructor.call(this);
6241 };
6243 Ext.extend(Ext.util.MixedCollection, Ext.util.Observable, {
6244 allowFunctions : false,
6247 add : function(key, o){
6248 if(arguments.length == 1){
6249 o = arguments[0];
6250 key = this.getKey(o);
6252 if(typeof key == "undefined" || key === null){
6253 this.length++;
6254 this.items.push(o);
6255 this.keys.push(null);
6256 }else{
6257 var old = this.map[key];
6258 if(old){
6259 return this.replace(key, o);
6261 this.length++;
6262 this.items.push(o);
6263 this.map[key] = o;
6264 this.keys.push(key);
6266 this.fireEvent("add", this.length-1, o, key);
6267 return o;
6268 },
6271 getKey : function(o){
6272 return o.id;
6273 },
6276 replace : function(key, o){
6277 if(arguments.length == 1){
6278 o = arguments[0];
6279 key = this.getKey(o);
6281 var old = this.item(key);
6282 if(typeof key == "undefined" || key === null || typeof old == "undefined"){
6283 return this.add(key, o);
6285 var index = this.indexOfKey(key);
6286 this.items[index] = o;
6287 this.map[key] = o;
6288 this.fireEvent("replace", key, old, o);
6289 return o;
6290 },
6293 addAll : function(objs){
6294 if(arguments.length > 1 || Ext.isArray(objs)){
6295 var args = arguments.length > 1 ? arguments : objs;
6296 for(var i = 0, len = args.length; i < len; i++){
6297 this.add(args[i]);
6299 }else{
6300 for(var key in objs){
6301 if(this.allowFunctions || typeof objs[key] != "function"){
6302 this.add(key, objs[key]);
6306 },
6309 each : function(fn, scope){
6310 var items = [].concat(this.items);
6311 for(var i = 0, len = items.length; i < len; i++){
6312 if(fn.call(scope || items[i], items[i], i, len) === false){
6313 break;
6316 },
6319 eachKey : function(fn, scope){
6320 for(var i = 0, len = this.keys.length; i < len; i++){
6321 fn.call(scope || window, this.keys[i], this.items[i], i, len);
6323 },
6326 find : function(fn, scope){
6327 for(var i = 0, len = this.items.length; i < len; i++){
6328 if(fn.call(scope || window, this.items[i], this.keys[i])){
6329 return this.items[i];
6332 return null;
6333 },
6336 insert : function(index, key, o){
6337 if(arguments.length == 2){
6338 o = arguments[1];
6339 key = this.getKey(o);
6341 if(index >= this.length){
6342 return this.add(key, o);
6344 this.length++;
6345 this.items.splice(index, 0, o);
6346 if(typeof key != "undefined" && key != null){
6347 this.map[key] = o;
6349 this.keys.splice(index, 0, key);
6350 this.fireEvent("add", index, o, key);
6351 return o;
6352 },
6355 remove : function(o){
6356 return this.removeAt(this.indexOf(o));
6357 },
6360 removeAt : function(index){
6361 if(index < this.length && index >= 0){
6362 this.length--;
6363 var o = this.items[index];
6364 this.items.splice(index, 1);
6365 var key = this.keys[index];
6366 if(typeof key != "undefined"){
6367 delete this.map[key];
6369 this.keys.splice(index, 1);
6370 this.fireEvent("remove", o, key);
6371 return o;
6373 return false;
6374 },
6377 removeKey : function(key){
6378 return this.removeAt(this.indexOfKey(key));
6379 },
6382 getCount : function(){
6383 return this.length;
6384 },
6387 indexOf : function(o){
6388 return this.items.indexOf(o);
6389 },
6392 indexOfKey : function(key){
6393 return this.keys.indexOf(key);
6394 },
6397 item : function(key){
6398 var item = typeof this.map[key] != "undefined" ? this.map[key] : this.items[key];
6399 return typeof item != 'function' || this.allowFunctions ? item : null;
6400 },
6403 itemAt : function(index){
6404 return this.items[index];
6405 },
6408 key : function(key){
6409 return this.map[key];
6410 },
6413 contains : function(o){
6414 return this.indexOf(o) != -1;
6415 },
6418 containsKey : function(key){
6419 return typeof this.map[key] != "undefined";
6420 },
6423 clear : function(){
6424 this.length = 0;
6425 this.items = [];
6426 this.keys = [];
6427 this.map = {};
6428 this.fireEvent("clear");
6429 },
6432 first : function(){
6433 return this.items[0];
6434 },
6437 last : function(){
6438 return this.items[this.length-1];
6439 },
6442 _sort : function(property, dir, fn){
6443 var dsc = String(dir).toUpperCase() == "DESC" ? -1 : 1;
6444 fn = fn || function(a, b){
6445 return a-b;
6446 };
6447 var c = [], k = this.keys, items = this.items;
6448 for(var i = 0, len = items.length; i < len; i++){
6449 c[c.length] = {key: k[i], value: items[i], index: i};
6451 c.sort(function(a, b){
6452 var v = fn(a[property], b[property]) * dsc;
6453 if(v == 0){
6454 v = (a.index < b.index ? -1 : 1);
6456 return v;
6457 });
6458 for(var i = 0, len = c.length; i < len; i++){
6459 items[i] = c[i].value;
6460 k[i] = c[i].key;
6462 this.fireEvent("sort", this);
6463 },
6466 sort : function(dir, fn){
6467 this._sort("value", dir, fn);
6468 },
6471 keySort : function(dir, fn){
6472 this._sort("key", dir, fn || function(a, b){
6473 return String(a).toUpperCase()-String(b).toUpperCase();
6474 });
6475 },
6478 getRange : function(start, end){
6479 var items = this.items;
6480 if(items.length < 1){
6481 return [];
6483 start = start || 0;
6484 end = Math.min(typeof end == "undefined" ? this.length-1 : end, this.length-1);
6485 var r = [];
6486 if(start <= end){
6487 for(var i = start; i <= end; i++) {
6488 r[r.length] = items[i];
6490 }else{
6491 for(var i = start; i >= end; i--) {
6492 r[r.length] = items[i];
6495 return r;
6496 },
6499 filter : function(property, value, anyMatch, caseSensitive){
6500 if(Ext.isEmpty(value, false)){
6501 return this.clone();
6503 value = this.createValueMatcher(value, anyMatch, caseSensitive);
6504 return this.filterBy(function(o){
6505 return o && value.test(o[property]);
6506 });
6507 },
6510 filterBy : function(fn, scope){
6511 var r = new Ext.util.MixedCollection();
6512 r.getKey = this.getKey;
6513 var k = this.keys, it = this.items;
6514 for(var i = 0, len = it.length; i < len; i++){
6515 if(fn.call(scope||this, it[i], k[i])){
6516 r.add(k[i], it[i]);
6519 return r;
6520 },
6523 findIndex : function(property, value, start, anyMatch, caseSensitive){
6524 if(Ext.isEmpty(value, false)){
6525 return -1;
6527 value = this.createValueMatcher(value, anyMatch, caseSensitive);
6528 return this.findIndexBy(function(o){
6529 return o && value.test(o[property]);
6530 }, null, start);
6531 },
6534 findIndexBy : function(fn, scope, start){
6535 var k = this.keys, it = this.items;
6536 for(var i = (start||0), len = it.length; i < len; i++){
6537 if(fn.call(scope||this, it[i], k[i])){
6538 return i;
6541 if(typeof start == 'number' && start > 0){
6542 for(var i = 0; i < start; i++){
6543 if(fn.call(scope||this, it[i], k[i])){
6544 return i;
6548 return -1;
6549 },
6552 createValueMatcher : function(value, anyMatch, caseSensitive){
6553 if(!value.exec){
6554 value = String(value);
6555 value = new RegExp((anyMatch === true ? '' : '^') + Ext.escapeRe(value), caseSensitive ? '' : 'i');
6557 return value;
6558 },
6561 clone : function(){
6562 var r = new Ext.util.MixedCollection();
6563 var k = this.keys, it = this.items;
6564 for(var i = 0, len = it.length; i < len; i++){
6565 r.add(k[i], it[i]);
6567 r.getKey = this.getKey;
6568 return r;
6570 });
6572 Ext.util.MixedCollection.prototype.get = Ext.util.MixedCollection.prototype.item;
6574 Ext.util.JSON = new (function(){
6575 var useHasOwn = !!{}.hasOwnProperty;
6578 var pad = function(n) {
6579 return n < 10 ? "0" + n : n;
6580 };
6582 var m = {
6583 "\b": '\\b',
6584 "\t": '\\t',
6585 "\n": '\\n',
6586 "\f": '\\f',
6587 "\r": '\\r',
6588 '"' : '\\"',
6589 "\\": '\\\\'
6590 };
6592 var encodeString = function(s){
6593 if (/["\\\x00-\x1f]/.test(s)) {
6594 return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) {
6595 var c = m[b];
6596 if(c){
6597 return c;
6599 c = b.charCodeAt();
6600 return "\\u00" +
6601 Math.floor(c / 16).toString(16) +
6602 (c % 16).toString(16);
6603 }) + '"';
6605 return '"' + s + '"';
6606 };
6608 var encodeArray = function(o){
6609 var a = ["["], b, i, l = o.length, v;
6610 for (i = 0; i < l; i += 1) {
6611 v = o[i];
6612 switch (typeof v) {
6613 case "undefined":
6614 case "function":
6615 case "unknown":
6616 break;
6617 default:
6618 if (b) {
6619 a.push(',');
6621 a.push(v === null ? "null" : Ext.util.JSON.encode(v));
6622 b = true;
6625 a.push("]");
6626 return a.join("");
6627 };
6629 this.encodeDate = function(o){
6630 return '"' + o.getFullYear() + "-" +
6631 pad(o.getMonth() + 1) + "-" +
6632 pad(o.getDate()) + "T" +
6633 pad(o.getHours()) + ":" +
6634 pad(o.getMinutes()) + ":" +
6635 pad(o.getSeconds()) + '"';
6636 };
6639 this.encode = function(o){
6640 if(typeof o == "undefined" || o === null){
6641 return "null";
6642 }else if(Ext.isArray(o)){
6643 return encodeArray(o);
6644 }else if(Ext.isDate(o)){
6645 return Ext.util.JSON.encodeDate(o);
6646 }else if(typeof o == "string"){
6647 return encodeString(o);
6648 }else if(typeof o == "number"){
6649 return isFinite(o) ? String(o) : "null";
6650 }else if(typeof o == "boolean"){
6651 return String(o);
6652 }else {
6653 var a = ["{"], b, i, v;
6654 for (i in o) {
6655 if(!useHasOwn || o.hasOwnProperty(i)) {
6656 v = o[i];
6657 switch (typeof v) {
6658 case "undefined":
6659 case "function":
6660 case "unknown":
6661 break;
6662 default:
6663 if(b){
6664 a.push(',');
6666 a.push(this.encode(i), ":",
6667 v === null ? "null" : this.encode(v));
6668 b = true;
6672 a.push("}");
6673 return a.join("");
6675 };
6678 this.decode = function(json){
6679 return eval("(" + json + ')');
6680 };
6681 })();
6683 Ext.encode = Ext.util.JSON.encode;
6685 Ext.decode = Ext.util.JSON.decode;
6688 Ext.util.Format = function(){
6689 var trimRe = /^\s+|\s+$/g;
6690 return {
6692 ellipsis : function(value, len){
6693 if(value && value.length > len){
6694 return value.substr(0, len-3)+"...";
6696 return value;
6697 },
6700 undef : function(value){
6701 return value !== undefined ? value : "";
6702 },
6705 defaultValue : function(value, defaultValue){
6706 return value !== undefined && value !== '' ? value : defaultValue;
6707 },
6710 htmlEncode : function(value){
6711 return !value ? value : String(value).replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;").replace(/"/g, "&quot;");
6712 },
6715 htmlDecode : function(value){
6716 return !value ? value : String(value).replace(/&amp;/g, "&").replace(/&gt;/g, ">").replace(/&lt;/g, "<").replace(/&quot;/g, '"');
6717 },
6720 trim : function(value){
6721 return String(value).replace(trimRe, "");
6722 },
6725 substr : function(value, start, length){
6726 return String(value).substr(start, length);
6727 },
6730 lowercase : function(value){
6731 return String(value).toLowerCase();
6732 },
6735 uppercase : function(value){
6736 return String(value).toUpperCase();
6737 },
6740 capitalize : function(value){
6741 return !value ? value : value.charAt(0).toUpperCase() + value.substr(1).toLowerCase();
6742 },
6745 call : function(value, fn){
6746 if(arguments.length > 2){
6747 var args = Array.prototype.slice.call(arguments, 2);
6748 args.unshift(value);
6749 return eval(fn).apply(window, args);
6750 }else{
6751 return eval(fn).call(window, value);
6753 },
6756 usMoney : function(v){
6757 v = (Math.round((v-0)*100))/100;
6758 v = (v == Math.floor(v)) ? v + ".00" : ((v*10 == Math.floor(v*10)) ? v + "0" : v);
6759 v = String(v);
6760 var ps = v.split('.');
6761 var whole = ps[0];
6762 var sub = ps[1] ? '.'+ ps[1] : '.00';
6763 var r = /(\d+)(\d{3})/;
6764 while (r.test(whole)) {
6765 whole = whole.replace(r, '$1' + ',' + '$2');
6767 v = whole + sub;
6768 if(v.charAt(0) == '-'){
6769 return '-$' + v.substr(1);
6771 return "$" + v;
6772 },
6775 date : function(v, format){
6776 if(!v){
6777 return "";
6779 if(!Ext.isDate(v)){
6780 v = new Date(Date.parse(v));
6782 return v.dateFormat(format || "m/d/Y");
6783 },
6786 dateRenderer : function(format){
6787 return function(v){
6788 return Ext.util.Format.date(v, format);
6789 };
6790 },
6793 stripTagsRE : /<\/?[^>]+>/gi,
6796 stripTags : function(v){
6797 return !v ? v : String(v).replace(this.stripTagsRE, "");
6798 },
6800 stripScriptsRe : /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,
6803 stripScripts : function(v){
6804 return !v ? v : String(v).replace(this.stripScriptsRe, "");
6805 },
6808 fileSize : function(size){
6809 if(size < 1024) {
6810 return size + " bytes";
6811 } else if(size < 1048576) {
6812 return (Math.round(((size*10) / 1024))/10) + " KB";
6813 } else {
6814 return (Math.round(((size*10) / 1048576))/10) + " MB";
6816 },
6818 math : function(){
6819 var fns = {};
6820 return function(v, a){
6821 if(!fns[a]){
6822 fns[a] = new Function('v', 'return v ' + a + ';');
6824 return fns[a](v);
6826 }()
6827 };
6828 }();
6830 Ext.XTemplate = function(){
6831 Ext.XTemplate.superclass.constructor.apply(this, arguments);
6832 var s = this.html;
6834 s = ['<tpl>', s, '</tpl>'].join('');
6836 var re = /<tpl\b[^>]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/;
6838 var nameRe = /^<tpl\b[^>]*?for="(.*?)"/;
6839 var ifRe = /^<tpl\b[^>]*?if="(.*?)"/;
6840 var execRe = /^<tpl\b[^>]*?exec="(.*?)"/;
6841 var m, id = 0;
6842 var tpls = [];
6844 while(m = s.match(re)){
6845 var m2 = m[0].match(nameRe);
6846 var m3 = m[0].match(ifRe);
6847 var m4 = m[0].match(execRe);
6848 var exp = null, fn = null, exec = null;
6849 var name = m2 && m2[1] ? m2[1] : '';
6850 if(m3){
6851 exp = m3 && m3[1] ? m3[1] : null;
6852 if(exp){
6853 fn = new Function('values', 'parent', 'xindex', 'xcount', 'with(values){ return '+(Ext.util.Format.htmlDecode(exp))+'; }');
6856 if(m4){
6857 exp = m4 && m4[1] ? m4[1] : null;
6858 if(exp){
6859 exec = new Function('values', 'parent', 'xindex', 'xcount', 'with(values){ '+(Ext.util.Format.htmlDecode(exp))+'; }');
6862 if(name){
6863 switch(name){
6864 case '.': name = new Function('values', 'parent', 'with(values){ return values; }'); break;
6865 case '..': name = new Function('values', 'parent', 'with(values){ return parent; }'); break;
6866 default: name = new Function('values', 'parent', 'with(values){ return '+name+'; }');
6869 tpls.push({
6870 id: id,
6871 target: name,
6872 exec: exec,
6873 test: fn,
6874 body: m[1]||''
6875 });
6876 s = s.replace(m[0], '{xtpl'+ id + '}');
6877 ++id;
6879 for(var i = tpls.length-1; i >= 0; --i){
6880 this.compileTpl(tpls[i]);
6882 this.master = tpls[tpls.length-1];
6883 this.tpls = tpls;
6884 };
6885 Ext.extend(Ext.XTemplate, Ext.Template, {
6886 re : /\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\\]\s?[\d\.\+\-\*\\\(\)]+)?\}/g,
6887 codeRe : /\{\[((?:\\\]|.|\n)*?)\]\}/g,
6889 applySubTemplate : function(id, values, parent, xindex, xcount){
6890 var t = this.tpls[id];
6891 if(t.test && !t.test.call(this, values, parent, xindex, xcount)){
6892 return '';
6894 if(t.exec && t.exec.call(this, values, parent, xindex, xcount)){
6895 return '';
6897 var vs = t.target ? t.target.call(this, values, parent) : values;
6898 parent = t.target ? values : parent;
6899 if(t.target && Ext.isArray(vs)){
6900 var buf = [];
6901 for(var i = 0, len = vs.length; i < len; i++){
6902 buf[buf.length] = t.compiled.call(this, vs[i], parent, i+1, len);
6904 return buf.join('');
6906 return t.compiled.call(this, vs, parent, xindex, xcount);
6907 },
6909 compileTpl : function(tpl){
6910 var fm = Ext.util.Format;
6911 var useF = this.disableFormats !== true;
6912 var sep = Ext.isGecko ? "+" : ",";
6913 var fn = function(m, name, format, args, math){
6914 if(name.substr(0, 4) == 'xtpl'){
6915 return "'"+ sep +'this.applySubTemplate('+name.substr(4)+', values, parent, xindex, xcount)'+sep+"'";
6917 var v;
6918 if(name === '.'){
6919 v = 'values';
6920 }else if(name === '#'){
6921 v = 'xindex';
6922 }else if(name.indexOf('.') != -1){
6923 v = name;
6924 }else{
6925 v = "values['" + name + "']";
6927 if(math){
6928 v = '(' + v + math + ')';
6930 if(format && useF){
6931 args = args ? ',' + args : "";
6932 if(format.substr(0, 5) != "this."){
6933 format = "fm." + format + '(';
6934 }else{
6935 format = 'this.call("'+ format.substr(5) + '", ';
6936 args = ", values";
6938 }else{
6939 args= ''; format = "("+v+" === undefined ? '' : ";
6941 return "'"+ sep + format + v + args + ")"+sep+"'";
6942 };
6943 var codeFn = function(m, code){
6944 return "'"+ sep +'('+code+')'+sep+"'";
6945 };
6947 var body;
6948 if(Ext.isGecko){
6949 body = "tpl.compiled = function(values, parent, xindex, xcount){ return '" +
6950 tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn) +
6951 "';};";
6952 }else{
6953 body = ["tpl.compiled = function(values, parent, xindex, xcount){ return ['"];
6954 body.push(tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn));
6955 body.push("'].join('');};");
6956 body = body.join('');
6958 eval(body);
6959 return this;
6960 },
6963 applyTemplate : function(values){
6964 return this.master.compiled.call(this, values, {}, 1, 1);
6965 },
6968 compile : function(){return this;}
6974 });
6976 Ext.XTemplate.prototype.apply = Ext.XTemplate.prototype.applyTemplate;
6979 Ext.XTemplate.from = function(el){
6980 el = Ext.getDom(el);
6981 return new Ext.XTemplate(el.value || el.innerHTML);
6982 };
6984 Ext.util.CSS = function(){
6985 var rules = null;
6986 var doc = document;
6988 var camelRe = /(-[a-z])/gi;
6989 var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };
6991 return {
6993 createStyleSheet : function(cssText, id){
6994 var ss;
6995 var head = doc.getElementsByTagName("head")[0];
6996 var rules = doc.createElement("style");
6997 rules.setAttribute("type", "text/css");
6998 if(id){
6999 rules.setAttribute("id", id);
7001 if(Ext.isIE){
7002 head.appendChild(rules);
7003 ss = rules.styleSheet;
7004 ss.cssText = cssText;
7005 }else{
7006 try{
7007 rules.appendChild(doc.createTextNode(cssText));
7008 }catch(e){
7009 rules.cssText = cssText;
7011 head.appendChild(rules);
7012 ss = rules.styleSheet ? rules.styleSheet : (rules.sheet || doc.styleSheets[doc.styleSheets.length-1]);
7014 this.cacheStyleSheet(ss);
7015 return ss;
7016 },
7019 removeStyleSheet : function(id){
7020 var existing = doc.getElementById(id);
7021 if(existing){
7022 existing.parentNode.removeChild(existing);
7024 },
7027 swapStyleSheet : function(id, url){
7028 this.removeStyleSheet(id);
7029 var ss = doc.createElement("link");
7030 ss.setAttribute("rel", "stylesheet");
7031 ss.setAttribute("type", "text/css");
7032 ss.setAttribute("id", id);
7033 ss.setAttribute("href", url);
7034 doc.getElementsByTagName("head")[0].appendChild(ss);
7035 },
7038 refreshCache : function(){
7039 return this.getRules(true);
7040 },
7043 cacheStyleSheet : function(ss){
7044 if(!rules){
7045 rules = {};
7047 try{
7048 var ssRules = ss.cssRules || ss.rules;
7049 for(var j = ssRules.length-1; j >= 0; --j){
7050 rules[ssRules[j].selectorText] = ssRules[j];
7052 }catch(e){}
7053 },
7056 getRules : function(refreshCache){
7057 if(rules == null || refreshCache){
7058 rules = {};
7059 var ds = doc.styleSheets;
7060 for(var i =0, len = ds.length; i < len; i++){
7061 try{
7062 this.cacheStyleSheet(ds[i]);
7063 }catch(e){}
7066 return rules;
7067 },
7070 getRule : function(selector, refreshCache){
7071 var rs = this.getRules(refreshCache);
7072 if(!Ext.isArray(selector)){
7073 return rs[selector];
7075 for(var i = 0; i < selector.length; i++){
7076 if(rs[selector[i]]){
7077 return rs[selector[i]];
7080 return null;
7081 },
7085 updateRule : function(selector, property, value){
7086 if(!Ext.isArray(selector)){
7087 var rule = this.getRule(selector);
7088 if(rule){
7089 rule.style[property.replace(camelRe, camelFn)] = value;
7090 return true;
7092 }else{
7093 for(var i = 0; i < selector.length; i++){
7094 if(this.updateRule(selector[i], property, value)){
7095 return true;
7099 return false;
7101 };
7102 }();
7104 Ext.util.ClickRepeater = function(el, config)
7106 this.el = Ext.get(el);
7107 this.el.unselectable();
7109 Ext.apply(this, config);
7111 this.addEvents(
7113 "mousedown",
7115 "click",
7117 "mouseup"
7118 );
7120 this.el.on("mousedown", this.handleMouseDown, this);
7121 if(this.preventDefault || this.stopDefault){
7122 this.el.on("click", function(e){
7123 if(this.preventDefault){
7124 e.preventDefault();
7126 if(this.stopDefault){
7127 e.stopEvent();
7129 }, this);
7132 if(this.handler){
7133 this.on("click", this.handler, this.scope || this);
7136 Ext.util.ClickRepeater.superclass.constructor.call(this);
7137 };
7139 Ext.extend(Ext.util.ClickRepeater, Ext.util.Observable, {
7140 interval : 20,
7141 delay: 250,
7142 preventDefault : true,
7143 stopDefault : false,
7144 timer : 0,
7146 handleMouseDown : function(){
7147 clearTimeout(this.timer);
7148 this.el.blur();
7149 if(this.pressClass){
7150 this.el.addClass(this.pressClass);
7152 this.mousedownTime = new Date();
7154 Ext.getDoc().on("mouseup", this.handleMouseUp, this);
7155 this.el.on("mouseout", this.handleMouseOut, this);
7157 this.fireEvent("mousedown", this);
7158 this.fireEvent("click", this);
7160 if (this.accelerate) {
7161 this.delay = 400;
7163 this.timer = this.click.defer(this.delay || this.interval, this);
7164 },
7166 click : function(){
7167 this.fireEvent("click", this);
7168 this.timer = this.click.defer(this.accelerate ?
7169 this.easeOutExpo(this.mousedownTime.getElapsed(),
7170 400,
7171 -390,
7172 12000) :
7173 this.interval, this);
7174 },
7176 easeOutExpo : function (t, b, c, d) {
7177 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
7178 },
7180 handleMouseOut : function(){
7181 clearTimeout(this.timer);
7182 if(this.pressClass){
7183 this.el.removeClass(this.pressClass);
7185 this.el.on("mouseover", this.handleMouseReturn, this);
7186 },
7188 handleMouseReturn : function(){
7189 this.el.un("mouseover", this.handleMouseReturn);
7190 if(this.pressClass){
7191 this.el.addClass(this.pressClass);
7193 this.click();
7194 },
7196 handleMouseUp : function(){
7197 clearTimeout(this.timer);
7198 this.el.un("mouseover", this.handleMouseReturn);
7199 this.el.un("mouseout", this.handleMouseOut);
7200 Ext.getDoc().un("mouseup", this.handleMouseUp);
7201 this.el.removeClass(this.pressClass);
7202 this.fireEvent("mouseup", this);
7204 });
7206 Ext.KeyNav = function(el, config){
7207 this.el = Ext.get(el);
7208 Ext.apply(this, config);
7209 if(!this.disabled){
7210 this.disabled = true;
7211 this.enable();
7213 };
7215 Ext.KeyNav.prototype = {
7217 disabled : false,
7219 defaultEventAction: "stopEvent",
7221 forceKeyDown : false,
7223 prepareEvent : function(e){
7224 var k = e.getKey();
7225 var h = this.keyToHandler[k];
7226 if(Ext.isSafari2 && h && k >= 37 && k <= 40){
7227 e.stopEvent();
7229 },
7231 relay : function(e){
7232 var k = e.getKey();
7233 var h = this.keyToHandler[k];
7234 if(h && this[h]){
7235 if(this.doRelay(e, this[h], h) !== true){
7236 e[this.defaultEventAction]();
7239 },
7241 doRelay : function(e, h, hname){
7242 return h.call(this.scope || this, e);
7243 },
7245 enter : false,
7246 left : false,
7247 right : false,
7248 up : false,
7249 down : false,
7250 tab : false,
7251 esc : false,
7252 pageUp : false,
7253 pageDown : false,
7254 del : false,
7255 home : false,
7256 end : false,
7258 keyToHandler : {
7259 37 : "left",
7260 39 : "right",
7261 38 : "up",
7262 40 : "down",
7263 33 : "pageUp",
7264 34 : "pageDown",
7265 46 : "del",
7266 36 : "home",
7267 35 : "end",
7268 13 : "enter",
7269 27 : "esc",
7270 9 : "tab"
7271 },
7274 enable: function(){
7275 if(this.disabled){
7276 if(this.forceKeyDown || Ext.isIE || Ext.isSafari3 || Ext.isAir){
7277 this.el.on("keydown", this.relay, this);
7278 }else{
7279 this.el.on("keydown", this.prepareEvent, this);
7280 this.el.on("keypress", this.relay, this);
7282 this.disabled = false;
7284 },
7287 disable: function(){
7288 if(!this.disabled){
7289 if(this.forceKeyDown || Ext.isIE || Ext.isSafari3 || Ext.isAir){
7290 this.el.un("keydown", this.relay);
7291 }else{
7292 this.el.un("keydown", this.prepareEvent);
7293 this.el.un("keypress", this.relay);
7295 this.disabled = true;
7298 };
7300 Ext.KeyMap = function(el, config, eventName){
7301 this.el = Ext.get(el);
7302 this.eventName = eventName || "keydown";
7303 this.bindings = [];
7304 if(config){
7305 this.addBinding(config);
7307 this.enable();
7308 };
7310 Ext.KeyMap.prototype = {
7312 stopEvent : false,
7315 addBinding : function(config){
7316 if(Ext.isArray(config)){
7317 for(var i = 0, len = config.length; i < len; i++){
7318 this.addBinding(config[i]);
7320 return;
7322 var keyCode = config.key,
7323 shift = config.shift,
7324 ctrl = config.ctrl,
7325 alt = config.alt,
7326 fn = config.fn || config.handler,
7327 scope = config.scope;
7329 if(typeof keyCode == "string"){
7330 var ks = [];
7331 var keyString = keyCode.toUpperCase();
7332 for(var j = 0, len = keyString.length; j < len; j++){
7333 ks.push(keyString.charCodeAt(j));
7335 keyCode = ks;
7337 var keyArray = Ext.isArray(keyCode);
7339 var handler = function(e){
7340 if((!shift || e.shiftKey) && (!ctrl || e.ctrlKey) && (!alt || e.altKey)){
7341 var k = e.getKey();
7342 if(keyArray){
7343 for(var i = 0, len = keyCode.length; i < len; i++){
7344 if(keyCode[i] == k){
7345 if(this.stopEvent){
7346 e.stopEvent();
7348 fn.call(scope || window, k, e);
7349 return;
7352 }else{
7353 if(k == keyCode){
7354 if(this.stopEvent){
7355 e.stopEvent();
7357 fn.call(scope || window, k, e);
7361 };
7362 this.bindings.push(handler);
7363 },
7366 on : function(key, fn, scope){
7367 var keyCode, shift, ctrl, alt;
7368 if(typeof key == "object" && !Ext.isArray(key)){
7369 keyCode = key.key;
7370 shift = key.shift;
7371 ctrl = key.ctrl;
7372 alt = key.alt;
7373 }else{
7374 keyCode = key;
7376 this.addBinding({
7377 key: keyCode,
7378 shift: shift,
7379 ctrl: ctrl,
7380 alt: alt,
7381 fn: fn,
7382 scope: scope
7383 })
7384 },
7387 handleKeyDown : function(e){
7388 if(this.enabled){
7389 var b = this.bindings;
7390 for(var i = 0, len = b.length; i < len; i++){
7391 b[i].call(this, e);
7394 },
7397 isEnabled : function(){
7398 return this.enabled;
7399 },
7402 enable: function(){
7403 if(!this.enabled){
7404 this.el.on(this.eventName, this.handleKeyDown, this);
7405 this.enabled = true;
7407 },
7410 disable: function(){
7411 if(this.enabled){
7412 this.el.removeListener(this.eventName, this.handleKeyDown, this);
7413 this.enabled = false;
7416 };
7418 Ext.util.TextMetrics = function(){
7419 var shared;
7420 return {
7422 measure : function(el, text, fixedWidth){
7423 if(!shared){
7424 shared = Ext.util.TextMetrics.Instance(el, fixedWidth);
7426 shared.bind(el);
7427 shared.setFixedWidth(fixedWidth || 'auto');
7428 return shared.getSize(text);
7429 },
7432 createInstance : function(el, fixedWidth){
7433 return Ext.util.TextMetrics.Instance(el, fixedWidth);
7435 };
7436 }();
7438 Ext.util.TextMetrics.Instance = function(bindTo, fixedWidth){
7439 var ml = new Ext.Element(document.createElement('div'));
7440 document.body.appendChild(ml.dom);
7441 ml.position('absolute');
7442 ml.setLeftTop(-1000, -1000);
7443 ml.hide();
7445 if(fixedWidth){
7446 ml.setWidth(fixedWidth);
7449 var instance = {
7451 getSize : function(text){
7452 ml.update(text);
7453 var s = ml.getSize();
7454 ml.update('');
7455 return s;
7456 },
7459 bind : function(el){
7460 ml.setStyle(
7461 Ext.fly(el).getStyles('font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing')
7462 );
7463 },
7466 setFixedWidth : function(width){
7467 ml.setWidth(width);
7468 },
7471 getWidth : function(text){
7472 ml.dom.style.width = 'auto';
7473 return this.getSize(text).width;
7474 },
7477 getHeight : function(text){
7478 return this.getSize(text).height;
7480 };
7482 instance.bind(bindTo);
7484 return instance;
7485 };
7487 Ext.Element.measureText = Ext.util.TextMetrics.measure;
7490 (function() {
7492 var Event=Ext.EventManager;
7493 var Dom=Ext.lib.Dom;
7496 Ext.dd.DragDrop = function(id, sGroup, config) {
7497 if(id) {
7498 this.init(id, sGroup, config);
7500 };
7502 Ext.dd.DragDrop.prototype = {
7505 id: null,
7508 config: null,
7511 dragElId: null,
7514 handleElId: null,
7517 invalidHandleTypes: null,
7520 invalidHandleIds: null,
7523 invalidHandleClasses: null,
7526 startPageX: 0,
7529 startPageY: 0,
7532 groups: null,
7535 locked: false,
7538 lock: function() { this.locked = true; },
7541 unlock: function() { this.locked = false; },
7544 isTarget: true,
7547 padding: null,
7550 _domRef: null,
7553 __ygDragDrop: true,
7556 constrainX: false,
7559 constrainY: false,
7562 minX: 0,
7565 maxX: 0,
7568 minY: 0,
7571 maxY: 0,
7574 maintainOffset: false,
7577 xTicks: null,
7580 yTicks: null,
7583 primaryButtonOnly: true,
7586 available: false,
7589 hasOuterHandles: false,
7592 b4StartDrag: function(x, y) { },
7595 startDrag: function(x, y) { },
7598 b4Drag: function(e) { },
7601 onDrag: function(e) { },
7604 onDragEnter: function(e, id) { },
7607 b4DragOver: function(e) { },
7610 onDragOver: function(e, id) { },
7613 b4DragOut: function(e) { },
7616 onDragOut: function(e, id) { },
7619 b4DragDrop: function(e) { },
7622 onDragDrop: function(e, id) { },
7625 onInvalidDrop: function(e) { },
7628 b4EndDrag: function(e) { },
7631 endDrag: function(e) { },
7634 b4MouseDown: function(e) { },
7637 onMouseDown: function(e) { },
7640 onMouseUp: function(e) { },
7643 onAvailable: function () {
7644 },
7647 defaultPadding : {left:0, right:0, top:0, bottom:0},
7650 constrainTo : function(constrainTo, pad, inContent){
7651 if(typeof pad == "number"){
7652 pad = {left: pad, right:pad, top:pad, bottom:pad};
7654 pad = pad || this.defaultPadding;
7655 var b = Ext.get(this.getEl()).getBox();
7656 var ce = Ext.get(constrainTo);
7657 var s = ce.getScroll();
7658 var c, cd = ce.dom;
7659 if(cd == document.body){
7660 c = { x: s.left, y: s.top, width: Ext.lib.Dom.getViewWidth(), height: Ext.lib.Dom.getViewHeight()};
7661 }else{
7662 var xy = ce.getXY();
7663 c = {x : xy[0]+s.left, y: xy[1]+s.top, width: cd.clientWidth, height: cd.clientHeight};
7667 var topSpace = b.y - c.y;
7668 var leftSpace = b.x - c.x;
7670 this.resetConstraints();
7671 this.setXConstraint(leftSpace - (pad.left||0),
7672 c.width - leftSpace - b.width - (pad.right||0),
7673 this.xTickSize
7674 );
7675 this.setYConstraint(topSpace - (pad.top||0),
7676 c.height - topSpace - b.height - (pad.bottom||0),
7677 this.yTickSize
7678 );
7679 },
7682 getEl: function() {
7683 if (!this._domRef) {
7684 this._domRef = Ext.getDom(this.id);
7687 return this._domRef;
7688 },
7691 getDragEl: function() {
7692 return Ext.getDom(this.dragElId);
7693 },
7696 init: function(id, sGroup, config) {
7697 this.initTarget(id, sGroup, config);
7698 Event.on(this.id, "mousedown", this.handleMouseDown, this);
7700 },
7703 initTarget: function(id, sGroup, config) {
7706 this.config = config || {};
7709 this.DDM = Ext.dd.DDM;
7711 this.groups = {};
7715 if (typeof id !== "string") {
7716 id = Ext.id(id);
7720 this.id = id;
7723 this.addToGroup((sGroup) ? sGroup : "default");
7727 this.handleElId = id;
7730 this.setDragElId(id);
7733 this.invalidHandleTypes = { A: "A" };
7734 this.invalidHandleIds = {};
7735 this.invalidHandleClasses = [];
7737 this.applyConfig();
7739 this.handleOnAvailable();
7740 },
7743 applyConfig: function() {
7747 this.padding = this.config.padding || [0, 0, 0, 0];
7748 this.isTarget = (this.config.isTarget !== false);
7749 this.maintainOffset = (this.config.maintainOffset);
7750 this.primaryButtonOnly = (this.config.primaryButtonOnly !== false);
7752 },
7755 handleOnAvailable: function() {
7756 this.available = true;
7757 this.resetConstraints();
7758 this.onAvailable();
7759 },
7762 setPadding: function(iTop, iRight, iBot, iLeft) {
7764 if (!iRight && 0 !== iRight) {
7765 this.padding = [iTop, iTop, iTop, iTop];
7766 } else if (!iBot && 0 !== iBot) {
7767 this.padding = [iTop, iRight, iTop, iRight];
7768 } else {
7769 this.padding = [iTop, iRight, iBot, iLeft];
7771 },
7774 setInitPosition: function(diffX, diffY) {
7775 var el = this.getEl();
7777 if (!this.DDM.verifyEl(el)) {
7778 return;
7781 var dx = diffX || 0;
7782 var dy = diffY || 0;
7784 var p = Dom.getXY( el );
7786 this.initPageX = p[0] - dx;
7787 this.initPageY = p[1] - dy;
7789 this.lastPageX = p[0];
7790 this.lastPageY = p[1];
7793 this.setStartPosition(p);
7794 },
7797 setStartPosition: function(pos) {
7798 var p = pos || Dom.getXY( this.getEl() );
7799 this.deltaSetXY = null;
7801 this.startPageX = p[0];
7802 this.startPageY = p[1];
7803 },
7806 addToGroup: function(sGroup) {
7807 this.groups[sGroup] = true;
7808 this.DDM.regDragDrop(this, sGroup);
7809 },
7812 removeFromGroup: function(sGroup) {
7813 if (this.groups[sGroup]) {
7814 delete this.groups[sGroup];
7817 this.DDM.removeDDFromGroup(this, sGroup);
7818 },
7821 setDragElId: function(id) {
7822 this.dragElId = id;
7823 },
7826 setHandleElId: function(id) {
7827 if (typeof id !== "string") {
7828 id = Ext.id(id);
7830 this.handleElId = id;
7831 this.DDM.regHandle(this.id, id);
7832 },
7835 setOuterHandleElId: function(id) {
7836 if (typeof id !== "string") {
7837 id = Ext.id(id);
7839 Event.on(id, "mousedown",
7840 this.handleMouseDown, this);
7841 this.setHandleElId(id);
7843 this.hasOuterHandles = true;
7844 },
7847 unreg: function() {
7848 Event.un(this.id, "mousedown",
7849 this.handleMouseDown);
7850 this._domRef = null;
7851 this.DDM._remove(this);
7852 },
7854 destroy : function(){
7855 this.unreg();
7856 },
7859 isLocked: function() {
7860 return (this.DDM.isLocked() || this.locked);
7861 },
7864 handleMouseDown: function(e, oDD){
7865 if (this.primaryButtonOnly && e.button != 0) {
7866 return;
7869 if (this.isLocked()) {
7870 return;
7873 this.DDM.refreshCache(this.groups);
7875 var pt = new Ext.lib.Point(Ext.lib.Event.getPageX(e), Ext.lib.Event.getPageY(e));
7876 if (!this.hasOuterHandles && !this.DDM.isOverTarget(pt, this) ) {
7877 } else {
7878 if (this.clickValidator(e)) {
7881 this.setStartPosition();
7884 this.b4MouseDown(e);
7885 this.onMouseDown(e);
7887 this.DDM.handleMouseDown(e, this);
7889 this.DDM.stopEvent(e);
7890 } else {
7895 },
7897 clickValidator: function(e) {
7898 var target = e.getTarget();
7899 return ( this.isValidHandleChild(target) &&
7900 (this.id == this.handleElId ||
7901 this.DDM.handleWasClicked(target, this.id)) );
7902 },
7905 addInvalidHandleType: function(tagName) {
7906 var type = tagName.toUpperCase();
7907 this.invalidHandleTypes[type] = type;
7908 },
7911 addInvalidHandleId: function(id) {
7912 if (typeof id !== "string") {
7913 id = Ext.id(id);
7915 this.invalidHandleIds[id] = id;
7916 },
7919 addInvalidHandleClass: function(cssClass) {
7920 this.invalidHandleClasses.push(cssClass);
7921 },
7924 removeInvalidHandleType: function(tagName) {
7925 var type = tagName.toUpperCase();
7927 delete this.invalidHandleTypes[type];
7928 },
7931 removeInvalidHandleId: function(id) {
7932 if (typeof id !== "string") {
7933 id = Ext.id(id);
7935 delete this.invalidHandleIds[id];
7936 },
7939 removeInvalidHandleClass: function(cssClass) {
7940 for (var i=0, len=this.invalidHandleClasses.length; i<len; ++i) {
7941 if (this.invalidHandleClasses[i] == cssClass) {
7942 delete this.invalidHandleClasses[i];
7945 },
7948 isValidHandleChild: function(node) {
7950 var valid = true;
7952 var nodeName;
7953 try {
7954 nodeName = node.nodeName.toUpperCase();
7955 } catch(e) {
7956 nodeName = node.nodeName;
7958 valid = valid && !this.invalidHandleTypes[nodeName];
7959 valid = valid && !this.invalidHandleIds[node.id];
7961 for (var i=0, len=this.invalidHandleClasses.length; valid && i<len; ++i) {
7962 valid = !Dom.hasClass(node, this.invalidHandleClasses[i]);
7966 return valid;
7968 },
7971 setXTicks: function(iStartX, iTickSize) {
7972 this.xTicks = [];
7973 this.xTickSize = iTickSize;
7975 var tickMap = {};
7977 for (var i = this.initPageX; i >= this.minX; i = i - iTickSize) {
7978 if (!tickMap[i]) {
7979 this.xTicks[this.xTicks.length] = i;
7980 tickMap[i] = true;
7984 for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) {
7985 if (!tickMap[i]) {
7986 this.xTicks[this.xTicks.length] = i;
7987 tickMap[i] = true;
7991 this.xTicks.sort(this.DDM.numericSort) ;
7992 },
7995 setYTicks: function(iStartY, iTickSize) {
7996 this.yTicks = [];
7997 this.yTickSize = iTickSize;
7999 var tickMap = {};
8001 for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) {
8002 if (!tickMap[i]) {
8003 this.yTicks[this.yTicks.length] = i;
8004 tickMap[i] = true;
8008 for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) {
8009 if (!tickMap[i]) {
8010 this.yTicks[this.yTicks.length] = i;
8011 tickMap[i] = true;
8015 this.yTicks.sort(this.DDM.numericSort) ;
8016 },
8019 setXConstraint: function(iLeft, iRight, iTickSize) {
8020 this.leftConstraint = iLeft;
8021 this.rightConstraint = iRight;
8023 this.minX = this.initPageX - iLeft;
8024 this.maxX = this.initPageX + iRight;
8025 if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); }
8027 this.constrainX = true;
8028 },
8031 clearConstraints: function() {
8032 this.constrainX = false;
8033 this.constrainY = false;
8034 this.clearTicks();
8035 },
8038 clearTicks: function() {
8039 this.xTicks = null;
8040 this.yTicks = null;
8041 this.xTickSize = 0;
8042 this.yTickSize = 0;
8043 },
8046 setYConstraint: function(iUp, iDown, iTickSize) {
8047 this.topConstraint = iUp;
8048 this.bottomConstraint = iDown;
8050 this.minY = this.initPageY - iUp;
8051 this.maxY = this.initPageY + iDown;
8052 if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); }
8054 this.constrainY = true;
8056 },
8059 resetConstraints: function() {
8063 if (this.initPageX || this.initPageX === 0) {
8065 var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0;
8066 var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0;
8068 this.setInitPosition(dx, dy);
8071 } else {
8072 this.setInitPosition();
8075 if (this.constrainX) {
8076 this.setXConstraint( this.leftConstraint,
8077 this.rightConstraint,
8078 this.xTickSize );
8081 if (this.constrainY) {
8082 this.setYConstraint( this.topConstraint,
8083 this.bottomConstraint,
8084 this.yTickSize );
8086 },
8089 getTick: function(val, tickArray) {
8091 if (!tickArray) {
8094 return val;
8095 } else if (tickArray[0] >= val) {
8098 return tickArray[0];
8099 } else {
8100 for (var i=0, len=tickArray.length; i<len; ++i) {
8101 var next = i + 1;
8102 if (tickArray[next] && tickArray[next] >= val) {
8103 var diff1 = val - tickArray[i];
8104 var diff2 = tickArray[next] - val;
8105 return (diff2 > diff1) ? tickArray[i] : tickArray[next];
8111 return tickArray[tickArray.length - 1];
8113 },
8116 toString: function() {
8117 return ("DragDrop " + this.id);
8120 };
8122 })();
8127 if (!Ext.dd.DragDropMgr) {
8130 Ext.dd.DragDropMgr = function() {
8132 var Event = Ext.EventManager;
8134 return {
8137 ids: {},
8140 handleIds: {},
8143 dragCurrent: null,
8146 dragOvers: {},
8149 deltaX: 0,
8152 deltaY: 0,
8155 preventDefault: true,
8158 stopPropagation: true,
8161 initialized: false,
8164 locked: false,
8167 init: function() {
8168 this.initialized = true;
8169 },
8172 POINT: 0,
8175 INTERSECT: 1,
8178 mode: 0,
8181 _execOnAll: function(sMethod, args) {
8182 for (var i in this.ids) {
8183 for (var j in this.ids[i]) {
8184 var oDD = this.ids[i][j];
8185 if (! this.isTypeOfDD(oDD)) {
8186 continue;
8188 oDD[sMethod].apply(oDD, args);
8191 },
8194 _onLoad: function() {
8196 this.init();
8199 Event.on(document, "mouseup", this.handleMouseUp, this, true);
8200 Event.on(document, "mousemove", this.handleMouseMove, this, true);
8201 Event.on(window, "unload", this._onUnload, this, true);
8202 Event.on(window, "resize", this._onResize, this, true);
8205 },
8208 _onResize: function(e) {
8209 this._execOnAll("resetConstraints", []);
8210 },
8213 lock: function() { this.locked = true; },
8216 unlock: function() { this.locked = false; },
8219 isLocked: function() { return this.locked; },
8222 locationCache: {},
8225 useCache: true,
8228 clickPixelThresh: 3,
8231 clickTimeThresh: 350,
8234 dragThreshMet: false,
8237 clickTimeout: null,
8240 startX: 0,
8243 startY: 0,
8246 regDragDrop: function(oDD, sGroup) {
8247 if (!this.initialized) { this.init(); }
8249 if (!this.ids[sGroup]) {
8250 this.ids[sGroup] = {};
8252 this.ids[sGroup][oDD.id] = oDD;
8253 },
8256 removeDDFromGroup: function(oDD, sGroup) {
8257 if (!this.ids[sGroup]) {
8258 this.ids[sGroup] = {};
8261 var obj = this.ids[sGroup];
8262 if (obj && obj[oDD.id]) {
8263 delete obj[oDD.id];
8265 },
8268 _remove: function(oDD) {
8269 for (var g in oDD.groups) {
8270 if (g && this.ids[g][oDD.id]) {
8271 delete this.ids[g][oDD.id];
8274 delete this.handleIds[oDD.id];
8275 },
8278 regHandle: function(sDDId, sHandleId) {
8279 if (!this.handleIds[sDDId]) {
8280 this.handleIds[sDDId] = {};
8282 this.handleIds[sDDId][sHandleId] = sHandleId;
8283 },
8286 isDragDrop: function(id) {
8287 return ( this.getDDById(id) ) ? true : false;
8288 },
8291 getRelated: function(p_oDD, bTargetsOnly) {
8292 var oDDs = [];
8293 for (var i in p_oDD.groups) {
8294 for (j in this.ids[i]) {
8295 var dd = this.ids[i][j];
8296 if (! this.isTypeOfDD(dd)) {
8297 continue;
8299 if (!bTargetsOnly || dd.isTarget) {
8300 oDDs[oDDs.length] = dd;
8305 return oDDs;
8306 },
8309 isLegalTarget: function (oDD, oTargetDD) {
8310 var targets = this.getRelated(oDD, true);
8311 for (var i=0, len=targets.length;i<len;++i) {
8312 if (targets[i].id == oTargetDD.id) {
8313 return true;
8317 return false;
8318 },
8321 isTypeOfDD: function (oDD) {
8322 return (oDD && oDD.__ygDragDrop);
8323 },
8326 isHandle: function(sDDId, sHandleId) {
8327 return ( this.handleIds[sDDId] &&
8328 this.handleIds[sDDId][sHandleId] );
8329 },
8332 getDDById: function(id) {
8333 for (var i in this.ids) {
8334 if (this.ids[i][id]) {
8335 return this.ids[i][id];
8338 return null;
8339 },
8342 handleMouseDown: function(e, oDD) {
8343 if(Ext.QuickTips){
8344 Ext.QuickTips.disable();
8346 this.currentTarget = e.getTarget();
8348 this.dragCurrent = oDD;
8350 var el = oDD.getEl();
8353 this.startX = e.getPageX();
8354 this.startY = e.getPageY();
8356 this.deltaX = this.startX - el.offsetLeft;
8357 this.deltaY = this.startY - el.offsetTop;
8359 this.dragThreshMet = false;
8361 this.clickTimeout = setTimeout(
8362 function() {
8363 var DDM = Ext.dd.DDM;
8364 DDM.startDrag(DDM.startX, DDM.startY);
8365 },
8366 this.clickTimeThresh );
8367 },
8370 startDrag: function(x, y) {
8371 clearTimeout(this.clickTimeout);
8372 if (this.dragCurrent) {
8373 this.dragCurrent.b4StartDrag(x, y);
8374 this.dragCurrent.startDrag(x, y);
8376 this.dragThreshMet = true;
8377 },
8380 handleMouseUp: function(e) {
8382 if(Ext.QuickTips){
8383 Ext.QuickTips.enable();
8385 if (! this.dragCurrent) {
8386 return;
8389 clearTimeout(this.clickTimeout);
8391 if (this.dragThreshMet) {
8392 this.fireEvents(e, true);
8393 } else {
8396 this.stopDrag(e);
8398 this.stopEvent(e);
8399 },
8402 stopEvent: function(e){
8403 if(this.stopPropagation) {
8404 e.stopPropagation();
8407 if (this.preventDefault) {
8408 e.preventDefault();
8410 },
8413 stopDrag: function(e) {
8415 if (this.dragCurrent) {
8416 if (this.dragThreshMet) {
8417 this.dragCurrent.b4EndDrag(e);
8418 this.dragCurrent.endDrag(e);
8421 this.dragCurrent.onMouseUp(e);
8424 this.dragCurrent = null;
8425 this.dragOvers = {};
8426 },
8429 handleMouseMove: function(e) {
8430 if (! this.dragCurrent) {
8431 return true;
8437 if (Ext.isIE && (e.button !== 0 && e.button !== 1 && e.button !== 2)) {
8438 this.stopEvent(e);
8439 return this.handleMouseUp(e);
8442 if (!this.dragThreshMet) {
8443 var diffX = Math.abs(this.startX - e.getPageX());
8444 var diffY = Math.abs(this.startY - e.getPageY());
8445 if (diffX > this.clickPixelThresh ||
8446 diffY > this.clickPixelThresh) {
8447 this.startDrag(this.startX, this.startY);
8451 if (this.dragThreshMet) {
8452 this.dragCurrent.b4Drag(e);
8453 this.dragCurrent.onDrag(e);
8454 if(!this.dragCurrent.moveOnly){
8455 this.fireEvents(e, false);
8459 this.stopEvent(e);
8461 return true;
8462 },
8465 fireEvents: function(e, isDrop) {
8466 var dc = this.dragCurrent;
8470 if (!dc || dc.isLocked()) {
8471 return;
8474 var pt = e.getPoint();
8477 var oldOvers = [];
8479 var outEvts = [];
8480 var overEvts = [];
8481 var dropEvts = [];
8482 var enterEvts = [];
8486 for (var i in this.dragOvers) {
8488 var ddo = this.dragOvers[i];
8490 if (! this.isTypeOfDD(ddo)) {
8491 continue;
8494 if (! this.isOverTarget(pt, ddo, this.mode)) {
8495 outEvts.push( ddo );
8498 oldOvers[i] = true;
8499 delete this.dragOvers[i];
8502 for (var sGroup in dc.groups) {
8504 if ("string" != typeof sGroup) {
8505 continue;
8508 for (i in this.ids[sGroup]) {
8509 var oDD = this.ids[sGroup][i];
8510 if (! this.isTypeOfDD(oDD)) {
8511 continue;
8514 if (oDD.isTarget && !oDD.isLocked() && oDD != dc) {
8515 if (this.isOverTarget(pt, oDD, this.mode)) {
8517 if (isDrop) {
8518 dropEvts.push( oDD );
8520 } else {
8523 if (!oldOvers[oDD.id]) {
8524 enterEvts.push( oDD );
8526 } else {
8527 overEvts.push( oDD );
8530 this.dragOvers[oDD.id] = oDD;
8537 if (this.mode) {
8538 if (outEvts.length) {
8539 dc.b4DragOut(e, outEvts);
8540 dc.onDragOut(e, outEvts);
8543 if (enterEvts.length) {
8544 dc.onDragEnter(e, enterEvts);
8547 if (overEvts.length) {
8548 dc.b4DragOver(e, overEvts);
8549 dc.onDragOver(e, overEvts);
8552 if (dropEvts.length) {
8553 dc.b4DragDrop(e, dropEvts);
8554 dc.onDragDrop(e, dropEvts);
8557 } else {
8559 var len = 0;
8560 for (i=0, len=outEvts.length; i<len; ++i) {
8561 dc.b4DragOut(e, outEvts[i].id);
8562 dc.onDragOut(e, outEvts[i].id);
8566 for (i=0,len=enterEvts.length; i<len; ++i) {
8568 dc.onDragEnter(e, enterEvts[i].id);
8572 for (i=0,len=overEvts.length; i<len; ++i) {
8573 dc.b4DragOver(e, overEvts[i].id);
8574 dc.onDragOver(e, overEvts[i].id);
8578 for (i=0, len=dropEvts.length; i<len; ++i) {
8579 dc.b4DragDrop(e, dropEvts[i].id);
8580 dc.onDragDrop(e, dropEvts[i].id);
8586 if (isDrop && !dropEvts.length) {
8587 dc.onInvalidDrop(e);
8590 },
8593 getBestMatch: function(dds) {
8594 var winner = null;
8601 var len = dds.length;
8603 if (len == 1) {
8604 winner = dds[0];
8605 } else {
8607 for (var i=0; i<len; ++i) {
8608 var dd = dds[i];
8612 if (dd.cursorIsOver) {
8613 winner = dd;
8614 break;
8616 } else {
8617 if (!winner ||
8618 winner.overlap.getArea() < dd.overlap.getArea()) {
8619 winner = dd;
8625 return winner;
8626 },
8629 refreshCache: function(groups) {
8630 for (var sGroup in groups) {
8631 if ("string" != typeof sGroup) {
8632 continue;
8634 for (var i in this.ids[sGroup]) {
8635 var oDD = this.ids[sGroup][i];
8637 if (this.isTypeOfDD(oDD)) {
8639 var loc = this.getLocation(oDD);
8640 if (loc) {
8641 this.locationCache[oDD.id] = loc;
8642 } else {
8643 delete this.locationCache[oDD.id];
8651 },
8654 verifyEl: function(el) {
8655 if (el) {
8656 var parent;
8657 if(Ext.isIE){
8658 try{
8659 parent = el.offsetParent;
8660 }catch(e){}
8661 }else{
8662 parent = el.offsetParent;
8664 if (parent) {
8665 return true;
8669 return false;
8670 },
8673 getLocation: function(oDD) {
8674 if (! this.isTypeOfDD(oDD)) {
8675 return null;
8678 var el = oDD.getEl(), pos, x1, x2, y1, y2, t, r, b, l;
8680 try {
8681 pos= Ext.lib.Dom.getXY(el);
8682 } catch (e) { }
8684 if (!pos) {
8685 return null;
8688 x1 = pos[0];
8689 x2 = x1 + el.offsetWidth;
8690 y1 = pos[1];
8691 y2 = y1 + el.offsetHeight;
8693 t = y1 - oDD.padding[0];
8694 r = x2 + oDD.padding[1];
8695 b = y2 + oDD.padding[2];
8696 l = x1 - oDD.padding[3];
8698 return new Ext.lib.Region( t, r, b, l );
8699 },
8702 isOverTarget: function(pt, oTarget, intersect) {
8704 var loc = this.locationCache[oTarget.id];
8705 if (!loc || !this.useCache) {
8706 loc = this.getLocation(oTarget);
8707 this.locationCache[oTarget.id] = loc;
8711 if (!loc) {
8712 return false;
8715 oTarget.cursorIsOver = loc.contains( pt );
8722 var dc = this.dragCurrent;
8723 if (!dc || !dc.getTargetCoord ||
8724 (!intersect && !dc.constrainX && !dc.constrainY)) {
8725 return oTarget.cursorIsOver;
8728 oTarget.overlap = null;
8734 var pos = dc.getTargetCoord(pt.x, pt.y);
8736 var el = dc.getDragEl();
8737 var curRegion = new Ext.lib.Region( pos.y,
8738 pos.x + el.offsetWidth,
8739 pos.y + el.offsetHeight,
8740 pos.x );
8742 var overlap = curRegion.intersect(loc);
8744 if (overlap) {
8745 oTarget.overlap = overlap;
8746 return (intersect) ? true : oTarget.cursorIsOver;
8747 } else {
8748 return false;
8750 },
8753 _onUnload: function(e, me) {
8754 Ext.dd.DragDropMgr.unregAll();
8755 },
8758 unregAll: function() {
8760 if (this.dragCurrent) {
8761 this.stopDrag();
8762 this.dragCurrent = null;
8765 this._execOnAll("unreg", []);
8767 for (var i in this.elementCache) {
8768 delete this.elementCache[i];
8771 this.elementCache = {};
8772 this.ids = {};
8773 },
8776 elementCache: {},
8779 getElWrapper: function(id) {
8780 var oWrapper = this.elementCache[id];
8781 if (!oWrapper || !oWrapper.el) {
8782 oWrapper = this.elementCache[id] =
8783 new this.ElementWrapper(Ext.getDom(id));
8785 return oWrapper;
8786 },
8789 getElement: function(id) {
8790 return Ext.getDom(id);
8791 },
8794 getCss: function(id) {
8795 var el = Ext.getDom(id);
8796 return (el) ? el.style : null;
8797 },
8800 ElementWrapper: function(el) {
8802 this.el = el || null;
8804 this.id = this.el && el.id;
8806 this.css = this.el && el.style;
8807 },
8810 getPosX: function(el) {
8811 return Ext.lib.Dom.getX(el);
8812 },
8815 getPosY: function(el) {
8816 return Ext.lib.Dom.getY(el);
8817 },
8820 swapNode: function(n1, n2) {
8821 if (n1.swapNode) {
8822 n1.swapNode(n2);
8823 } else {
8824 var p = n2.parentNode;
8825 var s = n2.nextSibling;
8827 if (s == n1) {
8828 p.insertBefore(n1, n2);
8829 } else if (n2 == n1.nextSibling) {
8830 p.insertBefore(n2, n1);
8831 } else {
8832 n1.parentNode.replaceChild(n2, n1);
8833 p.insertBefore(n1, s);
8836 },
8839 getScroll: function () {
8840 var t, l, dde=document.documentElement, db=document.body;
8841 if (dde && (dde.scrollTop || dde.scrollLeft)) {
8842 t = dde.scrollTop;
8843 l = dde.scrollLeft;
8844 } else if (db) {
8845 t = db.scrollTop;
8846 l = db.scrollLeft;
8847 } else {
8850 return { top: t, left: l };
8851 },
8854 getStyle: function(el, styleProp) {
8855 return Ext.fly(el).getStyle(styleProp);
8856 },
8859 getScrollTop: function () { return this.getScroll().top; },
8862 getScrollLeft: function () { return this.getScroll().left; },
8865 moveToEl: function (moveEl, targetEl) {
8866 var aCoord = Ext.lib.Dom.getXY(targetEl);
8867 Ext.lib.Dom.setXY(moveEl, aCoord);
8868 },
8871 numericSort: function(a, b) { return (a - b); },
8874 _timeoutCount: 0,
8877 _addListeners: function() {
8878 var DDM = Ext.dd.DDM;
8879 if ( Ext.lib.Event && document ) {
8880 DDM._onLoad();
8881 } else {
8882 if (DDM._timeoutCount > 2000) {
8883 } else {
8884 setTimeout(DDM._addListeners, 10);
8885 if (document && document.body) {
8886 DDM._timeoutCount += 1;
8890 },
8893 handleWasClicked: function(node, id) {
8894 if (this.isHandle(id, node.id)) {
8895 return true;
8896 } else {
8898 var p = node.parentNode;
8900 while (p) {
8901 if (this.isHandle(id, p.id)) {
8902 return true;
8903 } else {
8904 p = p.parentNode;
8909 return false;
8912 };
8914 }();
8917 Ext.dd.DDM = Ext.dd.DragDropMgr;
8918 Ext.dd.DDM._addListeners();
8923 Ext.dd.DD = function(id, sGroup, config) {
8924 if (id) {
8925 this.init(id, sGroup, config);
8927 };
8929 Ext.extend(Ext.dd.DD, Ext.dd.DragDrop, {
8932 scroll: true,
8935 autoOffset: function(iPageX, iPageY) {
8936 var x = iPageX - this.startPageX;
8937 var y = iPageY - this.startPageY;
8938 this.setDelta(x, y);
8939 },
8942 setDelta: function(iDeltaX, iDeltaY) {
8943 this.deltaX = iDeltaX;
8944 this.deltaY = iDeltaY;
8945 },
8948 setDragElPos: function(iPageX, iPageY) {
8952 var el = this.getDragEl();
8953 this.alignElWithMouse(el, iPageX, iPageY);
8954 },
8957 alignElWithMouse: function(el, iPageX, iPageY) {
8958 var oCoord = this.getTargetCoord(iPageX, iPageY);
8959 var fly = el.dom ? el : Ext.fly(el, '_dd');
8960 if (!this.deltaSetXY) {
8961 var aCoord = [oCoord.x, oCoord.y];
8962 fly.setXY(aCoord);
8963 var newLeft = fly.getLeft(true);
8964 var newTop = fly.getTop(true);
8965 this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ];
8966 } else {
8967 fly.setLeftTop(oCoord.x + this.deltaSetXY[0], oCoord.y + this.deltaSetXY[1]);
8970 this.cachePosition(oCoord.x, oCoord.y);
8971 this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
8972 return oCoord;
8973 },
8976 cachePosition: function(iPageX, iPageY) {
8977 if (iPageX) {
8978 this.lastPageX = iPageX;
8979 this.lastPageY = iPageY;
8980 } else {
8981 var aCoord = Ext.lib.Dom.getXY(this.getEl());
8982 this.lastPageX = aCoord[0];
8983 this.lastPageY = aCoord[1];
8985 },
8988 autoScroll: function(x, y, h, w) {
8990 if (this.scroll) {
8992 var clientH = Ext.lib.Dom.getViewHeight();
8995 var clientW = Ext.lib.Dom.getViewWidth();
8998 var st = this.DDM.getScrollTop();
9001 var sl = this.DDM.getScrollLeft();
9004 var bot = h + y;
9007 var right = w + x;
9012 var toBot = (clientH + st - y - this.deltaY);
9015 var toRight = (clientW + sl - x - this.deltaX);
9020 var thresh = 40;
9025 var scrAmt = (document.all) ? 80 : 30;
9029 if ( bot > clientH && toBot < thresh ) {
9030 window.scrollTo(sl, st + scrAmt);
9035 if ( y < st && st > 0 && y - st < thresh ) {
9036 window.scrollTo(sl, st - scrAmt);
9041 if ( right > clientW && toRight < thresh ) {
9042 window.scrollTo(sl + scrAmt, st);
9047 if ( x < sl && sl > 0 && x - sl < thresh ) {
9048 window.scrollTo(sl - scrAmt, st);
9051 },
9054 getTargetCoord: function(iPageX, iPageY) {
9057 var x = iPageX - this.deltaX;
9058 var y = iPageY - this.deltaY;
9060 if (this.constrainX) {
9061 if (x < this.minX) { x = this.minX; }
9062 if (x > this.maxX) { x = this.maxX; }
9065 if (this.constrainY) {
9066 if (y < this.minY) { y = this.minY; }
9067 if (y > this.maxY) { y = this.maxY; }
9070 x = this.getTick(x, this.xTicks);
9071 y = this.getTick(y, this.yTicks);
9074 return {x:x, y:y};
9075 },
9078 applyConfig: function() {
9079 Ext.dd.DD.superclass.applyConfig.call(this);
9080 this.scroll = (this.config.scroll !== false);
9081 },
9084 b4MouseDown: function(e) {
9086 this.autoOffset(e.getPageX(),
9087 e.getPageY());
9088 },
9091 b4Drag: function(e) {
9092 this.setDragElPos(e.getPageX(),
9093 e.getPageY());
9094 },
9096 toString: function() {
9097 return ("DD " + this.id);
9105 });
9107 Ext.dd.DDProxy = function(id, sGroup, config) {
9108 if (id) {
9109 this.init(id, sGroup, config);
9110 this.initFrame();
9112 };
9115 Ext.dd.DDProxy.dragElId = "ygddfdiv";
9117 Ext.extend(Ext.dd.DDProxy, Ext.dd.DD, {
9120 resizeFrame: true,
9123 centerFrame: false,
9126 createFrame: function() {
9127 var self = this;
9128 var body = document.body;
9130 if (!body || !body.firstChild) {
9131 setTimeout( function() { self.createFrame(); }, 50 );
9132 return;
9135 var div = this.getDragEl();
9137 if (!div) {
9138 div = document.createElement("div");
9139 div.id = this.dragElId;
9140 var s = div.style;
9142 s.position = "absolute";
9143 s.visibility = "hidden";
9144 s.cursor = "move";
9145 s.border = "2px solid #aaa";
9146 s.zIndex = 999;
9151 body.insertBefore(div, body.firstChild);
9153 },
9156 initFrame: function() {
9157 this.createFrame();
9158 },
9160 applyConfig: function() {
9161 Ext.dd.DDProxy.superclass.applyConfig.call(this);
9163 this.resizeFrame = (this.config.resizeFrame !== false);
9164 this.centerFrame = (this.config.centerFrame);
9165 this.setDragElId(this.config.dragElId || Ext.dd.DDProxy.dragElId);
9166 },
9169 showFrame: function(iPageX, iPageY) {
9170 var el = this.getEl();
9171 var dragEl = this.getDragEl();
9172 var s = dragEl.style;
9174 this._resizeProxy();
9176 if (this.centerFrame) {
9177 this.setDelta( Math.round(parseInt(s.width, 10)/2),
9178 Math.round(parseInt(s.height, 10)/2) );
9181 this.setDragElPos(iPageX, iPageY);
9183 Ext.fly(dragEl).show();
9184 },
9187 _resizeProxy: function() {
9188 if (this.resizeFrame) {
9189 var el = this.getEl();
9190 Ext.fly(this.getDragEl()).setSize(el.offsetWidth, el.offsetHeight);
9192 },
9195 b4MouseDown: function(e) {
9196 var x = e.getPageX();
9197 var y = e.getPageY();
9198 this.autoOffset(x, y);
9199 this.setDragElPos(x, y);
9200 },
9203 b4StartDrag: function(x, y) {
9205 this.showFrame(x, y);
9206 },
9209 b4EndDrag: function(e) {
9210 Ext.fly(this.getDragEl()).hide();
9211 },
9216 endDrag: function(e) {
9218 var lel = this.getEl();
9219 var del = this.getDragEl();
9222 del.style.visibility = "";
9224 this.beforeMove();
9227 lel.style.visibility = "hidden";
9228 Ext.dd.DDM.moveToEl(lel, del);
9229 del.style.visibility = "hidden";
9230 lel.style.visibility = "";
9232 this.afterDrag();
9233 },
9235 beforeMove : function(){
9237 },
9239 afterDrag : function(){
9241 },
9243 toString: function() {
9244 return ("DDProxy " + this.id);
9247 });
9249 Ext.dd.DDTarget = function(id, sGroup, config) {
9250 if (id) {
9251 this.initTarget(id, sGroup, config);
9253 };
9256 Ext.extend(Ext.dd.DDTarget, Ext.dd.DragDrop, {
9257 toString: function() {
9258 return ("DDTarget " + this.id);
9260 });
9262 Ext.dd.DragTracker = function(config){
9263 Ext.apply(this, config);
9264 this.addEvents(
9265 'mousedown',
9266 'mouseup',
9267 'mousemove',
9268 'dragstart',
9269 'dragend',
9270 'drag'
9271 );
9273 this.dragRegion = new Ext.lib.Region(0,0,0,0);
9275 if(this.el){
9276 this.initEl(this.el);
9280 Ext.extend(Ext.dd.DragTracker, Ext.util.Observable, {
9281 active: false,
9282 tolerance: 5,
9283 autoStart: false,
9285 initEl: function(el){
9286 this.el = Ext.get(el);
9287 el.on('mousedown', this.onMouseDown, this,
9288 this.delegate ? {delegate: this.delegate} : undefined);
9289 },
9291 destroy : function(){
9292 this.el.un('mousedown', this.onMouseDown, this);
9293 },
9295 onMouseDown: function(e, target){
9296 if(this.fireEvent('mousedown', this, e) !== false && this.onBeforeStart(e) !== false){
9297 this.startXY = this.lastXY = e.getXY();
9298 this.dragTarget = this.delegate ? target : this.el.dom;
9299 e.preventDefault();
9300 var doc = Ext.getDoc();
9301 doc.on('mouseup', this.onMouseUp, this);
9302 doc.on('mousemove', this.onMouseMove, this);
9303 doc.on('selectstart', this.stopSelect, this);
9304 if(this.autoStart){
9305 this.timer = this.triggerStart.defer(this.autoStart === true ? 1000 : this.autoStart, this);
9308 },
9310 onMouseMove: function(e, target){
9311 e.preventDefault();
9312 var xy = e.getXY(), s = this.startXY;
9313 this.lastXY = xy;
9314 if(!this.active){
9315 if(Math.abs(s[0]-xy[0]) > this.tolerance || Math.abs(s[1]-xy[1]) > this.tolerance){
9316 this.triggerStart();
9317 }else{
9318 return;
9321 this.fireEvent('mousemove', this, e);
9322 this.onDrag(e);
9323 this.fireEvent('drag', this, e);
9324 },
9326 onMouseUp: function(e){
9327 var doc = Ext.getDoc();
9328 doc.un('mousemove', this.onMouseMove, this);
9329 doc.un('mouseup', this.onMouseUp, this);
9330 doc.un('selectstart', this.stopSelect, this);
9331 e.preventDefault();
9332 this.clearStart();
9333 this.active = false;
9334 delete this.elRegion;
9335 this.fireEvent('mouseup', this, e);
9336 this.onEnd(e);
9337 this.fireEvent('dragend', this, e);
9338 },
9340 triggerStart: function(isTimer){
9341 this.clearStart();
9342 this.active = true;
9343 this.onStart(this.startXY);
9344 this.fireEvent('dragstart', this, this.startXY);
9345 },
9347 clearStart : function(){
9348 if(this.timer){
9349 clearTimeout(this.timer);
9350 delete this.timer;
9352 },
9354 stopSelect : function(e){
9355 e.stopEvent();
9356 return false;
9357 },
9359 onBeforeStart : function(e){
9361 },
9363 onStart : function(xy){
9365 },
9367 onDrag : function(e){
9369 },
9371 onEnd : function(e){
9373 },
9375 getDragTarget : function(){
9376 return this.dragTarget;
9377 },
9379 getDragCt : function(){
9380 return this.el;
9381 },
9383 getXY : function(constrain){
9384 return constrain ?
9385 this.constrainModes[constrain].call(this, this.lastXY) : this.lastXY;
9386 },
9388 getOffset : function(constrain){
9389 var xy = this.getXY(constrain);
9390 var s = this.startXY;
9391 return [s[0]-xy[0], s[1]-xy[1]];
9392 },
9394 constrainModes: {
9395 'point' : function(xy){
9397 if(!this.elRegion){
9398 this.elRegion = this.getDragCt().getRegion();
9401 var dr = this.dragRegion;
9403 dr.left = xy[0];
9404 dr.top = xy[1];
9405 dr.right = xy[0];
9406 dr.bottom = xy[1];
9408 dr.constrainTo(this.elRegion);
9410 return [dr.left, dr.top];
9413 });
9415 Ext.dd.ScrollManager = function(){
9416 var ddm = Ext.dd.DragDropMgr;
9417 var els = {};
9418 var dragEl = null;
9419 var proc = {};
9421 var onStop = function(e){
9422 dragEl = null;
9423 clearProc();
9424 };
9426 var triggerRefresh = function(){
9427 if(ddm.dragCurrent){
9428 ddm.refreshCache(ddm.dragCurrent.groups);
9430 };
9432 var doScroll = function(){
9433 if(ddm.dragCurrent){
9434 var dds = Ext.dd.ScrollManager;
9435 var inc = proc.el.ddScrollConfig ?
9436 proc.el.ddScrollConfig.increment : dds.increment;
9437 if(!dds.animate){
9438 if(proc.el.scroll(proc.dir, inc)){
9439 triggerRefresh();
9441 }else{
9442 proc.el.scroll(proc.dir, inc, true, dds.animDuration, triggerRefresh);
9445 };
9447 var clearProc = function(){
9448 if(proc.id){
9449 clearInterval(proc.id);
9451 proc.id = 0;
9452 proc.el = null;
9453 proc.dir = "";
9454 };
9456 var startProc = function(el, dir){
9457 clearProc();
9458 proc.el = el;
9459 proc.dir = dir;
9460 proc.id = setInterval(doScroll, Ext.dd.ScrollManager.frequency);
9461 };
9463 var onFire = function(e, isDrop){
9464 if(isDrop || !ddm.dragCurrent){ return; }
9465 var dds = Ext.dd.ScrollManager;
9466 if(!dragEl || dragEl != ddm.dragCurrent){
9467 dragEl = ddm.dragCurrent;
9469 dds.refreshCache();
9472 var xy = Ext.lib.Event.getXY(e);
9473 var pt = new Ext.lib.Point(xy[0], xy[1]);
9474 for(var id in els){
9475 var el = els[id], r = el._region;
9476 var c = el.ddScrollConfig ? el.ddScrollConfig : dds;
9477 if(r && r.contains(pt) && el.isScrollable()){
9478 if(r.bottom - pt.y <= c.vthresh){
9479 if(proc.el != el){
9480 startProc(el, "down");
9482 return;
9483 }else if(r.right - pt.x <= c.hthresh){
9484 if(proc.el != el){
9485 startProc(el, "left");
9487 return;
9488 }else if(pt.y - r.top <= c.vthresh){
9489 if(proc.el != el){
9490 startProc(el, "up");
9492 return;
9493 }else if(pt.x - r.left <= c.hthresh){
9494 if(proc.el != el){
9495 startProc(el, "right");
9497 return;
9501 clearProc();
9502 };
9504 ddm.fireEvents = ddm.fireEvents.createSequence(onFire, ddm);
9505 ddm.stopDrag = ddm.stopDrag.createSequence(onStop, ddm);
9507 return {
9509 register : function(el){
9510 if(Ext.isArray(el)){
9511 for(var i = 0, len = el.length; i < len; i++) {
9512 this.register(el[i]);
9514 }else{
9515 el = Ext.get(el);
9516 els[el.id] = el;
9518 },
9521 unregister : function(el){
9522 if(Ext.isArray(el)){
9523 for(var i = 0, len = el.length; i < len; i++) {
9524 this.unregister(el[i]);
9526 }else{
9527 el = Ext.get(el);
9528 delete els[el.id];
9530 },
9533 vthresh : 25,
9535 hthresh : 25,
9538 increment : 100,
9541 frequency : 500,
9544 animate: true,
9547 animDuration: .4,
9550 refreshCache : function(){
9551 for(var id in els){
9552 if(typeof els[id] == 'object'){
9553 els[id]._region = els[id].getRegion();
9557 };
9558 }();
9560 Ext.dd.Registry = function(){
9561 var elements = {};
9562 var handles = {};
9563 var autoIdSeed = 0;
9565 var getId = function(el, autogen){
9566 if(typeof el == "string"){
9567 return el;
9569 var id = el.id;
9570 if(!id && autogen !== false){
9571 id = "extdd-" + (++autoIdSeed);
9572 el.id = id;
9574 return id;
9575 };
9577 return {
9579 register : function(el, data){
9580 data = data || {};
9581 if(typeof el == "string"){
9582 el = document.getElementById(el);
9584 data.ddel = el;
9585 elements[getId(el)] = data;
9586 if(data.isHandle !== false){
9587 handles[data.ddel.id] = data;
9589 if(data.handles){
9590 var hs = data.handles;
9591 for(var i = 0, len = hs.length; i < len; i++){
9592 handles[getId(hs[i])] = data;
9595 },
9598 unregister : function(el){
9599 var id = getId(el, false);
9600 var data = elements[id];
9601 if(data){
9602 delete elements[id];
9603 if(data.handles){
9604 var hs = data.handles;
9605 for(var i = 0, len = hs.length; i < len; i++){
9606 delete handles[getId(hs[i], false)];
9610 },
9613 getHandle : function(id){
9614 if(typeof id != "string"){
9615 id = id.id;
9617 return handles[id];
9618 },
9621 getHandleFromEvent : function(e){
9622 var t = Ext.lib.Event.getTarget(e);
9623 return t ? handles[t.id] : null;
9624 },
9627 getTarget : function(id){
9628 if(typeof id != "string"){
9629 id = id.id;
9631 return elements[id];
9632 },
9635 getTargetFromEvent : function(e){
9636 var t = Ext.lib.Event.getTarget(e);
9637 return t ? elements[t.id] || handles[t.id] : null;
9639 };
9640 }();
9642 Ext.dd.StatusProxy = function(config){
9643 Ext.apply(this, config);
9644 this.id = this.id || Ext.id();
9645 this.el = new Ext.Layer({
9646 dh: {
9647 id: this.id, tag: "div", cls: "x-dd-drag-proxy "+this.dropNotAllowed, children: [
9648 {tag: "div", cls: "x-dd-drop-icon"},
9649 {tag: "div", cls: "x-dd-drag-ghost"}
9651 },
9652 shadow: !config || config.shadow !== false
9653 });
9654 this.ghost = Ext.get(this.el.dom.childNodes[1]);
9655 this.dropStatus = this.dropNotAllowed;
9656 };
9658 Ext.dd.StatusProxy.prototype = {
9660 dropAllowed : "x-dd-drop-ok",
9662 dropNotAllowed : "x-dd-drop-nodrop",
9665 setStatus : function(cssClass){
9666 cssClass = cssClass || this.dropNotAllowed;
9667 if(this.dropStatus != cssClass){
9668 this.el.replaceClass(this.dropStatus, cssClass);
9669 this.dropStatus = cssClass;
9671 },
9674 reset : function(clearGhost){
9675 this.el.dom.className = "x-dd-drag-proxy " + this.dropNotAllowed;
9676 this.dropStatus = this.dropNotAllowed;
9677 if(clearGhost){
9678 this.ghost.update("");
9680 },
9683 update : function(html){
9684 if(typeof html == "string"){
9685 this.ghost.update(html);
9686 }else{
9687 this.ghost.update("");
9688 html.style.margin = "0";
9689 this.ghost.dom.appendChild(html);
9691 },
9694 getEl : function(){
9695 return this.el;
9696 },
9699 getGhost : function(){
9700 return this.ghost;
9701 },
9704 hide : function(clear){
9705 this.el.hide();
9706 if(clear){
9707 this.reset(true);
9709 },
9712 stop : function(){
9713 if(this.anim && this.anim.isAnimated && this.anim.isAnimated()){
9714 this.anim.stop();
9716 },
9719 show : function(){
9720 this.el.show();
9721 },
9724 sync : function(){
9725 this.el.sync();
9726 },
9729 repair : function(xy, callback, scope){
9730 this.callback = callback;
9731 this.scope = scope;
9732 if(xy && this.animRepair !== false){
9733 this.el.addClass("x-dd-drag-repair");
9734 this.el.hideUnders(true);
9735 this.anim = this.el.shift({
9736 duration: this.repairDuration || .5,
9737 easing: 'easeOut',
9738 xy: xy,
9739 stopFx: true,
9740 callback: this.afterRepair,
9741 scope: this
9742 });
9743 }else{
9744 this.afterRepair();
9746 },
9749 afterRepair : function(){
9750 this.hide(true);
9751 if(typeof this.callback == "function"){
9752 this.callback.call(this.scope || this);
9754 this.callback = null;
9755 this.scope = null;
9757 };
9759 Ext.dd.DragSource = function(el, config){
9760 this.el = Ext.get(el);
9761 if(!this.dragData){
9762 this.dragData = {};
9765 Ext.apply(this, config);
9767 if(!this.proxy){
9768 this.proxy = new Ext.dd.StatusProxy();
9770 Ext.dd.DragSource.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group,
9771 {dragElId : this.proxy.id, resizeFrame: false, isTarget: false, scroll: this.scroll === true});
9773 this.dragging = false;
9774 };
9776 Ext.extend(Ext.dd.DragSource, Ext.dd.DDProxy, {
9779 dropAllowed : "x-dd-drop-ok",
9781 dropNotAllowed : "x-dd-drop-nodrop",
9784 getDragData : function(e){
9785 return this.dragData;
9786 },
9789 onDragEnter : function(e, id){
9790 var target = Ext.dd.DragDropMgr.getDDById(id);
9791 this.cachedTarget = target;
9792 if(this.beforeDragEnter(target, e, id) !== false){
9793 if(target.isNotifyTarget){
9794 var status = target.notifyEnter(this, e, this.dragData);
9795 this.proxy.setStatus(status);
9796 }else{
9797 this.proxy.setStatus(this.dropAllowed);
9800 if(this.afterDragEnter){
9802 this.afterDragEnter(target, e, id);
9805 },
9808 beforeDragEnter : function(target, e, id){
9809 return true;
9810 },
9813 alignElWithMouse: function() {
9814 Ext.dd.DragSource.superclass.alignElWithMouse.apply(this, arguments);
9815 this.proxy.sync();
9816 },
9819 onDragOver : function(e, id){
9820 var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
9821 if(this.beforeDragOver(target, e, id) !== false){
9822 if(target.isNotifyTarget){
9823 var status = target.notifyOver(this, e, this.dragData);
9824 this.proxy.setStatus(status);
9827 if(this.afterDragOver){
9829 this.afterDragOver(target, e, id);
9832 },
9835 beforeDragOver : function(target, e, id){
9836 return true;
9837 },
9840 onDragOut : function(e, id){
9841 var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
9842 if(this.beforeDragOut(target, e, id) !== false){
9843 if(target.isNotifyTarget){
9844 target.notifyOut(this, e, this.dragData);
9846 this.proxy.reset();
9847 if(this.afterDragOut){
9849 this.afterDragOut(target, e, id);
9852 this.cachedTarget = null;
9853 },
9856 beforeDragOut : function(target, e, id){
9857 return true;
9858 },
9861 onDragDrop : function(e, id){
9862 var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
9863 if(this.beforeDragDrop(target, e, id) !== false){
9864 if(target.isNotifyTarget){
9865 if(target.notifyDrop(this, e, this.dragData)){
9866 this.onValidDrop(target, e, id);
9867 }else{
9868 this.onInvalidDrop(target, e, id);
9870 }else{
9871 this.onValidDrop(target, e, id);
9874 if(this.afterDragDrop){
9876 this.afterDragDrop(target, e, id);
9879 delete this.cachedTarget;
9880 },
9883 beforeDragDrop : function(target, e, id){
9884 return true;
9885 },
9888 onValidDrop : function(target, e, id){
9889 this.hideProxy();
9890 if(this.afterValidDrop){
9892 this.afterValidDrop(target, e, id);
9894 },
9897 getRepairXY : function(e, data){
9898 return this.el.getXY();
9899 },
9902 onInvalidDrop : function(target, e, id){
9903 this.beforeInvalidDrop(target, e, id);
9904 if(this.cachedTarget){
9905 if(this.cachedTarget.isNotifyTarget){
9906 this.cachedTarget.notifyOut(this, e, this.dragData);
9908 this.cacheTarget = null;
9910 this.proxy.repair(this.getRepairXY(e, this.dragData), this.afterRepair, this);
9912 if(this.afterInvalidDrop){
9914 this.afterInvalidDrop(e, id);
9916 },
9919 afterRepair : function(){
9920 if(Ext.enableFx){
9921 this.el.highlight(this.hlColor || "c3daf9");
9923 this.dragging = false;
9924 },
9927 beforeInvalidDrop : function(target, e, id){
9928 return true;
9929 },
9932 handleMouseDown : function(e){
9933 if(this.dragging) {
9934 return;
9936 var data = this.getDragData(e);
9937 if(data && this.onBeforeDrag(data, e) !== false){
9938 this.dragData = data;
9939 this.proxy.stop();
9940 Ext.dd.DragSource.superclass.handleMouseDown.apply(this, arguments);
9942 },
9945 onBeforeDrag : function(data, e){
9946 return true;
9947 },
9950 onStartDrag : Ext.emptyFn,
9953 startDrag : function(x, y){
9954 this.proxy.reset();
9955 this.dragging = true;
9956 this.proxy.update("");
9957 this.onInitDrag(x, y);
9958 this.proxy.show();
9959 },
9962 onInitDrag : function(x, y){
9963 var clone = this.el.dom.cloneNode(true);
9964 clone.id = Ext.id();
9965 this.proxy.update(clone);
9966 this.onStartDrag(x, y);
9967 return true;
9968 },
9971 getProxy : function(){
9972 return this.proxy;
9973 },
9976 hideProxy : function(){
9977 this.proxy.hide();
9978 this.proxy.reset(true);
9979 this.dragging = false;
9980 },
9983 triggerCacheRefresh : function(){
9984 Ext.dd.DDM.refreshCache(this.groups);
9985 },
9988 b4EndDrag: function(e) {
9989 },
9992 endDrag : function(e){
9993 this.onEndDrag(this.dragData, e);
9994 },
9997 onEndDrag : function(data, e){
9998 },
10001 autoOffset : function(x, y) {
10002 this.setDelta(-12, -20);
10004 });
10006 Ext.dd.DropTarget = function(el, config){
10007 this.el = Ext.get(el);
10009 Ext.apply(this, config);
10011 if(this.containerScroll){
10012 Ext.dd.ScrollManager.register(this.el);
10015 Ext.dd.DropTarget.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group,
10016 {isTarget: true});
10018 };
10020 Ext.extend(Ext.dd.DropTarget, Ext.dd.DDTarget, {
10024 dropAllowed : "x-dd-drop-ok",
10026 dropNotAllowed : "x-dd-drop-nodrop",
10029 isTarget : true,
10032 isNotifyTarget : true,
10035 notifyEnter : function(dd, e, data){
10036 if(this.overClass){
10037 this.el.addClass(this.overClass);
10039 return this.dropAllowed;
10040 },
10043 notifyOver : function(dd, e, data){
10044 return this.dropAllowed;
10045 },
10048 notifyOut : function(dd, e, data){
10049 if(this.overClass){
10050 this.el.removeClass(this.overClass);
10052 },
10055 notifyDrop : function(dd, e, data){
10056 return false;
10058 });
10060 Ext.dd.DragZone = function(el, config){
10061 Ext.dd.DragZone.superclass.constructor.call(this, el, config);
10062 if(this.containerScroll){
10063 Ext.dd.ScrollManager.register(this.el);
10065 };
10067 Ext.extend(Ext.dd.DragZone, Ext.dd.DragSource, {
10072 getDragData : function(e){
10073 return Ext.dd.Registry.getHandleFromEvent(e);
10074 },
10077 onInitDrag : function(x, y){
10078 this.proxy.update(this.dragData.ddel.cloneNode(true));
10079 this.onStartDrag(x, y);
10080 return true;
10081 },
10084 afterRepair : function(){
10085 if(Ext.enableFx){
10086 Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9");
10088 this.dragging = false;
10089 },
10092 getRepairXY : function(e){
10093 return Ext.Element.fly(this.dragData.ddel).getXY();
10095 });
10097 Ext.dd.DropZone = function(el, config){
10098 Ext.dd.DropZone.superclass.constructor.call(this, el, config);
10099 };
10101 Ext.extend(Ext.dd.DropZone, Ext.dd.DropTarget, {
10103 getTargetFromEvent : function(e){
10104 return Ext.dd.Registry.getTargetFromEvent(e);
10105 },
10108 onNodeEnter : function(n, dd, e, data){
10110 },
10113 onNodeOver : function(n, dd, e, data){
10114 return this.dropAllowed;
10115 },
10118 onNodeOut : function(n, dd, e, data){
10120 },
10123 onNodeDrop : function(n, dd, e, data){
10124 return false;
10125 },
10128 onContainerOver : function(dd, e, data){
10129 return this.dropNotAllowed;
10130 },
10133 onContainerDrop : function(dd, e, data){
10134 return false;
10135 },
10138 notifyEnter : function(dd, e, data){
10139 return this.dropNotAllowed;
10140 },
10143 notifyOver : function(dd, e, data){
10144 var n = this.getTargetFromEvent(e);
10145 if(!n){
10146 if(this.lastOverNode){
10147 this.onNodeOut(this.lastOverNode, dd, e, data);
10148 this.lastOverNode = null;
10150 return this.onContainerOver(dd, e, data);
10152 if(this.lastOverNode != n){
10153 if(this.lastOverNode){
10154 this.onNodeOut(this.lastOverNode, dd, e, data);
10156 this.onNodeEnter(n, dd, e, data);
10157 this.lastOverNode = n;
10159 return this.onNodeOver(n, dd, e, data);
10160 },
10163 notifyOut : function(dd, e, data){
10164 if(this.lastOverNode){
10165 this.onNodeOut(this.lastOverNode, dd, e, data);
10166 this.lastOverNode = null;
10168 },
10171 notifyDrop : function(dd, e, data){
10172 if(this.lastOverNode){
10173 this.onNodeOut(this.lastOverNode, dd, e, data);
10174 this.lastOverNode = null;
10176 var n = this.getTargetFromEvent(e);
10177 return n ?
10178 this.onNodeDrop(n, dd, e, data) :
10179 this.onContainerDrop(dd, e, data);
10180 },
10183 triggerCacheRefresh : function(){
10184 Ext.dd.DDM.refreshCache(this.groups);
10186 });
10189 Ext.data.SortTypes = {
10191 none : function(s){
10192 return s;
10193 },
10196 stripTagsRE : /<\/?[^>]+>/gi,
10199 asText : function(s){
10200 return String(s).replace(this.stripTagsRE, "");
10201 },
10204 asUCText : function(s){
10205 return String(s).toUpperCase().replace(this.stripTagsRE, "");
10206 },
10209 asUCString : function(s) {
10210 return String(s).toUpperCase();
10211 },
10214 asDate : function(s) {
10215 if(!s){
10216 return 0;
10218 if(Ext.isDate(s)){
10219 return s.getTime();
10221 return Date.parse(String(s));
10222 },
10225 asFloat : function(s) {
10226 var val = parseFloat(String(s).replace(/,/g, ""));
10227 if(isNaN(val)) val = 0;
10228 return val;
10229 },
10232 asInt : function(s) {
10233 var val = parseInt(String(s).replace(/,/g, ""));
10234 if(isNaN(val)) val = 0;
10235 return val;
10237 };
10239 Ext.data.Record = function(data, id){
10240 this.id = (id || id === 0) ? id : ++Ext.data.Record.AUTO_ID;
10241 this.data = data;
10242 };
10245 Ext.data.Record.create = function(o){
10246 var f = Ext.extend(Ext.data.Record, {});
10247 var p = f.prototype;
10248 p.fields = new Ext.util.MixedCollection(false, function(field){
10249 return field.name;
10250 });
10251 for(var i = 0, len = o.length; i < len; i++){
10252 p.fields.add(new Ext.data.Field(o[i]));
10254 f.getField = function(name){
10255 return p.fields.get(name);
10256 };
10257 return f;
10258 };
10260 Ext.data.Record.AUTO_ID = 1000;
10261 Ext.data.Record.EDIT = 'edit';
10262 Ext.data.Record.REJECT = 'reject';
10263 Ext.data.Record.COMMIT = 'commit';
10265 Ext.data.Record.prototype = {
10269 dirty : false,
10270 editing : false,
10271 error: null,
10273 modified: null,
10275 join : function(store){
10276 this.store = store;
10277 },
10280 set : function(name, value){
10281 if(String(this.data[name]) == String(value)){
10282 return;
10284 this.dirty = true;
10285 if(!this.modified){
10286 this.modified = {};
10288 if(typeof this.modified[name] == 'undefined'){
10289 this.modified[name] = this.data[name];
10291 this.data[name] = value;
10292 if(!this.editing && this.store){
10293 this.store.afterEdit(this);
10295 },
10298 get : function(name){
10299 return this.data[name];
10300 },
10303 beginEdit : function(){
10304 this.editing = true;
10305 this.modified = {};
10306 },
10309 cancelEdit : function(){
10310 this.editing = false;
10311 delete this.modified;
10312 },
10315 endEdit : function(){
10316 this.editing = false;
10317 if(this.dirty && this.store){
10318 this.store.afterEdit(this);
10320 },
10323 reject : function(silent){
10324 var m = this.modified;
10325 for(var n in m){
10326 if(typeof m[n] != "function"){
10327 this.data[n] = m[n];
10330 this.dirty = false;
10331 delete this.modified;
10332 this.editing = false;
10333 if(this.store && silent !== true){
10334 this.store.afterReject(this);
10336 },
10339 commit : function(silent){
10340 this.dirty = false;
10341 delete this.modified;
10342 this.editing = false;
10343 if(this.store && silent !== true){
10344 this.store.afterCommit(this);
10346 },
10349 getChanges : function(){
10350 var m = this.modified, cs = {};
10351 for(var n in m){
10352 if(m.hasOwnProperty(n)){
10353 cs[n] = this.data[n];
10356 return cs;
10357 },
10359 hasError : function(){
10360 return this.error != null;
10361 },
10363 clearError : function(){
10364 this.error = null;
10365 },
10368 copy : function(newId) {
10369 return new this.constructor(Ext.apply({}, this.data), newId || this.id);
10370 },
10373 isModified : function(fieldName){
10374 return this.modified && this.modified.hasOwnProperty(fieldName);
10376 };
10378 Ext.StoreMgr = Ext.apply(new Ext.util.MixedCollection(), {
10382 register : function(){
10383 for(var i = 0, s; s = arguments[i]; i++){
10384 this.add(s);
10386 },
10389 unregister : function(){
10390 for(var i = 0, s; s = arguments[i]; i++){
10391 this.remove(this.lookup(s));
10393 },
10396 lookup : function(id){
10397 return typeof id == "object" ? id : this.get(id);
10398 },
10400 getKey : function(o){
10401 return o.storeId || o.id;
10403 });
10405 Ext.data.Store = function(config){
10406 this.data = new Ext.util.MixedCollection(false);
10407 this.data.getKey = function(o){
10408 return o.id;
10409 };
10411 this.baseParams = {};
10412 this.paramNames = {
10413 "start" : "start",
10414 "limit" : "limit",
10415 "sort" : "sort",
10416 "dir" : "dir"
10417 };
10419 if(config && config.data){
10420 this.inlineData = config.data;
10421 delete config.data;
10424 Ext.apply(this, config);
10426 if(this.url && !this.proxy){
10427 this.proxy = new Ext.data.HttpProxy({url: this.url});
10430 if(this.reader){ if(!this.recordType){
10431 this.recordType = this.reader.recordType;
10433 if(this.reader.onMetaChange){
10434 this.reader.onMetaChange = this.onMetaChange.createDelegate(this);
10438 if(this.recordType){
10439 this.fields = this.recordType.prototype.fields;
10441 this.modified = [];
10443 this.addEvents(
10445 'datachanged',
10447 'metachange',
10449 'add',
10451 'remove',
10453 'update',
10455 'clear',
10457 'beforeload',
10459 'load',
10461 'loadexception'
10462 );
10464 if(this.proxy){
10465 this.relayEvents(this.proxy, ["loadexception"]);
10468 this.sortToggle = {};
10469 if(this.sortInfo){
10470 this.setDefaultSort(this.sortInfo.field, this.sortInfo.direction);
10473 Ext.data.Store.superclass.constructor.call(this);
10475 if(this.storeId || this.id){
10476 Ext.StoreMgr.register(this);
10478 if(this.inlineData){
10479 this.loadData(this.inlineData);
10480 delete this.inlineData;
10481 }else if(this.autoLoad){
10482 this.load.defer(10, this, [
10483 typeof this.autoLoad == 'object' ?
10484 this.autoLoad : undefined]);
10486 };
10487 Ext.extend(Ext.data.Store, Ext.util.Observable, {
10497 remoteSort : false,
10500 pruneModifiedRecords : false,
10503 lastOptions : null,
10505 destroy : function(){
10506 if(this.id){
10507 Ext.StoreMgr.unregister(this);
10509 this.data = null;
10510 this.purgeListeners();
10511 },
10514 add : function(records){
10515 records = [].concat(records);
10516 if(records.length < 1){
10517 return;
10519 for(var i = 0, len = records.length; i < len; i++){
10520 records[i].join(this);
10522 var index = this.data.length;
10523 this.data.addAll(records);
10524 if(this.snapshot){
10525 this.snapshot.addAll(records);
10527 this.fireEvent("add", this, records, index);
10528 },
10531 addSorted : function(record){
10532 var index = this.findInsertIndex(record);
10533 this.insert(index, record);
10534 },
10537 remove : function(record){
10538 var index = this.data.indexOf(record);
10539 this.data.removeAt(index);
10540 if(this.pruneModifiedRecords){
10541 this.modified.remove(record);
10543 if(this.snapshot){
10544 this.snapshot.remove(record);
10546 this.fireEvent("remove", this, record, index);
10547 },
10550 removeAll : function(){
10551 this.data.clear();
10552 if(this.snapshot){
10553 this.snapshot.clear();
10555 if(this.pruneModifiedRecords){
10556 this.modified = [];
10558 this.fireEvent("clear", this);
10559 },
10562 insert : function(index, records){
10563 records = [].concat(records);
10564 for(var i = 0, len = records.length; i < len; i++){
10565 this.data.insert(index, records[i]);
10566 records[i].join(this);
10568 this.fireEvent("add", this, records, index);
10569 },
10572 indexOf : function(record){
10573 return this.data.indexOf(record);
10574 },
10577 indexOfId : function(id){
10578 return this.data.indexOfKey(id);
10579 },
10582 getById : function(id){
10583 return this.data.key(id);
10584 },
10587 getAt : function(index){
10588 return this.data.itemAt(index);
10589 },
10592 getRange : function(start, end){
10593 return this.data.getRange(start, end);
10594 },
10596 storeOptions : function(o){
10597 o = Ext.apply({}, o);
10598 delete o.callback;
10599 delete o.scope;
10600 this.lastOptions = o;
10601 },
10604 load : function(options){
10605 options = options || {};
10606 if(this.fireEvent("beforeload", this, options) !== false){
10607 this.storeOptions(options);
10608 var p = Ext.apply(options.params || {}, this.baseParams);
10609 if(this.sortInfo && this.remoteSort){
10610 var pn = this.paramNames;
10611 p[pn["sort"]] = this.sortInfo.field;
10612 p[pn["dir"]] = this.sortInfo.direction;
10614 this.proxy.load(p, this.reader, this.loadRecords, this, options);
10615 return true;
10616 } else {
10617 return false;
10619 },
10622 reload : function(options){
10623 this.load(Ext.applyIf(options||{}, this.lastOptions));
10624 },
10626 loadRecords : function(o, options, success){
10627 if(!o || success === false){
10628 if(success !== false){
10629 this.fireEvent("load", this, [], options);
10631 if(options.callback){
10632 options.callback.call(options.scope || this, [], options, false);
10634 return;
10636 var r = o.records, t = o.totalRecords || r.length;
10637 if(!options || options.add !== true){
10638 if(this.pruneModifiedRecords){
10639 this.modified = [];
10641 for(var i = 0, len = r.length; i < len; i++){
10642 r[i].join(this);
10644 if(this.snapshot){
10645 this.data = this.snapshot;
10646 delete this.snapshot;
10648 this.data.clear();
10649 this.data.addAll(r);
10650 this.totalLength = t;
10651 this.applySort();
10652 this.fireEvent("datachanged", this);
10653 }else{
10654 this.totalLength = Math.max(t, this.data.length+r.length);
10655 this.add(r);
10657 this.fireEvent("load", this, r, options);
10658 if(options.callback){
10659 options.callback.call(options.scope || this, r, options, true);
10661 },
10664 loadData : function(o, append){
10665 var r = this.reader.readRecords(o);
10666 this.loadRecords(r, {add: append}, true);
10667 },
10670 getCount : function(){
10671 return this.data.length || 0;
10672 },
10675 getTotalCount : function(){
10676 return this.totalLength || 0;
10677 },
10680 getSortState : function(){
10681 return this.sortInfo;
10682 },
10684 applySort : function(){
10685 if(this.sortInfo && !this.remoteSort){
10686 var s = this.sortInfo, f = s.field;
10687 this.sortData(f, s.direction);
10689 },
10691 sortData : function(f, direction){
10692 direction = direction || 'ASC';
10693 var st = this.fields.get(f).sortType;
10694 var fn = function(r1, r2){
10695 var v1 = st(r1.data[f]), v2 = st(r2.data[f]);
10696 return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
10697 };
10698 this.data.sort(direction, fn);
10699 if(this.snapshot && this.snapshot != this.data){
10700 this.snapshot.sort(direction, fn);
10702 },
10705 setDefaultSort : function(field, dir){
10706 dir = dir ? dir.toUpperCase() : "ASC";
10707 this.sortInfo = {field: field, direction: dir};
10708 this.sortToggle[field] = dir;
10709 },
10712 sort : function(fieldName, dir){
10713 var f = this.fields.get(fieldName);
10714 if(!f){
10715 return false;
10717 if(!dir){
10718 if(this.sortInfo && this.sortInfo.field == f.name){ dir = (this.sortToggle[f.name] || "ASC").toggle("ASC", "DESC");
10719 }else{
10720 dir = f.sortDir;
10723 var st = (this.sortToggle) ? this.sortToggle[f.name] : null;
10724 var si = (this.sortInfo) ? this.sortInfo : null;
10726 this.sortToggle[f.name] = dir;
10727 this.sortInfo = {field: f.name, direction: dir};
10728 if(!this.remoteSort){
10729 this.applySort();
10730 this.fireEvent("datachanged", this);
10731 }else{
10732 if (!this.load(this.lastOptions)) {
10733 if (st) {
10734 this.sortToggle[f.name] = st;
10736 if (si) {
10737 this.sortInfo = si;
10741 },
10744 each : function(fn, scope){
10745 this.data.each(fn, scope);
10746 },
10749 getModifiedRecords : function(){
10750 return this.modified;
10751 },
10753 createFilterFn : function(property, value, anyMatch, caseSensitive){
10754 if(Ext.isEmpty(value, false)){
10755 return false;
10757 value = this.data.createValueMatcher(value, anyMatch, caseSensitive);
10758 return function(r){
10759 return value.test(r.data[property]);
10760 };
10761 },
10764 sum : function(property, start, end){
10765 var rs = this.data.items, v = 0;
10766 start = start || 0;
10767 end = (end || end === 0) ? end : rs.length-1;
10769 for(var i = start; i <= end; i++){
10770 v += (rs[i].data[property] || 0);
10772 return v;
10773 },
10776 filter : function(property, value, anyMatch, caseSensitive){
10777 var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
10778 return fn ? this.filterBy(fn) : this.clearFilter();
10779 },
10782 filterBy : function(fn, scope){
10783 this.snapshot = this.snapshot || this.data;
10784 this.data = this.queryBy(fn, scope||this);
10785 this.fireEvent("datachanged", this);
10786 },
10789 query : function(property, value, anyMatch, caseSensitive){
10790 var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
10791 return fn ? this.queryBy(fn) : this.data.clone();
10792 },
10795 queryBy : function(fn, scope){
10796 var data = this.snapshot || this.data;
10797 return data.filterBy(fn, scope||this);
10798 },
10801 find : function(property, value, start, anyMatch, caseSensitive){
10802 var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
10803 return fn ? this.data.findIndexBy(fn, null, start) : -1;
10804 },
10807 findBy : function(fn, scope, start){
10808 return this.data.findIndexBy(fn, scope, start);
10809 },
10812 collect : function(dataIndex, allowNull, bypassFilter){
10813 var d = (bypassFilter === true && this.snapshot) ?
10814 this.snapshot.items : this.data.items;
10815 var v, sv, r = [], l = {};
10816 for(var i = 0, len = d.length; i < len; i++){
10817 v = d[i].data[dataIndex];
10818 sv = String(v);
10819 if((allowNull || !Ext.isEmpty(v)) && !l[sv]){
10820 l[sv] = true;
10821 r[r.length] = v;
10824 return r;
10825 },
10828 clearFilter : function(suppressEvent){
10829 if(this.isFiltered()){
10830 this.data = this.snapshot;
10831 delete this.snapshot;
10832 if(suppressEvent !== true){
10833 this.fireEvent("datachanged", this);
10836 },
10839 isFiltered : function(){
10840 return this.snapshot && this.snapshot != this.data;
10841 },
10843 afterEdit : function(record){
10844 if(this.modified.indexOf(record) == -1){
10845 this.modified.push(record);
10847 this.fireEvent("update", this, record, Ext.data.Record.EDIT);
10848 },
10850 afterReject : function(record){
10851 this.modified.remove(record);
10852 this.fireEvent("update", this, record, Ext.data.Record.REJECT);
10853 },
10855 afterCommit : function(record){
10856 this.modified.remove(record);
10857 this.fireEvent("update", this, record, Ext.data.Record.COMMIT);
10858 },
10861 commitChanges : function(){
10862 var m = this.modified.slice(0);
10863 this.modified = [];
10864 for(var i = 0, len = m.length; i < len; i++){
10865 m[i].commit();
10867 },
10870 rejectChanges : function(){
10871 var m = this.modified.slice(0);
10872 this.modified = [];
10873 for(var i = 0, len = m.length; i < len; i++){
10874 m[i].reject();
10876 },
10878 onMetaChange : function(meta, rtype, o){
10879 this.recordType = rtype;
10880 this.fields = rtype.prototype.fields;
10881 delete this.snapshot;
10882 this.sortInfo = meta.sortInfo;
10883 this.modified = [];
10884 this.fireEvent('metachange', this, this.reader.meta);
10885 },
10887 findInsertIndex : function(record){
10888 this.suspendEvents();
10889 var data = this.data.clone();
10890 this.data.add(record);
10891 this.applySort();
10892 var index = this.data.indexOf(record);
10893 this.data = data;
10894 this.resumeEvents();
10895 return index;
10897 });
10899 Ext.data.SimpleStore = function(config){
10900 Ext.data.SimpleStore.superclass.constructor.call(this, Ext.apply(config, {
10901 reader: new Ext.data.ArrayReader({
10902 id: config.id
10903 },
10904 Ext.data.Record.create(config.fields)
10906 }));
10907 };
10908 Ext.extend(Ext.data.SimpleStore, Ext.data.Store, {
10909 loadData : function(data, append){
10910 if(this.expandData === true){
10911 var r = [];
10912 for(var i = 0, len = data.length; i < len; i++){
10913 r[r.length] = [data[i]];
10915 data = r;
10917 Ext.data.SimpleStore.superclass.loadData.call(this, data, append);
10919 });
10921 Ext.data.JsonStore = function(c){
10922 Ext.data.JsonStore.superclass.constructor.call(this, Ext.apply(c, {
10923 proxy: !c.data ? new Ext.data.HttpProxy({url: c.url}) : undefined,
10924 reader: new Ext.data.JsonReader(c, c.fields)
10925 }));
10926 };
10927 Ext.extend(Ext.data.JsonStore, Ext.data.Store);
10931 Ext.data.Field = function(config){
10932 if(typeof config == "string"){
10933 config = {name: config};
10935 Ext.apply(this, config);
10937 if(!this.type){
10938 this.type = "auto";
10941 var st = Ext.data.SortTypes;
10943 if(typeof this.sortType == "string"){
10944 this.sortType = st[this.sortType];
10948 if(!this.sortType){
10949 switch(this.type){
10950 case "string":
10951 this.sortType = st.asUCString;
10952 break;
10953 case "date":
10954 this.sortType = st.asDate;
10955 break;
10956 default:
10957 this.sortType = st.none;
10962 var stripRe = /[\$,%]/g;
10966 if(!this.convert){
10967 var cv, dateFormat = this.dateFormat;
10968 switch(this.type){
10969 case "":
10970 case "auto":
10971 case undefined:
10972 cv = function(v){ return v; };
10973 break;
10974 case "string":
10975 cv = function(v){ return (v === undefined || v === null) ? '' : String(v); };
10976 break;
10977 case "int":
10978 cv = function(v){
10979 return v !== undefined && v !== null && v !== '' ?
10980 parseInt(String(v).replace(stripRe, ""), 10) : '';
10981 };
10982 break;
10983 case "float":
10984 cv = function(v){
10985 return v !== undefined && v !== null && v !== '' ?
10986 parseFloat(String(v).replace(stripRe, ""), 10) : '';
10987 };
10988 break;
10989 case "bool":
10990 case "boolean":
10991 cv = function(v){ return v === true || v === "true" || v == 1; };
10992 break;
10993 case "date":
10994 cv = function(v){
10995 if(!v){
10996 return '';
10998 if(Ext.isDate(v)){
10999 return v;
11001 if(dateFormat){
11002 if(dateFormat == "timestamp"){
11003 return new Date(v*1000);
11005 if(dateFormat == "time"){
11006 return new Date(parseInt(v, 10));
11008 return Date.parseDate(v, dateFormat);
11010 var parsed = Date.parse(v);
11011 return parsed ? new Date(parsed) : null;
11012 };
11013 break;
11016 this.convert = cv;
11018 };
11020 Ext.data.Field.prototype = {
11021 dateFormat: null,
11022 defaultValue: "",
11023 mapping: null,
11024 sortType : null,
11025 sortDir : "ASC"
11026 };
11028 Ext.data.DataReader = function(meta, recordType){
11030 this.meta = meta;
11031 this.recordType = Ext.isArray(recordType) ?
11032 Ext.data.Record.create(recordType) : recordType;
11033 };
11035 Ext.data.DataReader.prototype = {
11037 };
11039 Ext.data.DataProxy = function(){
11040 this.addEvents(
11042 'beforeload',
11044 'load'
11045 );
11046 Ext.data.DataProxy.superclass.constructor.call(this);
11047 };
11049 Ext.extend(Ext.data.DataProxy, Ext.util.Observable);
11051 Ext.data.MemoryProxy = function(data){
11052 Ext.data.MemoryProxy.superclass.constructor.call(this);
11053 this.data = data;
11054 };
11056 Ext.extend(Ext.data.MemoryProxy, Ext.data.DataProxy, {
11060 load : function(params, reader, callback, scope, arg){
11061 params = params || {};
11062 var result;
11063 try {
11064 result = reader.readRecords(this.data);
11065 }catch(e){
11066 this.fireEvent("loadexception", this, arg, null, e);
11067 callback.call(scope, null, arg, false);
11068 return;
11070 callback.call(scope, result, arg, true);
11071 },
11074 update : function(params, records){
11077 });
11079 Ext.data.HttpProxy = function(conn){
11080 Ext.data.HttpProxy.superclass.constructor.call(this);
11082 this.conn = conn;
11083 this.useAjax = !conn || !conn.events;
11086 };
11088 Ext.extend(Ext.data.HttpProxy, Ext.data.DataProxy, {
11090 getConnection : function(){
11091 return this.useAjax ? Ext.Ajax : this.conn;
11092 },
11095 load : function(params, reader, callback, scope, arg){
11096 if(this.fireEvent("beforeload", this, params) !== false){
11097 var o = {
11098 params : params || {},
11099 request: {
11100 callback : callback,
11101 scope : scope,
11102 arg : arg
11103 },
11104 reader: reader,
11105 callback : this.loadResponse,
11106 scope: this
11107 };
11108 if(this.useAjax){
11109 Ext.applyIf(o, this.conn);
11110 if(this.activeRequest){
11111 Ext.Ajax.abort(this.activeRequest);
11113 this.activeRequest = Ext.Ajax.request(o);
11114 }else{
11115 this.conn.request(o);
11117 }else{
11118 callback.call(scope||this, null, arg, false);
11120 },
11123 loadResponse : function(o, success, response){
11124 delete this.activeRequest;
11125 if(!success){
11126 this.fireEvent("loadexception", this, o, response);
11127 o.request.callback.call(o.request.scope, null, o.request.arg, false);
11128 return;
11130 var result;
11131 try {
11132 result = o.reader.read(response);
11133 }catch(e){
11134 this.fireEvent("loadexception", this, o, response, e);
11135 o.request.callback.call(o.request.scope, null, o.request.arg, false);
11136 return;
11138 this.fireEvent("load", this, o, o.request.arg);
11139 o.request.callback.call(o.request.scope, result, o.request.arg, true);
11140 },
11143 update : function(dataSet){
11145 },
11148 updateResponse : function(dataSet){
11151 });
11153 Ext.data.ScriptTagProxy = function(config){
11154 Ext.data.ScriptTagProxy.superclass.constructor.call(this);
11155 Ext.apply(this, config);
11156 this.head = document.getElementsByTagName("head")[0];
11159 };
11161 Ext.data.ScriptTagProxy.TRANS_ID = 1000;
11163 Ext.extend(Ext.data.ScriptTagProxy, Ext.data.DataProxy, {
11166 timeout : 30000,
11168 callbackParam : "callback",
11170 nocache : true,
11173 load : function(params, reader, callback, scope, arg){
11174 if(this.fireEvent("beforeload", this, params) !== false){
11176 var p = Ext.urlEncode(Ext.apply(params, this.extraParams));
11178 var url = this.url;
11179 url += (url.indexOf("?") != -1 ? "&" : "?") + p;
11180 if(this.nocache){
11181 url += "&_dc=" + (new Date().getTime());
11183 var transId = ++Ext.data.ScriptTagProxy.TRANS_ID;
11184 var trans = {
11185 id : transId,
11186 cb : "stcCallback"+transId,
11187 scriptId : "stcScript"+transId,
11188 params : params,
11189 arg : arg,
11190 url : url,
11191 callback : callback,
11192 scope : scope,
11193 reader : reader
11194 };
11195 var conn = this;
11197 window[trans.cb] = function(o){
11198 conn.handleResponse(o, trans);
11199 };
11201 url += String.format("&{0}={1}", this.callbackParam, trans.cb);
11203 if(this.autoAbort !== false){
11204 this.abort();
11207 trans.timeoutId = this.handleFailure.defer(this.timeout, this, [trans]);
11209 var script = document.createElement("script");
11210 script.setAttribute("src", url);
11211 script.setAttribute("type", "text/javascript");
11212 script.setAttribute("id", trans.scriptId);
11213 this.head.appendChild(script);
11215 this.trans = trans;
11216 }else{
11217 callback.call(scope||this, null, arg, false);
11219 },
11222 isLoading : function(){
11223 return this.trans ? true : false;
11224 },
11227 abort : function(){
11228 if(this.isLoading()){
11229 this.destroyTrans(this.trans);
11231 },
11234 destroyTrans : function(trans, isLoaded){
11235 this.head.removeChild(document.getElementById(trans.scriptId));
11236 clearTimeout(trans.timeoutId);
11237 if(isLoaded){
11238 window[trans.cb] = undefined;
11239 try{
11240 delete window[trans.cb];
11241 }catch(e){}
11242 }else{
11244 window[trans.cb] = function(){
11245 window[trans.cb] = undefined;
11246 try{
11247 delete window[trans.cb];
11248 }catch(e){}
11249 };
11251 },
11254 handleResponse : function(o, trans){
11255 this.trans = false;
11256 this.destroyTrans(trans, true);
11257 var result;
11258 try {
11259 result = trans.reader.readRecords(o);
11260 }catch(e){
11261 this.fireEvent("loadexception", this, o, trans.arg, e);
11262 trans.callback.call(trans.scope||window, null, trans.arg, false);
11263 return;
11265 this.fireEvent("load", this, o, trans.arg);
11266 trans.callback.call(trans.scope||window, result, trans.arg, true);
11267 },
11270 handleFailure : function(trans){
11271 this.trans = false;
11272 this.destroyTrans(trans, false);
11273 this.fireEvent("loadexception", this, null, trans.arg);
11274 trans.callback.call(trans.scope||window, null, trans.arg, false);
11276 });
11278 Ext.data.JsonReader = function(meta, recordType){
11279 meta = meta || {};
11280 Ext.data.JsonReader.superclass.constructor.call(this, meta, recordType || meta.fields);
11281 };
11282 Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
11285 read : function(response){
11286 var json = response.responseText;
11287 var o = eval("("+json+")");
11288 if(!o) {
11289 throw {message: "JsonReader.read: Json object not found"};
11291 return this.readRecords(o);
11292 },
11294 onMetaChange : function(meta, recordType, o){
11296 },
11299 simpleAccess: function(obj, subsc) {
11300 return obj[subsc];
11301 },
11304 getJsonAccessor: function(){
11305 var re = /[\[\.]/;
11306 return function(expr) {
11307 try {
11308 return(re.test(expr))
11309 ? new Function("obj", "return obj." + expr)
11310 : function(obj){
11311 return obj[expr];
11312 };
11313 } catch(e){}
11314 return Ext.emptyFn;
11315 };
11316 }(),
11319 readRecords : function(o){
11321 this.jsonData = o;
11322 if(o.metaData){
11323 delete this.ef;
11324 this.meta = o.metaData;
11325 this.recordType = Ext.data.Record.create(o.metaData.fields);
11326 this.onMetaChange(this.meta, this.recordType, o);
11328 var s = this.meta, Record = this.recordType,
11329 f = Record.prototype.fields, fi = f.items, fl = f.length;
11331 if (!this.ef) {
11332 if(s.totalProperty) {
11333 this.getTotal = this.getJsonAccessor(s.totalProperty);
11335 if(s.successProperty) {
11336 this.getSuccess = this.getJsonAccessor(s.successProperty);
11338 this.getRoot = s.root ? this.getJsonAccessor(s.root) : function(p){return p;};
11339 if (s.id) {
11340 var g = this.getJsonAccessor(s.id);
11341 this.getId = function(rec) {
11342 var r = g(rec);
11343 return (r === undefined || r === "") ? null : r;
11344 };
11345 } else {
11346 this.getId = function(){return null;};
11348 this.ef = [];
11349 for(var i = 0; i < fl; i++){
11350 f = fi[i];
11351 var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
11352 this.ef[i] = this.getJsonAccessor(map);
11356 var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;
11357 if(s.totalProperty){
11358 var v = parseInt(this.getTotal(o), 10);
11359 if(!isNaN(v)){
11360 totalRecords = v;
11363 if(s.successProperty){
11364 var v = this.getSuccess(o);
11365 if(v === false || v === 'false'){
11366 success = false;
11369 var records = [];
11370 for(var i = 0; i < c; i++){
11371 var n = root[i];
11372 var values = {};
11373 var id = this.getId(n);
11374 for(var j = 0; j < fl; j++){
11375 f = fi[j];
11376 var v = this.ef[j](n);
11377 values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, n);
11379 var record = new Record(values, id);
11380 record.json = n;
11381 records[i] = record;
11383 return {
11384 success : success,
11385 records : records,
11386 totalRecords : totalRecords
11387 };
11389 });
11391 Ext.data.XmlReader = function(meta, recordType){
11392 meta = meta || {};
11393 Ext.data.XmlReader.superclass.constructor.call(this, meta, recordType || meta.fields);
11394 };
11395 Ext.extend(Ext.data.XmlReader, Ext.data.DataReader, {
11397 read : function(response){
11398 var doc = response.responseXML;
11399 if(!doc) {
11400 throw {message: "XmlReader.read: XML Document not available"};
11402 return this.readRecords(doc);
11403 },
11406 readRecords : function(doc){
11408 this.xmlData = doc;
11409 var root = doc.documentElement || doc;
11410 var q = Ext.DomQuery;
11411 var recordType = this.recordType, fields = recordType.prototype.fields;
11412 var sid = this.meta.id;
11413 var totalRecords = 0, success = true;
11414 if(this.meta.totalRecords){
11415 totalRecords = q.selectNumber(this.meta.totalRecords, root, 0);
11418 if(this.meta.success){
11419 var sv = q.selectValue(this.meta.success, root, true);
11420 success = sv !== false && sv !== 'false';
11422 var records = [];
11423 var ns = q.select(this.meta.record, root);
11424 for(var i = 0, len = ns.length; i < len; i++) {
11425 var n = ns[i];
11426 var values = {};
11427 var id = sid ? q.selectValue(sid, n) : undefined;
11428 for(var j = 0, jlen = fields.length; j < jlen; j++){
11429 var f = fields.items[j];
11430 var v = q.selectValue(f.mapping || f.name, n, f.defaultValue);
11431 v = f.convert(v, n);
11432 values[f.name] = v;
11434 var record = new recordType(values, id);
11435 record.node = n;
11436 records[records.length] = record;
11439 return {
11440 success : success,
11441 records : records,
11442 totalRecords : totalRecords || records.length
11443 };
11445 });
11447 Ext.data.ArrayReader = Ext.extend(Ext.data.JsonReader, {
11449 readRecords : function(o){
11450 var sid = this.meta ? this.meta.id : null;
11451 var recordType = this.recordType, fields = recordType.prototype.fields;
11452 var records = [];
11453 var root = o;
11454 for(var i = 0; i < root.length; i++){
11455 var n = root[i];
11456 var values = {};
11457 var id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);
11458 for(var j = 0, jlen = fields.length; j < jlen; j++){
11459 var f = fields.items[j];
11460 var k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;
11461 var v = n[k] !== undefined ? n[k] : f.defaultValue;
11462 v = f.convert(v, n);
11463 values[f.name] = v;
11465 var record = new recordType(values, id);
11466 record.json = n;
11467 records[records.length] = record;
11469 return {
11470 records : records,
11471 totalRecords : records.length
11472 };
11474 });
11476 Ext.data.Tree = function(root){
11477 this.nodeHash = {};
11479 this.root = null;
11480 if(root){
11481 this.setRootNode(root);
11483 this.addEvents(
11485 "append",
11487 "remove",
11489 "move",
11491 "insert",
11493 "beforeappend",
11495 "beforeremove",
11497 "beforemove",
11499 "beforeinsert"
11500 );
11502 Ext.data.Tree.superclass.constructor.call(this);
11503 };
11505 Ext.extend(Ext.data.Tree, Ext.util.Observable, {
11507 pathSeparator: "/",
11510 proxyNodeEvent : function(){
11511 return this.fireEvent.apply(this, arguments);
11512 },
11515 getRootNode : function(){
11516 return this.root;
11517 },
11520 setRootNode : function(node){
11521 this.root = node;
11522 node.ownerTree = this;
11523 node.isRoot = true;
11524 this.registerNode(node);
11525 return node;
11526 },
11529 getNodeById : function(id){
11530 return this.nodeHash[id];
11531 },
11534 registerNode : function(node){
11535 this.nodeHash[node.id] = node;
11536 },
11539 unregisterNode : function(node){
11540 delete this.nodeHash[node.id];
11541 },
11543 toString : function(){
11544 return "[Tree"+(this.id?" "+this.id:"")+"]";
11546 });
11549 Ext.data.Node = function(attributes){
11551 this.attributes = attributes || {};
11552 this.leaf = this.attributes.leaf;
11554 this.id = this.attributes.id;
11555 if(!this.id){
11556 this.id = Ext.id(null, "ynode-");
11557 this.attributes.id = this.id;
11560 this.childNodes = [];
11561 if(!this.childNodes.indexOf){
11562 this.childNodes.indexOf = function(o){
11563 for(var i = 0, len = this.length; i < len; i++){
11564 if(this[i] == o) return i;
11566 return -1;
11567 };
11570 this.parentNode = null;
11572 this.firstChild = null;
11574 this.lastChild = null;
11576 this.previousSibling = null;
11578 this.nextSibling = null;
11580 this.addEvents({
11582 "append" : true,
11584 "remove" : true,
11586 "move" : true,
11588 "insert" : true,
11590 "beforeappend" : true,
11592 "beforeremove" : true,
11594 "beforemove" : true,
11596 "beforeinsert" : true
11597 });
11598 this.listeners = this.attributes.listeners;
11599 Ext.data.Node.superclass.constructor.call(this);
11600 };
11602 Ext.extend(Ext.data.Node, Ext.util.Observable, {
11604 fireEvent : function(evtName){
11606 if(Ext.data.Node.superclass.fireEvent.apply(this, arguments) === false){
11607 return false;
11610 var ot = this.getOwnerTree();
11611 if(ot){
11612 if(ot.proxyNodeEvent.apply(ot, arguments) === false){
11613 return false;
11616 return true;
11617 },
11620 isLeaf : function(){
11621 return this.leaf === true;
11622 },
11625 setFirstChild : function(node){
11626 this.firstChild = node;
11627 },
11630 setLastChild : function(node){
11631 this.lastChild = node;
11632 },
11636 isLast : function(){
11637 return (!this.parentNode ? true : this.parentNode.lastChild == this);
11638 },
11641 isFirst : function(){
11642 return (!this.parentNode ? true : this.parentNode.firstChild == this);
11643 },
11645 hasChildNodes : function(){
11646 return !this.isLeaf() && this.childNodes.length > 0;
11647 },
11650 appendChild : function(node){
11651 var multi = false;
11652 if(Ext.isArray(node)){
11653 multi = node;
11654 }else if(arguments.length > 1){
11655 multi = arguments;
11658 if(multi){
11659 for(var i = 0, len = multi.length; i < len; i++) {
11660 this.appendChild(multi[i]);
11662 }else{
11663 if(this.fireEvent("beforeappend", this.ownerTree, this, node) === false){
11664 return false;
11666 var index = this.childNodes.length;
11667 var oldParent = node.parentNode;
11669 if(oldParent){
11670 if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index) === false){
11671 return false;
11673 oldParent.removeChild(node);
11675 index = this.childNodes.length;
11676 if(index == 0){
11677 this.setFirstChild(node);
11679 this.childNodes.push(node);
11680 node.parentNode = this;
11681 var ps = this.childNodes[index-1];
11682 if(ps){
11683 node.previousSibling = ps;
11684 ps.nextSibling = node;
11685 }else{
11686 node.previousSibling = null;
11688 node.nextSibling = null;
11689 this.setLastChild(node);
11690 node.setOwnerTree(this.getOwnerTree());
11691 this.fireEvent("append", this.ownerTree, this, node, index);
11692 if(oldParent){
11693 node.fireEvent("move", this.ownerTree, node, oldParent, this, index);
11695 return node;
11697 },
11700 removeChild : function(node){
11701 var index = this.childNodes.indexOf(node);
11702 if(index == -1){
11703 return false;
11705 if(this.fireEvent("beforeremove", this.ownerTree, this, node) === false){
11706 return false;
11710 this.childNodes.splice(index, 1);
11713 if(node.previousSibling){
11714 node.previousSibling.nextSibling = node.nextSibling;
11716 if(node.nextSibling){
11717 node.nextSibling.previousSibling = node.previousSibling;
11721 if(this.firstChild == node){
11722 this.setFirstChild(node.nextSibling);
11724 if(this.lastChild == node){
11725 this.setLastChild(node.previousSibling);
11728 node.setOwnerTree(null);
11730 node.parentNode = null;
11731 node.previousSibling = null;
11732 node.nextSibling = null;
11733 this.fireEvent("remove", this.ownerTree, this, node);
11734 return node;
11735 },
11738 insertBefore : function(node, refNode){
11739 if(!refNode){
11740 return this.appendChild(node);
11743 if(node == refNode){
11744 return false;
11747 if(this.fireEvent("beforeinsert", this.ownerTree, this, node, refNode) === false){
11748 return false;
11750 var index = this.childNodes.indexOf(refNode);
11751 var oldParent = node.parentNode;
11752 var refIndex = index;
11755 if(oldParent == this && this.childNodes.indexOf(node) < index){
11756 refIndex--;
11760 if(oldParent){
11761 if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index, refNode) === false){
11762 return false;
11764 oldParent.removeChild(node);
11766 if(refIndex == 0){
11767 this.setFirstChild(node);
11769 this.childNodes.splice(refIndex, 0, node);
11770 node.parentNode = this;
11771 var ps = this.childNodes[refIndex-1];
11772 if(ps){
11773 node.previousSibling = ps;
11774 ps.nextSibling = node;
11775 }else{
11776 node.previousSibling = null;
11778 node.nextSibling = refNode;
11779 refNode.previousSibling = node;
11780 node.setOwnerTree(this.getOwnerTree());
11781 this.fireEvent("insert", this.ownerTree, this, node, refNode);
11782 if(oldParent){
11783 node.fireEvent("move", this.ownerTree, node, oldParent, this, refIndex, refNode);
11785 return node;
11786 },
11789 remove : function(){
11790 this.parentNode.removeChild(this);
11791 return this;
11792 },
11795 item : function(index){
11796 return this.childNodes[index];
11797 },
11800 replaceChild : function(newChild, oldChild){
11801 this.insertBefore(newChild, oldChild);
11802 this.removeChild(oldChild);
11803 return oldChild;
11804 },
11807 indexOf : function(child){
11808 return this.childNodes.indexOf(child);
11809 },
11812 getOwnerTree : function(){
11814 if(!this.ownerTree){
11815 var p = this;
11816 while(p){
11817 if(p.ownerTree){
11818 this.ownerTree = p.ownerTree;
11819 break;
11821 p = p.parentNode;
11824 return this.ownerTree;
11825 },
11828 getDepth : function(){
11829 var depth = 0;
11830 var p = this;
11831 while(p.parentNode){
11832 ++depth;
11833 p = p.parentNode;
11835 return depth;
11836 },
11839 setOwnerTree : function(tree){
11841 if(tree != this.ownerTree){
11842 if(this.ownerTree){
11843 this.ownerTree.unregisterNode(this);
11845 this.ownerTree = tree;
11846 var cs = this.childNodes;
11847 for(var i = 0, len = cs.length; i < len; i++) {
11848 cs[i].setOwnerTree(tree);
11850 if(tree){
11851 tree.registerNode(this);
11854 },
11857 getPath : function(attr){
11858 attr = attr || "id";
11859 var p = this.parentNode;
11860 var b = [this.attributes[attr]];
11861 while(p){
11862 b.unshift(p.attributes[attr]);
11863 p = p.parentNode;
11865 var sep = this.getOwnerTree().pathSeparator;
11866 return sep + b.join(sep);
11867 },
11870 bubble : function(fn, scope, args){
11871 var p = this;
11872 while(p){
11873 if(fn.apply(scope || p, args || [p]) === false){
11874 break;
11876 p = p.parentNode;
11878 },
11881 cascade : function(fn, scope, args){
11882 if(fn.apply(scope || this, args || [this]) !== false){
11883 var cs = this.childNodes;
11884 for(var i = 0, len = cs.length; i < len; i++) {
11885 cs[i].cascade(fn, scope, args);
11888 },
11891 eachChild : function(fn, scope, args){
11892 var cs = this.childNodes;
11893 for(var i = 0, len = cs.length; i < len; i++) {
11894 if(fn.apply(scope || this, args || [cs[i]]) === false){
11895 break;
11898 },
11901 findChild : function(attribute, value){
11902 var cs = this.childNodes;
11903 for(var i = 0, len = cs.length; i < len; i++) {
11904 if(cs[i].attributes[attribute] == value){
11905 return cs[i];
11908 return null;
11909 },
11912 findChildBy : function(fn, scope){
11913 var cs = this.childNodes;
11914 for(var i = 0, len = cs.length; i < len; i++) {
11915 if(fn.call(scope||cs[i], cs[i]) === true){
11916 return cs[i];
11919 return null;
11920 },
11923 sort : function(fn, scope){
11924 var cs = this.childNodes;
11925 var len = cs.length;
11926 if(len > 0){
11927 var sortFn = scope ? function(){fn.apply(scope, arguments);} : fn;
11928 cs.sort(sortFn);
11929 for(var i = 0; i < len; i++){
11930 var n = cs[i];
11931 n.previousSibling = cs[i-1];
11932 n.nextSibling = cs[i+1];
11933 if(i == 0){
11934 this.setFirstChild(n);
11936 if(i == len-1){
11937 this.setLastChild(n);
11941 },
11944 contains : function(node){
11945 return node.isAncestor(this);
11946 },
11949 isAncestor : function(node){
11950 var p = this.parentNode;
11951 while(p){
11952 if(p == node){
11953 return true;
11955 p = p.parentNode;
11957 return false;
11958 },
11960 toString : function(){
11961 return "[Node"+(this.id?" "+this.id:"")+"]";
11963 });
11965 Ext.data.GroupingStore = Ext.extend(Ext.data.Store, {
11968 remoteGroup : false,
11970 groupOnSort:false,
11973 clearGrouping : function(){
11974 this.groupField = false;
11975 if(this.remoteGroup){
11976 if(this.baseParams){
11977 delete this.baseParams.groupBy;
11979 this.reload();
11980 }else{
11981 this.applySort();
11982 this.fireEvent('datachanged', this);
11984 },
11987 groupBy : function(field, forceRegroup){
11988 if(this.groupField == field && !forceRegroup){
11989 return;
11991 this.groupField = field;
11992 if(this.remoteGroup){
11993 if(!this.baseParams){
11994 this.baseParams = {};
11996 this.baseParams['groupBy'] = field;
11998 if(this.groupOnSort){
11999 this.sort(field);
12000 return;
12002 if(this.remoteGroup){
12003 this.reload();
12004 }else{
12005 var si = this.sortInfo || {};
12006 if(si.field != field){
12007 this.applySort();
12008 }else{
12009 this.sortData(field);
12011 this.fireEvent('datachanged', this);
12013 },
12016 applySort : function(){
12017 Ext.data.GroupingStore.superclass.applySort.call(this);
12018 if(!this.groupOnSort && !this.remoteGroup){
12019 var gs = this.getGroupState();
12020 if(gs && gs != this.sortInfo.field){
12021 this.sortData(this.groupField);
12024 },
12027 applyGrouping : function(alwaysFireChange){
12028 if(this.groupField !== false){
12029 this.groupBy(this.groupField, true);
12030 return true;
12031 }else{
12032 if(alwaysFireChange === true){
12033 this.fireEvent('datachanged', this);
12035 return false;
12037 },
12040 getGroupState : function(){
12041 return this.groupOnSort && this.groupField !== false ?
12042 (this.sortInfo ? this.sortInfo.field : undefined) : this.groupField;
12044 });
12046 Ext.ComponentMgr = function(){
12047 var all = new Ext.util.MixedCollection();
12048 var types = {};
12050 return {
12052 register : function(c){
12053 all.add(c);
12054 },
12057 unregister : function(c){
12058 all.remove(c);
12059 },
12062 get : function(id){
12063 return all.get(id);
12064 },
12067 onAvailable : function(id, fn, scope){
12068 all.on("add", function(index, o){
12069 if(o.id == id){
12070 fn.call(scope || o, o);
12071 all.un("add", fn, scope);
12073 });
12074 },
12077 all : all,
12080 registerType : function(xtype, cls){
12081 types[xtype] = cls;
12082 cls.xtype = xtype;
12083 },
12085 create : function(config, defaultType){
12086 return new types[config.xtype || defaultType](config);
12088 };
12089 }();
12092 Ext.reg = Ext.ComponentMgr.registerType; // this will be called a lot internally, shorthand to keep the bytes down
12094 Ext.Component = function(config){
12095 config = config || {};
12096 if(config.initialConfig){
12097 if(config.isAction){ this.baseAction = config;
12099 config = config.initialConfig; }else if(config.tagName || config.dom || typeof config == "string"){ config = {applyTo: config, id: config.id || config};
12103 this.initialConfig = config;
12105 Ext.apply(this, config);
12106 this.addEvents(
12108 'disable',
12110 'enable',
12112 'beforeshow',
12114 'show',
12116 'beforehide',
12118 'hide',
12120 'beforerender',
12122 'render',
12124 'beforedestroy',
12126 'destroy',
12128 'beforestaterestore',
12130 'staterestore',
12132 'beforestatesave',
12134 'statesave'
12135 );
12136 this.getId();
12137 Ext.ComponentMgr.register(this);
12138 Ext.Component.superclass.constructor.call(this);
12140 if(this.baseAction){
12141 this.baseAction.addComponent(this);
12144 this.initComponent();
12146 if(this.plugins){
12147 if(Ext.isArray(this.plugins)){
12148 for(var i = 0, len = this.plugins.length; i < len; i++){
12149 this.plugins[i].init(this);
12151 }else{
12152 this.plugins.init(this);
12156 if(this.stateful !== false){
12157 this.initState(config);
12160 if(this.applyTo){
12161 this.applyToMarkup(this.applyTo);
12162 delete this.applyTo;
12163 }else if(this.renderTo){
12164 this.render(this.renderTo);
12165 delete this.renderTo;
12167 };
12169 Ext.Component.AUTO_ID = 1000;
12171 Ext.extend(Ext.Component, Ext.util.Observable, {
12188 disabledClass : "x-item-disabled",
12190 allowDomMove : true,
12192 autoShow : false,
12194 hideMode: 'display',
12196 hideParent: false,
12200 hidden : false,
12202 disabled : false,
12204 rendered : false,
12206 ctype : "Ext.Component",
12208 actionMode : "el",
12210 getActionEl : function(){
12211 return this[this.actionMode];
12212 },
12215 initComponent : Ext.emptyFn,
12218 render : function(container, position){
12219 if(!this.rendered && this.fireEvent("beforerender", this) !== false){
12220 if(!container && this.el){
12221 this.el = Ext.get(this.el);
12222 container = this.el.dom.parentNode;
12223 this.allowDomMove = false;
12225 this.container = Ext.get(container);
12226 if(this.ctCls){
12227 this.container.addClass(this.ctCls);
12229 this.rendered = true;
12230 if(position !== undefined){
12231 if(typeof position == 'number'){
12232 position = this.container.dom.childNodes[position];
12233 }else{
12234 position = Ext.getDom(position);
12237 this.onRender(this.container, position || null);
12238 if(this.autoShow){
12239 this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]);
12241 if(this.cls){
12242 this.el.addClass(this.cls);
12243 delete this.cls;
12245 if(this.style){
12246 this.el.applyStyles(this.style);
12247 delete this.style;
12249 this.fireEvent("render", this);
12250 this.afterRender(this.container);
12251 if(this.hidden){
12252 this.hide();
12254 if(this.disabled){
12255 this.disable();
12258 this.initStateEvents();
12260 return this;
12261 },
12263 initState : function(config){
12264 if(Ext.state.Manager){
12265 var state = Ext.state.Manager.get(this.stateId || this.id);
12266 if(state){
12267 if(this.fireEvent('beforestaterestore', this, state) !== false){
12268 this.applyState(state);
12269 this.fireEvent('staterestore', this, state);
12273 },
12275 initStateEvents : function(){
12276 if(this.stateEvents){
12277 for(var i = 0, e; e = this.stateEvents[i]; i++){
12278 this.on(e, this.saveState, this, {delay:100});
12281 },
12283 applyState : function(state, config){
12284 if(state){
12285 Ext.apply(this, state);
12287 },
12289 getState : function(){
12290 return null;
12291 },
12293 saveState : function(){
12294 if(Ext.state.Manager){
12295 var state = this.getState();
12296 if(this.fireEvent('beforestatesave', this, state) !== false){
12297 Ext.state.Manager.set(this.stateId || this.id, state);
12298 this.fireEvent('statesave', this, state);
12301 },
12304 applyToMarkup : function(el){
12305 this.allowDomMove = false;
12306 this.el = Ext.get(el);
12307 this.render(this.el.dom.parentNode);
12308 },
12311 addClass : function(cls){
12312 if(this.el){
12313 this.el.addClass(cls);
12314 }else{
12315 this.cls = this.cls ? this.cls + ' ' + cls : cls;
12317 },
12320 removeClass : function(cls){
12321 if(this.el){
12322 this.el.removeClass(cls);
12323 }else if(this.cls){
12324 this.cls = this.cls.split(' ').remove(cls).join(' ');
12326 },
12328 onRender : function(ct, position){
12329 if(this.autoEl){
12330 if(typeof this.autoEl == 'string'){
12331 this.el = document.createElement(this.autoEl);
12332 }else{
12333 var div = document.createElement('div');
12334 Ext.DomHelper.overwrite(div, this.autoEl);
12335 this.el = div.firstChild;
12337 if (!this.el.id) {
12338 this.el.id = this.getId();
12341 if(this.el){
12342 this.el = Ext.get(this.el);
12343 if(this.allowDomMove !== false){
12344 ct.dom.insertBefore(this.el.dom, position);
12346 if(this.overCls) {
12347 this.el.addClassOnOver(this.overCls);
12350 },
12352 getAutoCreate : function(){
12353 var cfg = typeof this.autoCreate == "object" ?
12354 this.autoCreate : Ext.apply({}, this.defaultAutoCreate);
12355 if(this.id && !cfg.id){
12356 cfg.id = this.id;
12358 return cfg;
12359 },
12361 afterRender : Ext.emptyFn,
12364 destroy : function(){
12365 if(this.fireEvent("beforedestroy", this) !== false){
12366 this.beforeDestroy();
12367 if(this.rendered){
12368 this.el.removeAllListeners();
12369 this.el.remove();
12370 if(this.actionMode == "container"){
12371 this.container.remove();
12374 this.onDestroy();
12375 Ext.ComponentMgr.unregister(this);
12376 this.fireEvent("destroy", this);
12377 this.purgeListeners();
12379 },
12381 beforeDestroy : Ext.emptyFn,
12383 onDestroy : Ext.emptyFn,
12386 getEl : function(){
12387 return this.el;
12388 },
12391 getId : function(){
12392 return this.id || (this.id = "ext-comp-" + (++Ext.Component.AUTO_ID));
12393 },
12396 getItemId : function(){
12397 return this.itemId || this.getId();
12398 },
12401 focus : function(selectText, delay){
12402 if(delay){
12403 this.focus.defer(typeof delay == 'number' ? delay : 10, this, [selectText, false]);
12404 return;
12406 if(this.rendered){
12407 this.el.focus();
12408 if(selectText === true){
12409 this.el.dom.select();
12412 return this;
12413 },
12415 blur : function(){
12416 if(this.rendered){
12417 this.el.blur();
12419 return this;
12420 },
12423 disable : function(){
12424 if(this.rendered){
12425 this.onDisable();
12427 this.disabled = true;
12428 this.fireEvent("disable", this);
12429 return this;
12430 },
12432 onDisable : function(){
12433 this.getActionEl().addClass(this.disabledClass);
12434 this.el.dom.disabled = true;
12435 },
12438 enable : function(){
12439 if(this.rendered){
12440 this.onEnable();
12442 this.disabled = false;
12443 this.fireEvent("enable", this);
12444 return this;
12445 },
12447 onEnable : function(){
12448 this.getActionEl().removeClass(this.disabledClass);
12449 this.el.dom.disabled = false;
12450 },
12453 setDisabled : function(disabled){
12454 this[disabled ? "disable" : "enable"]();
12455 },
12458 show: function(){
12459 if(this.fireEvent("beforeshow", this) !== false){
12460 this.hidden = false;
12461 if(this.autoRender){
12462 this.render(typeof this.autoRender == 'boolean' ? Ext.getBody() : this.autoRender);
12464 if(this.rendered){
12465 this.onShow();
12467 this.fireEvent("show", this);
12469 return this;
12470 },
12472 onShow : function(){
12473 if(this.hideParent){
12474 this.container.removeClass('x-hide-' + this.hideMode);
12475 }else{
12476 this.getActionEl().removeClass('x-hide-' + this.hideMode);
12479 },
12482 hide: function(){
12483 if(this.fireEvent("beforehide", this) !== false){
12484 this.hidden = true;
12485 if(this.rendered){
12486 this.onHide();
12488 this.fireEvent("hide", this);
12490 return this;
12491 },
12493 onHide : function(){
12494 if(this.hideParent){
12495 this.container.addClass('x-hide-' + this.hideMode);
12496 }else{
12497 this.getActionEl().addClass('x-hide-' + this.hideMode);
12499 },
12502 setVisible: function(visible){
12503 if(visible) {
12504 this.show();
12505 }else{
12506 this.hide();
12508 return this;
12509 },
12512 isVisible : function(){
12513 return this.rendered && this.getActionEl().isVisible();
12514 },
12517 cloneConfig : function(overrides){
12518 overrides = overrides || {};
12519 var id = overrides.id || Ext.id();
12520 var cfg = Ext.applyIf(overrides, this.initialConfig);
12521 cfg.id = id; return new this.constructor(cfg);
12522 },
12525 getXType : function(){
12526 return this.constructor.xtype;
12527 },
12530 isXType : function(xtype, shallow){
12531 return !shallow ?
12532 ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 :
12533 this.constructor.xtype == xtype;
12534 },
12537 getXTypes : function(){
12538 var tc = this.constructor;
12539 if(!tc.xtypes){
12540 var c = [], sc = this;
12541 while(sc && sc.constructor.xtype){
12542 c.unshift(sc.constructor.xtype);
12543 sc = sc.constructor.superclass;
12545 tc.xtypeChain = c;
12546 tc.xtypes = c.join('/');
12548 return tc.xtypes;
12549 },
12552 findParentBy: function(fn) {
12553 for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt);
12554 return p || null;
12555 },
12558 findParentByType: function(xtype) {
12559 return typeof xtype == 'function' ?
12560 this.findParentBy(function(p){
12561 return p.constructor === xtype;
12562 }) :
12563 this.findParentBy(function(p){
12564 return p.constructor.xtype === xtype;
12565 });
12566 },
12568 mon : function(item, ename, fn, scope, opt){
12569 if(!this.mons){
12570 this.mons = [];
12571 this.on('beforedestroy', function(){
12572 for(var i= 0, len = this.mons.length; i < len; i++){
12573 var m = this.mons[i];
12574 m.item.un(m.ename, m.fn, m.scope);
12576 }, this);
12578 this.mons.push({
12579 item: item, ename: ename, fn: fn, scope: scope
12580 });
12581 item.on(ename, fn, scope, opt);
12583 });
12585 Ext.reg('component', Ext.Component);
12588 Ext.Action = function(config){
12589 this.initialConfig = config;
12590 this.items = [];
12593 Ext.Action.prototype = {
12602 isAction : true,
12605 setText : function(text){
12606 this.initialConfig.text = text;
12607 this.callEach('setText', [text]);
12608 },
12611 getText : function(){
12612 return this.initialConfig.text;
12613 },
12616 setIconClass : function(cls){
12617 this.initialConfig.iconCls = cls;
12618 this.callEach('setIconClass', [cls]);
12619 },
12622 getIconClass : function(){
12623 return this.initialConfig.iconCls;
12624 },
12627 setDisabled : function(v){
12628 this.initialConfig.disabled = v;
12629 this.callEach('setDisabled', [v]);
12630 },
12633 enable : function(){
12634 this.setDisabled(false);
12635 },
12638 disable : function(){
12639 this.setDisabled(true);
12640 },
12643 isDisabled : function(){
12644 return this.initialConfig.disabled;
12645 },
12648 setHidden : function(v){
12649 this.initialConfig.hidden = v;
12650 this.callEach('setVisible', [!v]);
12651 },
12654 show : function(){
12655 this.setHidden(false);
12656 },
12659 hide : function(){
12660 this.setHidden(true);
12661 },
12664 isHidden : function(){
12665 return this.initialConfig.hidden;
12666 },
12669 setHandler : function(fn, scope){
12670 this.initialConfig.handler = fn;
12671 this.initialConfig.scope = scope;
12672 this.callEach('setHandler', [fn, scope]);
12673 },
12676 each : function(fn, scope){
12677 Ext.each(this.items, fn, scope);
12678 },
12681 callEach : function(fnName, args){
12682 var cs = this.items;
12683 for(var i = 0, len = cs.length; i < len; i++){
12684 cs[i][fnName].apply(cs[i], args);
12686 },
12689 addComponent : function(comp){
12690 this.items.push(comp);
12691 comp.on('destroy', this.removeComponent, this);
12692 },
12695 removeComponent : function(comp){
12696 this.items.remove(comp);
12697 },
12700 execute : function(){
12701 this.initialConfig.handler.apply(this.initialConfig.scope || window, arguments);
12703 };
12705 (function(){
12706 Ext.Layer = function(config, existingEl){
12707 config = config || {};
12708 var dh = Ext.DomHelper;
12709 var cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body;
12710 if(existingEl){
12711 this.dom = Ext.getDom(existingEl);
12713 if(!this.dom){
12714 var o = config.dh || {tag: "div", cls: "x-layer"};
12715 this.dom = dh.append(pel, o);
12717 if(config.cls){
12718 this.addClass(config.cls);
12720 this.constrain = config.constrain !== false;
12721 this.visibilityMode = Ext.Element.VISIBILITY;
12722 if(config.id){
12723 this.id = this.dom.id = config.id;
12724 }else{
12725 this.id = Ext.id(this.dom);
12727 this.zindex = config.zindex || this.getZIndex();
12728 this.position("absolute", this.zindex);
12729 if(config.shadow){
12730 this.shadowOffset = config.shadowOffset || 4;
12731 this.shadow = new Ext.Shadow({
12732 offset : this.shadowOffset,
12733 mode : config.shadow
12734 });
12735 }else{
12736 this.shadowOffset = 0;
12738 this.useShim = config.shim !== false && Ext.useShims;
12739 this.useDisplay = config.useDisplay;
12740 this.hide();
12741 };
12743 var supr = Ext.Element.prototype;
12746 var shims = [];
12748 Ext.extend(Ext.Layer, Ext.Element, {
12750 getZIndex : function(){
12751 return this.zindex || parseInt(this.getStyle("z-index"), 10) || 11000;
12752 },
12754 getShim : function(){
12755 if(!this.useShim){
12756 return null;
12758 if(this.shim){
12759 return this.shim;
12761 var shim = shims.shift();
12762 if(!shim){
12763 shim = this.createShim();
12764 shim.enableDisplayMode('block');
12765 shim.dom.style.display = 'none';
12766 shim.dom.style.visibility = 'visible';
12768 var pn = this.dom.parentNode;
12769 if(shim.dom.parentNode != pn){
12770 pn.insertBefore(shim.dom, this.dom);
12772 shim.setStyle('z-index', this.getZIndex()-2);
12773 this.shim = shim;
12774 return shim;
12775 },
12777 hideShim : function(){
12778 if(this.shim){
12779 this.shim.setDisplayed(false);
12780 shims.push(this.shim);
12781 delete this.shim;
12783 },
12785 disableShadow : function(){
12786 if(this.shadow){
12787 this.shadowDisabled = true;
12788 this.shadow.hide();
12789 this.lastShadowOffset = this.shadowOffset;
12790 this.shadowOffset = 0;
12792 },
12794 enableShadow : function(show){
12795 if(this.shadow){
12796 this.shadowDisabled = false;
12797 this.shadowOffset = this.lastShadowOffset;
12798 delete this.lastShadowOffset;
12799 if(show){
12800 this.sync(true);
12803 },
12808 sync : function(doShow){
12809 var sw = this.shadow;
12810 if(!this.updating && this.isVisible() && (sw || this.useShim)){
12811 var sh = this.getShim();
12813 var w = this.getWidth(),
12814 h = this.getHeight();
12816 var l = this.getLeft(true),
12817 t = this.getTop(true);
12819 if(sw && !this.shadowDisabled){
12820 if(doShow && !sw.isVisible()){
12821 sw.show(this);
12822 }else{
12823 sw.realign(l, t, w, h);
12825 if(sh){
12826 if(doShow){
12827 sh.show();
12830 var a = sw.adjusts, s = sh.dom.style;
12831 s.left = (Math.min(l, l+a.l))+"px";
12832 s.top = (Math.min(t, t+a.t))+"px";
12833 s.width = (w+a.w)+"px";
12834 s.height = (h+a.h)+"px";
12836 }else if(sh){
12837 if(doShow){
12838 sh.show();
12840 sh.setSize(w, h);
12841 sh.setLeftTop(l, t);
12845 },
12848 destroy : function(){
12849 this.hideShim();
12850 if(this.shadow){
12851 this.shadow.hide();
12853 this.removeAllListeners();
12854 Ext.removeNode(this.dom);
12855 Ext.Element.uncache(this.id);
12856 },
12858 remove : function(){
12859 this.destroy();
12860 },
12863 beginUpdate : function(){
12864 this.updating = true;
12865 },
12868 endUpdate : function(){
12869 this.updating = false;
12870 this.sync(true);
12871 },
12874 hideUnders : function(negOffset){
12875 if(this.shadow){
12876 this.shadow.hide();
12878 this.hideShim();
12879 },
12882 constrainXY : function(){
12883 if(this.constrain){
12884 var vw = Ext.lib.Dom.getViewWidth(),
12885 vh = Ext.lib.Dom.getViewHeight();
12886 var s = Ext.getDoc().getScroll();
12888 var xy = this.getXY();
12889 var x = xy[0], y = xy[1];
12890 var w = this.dom.offsetWidth+this.shadowOffset, h = this.dom.offsetHeight+this.shadowOffset;
12892 var moved = false;
12894 if((x + w) > vw+s.left){
12895 x = vw - w - this.shadowOffset;
12896 moved = true;
12898 if((y + h) > vh+s.top){
12899 y = vh - h - this.shadowOffset;
12900 moved = true;
12903 if(x < s.left){
12904 x = s.left;
12905 moved = true;
12907 if(y < s.top){
12908 y = s.top;
12909 moved = true;
12911 if(moved){
12912 if(this.avoidY){
12913 var ay = this.avoidY;
12914 if(y <= ay && (y+h) >= ay){
12915 y = ay-h-5;
12918 xy = [x, y];
12919 this.storeXY(xy);
12920 supr.setXY.call(this, xy);
12921 this.sync();
12924 },
12926 isVisible : function(){
12927 return this.visible;
12928 },
12931 showAction : function(){
12932 this.visible = true;
12933 if(this.useDisplay === true){
12934 this.setDisplayed("");
12935 }else if(this.lastXY){
12936 supr.setXY.call(this, this.lastXY);
12937 }else if(this.lastLT){
12938 supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]);
12940 },
12943 hideAction : function(){
12944 this.visible = false;
12945 if(this.useDisplay === true){
12946 this.setDisplayed(false);
12947 }else{
12948 this.setLeftTop(-10000,-10000);
12950 },
12953 setVisible : function(v, a, d, c, e){
12954 if(v){
12955 this.showAction();
12957 if(a && v){
12958 var cb = function(){
12959 this.sync(true);
12960 if(c){
12961 c();
12963 }.createDelegate(this);
12964 supr.setVisible.call(this, true, true, d, cb, e);
12965 }else{
12966 if(!v){
12967 this.hideUnders(true);
12969 var cb = c;
12970 if(a){
12971 cb = function(){
12972 this.hideAction();
12973 if(c){
12974 c();
12976 }.createDelegate(this);
12978 supr.setVisible.call(this, v, a, d, cb, e);
12979 if(v){
12980 this.sync(true);
12981 }else if(!a){
12982 this.hideAction();
12985 },
12987 storeXY : function(xy){
12988 delete this.lastLT;
12989 this.lastXY = xy;
12990 },
12992 storeLeftTop : function(left, top){
12993 delete this.lastXY;
12994 this.lastLT = [left, top];
12995 },
12998 beforeFx : function(){
12999 this.beforeAction();
13000 return Ext.Layer.superclass.beforeFx.apply(this, arguments);
13001 },
13004 afterFx : function(){
13005 Ext.Layer.superclass.afterFx.apply(this, arguments);
13006 this.sync(this.isVisible());
13007 },
13010 beforeAction : function(){
13011 if(!this.updating && this.shadow){
13012 this.shadow.hide();
13014 },
13017 setLeft : function(left){
13018 this.storeLeftTop(left, this.getTop(true));
13019 supr.setLeft.apply(this, arguments);
13020 this.sync();
13021 },
13023 setTop : function(top){
13024 this.storeLeftTop(this.getLeft(true), top);
13025 supr.setTop.apply(this, arguments);
13026 this.sync();
13027 },
13029 setLeftTop : function(left, top){
13030 this.storeLeftTop(left, top);
13031 supr.setLeftTop.apply(this, arguments);
13032 this.sync();
13033 },
13035 setXY : function(xy, a, d, c, e){
13036 this.fixDisplay();
13037 this.beforeAction();
13038 this.storeXY(xy);
13039 var cb = this.createCB(c);
13040 supr.setXY.call(this, xy, a, d, cb, e);
13041 if(!a){
13042 cb();
13044 },
13047 createCB : function(c){
13048 var el = this;
13049 return function(){
13050 el.constrainXY();
13051 el.sync(true);
13052 if(c){
13053 c();
13055 };
13056 },
13059 setX : function(x, a, d, c, e){
13060 this.setXY([x, this.getY()], a, d, c, e);
13061 },
13064 setY : function(y, a, d, c, e){
13065 this.setXY([this.getX(), y], a, d, c, e);
13066 },
13069 setSize : function(w, h, a, d, c, e){
13070 this.beforeAction();
13071 var cb = this.createCB(c);
13072 supr.setSize.call(this, w, h, a, d, cb, e);
13073 if(!a){
13074 cb();
13076 },
13079 setWidth : function(w, a, d, c, e){
13080 this.beforeAction();
13081 var cb = this.createCB(c);
13082 supr.setWidth.call(this, w, a, d, cb, e);
13083 if(!a){
13084 cb();
13086 },
13089 setHeight : function(h, a, d, c, e){
13090 this.beforeAction();
13091 var cb = this.createCB(c);
13092 supr.setHeight.call(this, h, a, d, cb, e);
13093 if(!a){
13094 cb();
13096 },
13099 setBounds : function(x, y, w, h, a, d, c, e){
13100 this.beforeAction();
13101 var cb = this.createCB(c);
13102 if(!a){
13103 this.storeXY([x, y]);
13104 supr.setXY.call(this, [x, y]);
13105 supr.setSize.call(this, w, h, a, d, cb, e);
13106 cb();
13107 }else{
13108 supr.setBounds.call(this, x, y, w, h, a, d, cb, e);
13110 return this;
13111 },
13114 setZIndex : function(zindex){
13115 this.zindex = zindex;
13116 this.setStyle("z-index", zindex + 2);
13117 if(this.shadow){
13118 this.shadow.setZIndex(zindex + 1);
13120 if(this.shim){
13121 this.shim.setStyle("z-index", zindex);
13124 });
13125 })();
13127 Ext.Shadow = function(config){
13128 Ext.apply(this, config);
13129 if(typeof this.mode != "string"){
13130 this.mode = this.defaultMode;
13132 var o = this.offset, a = {h: 0};
13133 var rad = Math.floor(this.offset/2);
13134 switch(this.mode.toLowerCase()){ case "drop":
13135 a.w = 0;
13136 a.l = a.t = o;
13137 a.t -= 1;
13138 if(Ext.isIE){
13139 a.l -= this.offset + rad;
13140 a.t -= this.offset + rad;
13141 a.w -= rad;
13142 a.h -= rad;
13143 a.t += 1;
13145 break;
13146 case "sides":
13147 a.w = (o*2);
13148 a.l = -o;
13149 a.t = o-1;
13150 if(Ext.isIE){
13151 a.l -= (this.offset - rad);
13152 a.t -= this.offset + rad;
13153 a.l += 1;
13154 a.w -= (this.offset - rad)*2;
13155 a.w -= rad + 1;
13156 a.h -= 1;
13158 break;
13159 case "frame":
13160 a.w = a.h = (o*2);
13161 a.l = a.t = -o;
13162 a.t += 1;
13163 a.h -= 2;
13164 if(Ext.isIE){
13165 a.l -= (this.offset - rad);
13166 a.t -= (this.offset - rad);
13167 a.l += 1;
13168 a.w -= (this.offset + rad + 1);
13169 a.h -= (this.offset + rad);
13170 a.h += 1;
13172 break;
13173 };
13175 this.adjusts = a;
13176 };
13178 Ext.Shadow.prototype = {
13181 offset: 4,
13183 defaultMode: "drop",
13186 show : function(target){
13187 target = Ext.get(target);
13188 if(!this.el){
13189 this.el = Ext.Shadow.Pool.pull();
13190 if(this.el.dom.nextSibling != target.dom){
13191 this.el.insertBefore(target);
13194 this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10)-1);
13195 if(Ext.isIE){
13196 this.el.dom.style.filter="progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius="+(this.offset)+")";
13198 this.realign(
13199 target.getLeft(true),
13200 target.getTop(true),
13201 target.getWidth(),
13202 target.getHeight()
13203 );
13204 this.el.dom.style.display = "block";
13205 },
13208 isVisible : function(){
13209 return this.el ? true : false;
13210 },
13213 realign : function(l, t, w, h){
13214 if(!this.el){
13215 return;
13217 var a = this.adjusts, d = this.el.dom, s = d.style;
13218 var iea = 0;
13219 s.left = (l+a.l)+"px";
13220 s.top = (t+a.t)+"px";
13221 var sw = (w+a.w), sh = (h+a.h), sws = sw +"px", shs = sh + "px";
13222 if(s.width != sws || s.height != shs){
13223 s.width = sws;
13224 s.height = shs;
13225 if(!Ext.isIE){
13226 var cn = d.childNodes;
13227 var sww = Math.max(0, (sw-12))+"px";
13228 cn[0].childNodes[1].style.width = sww;
13229 cn[1].childNodes[1].style.width = sww;
13230 cn[2].childNodes[1].style.width = sww;
13231 cn[1].style.height = Math.max(0, (sh-12))+"px";
13234 },
13237 hide : function(){
13238 if(this.el){
13239 this.el.dom.style.display = "none";
13240 Ext.Shadow.Pool.push(this.el);
13241 delete this.el;
13243 },
13246 setZIndex : function(z){
13247 this.zIndex = z;
13248 if(this.el){
13249 this.el.setStyle("z-index", z);
13252 };
13254 Ext.Shadow.Pool = function(){
13255 var p = [];
13256 var markup = Ext.isIE ?
13257 '<div class="x-ie-shadow"></div>' :
13258 '<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>';
13259 return {
13260 pull : function(){
13261 var sh = p.shift();
13262 if(!sh){
13263 sh = Ext.get(Ext.DomHelper.insertHtml("beforeBegin", document.body.firstChild, markup));
13264 sh.autoBoxAdjust = false;
13266 return sh;
13267 },
13269 push : function(sh){
13270 p.push(sh);
13272 };
13273 }();
13275 Ext.BoxComponent = Ext.extend(Ext.Component, {
13287 initComponent : function(){
13288 Ext.BoxComponent.superclass.initComponent.call(this);
13289 this.addEvents(
13291 'resize',
13293 'move'
13294 );
13295 },
13297 boxReady : false,
13298 deferHeight: false,
13301 setSize : function(w, h){
13302 if(typeof w == 'object'){
13303 h = w.height;
13304 w = w.width;
13306 if(!this.boxReady){
13307 this.width = w;
13308 this.height = h;
13309 return this;
13312 if(this.lastSize && this.lastSize.width == w && this.lastSize.height == h){
13313 return this;
13315 this.lastSize = {width: w, height: h};
13316 var adj = this.adjustSize(w, h);
13317 var aw = adj.width, ah = adj.height;
13318 if(aw !== undefined || ah !== undefined){ var rz = this.getResizeEl();
13319 if(!this.deferHeight && aw !== undefined && ah !== undefined){
13320 rz.setSize(aw, ah);
13321 }else if(!this.deferHeight && ah !== undefined){
13322 rz.setHeight(ah);
13323 }else if(aw !== undefined){
13324 rz.setWidth(aw);
13326 this.onResize(aw, ah, w, h);
13327 this.fireEvent('resize', this, aw, ah, w, h);
13329 return this;
13330 },
13333 setWidth : function(width){
13334 return this.setSize(width);
13335 },
13338 setHeight : function(height){
13339 return this.setSize(undefined, height);
13340 },
13343 getSize : function(){
13344 return this.el.getSize();
13345 },
13348 getPosition : function(local){
13349 if(local === true){
13350 return [this.el.getLeft(true), this.el.getTop(true)];
13352 return this.xy || this.el.getXY();
13353 },
13356 getBox : function(local){
13357 var s = this.el.getSize();
13358 if(local === true){
13359 s.x = this.el.getLeft(true);
13360 s.y = this.el.getTop(true);
13361 }else{
13362 var xy = this.xy || this.el.getXY();
13363 s.x = xy[0];
13364 s.y = xy[1];
13366 return s;
13367 },
13370 updateBox : function(box){
13371 this.setSize(box.width, box.height);
13372 this.setPagePosition(box.x, box.y);
13373 return this;
13374 },
13376 getResizeEl : function(){
13377 return this.resizeEl || this.el;
13378 },
13380 getPositionEl : function(){
13381 return this.positionEl || this.el;
13382 },
13385 setPosition : function(x, y){
13386 if(x && typeof x[1] == 'number'){
13387 y = x[1];
13388 x = x[0];
13390 this.x = x;
13391 this.y = y;
13392 if(!this.boxReady){
13393 return this;
13395 var adj = this.adjustPosition(x, y);
13396 var ax = adj.x, ay = adj.y;
13398 var el = this.getPositionEl();
13399 if(ax !== undefined || ay !== undefined){
13400 if(ax !== undefined && ay !== undefined){
13401 el.setLeftTop(ax, ay);
13402 }else if(ax !== undefined){
13403 el.setLeft(ax);
13404 }else if(ay !== undefined){
13405 el.setTop(ay);
13407 this.onPosition(ax, ay);
13408 this.fireEvent('move', this, ax, ay);
13410 return this;
13411 },
13414 setPagePosition : function(x, y){
13415 if(x && typeof x[1] == 'number'){
13416 y = x[1];
13417 x = x[0];
13419 this.pageX = x;
13420 this.pageY = y;
13421 if(!this.boxReady){
13422 return;
13424 if(x === undefined || y === undefined){ return;
13426 var p = this.el.translatePoints(x, y);
13427 this.setPosition(p.left, p.top);
13428 return this;
13429 },
13431 onRender : function(ct, position){
13432 Ext.BoxComponent.superclass.onRender.call(this, ct, position);
13433 if(this.resizeEl){
13434 this.resizeEl = Ext.get(this.resizeEl);
13436 if(this.positionEl){
13437 this.positionEl = Ext.get(this.positionEl);
13439 },
13441 afterRender : function(){
13442 Ext.BoxComponent.superclass.afterRender.call(this);
13443 this.boxReady = true;
13444 this.setSize(this.width, this.height);
13445 if(this.x || this.y){
13446 this.setPosition(this.x, this.y);
13447 }else if(this.pageX || this.pageY){
13448 this.setPagePosition(this.pageX, this.pageY);
13450 },
13453 syncSize : function(){
13454 delete this.lastSize;
13455 this.setSize(this.autoWidth ? undefined : this.el.getWidth(), this.autoHeight ? undefined : this.el.getHeight());
13456 return this;
13457 },
13460 onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
13462 },
13465 onPosition : function(x, y){
13467 },
13469 adjustSize : function(w, h){
13470 if(this.autoWidth){
13471 w = 'auto';
13473 if(this.autoHeight){
13474 h = 'auto';
13476 return {width : w, height: h};
13477 },
13479 adjustPosition : function(x, y){
13480 return {x : x, y: y};
13482 });
13483 Ext.reg('box', Ext.BoxComponent);
13485 Ext.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){
13488 this.el = Ext.get(dragElement, true);
13489 this.el.dom.unselectable = "on";
13491 this.resizingEl = Ext.get(resizingElement, true);
13494 this.orientation = orientation || Ext.SplitBar.HORIZONTAL;
13497 this.minSize = 0;
13500 this.maxSize = 2000;
13503 this.animate = false;
13506 this.useShim = false;
13509 this.shim = null;
13511 if(!existingProxy){
13513 this.proxy = Ext.SplitBar.createProxy(this.orientation);
13514 }else{
13515 this.proxy = Ext.get(existingProxy).dom;
13518 this.dd = new Ext.dd.DDProxy(this.el.dom.id, "XSplitBars", {dragElId : this.proxy.id});
13521 this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this);
13524 this.dd.endDrag = this.onEndProxyDrag.createDelegate(this);
13527 this.dragSpecs = {};
13530 this.adapter = new Ext.SplitBar.BasicLayoutAdapter();
13531 this.adapter.init(this);
13533 if(this.orientation == Ext.SplitBar.HORIZONTAL){
13535 this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? Ext.SplitBar.LEFT : Ext.SplitBar.RIGHT);
13536 this.el.addClass("x-splitbar-h");
13537 }else{
13539 this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? Ext.SplitBar.TOP : Ext.SplitBar.BOTTOM);
13540 this.el.addClass("x-splitbar-v");
13543 this.addEvents(
13545 "resize",
13547 "moved",
13549 "beforeresize",
13551 "beforeapply"
13552 );
13554 Ext.SplitBar.superclass.constructor.call(this);
13555 };
13557 Ext.extend(Ext.SplitBar, Ext.util.Observable, {
13558 onStartProxyDrag : function(x, y){
13559 this.fireEvent("beforeresize", this);
13560 this.overlay = Ext.DomHelper.append(document.body, {cls: "x-drag-overlay", html: "&#160;"}, true);
13561 this.overlay.unselectable();
13562 this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
13563 this.overlay.show();
13564 Ext.get(this.proxy).setDisplayed("block");
13565 var size = this.adapter.getElementSize(this);
13566 this.activeMinSize = this.getMinimumSize();;
13567 this.activeMaxSize = this.getMaximumSize();;
13568 var c1 = size - this.activeMinSize;
13569 var c2 = Math.max(this.activeMaxSize - size, 0);
13570 if(this.orientation == Ext.SplitBar.HORIZONTAL){
13571 this.dd.resetConstraints();
13572 this.dd.setXConstraint(
13573 this.placement == Ext.SplitBar.LEFT ? c1 : c2,
13574 this.placement == Ext.SplitBar.LEFT ? c2 : c1
13575 );
13576 this.dd.setYConstraint(0, 0);
13577 }else{
13578 this.dd.resetConstraints();
13579 this.dd.setXConstraint(0, 0);
13580 this.dd.setYConstraint(
13581 this.placement == Ext.SplitBar.TOP ? c1 : c2,
13582 this.placement == Ext.SplitBar.TOP ? c2 : c1
13583 );
13585 this.dragSpecs.startSize = size;
13586 this.dragSpecs.startPoint = [x, y];
13587 Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd, x, y);
13588 },
13591 onEndProxyDrag : function(e){
13592 Ext.get(this.proxy).setDisplayed(false);
13593 var endPoint = Ext.lib.Event.getXY(e);
13594 if(this.overlay){
13595 this.overlay.remove();
13596 delete this.overlay;
13598 var newSize;
13599 if(this.orientation == Ext.SplitBar.HORIZONTAL){
13600 newSize = this.dragSpecs.startSize +
13601 (this.placement == Ext.SplitBar.LEFT ?
13602 endPoint[0] - this.dragSpecs.startPoint[0] :
13603 this.dragSpecs.startPoint[0] - endPoint[0]
13604 );
13605 }else{
13606 newSize = this.dragSpecs.startSize +
13607 (this.placement == Ext.SplitBar.TOP ?
13608 endPoint[1] - this.dragSpecs.startPoint[1] :
13609 this.dragSpecs.startPoint[1] - endPoint[1]
13610 );
13612 newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize);
13613 if(newSize != this.dragSpecs.startSize){
13614 if(this.fireEvent('beforeapply', this, newSize) !== false){
13615 this.adapter.setElementSize(this, newSize);
13616 this.fireEvent("moved", this, newSize);
13617 this.fireEvent("resize", this, newSize);
13620 },
13623 getAdapter : function(){
13624 return this.adapter;
13625 },
13628 setAdapter : function(adapter){
13629 this.adapter = adapter;
13630 this.adapter.init(this);
13631 },
13634 getMinimumSize : function(){
13635 return this.minSize;
13636 },
13639 setMinimumSize : function(minSize){
13640 this.minSize = minSize;
13641 },
13644 getMaximumSize : function(){
13645 return this.maxSize;
13646 },
13649 setMaximumSize : function(maxSize){
13650 this.maxSize = maxSize;
13651 },
13654 setCurrentSize : function(size){
13655 var oldAnimate = this.animate;
13656 this.animate = false;
13657 this.adapter.setElementSize(this, size);
13658 this.animate = oldAnimate;
13659 },
13662 destroy : function(removeEl){
13663 if(this.shim){
13664 this.shim.remove();
13666 this.dd.unreg();
13667 Ext.removeNode(this.proxy);
13668 if(removeEl){
13669 this.el.remove();
13672 });
13675 Ext.SplitBar.createProxy = function(dir){
13676 var proxy = new Ext.Element(document.createElement("div"));
13677 proxy.unselectable();
13678 var cls = 'x-splitbar-proxy';
13679 proxy.addClass(cls + ' ' + (dir == Ext.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v'));
13680 document.body.appendChild(proxy.dom);
13681 return proxy.dom;
13682 };
13685 Ext.SplitBar.BasicLayoutAdapter = function(){
13686 };
13688 Ext.SplitBar.BasicLayoutAdapter.prototype = {
13690 init : function(s){
13692 },
13694 getElementSize : function(s){
13695 if(s.orientation == Ext.SplitBar.HORIZONTAL){
13696 return s.resizingEl.getWidth();
13697 }else{
13698 return s.resizingEl.getHeight();
13700 },
13703 setElementSize : function(s, newSize, onComplete){
13704 if(s.orientation == Ext.SplitBar.HORIZONTAL){
13705 if(!s.animate){
13706 s.resizingEl.setWidth(newSize);
13707 if(onComplete){
13708 onComplete(s, newSize);
13710 }else{
13711 s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut');
13713 }else{
13715 if(!s.animate){
13716 s.resizingEl.setHeight(newSize);
13717 if(onComplete){
13718 onComplete(s, newSize);
13720 }else{
13721 s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut');
13725 };
13728 Ext.SplitBar.AbsoluteLayoutAdapter = function(container){
13729 this.basic = new Ext.SplitBar.BasicLayoutAdapter();
13730 this.container = Ext.get(container);
13731 };
13733 Ext.SplitBar.AbsoluteLayoutAdapter.prototype = {
13734 init : function(s){
13735 this.basic.init(s);
13736 },
13738 getElementSize : function(s){
13739 return this.basic.getElementSize(s);
13740 },
13742 setElementSize : function(s, newSize, onComplete){
13743 this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s]));
13744 },
13746 moveSplitter : function(s){
13747 var yes = Ext.SplitBar;
13748 switch(s.placement){
13749 case yes.LEFT:
13750 s.el.setX(s.resizingEl.getRight());
13751 break;
13752 case yes.RIGHT:
13753 s.el.setStyle("right", (this.container.getWidth() - s.resizingEl.getLeft()) + "px");
13754 break;
13755 case yes.TOP:
13756 s.el.setY(s.resizingEl.getBottom());
13757 break;
13758 case yes.BOTTOM:
13759 s.el.setY(s.resizingEl.getTop() - s.el.getHeight());
13760 break;
13763 };
13766 Ext.SplitBar.VERTICAL = 1;
13769 Ext.SplitBar.HORIZONTAL = 2;
13772 Ext.SplitBar.LEFT = 1;
13775 Ext.SplitBar.RIGHT = 2;
13778 Ext.SplitBar.TOP = 3;
13781 Ext.SplitBar.BOTTOM = 4;
13784 Ext.Container = Ext.extend(Ext.BoxComponent, {
13794 autoDestroy: true,
13797 defaultType: 'panel',
13799 initComponent : function(){
13800 Ext.Container.superclass.initComponent.call(this);
13802 this.addEvents(
13804 'afterlayout',
13806 'beforeadd',
13808 'beforeremove',
13810 'add',
13812 'remove'
13813 );
13816 var items = this.items;
13817 if(items){
13818 delete this.items;
13819 if(Ext.isArray(items)){
13820 this.add.apply(this, items);
13821 }else{
13822 this.add(items);
13825 },
13827 initItems : function(){
13828 if(!this.items){
13829 this.items = new Ext.util.MixedCollection(false, this.getComponentId);
13830 this.getLayout(); }
13831 },
13833 setLayout : function(layout){
13834 if(this.layout && this.layout != layout){
13835 this.layout.setContainer(null);
13837 this.initItems();
13838 this.layout = layout;
13839 layout.setContainer(this);
13840 },
13842 render : function(){
13843 Ext.Container.superclass.render.apply(this, arguments);
13844 if(this.layout){
13845 if(typeof this.layout == 'string'){
13846 this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);
13848 this.setLayout(this.layout);
13850 if(this.activeItem !== undefined){
13851 var item = this.activeItem;
13852 delete this.activeItem;
13853 this.layout.setActiveItem(item);
13854 return;
13857 if(!this.ownerCt){
13858 this.doLayout();
13860 if(this.monitorResize === true){
13861 Ext.EventManager.onWindowResize(this.doLayout, this, [false]);
13863 },
13865 getLayoutTarget : function(){
13866 return this.el;
13867 },
13869 getComponentId : function(comp){
13870 return comp.itemId || comp.id;
13871 },
13874 add : function(comp){
13875 if(!this.items){
13876 this.initItems();
13878 var a = arguments, len = a.length;
13879 if(len > 1){
13880 for(var i = 0; i < len; i++) {
13881 this.add(a[i]);
13883 return;
13885 var c = this.lookupComponent(this.applyDefaults(comp));
13886 var pos = this.items.length;
13887 if(this.fireEvent('beforeadd', this, c, pos) !== false && this.onBeforeAdd(c) !== false){
13888 this.items.add(c);
13889 c.ownerCt = this;
13890 this.fireEvent('add', this, c, pos);
13892 return c;
13893 },
13896 insert : function(index, comp){
13897 if(!this.items){
13898 this.initItems();
13900 var a = arguments, len = a.length;
13901 if(len > 2){
13902 for(var i = len-1; i >= 1; --i) {
13903 this.insert(index, a[i]);
13905 return;
13907 var c = this.lookupComponent(this.applyDefaults(comp));
13909 if(c.ownerCt == this && this.items.indexOf(c) < index){
13910 --index;
13913 if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){
13914 this.items.insert(index, c);
13915 c.ownerCt = this;
13916 this.fireEvent('add', this, c, index);
13918 return c;
13919 },
13921 applyDefaults : function(c){
13922 if(this.defaults){
13923 if(typeof c == 'string'){
13924 c = Ext.ComponentMgr.get(c);
13925 Ext.apply(c, this.defaults);
13926 }else if(!c.events){
13927 Ext.applyIf(c, this.defaults);
13928 }else{
13929 Ext.apply(c, this.defaults);
13932 return c;
13933 },
13935 onBeforeAdd : function(item){
13936 if(item.ownerCt){
13937 item.ownerCt.remove(item, false);
13939 if(this.hideBorders === true){
13940 item.border = (item.border === true);
13942 },
13945 remove : function(comp, autoDestroy){
13946 var c = this.getComponent(comp);
13947 if(c && this.fireEvent('beforeremove', this, c) !== false){
13948 this.items.remove(c);
13949 delete c.ownerCt;
13950 if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){
13951 c.destroy();
13953 if(this.layout && this.layout.activeItem == c){
13954 delete this.layout.activeItem;
13956 this.fireEvent('remove', this, c);
13958 return c;
13959 },
13962 getComponent : function(comp){
13963 if(typeof comp == 'object'){
13964 return comp;
13966 return this.items.get(comp);
13967 },
13969 lookupComponent : function(comp){
13970 if(typeof comp == 'string'){
13971 return Ext.ComponentMgr.get(comp);
13972 }else if(!comp.events){
13973 return this.createComponent(comp);
13975 return comp;
13976 },
13978 createComponent : function(config){
13979 return Ext.ComponentMgr.create(config, this.defaultType);
13980 },
13983 doLayout : function(shallow){
13984 if(this.rendered && this.layout){
13985 this.layout.layout();
13987 if(shallow !== false && this.items){
13988 var cs = this.items.items;
13989 for(var i = 0, len = cs.length; i < len; i++) {
13990 var c = cs[i];
13991 if(c.doLayout){
13992 c.doLayout();
13996 },
13999 getLayout : function(){
14000 if(!this.layout){
14001 var layout = new Ext.layout.ContainerLayout(this.layoutConfig);
14002 this.setLayout(layout);
14004 return this.layout;
14005 },
14007 onDestroy : function(){
14008 if(this.items){
14009 var cs = this.items.items;
14010 for(var i = 0, len = cs.length; i < len; i++) {
14011 Ext.destroy(cs[i]);
14014 if(this.monitorResize){
14015 Ext.EventManager.removeResizeListener(this.doLayout, this);
14017 Ext.Container.superclass.onDestroy.call(this);
14018 },
14021 bubble : function(fn, scope, args){
14022 var p = this;
14023 while(p){
14024 if(fn.apply(scope || p, args || [p]) === false){
14025 break;
14027 p = p.ownerCt;
14029 },
14032 cascade : function(fn, scope, args){
14033 if(fn.apply(scope || this, args || [this]) !== false){
14034 if(this.items){
14035 var cs = this.items.items;
14036 for(var i = 0, len = cs.length; i < len; i++){
14037 if(cs[i].cascade){
14038 cs[i].cascade(fn, scope, args);
14039 }else{
14040 fn.apply(scope || this, args || [cs[i]]);
14045 },
14048 findById : function(id){
14049 var m, ct = this;
14050 this.cascade(function(c){
14051 if(ct != c && c.id === id){
14052 m = c;
14053 return false;
14055 });
14056 return m || null;
14057 },
14060 findByType : function(xtype){
14061 return typeof xtype == 'function' ?
14062 this.findBy(function(c){
14063 return c.constructor === xtype;
14064 }) :
14065 this.findBy(function(c){
14066 return c.constructor.xtype === xtype;
14067 });
14068 },
14071 find : function(prop, value){
14072 return this.findBy(function(c){
14073 return c[prop] === value;
14074 });
14075 },
14078 findBy : function(fn, scope){
14079 var m = [], ct = this;
14080 this.cascade(function(c){
14081 if(ct != c && fn.call(scope || c, c, ct) === true){
14082 m.push(c);
14084 });
14085 return m;
14087 });
14089 Ext.Container.LAYOUTS = {};
14090 Ext.reg('container', Ext.Container);
14092 Ext.layout.ContainerLayout = function(config){
14093 Ext.apply(this, config);
14094 };
14096 Ext.layout.ContainerLayout.prototype = {
14102 monitorResize:false,
14103 activeItem : null,
14105 layout : function(){
14106 var target = this.container.getLayoutTarget();
14107 this.onLayout(this.container, target);
14108 this.container.fireEvent('afterlayout', this.container, this);
14109 },
14111 onLayout : function(ct, target){
14112 this.renderAll(ct, target);
14113 },
14115 isValidParent : function(c, target){
14116 var el = c.getPositionEl ? c.getPositionEl() : c.getEl();
14117 return el.dom.parentNode == target.dom;
14118 },
14120 renderAll : function(ct, target){
14121 var items = ct.items.items;
14122 for(var i = 0, len = items.length; i < len; i++) {
14123 var c = items[i];
14124 if(c && (!c.rendered || !this.isValidParent(c, target))){
14125 this.renderItem(c, i, target);
14128 },
14130 renderItem : function(c, position, target){
14131 if(c && !c.rendered){
14132 c.render(target, position);
14133 if(this.extraCls){
14134 var t = c.getPositionEl ? c.getPositionEl() : c;
14135 t.addClass(this.extraCls);
14137 if (this.renderHidden && c != this.activeItem) {
14138 c.hide();
14140 }else if(c && !this.isValidParent(c, target)){
14141 if(this.extraCls){
14142 c.addClass(this.extraCls);
14144 if(typeof position == 'number'){
14145 position = target.dom.childNodes[position];
14147 target.dom.insertBefore(c.getEl().dom, position || null);
14148 if (this.renderHidden && c != this.activeItem) {
14149 c.hide();
14152 },
14154 onResize: function(){
14155 if(this.container.collapsed){
14156 return;
14158 var b = this.container.bufferResize;
14159 if(b){
14160 if(!this.resizeTask){
14161 this.resizeTask = new Ext.util.DelayedTask(this.layout, this);
14162 this.resizeBuffer = typeof b == 'number' ? b : 100;
14164 this.resizeTask.delay(this.resizeBuffer);
14165 }else{
14166 this.layout();
14168 },
14170 setContainer : function(ct){
14171 if(this.monitorResize && ct != this.container){
14172 if(this.container){
14173 this.container.un('resize', this.onResize, this);
14175 if(ct){
14176 ct.on('resize', this.onResize, this);
14179 this.container = ct;
14180 },
14182 parseMargins : function(v){
14183 var ms = v.split(' ');
14184 var len = ms.length;
14185 if(len == 1){
14186 ms[1] = ms[0];
14187 ms[2] = ms[0];
14188 ms[3] = ms[0];
14190 if(len == 2){
14191 ms[2] = ms[0];
14192 ms[3] = ms[1];
14194 return {
14195 top:parseInt(ms[0], 10) || 0,
14196 right:parseInt(ms[1], 10) || 0,
14197 bottom:parseInt(ms[2], 10) || 0,
14198 left:parseInt(ms[3], 10) || 0
14199 };
14201 };
14202 Ext.Container.LAYOUTS['auto'] = Ext.layout.ContainerLayout;
14204 Ext.layout.FitLayout = Ext.extend(Ext.layout.ContainerLayout, {
14206 monitorResize:true,
14209 onLayout : function(ct, target){
14210 Ext.layout.FitLayout.superclass.onLayout.call(this, ct, target);
14211 if(!this.container.collapsed){
14212 this.setItemSize(this.activeItem || ct.items.itemAt(0), target.getStyleSize());
14214 },
14217 setItemSize : function(item, size){
14218 if(item && size.height > 0){
14219 item.setSize(size);
14222 });
14223 Ext.Container.LAYOUTS['fit'] = Ext.layout.FitLayout;
14225 Ext.layout.CardLayout = Ext.extend(Ext.layout.FitLayout, {
14227 deferredRender : false,
14230 renderHidden : true,
14233 setActiveItem : function(item){
14234 item = this.container.getComponent(item);
14235 if(this.activeItem != item){
14236 if(this.activeItem){
14237 this.activeItem.hide();
14239 this.activeItem = item;
14240 item.show();
14241 this.layout();
14243 },
14246 renderAll : function(ct, target){
14247 if(this.deferredRender){
14248 this.renderItem(this.activeItem, undefined, target);
14249 }else{
14250 Ext.layout.CardLayout.superclass.renderAll.call(this, ct, target);
14253 });
14254 Ext.Container.LAYOUTS['card'] = Ext.layout.CardLayout;
14256 Ext.layout.AnchorLayout = Ext.extend(Ext.layout.ContainerLayout, {
14258 monitorResize:true,
14261 getAnchorViewSize : function(ct, target){
14262 return target.dom == document.body ?
14263 target.getViewSize() : target.getStyleSize();
14264 },
14267 onLayout : function(ct, target){
14268 Ext.layout.AnchorLayout.superclass.onLayout.call(this, ct, target);
14270 var size = this.getAnchorViewSize(ct, target);
14272 var w = size.width, h = size.height;
14274 if(w < 20 || h < 20){
14275 return;
14279 var aw, ah;
14280 if(ct.anchorSize){
14281 if(typeof ct.anchorSize == 'number'){
14282 aw = ct.anchorSize;
14283 }else{
14284 aw = ct.anchorSize.width;
14285 ah = ct.anchorSize.height;
14287 }else{
14288 aw = ct.initialConfig.width;
14289 ah = ct.initialConfig.height;
14292 var cs = ct.items.items, len = cs.length, i, c, a, cw, ch;
14293 for(i = 0; i < len; i++){
14294 c = cs[i];
14295 if(c.anchor){
14296 a = c.anchorSpec;
14297 if(!a){
14298 var vs = c.anchor.split(' ');
14299 c.anchorSpec = a = {
14300 right: this.parseAnchor(vs[0], c.initialConfig.width, aw),
14301 bottom: this.parseAnchor(vs[1], c.initialConfig.height, ah)
14302 };
14304 cw = a.right ? this.adjustWidthAnchor(a.right(w), c) : undefined;
14305 ch = a.bottom ? this.adjustHeightAnchor(a.bottom(h), c) : undefined;
14307 if(cw || ch){
14308 c.setSize(cw || undefined, ch || undefined);
14312 },
14315 parseAnchor : function(a, start, cstart){
14316 if(a && a != 'none'){
14317 var last;
14318 if(/^(r|right|b|bottom)$/i.test(a)){
14319 var diff = cstart - start;
14320 return function(v){
14321 if(v !== last){
14322 last = v;
14323 return v - diff;
14326 }else if(a.indexOf('%') != -1){
14327 var ratio = parseFloat(a.replace('%', ''))*.01;
14328 return function(v){
14329 if(v !== last){
14330 last = v;
14331 return Math.floor(v*ratio);
14334 }else{
14335 a = parseInt(a, 10);
14336 if(!isNaN(a)){
14337 return function(v){
14338 if(v !== last){
14339 last = v;
14340 return v + a;
14346 return false;
14347 },
14350 adjustWidthAnchor : function(value, comp){
14351 return value;
14352 },
14355 adjustHeightAnchor : function(value, comp){
14356 return value;
14360 });
14361 Ext.Container.LAYOUTS['anchor'] = Ext.layout.AnchorLayout;
14363 Ext.layout.ColumnLayout = Ext.extend(Ext.layout.ContainerLayout, {
14365 monitorResize:true,
14367 extraCls: 'x-column',
14369 scrollOffset : 0,
14372 isValidParent : function(c, target){
14373 return c.getEl().dom.parentNode == this.innerCt.dom;
14374 },
14377 onLayout : function(ct, target){
14378 var cs = ct.items.items, len = cs.length, c, i;
14380 if(!this.innerCt){
14381 target.addClass('x-column-layout-ct');
14385 this.innerCt = target.createChild({cls:'x-column-inner'});
14386 this.innerCt.createChild({cls:'x-clear'});
14388 this.renderAll(ct, this.innerCt);
14390 var size = target.getViewSize();
14392 if(size.width < 1 && size.height < 1){
14393 return;
14396 var w = size.width - target.getPadding('lr') - this.scrollOffset,
14397 h = size.height - target.getPadding('tb'),
14398 pw = w;
14400 this.innerCt.setWidth(w);
14405 for(i = 0; i < len; i++){
14406 c = cs[i];
14407 if(!c.columnWidth){
14408 pw -= (c.getSize().width + c.getEl().getMargins('lr'));
14412 pw = pw < 0 ? 0 : pw;
14414 for(i = 0; i < len; i++){
14415 c = cs[i];
14416 if(c.columnWidth){
14417 c.setSize(Math.floor(c.columnWidth*pw) - c.getEl().getMargins('lr'));
14423 });
14425 Ext.Container.LAYOUTS['column'] = Ext.layout.ColumnLayout;
14427 Ext.layout.BorderLayout = Ext.extend(Ext.layout.ContainerLayout, {
14428 monitorResize:true,
14429 rendered : false,
14431 onLayout : function(ct, target){
14432 var collapsed;
14433 if(!this.rendered){
14434 target.position();
14435 target.addClass('x-border-layout-ct');
14436 var items = ct.items.items;
14437 collapsed = [];
14438 for(var i = 0, len = items.length; i < len; i++) {
14439 var c = items[i];
14440 var pos = c.region;
14441 if(c.collapsed){
14442 collapsed.push(c);
14444 c.collapsed = false;
14445 if(!c.rendered){
14446 c.cls = c.cls ? c.cls +' x-border-panel' : 'x-border-panel';
14447 c.render(target, i);
14449 this[pos] = pos != 'center' && c.split ?
14450 new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) :
14451 new Ext.layout.BorderLayout.Region(this, c.initialConfig, pos);
14452 this[pos].render(target, c);
14454 this.rendered = true;
14457 var size = target.getViewSize();
14458 if(size.width < 20 || size.height < 20){ if(collapsed){
14459 this.restoreCollapsed = collapsed;
14461 return;
14462 }else if(this.restoreCollapsed){
14463 collapsed = this.restoreCollapsed;
14464 delete this.restoreCollapsed;
14467 var w = size.width, h = size.height;
14468 var centerW = w, centerH = h, centerY = 0, centerX = 0;
14470 var n = this.north, s = this.south, west = this.west, e = this.east, c = this.center;
14471 if(!c){
14472 throw 'No center region defined in BorderLayout ' + ct.id;
14475 if(n && n.isVisible()){
14476 var b = n.getSize();
14477 var m = n.getMargins();
14478 b.width = w - (m.left+m.right);
14479 b.x = m.left;
14480 b.y = m.top;
14481 centerY = b.height + b.y + m.bottom;
14482 centerH -= centerY;
14483 n.applyLayout(b);
14485 if(s && s.isVisible()){
14486 var b = s.getSize();
14487 var m = s.getMargins();
14488 b.width = w - (m.left+m.right);
14489 b.x = m.left;
14490 var totalHeight = (b.height + m.top + m.bottom);
14491 b.y = h - totalHeight + m.top;
14492 centerH -= totalHeight;
14493 s.applyLayout(b);
14495 if(west && west.isVisible()){
14496 var b = west.getSize();
14497 var m = west.getMargins();
14498 b.height = centerH - (m.top+m.bottom);
14499 b.x = m.left;
14500 b.y = centerY + m.top;
14501 var totalWidth = (b.width + m.left + m.right);
14502 centerX += totalWidth;
14503 centerW -= totalWidth;
14504 west.applyLayout(b);
14506 if(e && e.isVisible()){
14507 var b = e.getSize();
14508 var m = e.getMargins();
14509 b.height = centerH - (m.top+m.bottom);
14510 var totalWidth = (b.width + m.left + m.right);
14511 b.x = w - totalWidth + m.left;
14512 b.y = centerY + m.top;
14513 centerW -= totalWidth;
14514 e.applyLayout(b);
14517 var m = c.getMargins();
14518 var centerBox = {
14519 x: centerX + m.left,
14520 y: centerY + m.top,
14521 width: centerW - (m.left+m.right),
14522 height: centerH - (m.top+m.bottom)
14523 };
14524 c.applyLayout(centerBox);
14526 if(collapsed){
14527 for(var i = 0, len = collapsed.length; i < len; i++){
14528 collapsed[i].collapse(false);
14532 if(Ext.isIE && Ext.isStrict){ target.repaint();
14537 });
14540 Ext.layout.BorderLayout.Region = function(layout, config, pos){
14541 Ext.apply(this, config);
14542 this.layout = layout;
14543 this.position = pos;
14544 this.state = {};
14545 if(typeof this.margins == 'string'){
14546 this.margins = this.layout.parseMargins(this.margins);
14548 this.margins = Ext.applyIf(this.margins || {}, this.defaultMargins);
14549 if(this.collapsible){
14550 if(typeof this.cmargins == 'string'){
14551 this.cmargins = this.layout.parseMargins(this.cmargins);
14553 if(this.collapseMode == 'mini' && !this.cmargins){
14554 this.cmargins = {left:0,top:0,right:0,bottom:0};
14555 }else{
14556 this.cmargins = Ext.applyIf(this.cmargins || {},
14557 pos == 'north' || pos == 'south' ? this.defaultNSCMargins : this.defaultEWCMargins);
14560 };
14562 Ext.layout.BorderLayout.Region.prototype = {
14570 collapsible : false,
14572 split:false,
14574 floatable: true,
14576 minWidth:50,
14578 minHeight:50,
14580 defaultMargins : {left:0,top:0,right:0,bottom:0},
14581 defaultNSCMargins : {left:5,top:5,right:5,bottom:5},
14582 defaultEWCMargins : {left:5,top:0,right:5,bottom:0},
14585 isCollapsed : false,
14591 render : function(ct, p){
14592 this.panel = p;
14593 p.el.enableDisplayMode();
14594 this.targetEl = ct;
14595 this.el = p.el;
14597 var gs = p.getState, ps = this.position;
14598 p.getState = function(){
14599 return Ext.apply(gs.call(p) || {}, this.state);
14600 }.createDelegate(this);
14602 if(ps != 'center'){
14603 p.allowQueuedExpand = false;
14604 p.on({
14605 beforecollapse: this.beforeCollapse,
14606 collapse: this.onCollapse,
14607 beforeexpand: this.beforeExpand,
14608 expand: this.onExpand,
14609 hide: this.onHide,
14610 show: this.onShow,
14611 scope: this
14612 });
14613 if(this.collapsible){
14614 p.collapseEl = 'el';
14615 p.slideAnchor = this.getSlideAnchor();
14617 if(p.tools && p.tools.toggle){
14618 p.tools.toggle.addClass('x-tool-collapse-'+ps);
14619 p.tools.toggle.addClassOnOver('x-tool-collapse-'+ps+'-over');
14622 },
14624 getCollapsedEl : function(){
14625 if(!this.collapsedEl){
14626 if(!this.toolTemplate){
14627 var tt = new Ext.Template(
14628 '<div class="x-tool x-tool-{id}">&#160;</div>'
14629 );
14630 tt.disableFormats = true;
14631 tt.compile();
14632 Ext.layout.BorderLayout.Region.prototype.toolTemplate = tt;
14634 this.collapsedEl = this.targetEl.createChild({
14635 cls: "x-layout-collapsed x-layout-collapsed-"+this.position,
14636 id: this.panel.id + '-xcollapsed'
14637 });
14638 this.collapsedEl.enableDisplayMode('block');
14640 if(this.collapseMode == 'mini'){
14641 this.collapsedEl.addClass('x-layout-cmini-'+this.position);
14642 this.miniCollapsedEl = this.collapsedEl.createChild({
14643 cls: "x-layout-mini x-layout-mini-"+this.position, html: "&#160;"
14644 });
14645 this.miniCollapsedEl.addClassOnOver('x-layout-mini-over');
14646 this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
14647 this.collapsedEl.on('click', this.onExpandClick, this, {stopEvent:true});
14648 }else {
14649 var t = this.toolTemplate.append(
14650 this.collapsedEl.dom,
14651 {id:'expand-'+this.position}, true);
14652 t.addClassOnOver('x-tool-expand-'+this.position+'-over');
14653 t.on('click', this.onExpandClick, this, {stopEvent:true});
14655 if(this.floatable !== false){
14656 this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
14657 this.collapsedEl.on("click", this.collapseClick, this);
14661 return this.collapsedEl;
14662 },
14664 onExpandClick : function(e){
14665 if(this.isSlid){
14666 this.afterSlideIn();
14667 this.panel.expand(false);
14668 }else{
14669 this.panel.expand();
14671 },
14673 onCollapseClick : function(e){
14674 this.panel.collapse();
14675 },
14677 beforeCollapse : function(p, animate){
14678 this.lastAnim = animate;
14679 if(this.splitEl){
14680 this.splitEl.hide();
14682 this.getCollapsedEl().show();
14683 this.panel.el.setStyle('z-index', 100);
14684 this.isCollapsed = true;
14685 this.layout.layout();
14686 },
14688 onCollapse : function(animate){
14689 this.panel.el.setStyle('z-index', 1);
14690 if(this.lastAnim === false || this.panel.animCollapse === false){
14691 this.getCollapsedEl().dom.style.visibility = 'visible';
14692 }else{
14693 this.getCollapsedEl().slideIn(this.panel.slideAnchor, {duration:.2});
14695 this.state.collapsed = true;
14696 this.panel.saveState();
14697 },
14699 beforeExpand : function(animate){
14700 var c = this.getCollapsedEl();
14701 this.el.show();
14702 if(this.position == 'east' || this.position == 'west'){
14703 this.panel.setSize(undefined, c.getHeight());
14704 }else{
14705 this.panel.setSize(c.getWidth(), undefined);
14707 c.hide();
14708 c.dom.style.visibility = 'hidden';
14709 this.panel.el.setStyle('z-index', 100);
14710 },
14712 onExpand : function(){
14713 this.isCollapsed = false;
14714 if(this.splitEl){
14715 this.splitEl.show();
14717 this.layout.layout();
14718 this.panel.el.setStyle('z-index', 1);
14719 this.state.collapsed = false;
14720 this.panel.saveState();
14721 },
14723 collapseClick : function(e){
14724 if(this.isSlid){
14725 e.stopPropagation();
14726 this.slideIn();
14727 }else{
14728 e.stopPropagation();
14729 this.slideOut();
14731 },
14733 onHide : function(){
14734 if(this.isCollapsed){
14735 this.getCollapsedEl().hide();
14736 }else if(this.splitEl){
14737 this.splitEl.hide();
14739 },
14741 onShow : function(){
14742 if(this.isCollapsed){
14743 this.getCollapsedEl().show();
14744 }else if(this.splitEl){
14745 this.splitEl.show();
14747 },
14750 isVisible : function(){
14751 return !this.panel.hidden;
14752 },
14755 getMargins : function(){
14756 return this.isCollapsed && this.cmargins ? this.cmargins : this.margins;
14757 },
14760 getSize : function(){
14761 return this.isCollapsed ? this.getCollapsedEl().getSize() : this.panel.getSize();
14762 },
14765 setPanel : function(panel){
14766 this.panel = panel;
14767 },
14770 getMinWidth: function(){
14771 return this.minWidth;
14772 },
14775 getMinHeight: function(){
14776 return this.minHeight;
14777 },
14779 applyLayoutCollapsed : function(box){
14780 var ce = this.getCollapsedEl();
14781 ce.setLeftTop(box.x, box.y);
14782 ce.setSize(box.width, box.height);
14783 },
14785 applyLayout : function(box){
14786 if(this.isCollapsed){
14787 this.applyLayoutCollapsed(box);
14788 }else{
14789 this.panel.setPosition(box.x, box.y);
14790 this.panel.setSize(box.width, box.height);
14792 },
14794 beforeSlide: function(){
14795 this.panel.beforeEffect();
14796 },
14798 afterSlide : function(){
14799 this.panel.afterEffect();
14800 },
14802 initAutoHide : function(){
14803 if(this.autoHide !== false){
14804 if(!this.autoHideHd){
14805 var st = new Ext.util.DelayedTask(this.slideIn, this);
14806 this.autoHideHd = {
14807 "mouseout": function(e){
14808 if(!e.within(this.el, true)){
14809 st.delay(500);
14811 },
14812 "mouseover" : function(e){
14813 st.cancel();
14814 },
14815 scope : this
14816 };
14818 this.el.on(this.autoHideHd);
14820 },
14822 clearAutoHide : function(){
14823 if(this.autoHide !== false){
14824 this.el.un("mouseout", this.autoHideHd.mouseout);
14825 this.el.un("mouseover", this.autoHideHd.mouseover);
14827 },
14829 clearMonitor : function(){
14830 Ext.getDoc().un("click", this.slideInIf, this);
14831 },
14833 slideOut : function(){
14834 if(this.isSlid || this.el.hasActiveFx()){
14835 return;
14837 this.isSlid = true;
14838 var ts = this.panel.tools;
14839 if(ts && ts.toggle){
14840 ts.toggle.hide();
14842 this.el.show();
14843 if(this.position == 'east' || this.position == 'west'){
14844 this.panel.setSize(undefined, this.collapsedEl.getHeight());
14845 }else{
14846 this.panel.setSize(this.collapsedEl.getWidth(), undefined);
14848 this.restoreLT = [this.el.dom.style.left, this.el.dom.style.top];
14849 this.el.alignTo(this.collapsedEl, this.getCollapseAnchor());
14850 this.el.setStyle("z-index", 102);
14851 if(this.animFloat !== false){
14852 this.beforeSlide();
14853 this.el.slideIn(this.getSlideAnchor(), {
14854 callback: function(){
14855 this.afterSlide();
14856 this.initAutoHide();
14857 Ext.getDoc().on("click", this.slideInIf, this);
14858 },
14859 scope: this,
14860 block: true
14861 });
14862 }else{
14863 this.initAutoHide();
14864 Ext.getDoc().on("click", this.slideInIf, this);
14866 },
14868 afterSlideIn : function(){
14869 this.clearAutoHide();
14870 this.isSlid = false;
14871 this.clearMonitor();
14872 this.el.setStyle("z-index", "");
14873 this.el.dom.style.left = this.restoreLT[0];
14874 this.el.dom.style.top = this.restoreLT[1];
14876 var ts = this.panel.tools;
14877 if(ts && ts.toggle){
14878 ts.toggle.show();
14880 },
14882 slideIn : function(cb){
14883 if(!this.isSlid || this.el.hasActiveFx()){
14884 Ext.callback(cb);
14885 return;
14887 this.isSlid = false;
14888 if(this.animFloat !== false){
14889 this.beforeSlide();
14890 this.el.slideOut(this.getSlideAnchor(), {
14891 callback: function(){
14892 this.el.hide();
14893 this.afterSlide();
14894 this.afterSlideIn();
14895 Ext.callback(cb);
14896 },
14897 scope: this,
14898 block: true
14899 });
14900 }else{
14901 this.el.hide();
14902 this.afterSlideIn();
14904 },
14906 slideInIf : function(e){
14907 if(!e.within(this.el)){
14908 this.slideIn();
14910 },
14912 anchors : {
14913 "west" : "left",
14914 "east" : "right",
14915 "north" : "top",
14916 "south" : "bottom"
14917 },
14919 sanchors : {
14920 "west" : "l",
14921 "east" : "r",
14922 "north" : "t",
14923 "south" : "b"
14924 },
14926 canchors : {
14927 "west" : "tl-tr",
14928 "east" : "tr-tl",
14929 "north" : "tl-bl",
14930 "south" : "bl-tl"
14931 },
14933 getAnchor : function(){
14934 return this.anchors[this.position];
14935 },
14937 getCollapseAnchor : function(){
14938 return this.canchors[this.position];
14939 },
14941 getSlideAnchor : function(){
14942 return this.sanchors[this.position];
14943 },
14945 getAlignAdj : function(){
14946 var cm = this.cmargins;
14947 switch(this.position){
14948 case "west":
14949 return [0, 0];
14950 break;
14951 case "east":
14952 return [0, 0];
14953 break;
14954 case "north":
14955 return [0, 0];
14956 break;
14957 case "south":
14958 return [0, 0];
14959 break;
14961 },
14963 getExpandAdj : function(){
14964 var c = this.collapsedEl, cm = this.cmargins;
14965 switch(this.position){
14966 case "west":
14967 return [-(cm.right+c.getWidth()+cm.left), 0];
14968 break;
14969 case "east":
14970 return [cm.right+c.getWidth()+cm.left, 0];
14971 break;
14972 case "north":
14973 return [0, -(cm.top+cm.bottom+c.getHeight())];
14974 break;
14975 case "south":
14976 return [0, cm.top+cm.bottom+c.getHeight()];
14977 break;
14980 };
14983 Ext.layout.BorderLayout.SplitRegion = function(layout, config, pos){
14984 Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this, layout, config, pos);
14985 this.applyLayout = this.applyFns[pos];
14986 };
14988 Ext.extend(Ext.layout.BorderLayout.SplitRegion, Ext.layout.BorderLayout.Region, {
14990 splitTip : "Drag to resize.",
14992 collapsibleSplitTip : "Drag to resize. Double click to hide.",
14994 useSplitTips : false,
14996 splitSettings : {
14997 north : {
14998 orientation: Ext.SplitBar.VERTICAL,
14999 placement: Ext.SplitBar.TOP,
15000 maxFn : 'getVMaxSize',
15001 minProp: 'minHeight',
15002 maxProp: 'maxHeight'
15003 },
15004 south : {
15005 orientation: Ext.SplitBar.VERTICAL,
15006 placement: Ext.SplitBar.BOTTOM,
15007 maxFn : 'getVMaxSize',
15008 minProp: 'minHeight',
15009 maxProp: 'maxHeight'
15010 },
15011 east : {
15012 orientation: Ext.SplitBar.HORIZONTAL,
15013 placement: Ext.SplitBar.RIGHT,
15014 maxFn : 'getHMaxSize',
15015 minProp: 'minWidth',
15016 maxProp: 'maxWidth'
15017 },
15018 west : {
15019 orientation: Ext.SplitBar.HORIZONTAL,
15020 placement: Ext.SplitBar.LEFT,
15021 maxFn : 'getHMaxSize',
15022 minProp: 'minWidth',
15023 maxProp: 'maxWidth'
15025 },
15027 applyFns : {
15028 west : function(box){
15029 if(this.isCollapsed){
15030 return this.applyLayoutCollapsed(box);
15032 var sd = this.splitEl.dom, s = sd.style;
15033 this.panel.setPosition(box.x, box.y);
15034 var sw = sd.offsetWidth;
15035 s.left = (box.x+box.width-sw)+'px';
15036 s.top = (box.y)+'px';
15037 s.height = Math.max(0, box.height)+'px';
15038 this.panel.setSize(box.width-sw, box.height);
15039 },
15040 east : function(box){
15041 if(this.isCollapsed){
15042 return this.applyLayoutCollapsed(box);
15044 var sd = this.splitEl.dom, s = sd.style;
15045 var sw = sd.offsetWidth;
15046 this.panel.setPosition(box.x+sw, box.y);
15047 s.left = (box.x)+'px';
15048 s.top = (box.y)+'px';
15049 s.height = Math.max(0, box.height)+'px';
15050 this.panel.setSize(box.width-sw, box.height);
15051 },
15052 north : function(box){
15053 if(this.isCollapsed){
15054 return this.applyLayoutCollapsed(box);
15056 var sd = this.splitEl.dom, s = sd.style;
15057 var sh = sd.offsetHeight;
15058 this.panel.setPosition(box.x, box.y);
15059 s.left = (box.x)+'px';
15060 s.top = (box.y+box.height-sh)+'px';
15061 s.width = Math.max(0, box.width)+'px';
15062 this.panel.setSize(box.width, box.height-sh);
15063 },
15064 south : function(box){
15065 if(this.isCollapsed){
15066 return this.applyLayoutCollapsed(box);
15068 var sd = this.splitEl.dom, s = sd.style;
15069 var sh = sd.offsetHeight;
15070 this.panel.setPosition(box.x, box.y+sh);
15071 s.left = (box.x)+'px';
15072 s.top = (box.y)+'px';
15073 s.width = Math.max(0, box.width)+'px';
15074 this.panel.setSize(box.width, box.height-sh);
15076 },
15078 render : function(ct, p){
15079 Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p);
15081 var ps = this.position;
15083 this.splitEl = ct.createChild({
15084 cls: "x-layout-split x-layout-split-"+ps, html: "&#160;",
15085 id: this.panel.id + '-xsplit'
15086 });
15088 if(this.collapseMode == 'mini'){
15089 this.miniSplitEl = this.splitEl.createChild({
15090 cls: "x-layout-mini x-layout-mini-"+ps, html: "&#160;"
15091 });
15092 this.miniSplitEl.addClassOnOver('x-layout-mini-over');
15093 this.miniSplitEl.on('click', this.onCollapseClick, this, {stopEvent:true});
15096 var s = this.splitSettings[ps];
15098 this.split = new Ext.SplitBar(this.splitEl.dom, p.el, s.orientation);
15099 this.split.placement = s.placement;
15100 this.split.getMaximumSize = this[s.maxFn].createDelegate(this);
15101 this.split.minSize = this.minSize || this[s.minProp];
15102 this.split.on("beforeapply", this.onSplitMove, this);
15103 this.split.useShim = this.useShim === true;
15104 this.maxSize = this.maxSize || this[s.maxProp];
15106 if(p.hidden){
15107 this.splitEl.hide();
15110 if(this.useSplitTips){
15111 this.splitEl.dom.title = this.collapsible ? this.collapsibleSplitTip : this.splitTip;
15113 if(this.collapsible){
15114 this.splitEl.on("dblclick", this.onCollapseClick, this);
15116 },
15118 getSize : function(){
15119 if(this.isCollapsed){
15120 return this.collapsedEl.getSize();
15122 var s = this.panel.getSize();
15123 if(this.position == 'north' || this.position == 'south'){
15124 s.height += this.splitEl.dom.offsetHeight;
15125 }else{
15126 s.width += this.splitEl.dom.offsetWidth;
15128 return s;
15129 },
15131 getHMaxSize : function(){
15132 var cmax = this.maxSize || 10000;
15133 var center = this.layout.center;
15134 return Math.min(cmax, (this.el.getWidth()+center.el.getWidth())-center.getMinWidth());
15135 },
15137 getVMaxSize : function(){
15138 var cmax = this.maxSize || 10000;
15139 var center = this.layout.center;
15140 return Math.min(cmax, (this.el.getHeight()+center.el.getHeight())-center.getMinHeight());
15141 },
15143 onSplitMove : function(split, newSize){
15144 var s = this.panel.getSize();
15145 this.lastSplitSize = newSize;
15146 if(this.position == 'north' || this.position == 'south'){
15147 this.panel.setSize(s.width, newSize);
15148 this.state.height = newSize;
15149 }else{
15150 this.panel.setSize(newSize, s.height);
15151 this.state.width = newSize;
15153 this.layout.layout();
15154 this.panel.saveState();
15155 return false;
15156 },
15159 getSplitBar : function(){
15160 return this.split;
15162 });
15164 Ext.Container.LAYOUTS['border'] = Ext.layout.BorderLayout;
15166 Ext.layout.FormLayout = Ext.extend(Ext.layout.AnchorLayout, {
15170 labelSeparator : ':',
15172 getAnchorViewSize : function(ct, target){
15173 return ct.body.getStyleSize();
15174 },
15176 setContainer : function(ct){
15177 Ext.layout.FormLayout.superclass.setContainer.call(this, ct);
15179 if(ct.labelAlign){
15180 ct.addClass('x-form-label-'+ct.labelAlign);
15183 if(ct.hideLabels){
15184 this.labelStyle = "display:none";
15185 this.elementStyle = "padding-left:0;";
15186 this.labelAdjust = 0;
15187 }else{
15188 this.labelSeparator = ct.labelSeparator || this.labelSeparator;
15189 ct.labelWidth = ct.labelWidth || 100;
15190 if(typeof ct.labelWidth == 'number'){
15191 var pad = (typeof ct.labelPad == 'number' ? ct.labelPad : 5);
15192 this.labelAdjust = ct.labelWidth+pad;
15193 this.labelStyle = "width:"+ct.labelWidth+"px;";
15194 this.elementStyle = "padding-left:"+(ct.labelWidth+pad)+'px';
15196 if(ct.labelAlign == 'top'){
15197 this.labelStyle = "width:auto;";
15198 this.labelAdjust = 0;
15199 this.elementStyle = "padding-left:0;";
15203 if(!this.fieldTpl){
15204 var t = new Ext.Template(
15205 '<div class="x-form-item {5}" tabIndex="-1">',
15206 '<label for="{0}" style="{2}" class="x-form-item-label">{1}{4}</label>',
15207 '<div class="x-form-element" id="x-form-el-{0}" style="{3}">',
15208 '</div><div class="{6}"></div>',
15209 '</div>'
15210 );
15211 t.disableFormats = true;
15212 t.compile();
15213 Ext.layout.FormLayout.prototype.fieldTpl = t;
15215 },
15217 renderItem : function(c, position, target){
15218 if(c && !c.rendered && c.isFormField && c.inputType != 'hidden'){
15219 var args = [
15220 c.id, c.fieldLabel,
15221 c.labelStyle||this.labelStyle||'',
15222 this.elementStyle||'',
15223 typeof c.labelSeparator == 'undefined' ? this.labelSeparator : c.labelSeparator,
15224 (c.itemCls||this.container.itemCls||'') + (c.hideLabel ? ' x-hide-label' : ''),
15225 c.clearCls || 'x-form-clear-left'
15226 ];
15227 if(typeof position == 'number'){
15228 position = target.dom.childNodes[position] || null;
15230 if(position){
15231 this.fieldTpl.insertBefore(position, args);
15232 }else{
15233 this.fieldTpl.append(target, args);
15235 c.render('x-form-el-'+c.id);
15236 }else {
15237 Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
15239 },
15241 adjustWidthAnchor : function(value, comp){
15242 return value - (comp.isFormField ? (comp.hideLabel ? 0 : this.labelAdjust) : 0);
15243 },
15245 isValidParent : function(c, target){
15246 return true;
15250 });
15252 Ext.Container.LAYOUTS['form'] = Ext.layout.FormLayout;
15254 Ext.layout.Accordion = Ext.extend(Ext.layout.FitLayout, {
15256 fill : true,
15258 autoWidth : true,
15260 titleCollapse : true,
15262 hideCollapseTool : false,
15264 collapseFirst : false,
15266 animate : false,
15268 sequence : false,
15270 activeOnTop : false,
15272 renderItem : function(c){
15273 if(this.animate === false){
15274 c.animCollapse = false;
15276 c.collapsible = true;
15277 if(this.autoWidth){
15278 c.autoWidth = true;
15280 if(this.titleCollapse){
15281 c.titleCollapse = true;
15283 if(this.hideCollapseTool){
15284 c.hideCollapseTool = true;
15286 if(this.collapseFirst !== undefined){
15287 c.collapseFirst = this.collapseFirst;
15289 if(!this.activeItem && !c.collapsed){
15290 this.activeItem = c;
15291 }else if(this.activeItem){
15292 c.collapsed = true;
15294 Ext.layout.Accordion.superclass.renderItem.apply(this, arguments);
15295 c.header.addClass('x-accordion-hd');
15296 c.on('beforeexpand', this.beforeExpand, this);
15297 },
15300 beforeExpand : function(p, anim){
15301 var ai = this.activeItem;
15302 if(ai){
15303 if(this.sequence){
15304 delete this.activeItem;
15305 if (!ai.collapsed){
15306 ai.collapse({callback:function(){
15307 p.expand(anim || true);
15308 }, scope: this});
15309 return false;
15311 }else{
15312 ai.collapse(this.animate);
15315 this.activeItem = p;
15316 if(this.activeOnTop){
15317 p.el.dom.parentNode.insertBefore(p.el.dom, p.el.dom.parentNode.firstChild);
15319 this.layout();
15320 },
15323 setItemSize : function(item, size){
15324 if(this.fill && item){
15325 var items = this.container.items.items;
15326 var hh = 0;
15327 for(var i = 0, len = items.length; i < len; i++){
15328 var p = items[i];
15329 if(p != item){
15330 hh += (p.getSize().height - p.bwrap.getHeight());
15333 size.height -= hh;
15334 item.setSize(size);
15337 });
15338 Ext.Container.LAYOUTS['accordion'] = Ext.layout.Accordion;
15340 Ext.layout.TableLayout = Ext.extend(Ext.layout.ContainerLayout, {
15344 monitorResize:false,
15347 setContainer : function(ct){
15348 Ext.layout.TableLayout.superclass.setContainer.call(this, ct);
15350 this.currentRow = 0;
15351 this.currentColumn = 0;
15352 this.cells = [];
15353 },
15356 onLayout : function(ct, target){
15357 var cs = ct.items.items, len = cs.length, c, i;
15359 if(!this.table){
15360 target.addClass('x-table-layout-ct');
15362 this.table = target.createChild(
15363 {tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, null, true);
15365 this.renderAll(ct, target);
15367 },
15370 getRow : function(index){
15371 var row = this.table.tBodies[0].childNodes[index];
15372 if(!row){
15373 row = document.createElement('tr');
15374 this.table.tBodies[0].appendChild(row);
15376 return row;
15377 },
15380 getNextCell : function(c){
15381 var cell = this.getNextNonSpan(this.currentColumn, this.currentRow);
15382 var curCol = this.currentColumn = cell[0], curRow = this.currentRow = cell[1];
15383 for(var rowIndex = curRow; rowIndex < curRow + (c.rowspan || 1); rowIndex++){
15384 if(!this.cells[rowIndex]){
15385 this.cells[rowIndex] = [];
15387 for(var colIndex = curCol; colIndex < curCol + (c.colspan || 1); colIndex++){
15388 this.cells[rowIndex][colIndex] = true;
15391 var td = document.createElement('td');
15392 if(c.cellId){
15393 td.id = c.cellId;
15395 var cls = 'x-table-layout-cell';
15396 if(c.cellCls){
15397 cls += ' ' + c.cellCls;
15399 td.className = cls;
15400 if(c.colspan){
15401 td.colSpan = c.colspan;
15403 if(c.rowspan){
15404 td.rowSpan = c.rowspan;
15406 this.getRow(curRow).appendChild(td);
15407 return td;
15408 },
15411 getNextNonSpan: function(colIndex, rowIndex){
15412 var cols = this.columns;
15413 while((cols && colIndex >= cols) || (this.cells[rowIndex] && this.cells[rowIndex][colIndex])) {
15414 if(cols && colIndex >= cols){
15415 rowIndex++;
15416 colIndex = 0;
15417 }else{
15418 colIndex++;
15421 return [colIndex, rowIndex];
15422 },
15425 renderItem : function(c, position, target){
15426 if(c && !c.rendered){
15427 c.render(this.getNextCell(c));
15429 },
15432 isValidParent : function(c, target){
15433 return true;
15437 });
15439 Ext.Container.LAYOUTS['table'] = Ext.layout.TableLayout;
15441 Ext.layout.AbsoluteLayout = Ext.extend(Ext.layout.AnchorLayout, {
15442 extraCls: 'x-abs-layout-item',
15443 isForm: false,
15445 setContainer : function(ct){
15446 Ext.layout.AbsoluteLayout.superclass.setContainer.call(this, ct);
15447 if(ct.isXType('form')){
15448 this.isForm = true;
15450 },
15452 onLayout : function(ct, target){
15453 if(this.isForm){ ct.body.position(); } else { target.position(); }
15454 Ext.layout.AbsoluteLayout.superclass.onLayout.call(this, ct, target);
15455 },
15458 getAnchorViewSize : function(ct, target){
15459 return this.isForm ? ct.body.getStyleSize() : Ext.layout.AbsoluteLayout.superclass.getAnchorViewSize.call(this, ct, target);
15460 },
15463 isValidParent : function(c, target){
15464 return this.isForm ? true : Ext.layout.AbsoluteLayout.superclass.isValidParent.call(this, c, target);
15465 },
15468 adjustWidthAnchor : function(value, comp){
15469 return value ? value - comp.getPosition(true)[0] : value;
15470 },
15473 adjustHeightAnchor : function(value, comp){
15474 return value ? value - comp.getPosition(true)[1] : value;
15477 });
15478 Ext.Container.LAYOUTS['absolute'] = Ext.layout.AbsoluteLayout;
15480 Ext.Viewport = Ext.extend(Ext.Container, {
15493 initComponent : function() {
15494 Ext.Viewport.superclass.initComponent.call(this);
15495 document.getElementsByTagName('html')[0].className += ' x-viewport';
15496 this.el = Ext.getBody();
15497 this.el.setHeight = Ext.emptyFn;
15498 this.el.setWidth = Ext.emptyFn;
15499 this.el.setSize = Ext.emptyFn;
15500 this.el.dom.scroll = 'no';
15501 this.allowDomMove = false;
15502 this.autoWidth = true;
15503 this.autoHeight = true;
15504 Ext.EventManager.onWindowResize(this.fireResize, this);
15505 this.renderTo = this.el;
15506 },
15508 fireResize : function(w, h){
15509 this.fireEvent('resize', this, w, h, w, h);
15511 });
15512 Ext.reg('viewport', Ext.Viewport);
15514 Ext.Panel = Ext.extend(Ext.Container, {
15548 baseCls : 'x-panel',
15550 collapsedCls : 'x-panel-collapsed',
15552 maskDisabled: true,
15554 animCollapse: Ext.enableFx,
15556 headerAsText: true,
15558 buttonAlign: 'right',
15560 collapsed : false,
15562 collapseFirst: true,
15564 minButtonWidth:75,
15566 elements : 'body',
15568 toolTarget : 'header',
15569 collapseEl : 'bwrap',
15570 slideAnchor : 't',
15572 deferHeight: true,
15573 expandDefaults: {
15574 duration:.25
15575 },
15576 collapseDefaults: {
15577 duration:.25
15578 },
15580 initComponent : function(){
15581 Ext.Panel.superclass.initComponent.call(this);
15583 this.addEvents(
15585 'bodyresize',
15587 'titlechange',
15589 'collapse',
15591 'expand',
15593 'beforecollapse',
15595 'beforeexpand',
15597 'beforeclose',
15599 'close',
15601 'activate',
15603 'deactivate'
15604 );
15606 if(this.tbar){
15607 this.elements += ',tbar';
15608 if(typeof this.tbar == 'object'){
15609 this.topToolbar = this.tbar;
15611 delete this.tbar;
15613 if(this.bbar){
15614 this.elements += ',bbar';
15615 if(typeof this.bbar == 'object'){
15616 this.bottomToolbar = this.bbar;
15618 delete this.bbar;
15621 if(this.header === true){
15622 this.elements += ',header';
15623 delete this.header;
15624 }else if(this.title && this.header !== false){
15625 this.elements += ',header';
15628 if(this.footer === true){
15629 this.elements += ',footer';
15630 delete this.footer;
15633 if(this.buttons){
15634 var btns = this.buttons;
15636 this.buttons = [];
15637 for(var i = 0, len = btns.length; i < len; i++) {
15638 if(btns[i].render){ this.buttons.push(btns[i]);
15639 }else{
15640 this.addButton(btns[i]);
15644 if(this.autoLoad){
15645 this.on('render', this.doAutoLoad, this, {delay:10});
15647 },
15649 createElement : function(name, pnode){
15650 if(this[name]){
15651 pnode.appendChild(this[name].dom);
15652 return;
15655 if(name === 'bwrap' || this.elements.indexOf(name) != -1){
15656 if(this[name+'Cfg']){
15657 this[name] = Ext.fly(pnode).createChild(this[name+'Cfg']);
15658 }else{
15659 var el = document.createElement('div');
15660 el.className = this[name+'Cls'];
15661 this[name] = Ext.get(pnode.appendChild(el));
15664 },
15666 onRender : function(ct, position){
15667 Ext.Panel.superclass.onRender.call(this, ct, position);
15669 this.createClasses();
15671 if(this.el){ this.el.addClass(this.baseCls);
15672 this.header = this.el.down('.'+this.headerCls);
15673 this.bwrap = this.el.down('.'+this.bwrapCls);
15674 var cp = this.bwrap ? this.bwrap : this.el;
15675 this.tbar = cp.down('.'+this.tbarCls);
15676 this.body = cp.down('.'+this.bodyCls);
15677 this.bbar = cp.down('.'+this.bbarCls);
15678 this.footer = cp.down('.'+this.footerCls);
15679 this.fromMarkup = true;
15680 }else{
15681 this.el = ct.createChild({
15682 id: this.id,
15683 cls: this.baseCls
15684 }, position);
15686 var el = this.el, d = el.dom;
15688 if(this.cls){
15689 this.el.addClass(this.cls);
15692 if(this.buttons){
15693 this.elements += ',footer';
15697 if(this.frame){
15698 el.insertHtml('afterBegin', String.format(Ext.Element.boxMarkup, this.baseCls));
15700 this.createElement('header', d.firstChild.firstChild.firstChild);
15701 this.createElement('bwrap', d);
15703 var bw = this.bwrap.dom;
15704 var ml = d.childNodes[1], bl = d.childNodes[2];
15705 bw.appendChild(ml);
15706 bw.appendChild(bl);
15708 var mc = bw.firstChild.firstChild.firstChild;
15709 this.createElement('tbar', mc);
15710 this.createElement('body', mc);
15711 this.createElement('bbar', mc);
15712 this.createElement('footer', bw.lastChild.firstChild.firstChild);
15714 if(!this.footer){
15715 this.bwrap.dom.lastChild.className += ' x-panel-nofooter';
15717 }else{
15718 this.createElement('header', d);
15719 this.createElement('bwrap', d);
15721 var bw = this.bwrap.dom;
15722 this.createElement('tbar', bw);
15723 this.createElement('body', bw);
15724 this.createElement('bbar', bw);
15725 this.createElement('footer', bw);
15727 if(!this.header){
15728 this.body.addClass(this.bodyCls + '-noheader');
15729 if(this.tbar){
15730 this.tbar.addClass(this.tbarCls + '-noheader');
15735 if(this.border === false){
15736 this.el.addClass(this.baseCls + '-noborder');
15737 this.body.addClass(this.bodyCls + '-noborder');
15738 if(this.header){
15739 this.header.addClass(this.headerCls + '-noborder');
15741 if(this.footer){
15742 this.footer.addClass(this.footerCls + '-noborder');
15744 if(this.tbar){
15745 this.tbar.addClass(this.tbarCls + '-noborder');
15747 if(this.bbar){
15748 this.bbar.addClass(this.bbarCls + '-noborder');
15752 if(this.bodyBorder === false){
15753 this.body.addClass(this.bodyCls + '-noborder');
15756 if(this.bodyStyle){
15757 this.body.applyStyles(this.bodyStyle);
15760 this.bwrap.enableDisplayMode('block');
15762 if(this.header){
15763 this.header.unselectable();
15765 if(this.headerAsText){
15766 this.header.dom.innerHTML =
15767 '<span class="' + this.headerTextCls + '">'+this.header.dom.innerHTML+'</span>';
15769 if(this.iconCls){
15770 this.setIconClass(this.iconCls);
15775 if(this.floating){
15776 this.makeFloating(this.floating);
15779 if(this.collapsible){
15780 this.tools = this.tools ? this.tools.slice(0) : [];
15781 if(!this.hideCollapseTool){
15782 this.tools[this.collapseFirst?'unshift':'push']({
15783 id: 'toggle',
15784 handler : this.toggleCollapse,
15785 scope: this
15786 });
15788 if(this.titleCollapse && this.header){
15789 this.header.on('click', this.toggleCollapse, this);
15790 this.header.setStyle('cursor', 'pointer');
15793 if(this.tools){
15794 var ts = this.tools;
15795 this.tools = {};
15796 this.addTool.apply(this, ts);
15797 }else{
15798 this.tools = {};
15801 if(this.buttons && this.buttons.length > 0){
15802 var tb = this.footer.createChild({cls:'x-panel-btns-ct', cn: {
15803 cls:"x-panel-btns x-panel-btns-"+this.buttonAlign,
15804 html:'<table cellspacing="0"><tbody><tr></tr></tbody></table><div class="x-clear"></div>'
15805 }}, null, true);
15806 var tr = tb.getElementsByTagName('tr')[0];
15807 for(var i = 0, len = this.buttons.length; i < len; i++) {
15808 var b = this.buttons[i];
15809 var td = document.createElement('td');
15810 td.className = 'x-panel-btn-td';
15811 b.render(tr.appendChild(td));
15815 if(this.tbar && this.topToolbar){
15816 if(Ext.isArray(this.topToolbar)){
15817 this.topToolbar = new Ext.Toolbar(this.topToolbar);
15819 this.topToolbar.render(this.tbar);
15820 this.topToolbar.ownerCt = this;
15822 if(this.bbar && this.bottomToolbar){
15823 if(Ext.isArray(this.bottomToolbar)){
15824 this.bottomToolbar = new Ext.Toolbar(this.bottomToolbar);
15826 this.bottomToolbar.render(this.bbar);
15827 this.bottomToolbar.ownerCt = this;
15829 },
15832 setIconClass : function(cls){
15833 var old = this.iconCls;
15834 this.iconCls = cls;
15835 if(this.rendered && this.header){
15836 if(this.frame){
15837 this.header.addClass('x-panel-icon');
15838 this.header.replaceClass(old, this.iconCls);
15839 }else{
15840 var hd = this.header.dom;
15841 var img = hd.firstChild && String(hd.firstChild.tagName).toLowerCase() == 'img' ? hd.firstChild : null;
15842 if(img){
15843 Ext.fly(img).replaceClass(old, this.iconCls);
15844 }else{
15845 Ext.DomHelper.insertBefore(hd.firstChild, {
15846 tag:'img', src: Ext.BLANK_IMAGE_URL, cls:'x-panel-inline-icon '+this.iconCls
15847 });
15851 },
15853 makeFloating : function(cfg){
15854 this.floating = true;
15855 this.el = new Ext.Layer(
15856 typeof cfg == 'object' ? cfg : {
15857 shadow: this.shadow !== undefined ? this.shadow : 'sides',
15858 shadowOffset: this.shadowOffset,
15859 constrain:false,
15860 shim: this.shim === false ? false : undefined
15861 }, this.el
15862 );
15863 },
15866 getTopToolbar : function(){
15867 return this.topToolbar;
15868 },
15871 getBottomToolbar : function(){
15872 return this.bottomToolbar;
15873 },
15876 addButton : function(config, handler, scope){
15877 var bc = {
15878 handler: handler,
15879 scope: scope,
15880 minWidth: this.minButtonWidth,
15881 hideParent:true
15882 };
15883 if(typeof config == "string"){
15884 bc.text = config;
15885 }else{
15886 Ext.apply(bc, config);
15888 var btn = new Ext.Button(bc);
15889 btn.ownerCt = this;
15890 if(!this.buttons){
15891 this.buttons = [];
15893 this.buttons.push(btn);
15894 return btn;
15895 },
15897 addTool : function(){
15898 if(!this[this.toolTarget]) { return;
15900 if(!this.toolTemplate){
15901 var tt = new Ext.Template(
15902 '<div class="x-tool x-tool-{id}">&#160;</div>'
15903 );
15904 tt.disableFormats = true;
15905 tt.compile();
15906 Ext.Panel.prototype.toolTemplate = tt;
15908 for(var i = 0, a = arguments, len = a.length; i < len; i++) {
15909 var tc = a[i], overCls = 'x-tool-'+tc.id+'-over';
15910 var t = this.toolTemplate.insertFirst((tc.align !== 'left') ? this[this.toolTarget] : this[this.toolTarget].child('span'), tc, true);
15911 this.tools[tc.id] = t;
15912 t.enableDisplayMode('block');
15913 t.on('click', this.createToolHandler(t, tc, overCls, this));
15914 if(tc.on){
15915 t.on(tc.on);
15917 if(tc.hidden){
15918 t.hide();
15920 if(tc.qtip){
15921 if(typeof tc.qtip == 'object'){
15922 Ext.QuickTips.register(Ext.apply({
15923 target: t.id
15924 }, tc.qtip));
15925 } else {
15926 t.dom.qtip = tc.qtip;
15929 t.addClassOnOver(overCls);
15931 },
15933 onShow : function(){
15934 if(this.floating){
15935 return this.el.show();
15937 Ext.Panel.superclass.onShow.call(this);
15938 },
15940 onHide : function(){
15941 if(this.floating){
15942 return this.el.hide();
15944 Ext.Panel.superclass.onHide.call(this);
15945 },
15947 createToolHandler : function(t, tc, overCls, panel){
15948 return function(e){
15949 t.removeClass(overCls);
15950 e.stopEvent();
15951 if(tc.handler){
15952 tc.handler.call(tc.scope || t, e, t, panel);
15954 };
15955 },
15957 afterRender : function(){
15958 if(this.fromMarkup && this.height === undefined && !this.autoHeight){
15959 this.height = this.el.getHeight();
15961 if(this.floating && !this.hidden && !this.initHidden){
15962 this.el.show();
15964 if(this.title){
15965 this.setTitle(this.title);
15967 this.setAutoScroll();
15968 if(this.html){
15969 this.body.update(typeof this.html == 'object' ?
15970 Ext.DomHelper.markup(this.html) :
15971 this.html);
15972 delete this.html;
15974 if(this.contentEl){
15975 var ce = Ext.getDom(this.contentEl);
15976 Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']);
15977 this.body.dom.appendChild(ce);
15979 if(this.collapsed){
15980 this.collapsed = false;
15981 this.collapse(false);
15983 Ext.Panel.superclass.afterRender.call(this); this.initEvents();
15984 },
15986 setAutoScroll : function(){
15987 if(this.rendered && this.autoScroll){
15988 this.body.setOverflow('auto');
15990 },
15992 getKeyMap : function(){
15993 if(!this.keyMap){
15994 this.keyMap = new Ext.KeyMap(this.el, this.keys);
15996 return this.keyMap;
15997 },
15999 initEvents : function(){
16000 if(this.keys){
16001 this.getKeyMap();
16003 if(this.draggable){
16004 this.initDraggable();
16006 },
16008 initDraggable : function(){
16010 this.dd = new Ext.Panel.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);
16011 },
16013 beforeEffect : function(){
16014 if(this.floating){
16015 this.el.beforeAction();
16017 this.el.addClass('x-panel-animated');
16018 },
16020 afterEffect : function(){
16021 this.syncShadow();
16022 this.el.removeClass('x-panel-animated');
16023 },
16025 createEffect : function(a, cb, scope){
16026 var o = {
16027 scope:scope,
16028 block:true
16029 };
16030 if(a === true){
16031 o.callback = cb;
16032 return o;
16033 }else if(!a.callback){
16034 o.callback = cb;
16035 }else { o.callback = function(){
16036 cb.call(scope);
16037 Ext.callback(a.callback, a.scope);
16038 };
16040 return Ext.applyIf(o, a);
16041 },
16044 collapse : function(animate){
16045 if(this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforecollapse', this, animate) === false){
16046 return;
16048 var doAnim = animate === true || (animate !== false && this.animCollapse);
16049 this.beforeEffect();
16050 this.onCollapse(doAnim, animate);
16051 return this;
16052 },
16054 onCollapse : function(doAnim, animArg){
16055 if(doAnim){
16056 this[this.collapseEl].slideOut(this.slideAnchor,
16057 Ext.apply(this.createEffect(animArg||true, this.afterCollapse, this),
16058 this.collapseDefaults));
16059 }else{
16060 this[this.collapseEl].hide();
16061 this.afterCollapse();
16063 },
16065 afterCollapse : function(){
16066 this.collapsed = true;
16067 this.el.addClass(this.collapsedCls);
16068 this.afterEffect();
16069 this.fireEvent('collapse', this);
16070 },
16073 expand : function(animate){
16074 if(!this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforeexpand', this, animate) === false){
16075 return;
16077 var doAnim = animate === true || (animate !== false && this.animCollapse);
16078 this.el.removeClass(this.collapsedCls);
16079 this.beforeEffect();
16080 this.onExpand(doAnim, animate);
16081 return this;
16082 },
16084 onExpand : function(doAnim, animArg){
16085 if(doAnim){
16086 this[this.collapseEl].slideIn(this.slideAnchor,
16087 Ext.apply(this.createEffect(animArg||true, this.afterExpand, this),
16088 this.expandDefaults));
16089 }else{
16090 this[this.collapseEl].show();
16091 this.afterExpand();
16093 },
16095 afterExpand : function(){
16096 this.collapsed = false;
16097 this.afterEffect();
16098 this.fireEvent('expand', this);
16099 },
16102 toggleCollapse : function(animate){
16103 this[this.collapsed ? 'expand' : 'collapse'](animate);
16104 return this;
16105 },
16107 onDisable : function(){
16108 if(this.rendered && this.maskDisabled){
16109 this.el.mask();
16111 Ext.Panel.superclass.onDisable.call(this);
16112 },
16114 onEnable : function(){
16115 if(this.rendered && this.maskDisabled){
16116 this.el.unmask();
16118 Ext.Panel.superclass.onEnable.call(this);
16119 },
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);
16137 }else{
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);
16144 this.doLayout();
16145 }, this, {single:true});
16148 this.fireEvent('bodyresize', this, w, h);
16150 this.syncShadow();
16151 },
16153 adjustBodyHeight : function(h){
16154 return h;
16155 },
16157 adjustBodyWidth : function(w){
16158 return w;
16159 },
16161 onPosition : function(){
16162 this.syncShadow();
16163 },
16165 onDestroy : function(){
16166 if(this.tools){
16167 for(var k in this.tools){
16168 Ext.destroy(this.tools[k]);
16171 if(this.buttons){
16172 for(var b in this.buttons){
16173 Ext.destroy(this.buttons[b]);
16176 Ext.destroy(
16177 this.topToolbar,
16178 this.bottomToolbar
16179 );
16180 Ext.Panel.superclass.onDestroy.call(this);
16181 },
16184 getFrameWidth : function(){
16185 var w = this.el.getFrameWidth('lr');
16187 if(this.frame){
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');
16193 return w;
16194 },
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);
16202 if(this.frame){
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');
16208 }else{
16209 h += (this.header ? this.header.getHeight() : 0) +
16210 (this.footer ? this.footer.getHeight() : 0);
16212 return h;
16213 },
16216 getInnerWidth : function(){
16217 return this.getSize().width - this.getFrameWidth();
16218 },
16221 getInnerHeight : function(){
16222 return this.getSize().height - this.getFrameHeight();
16223 },
16225 syncShadow : function(){
16226 if(this.floating){
16227 this.el.sync(true);
16229 },
16231 getLayoutTarget : function(){
16232 return this.body;
16233 },
16236 setTitle : function(title, iconCls){
16237 this.title = title;
16238 if(this.header && this.headerAsText){
16239 this.header.child('span').update(title);
16241 if(iconCls){
16242 this.setIconClass(iconCls);
16244 this.fireEvent('titlechange', this, title);
16245 return this;
16246 },
16249 getUpdater : function(){
16250 return this.body.getUpdater();
16251 },
16254 load : function(){
16255 var um = this.body.getUpdater();
16256 um.update.apply(um, arguments);
16257 return this;
16258 },
16260 beforeDestroy : function(){
16261 Ext.Element.uncache(
16262 this.header,
16263 this.tbar,
16264 this.bbar,
16265 this.footer,
16266 this.body
16267 );
16268 },
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';
16278 },
16280 createGhost : function(cls, useShim, appendTo){
16281 var el = document.createElement('div');
16282 el.className = 'x-panel-ghost ' + (cls ? cls : '');
16283 if(this.header){
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';;
16288 if(!appendTo){
16289 this.container.dom.appendChild(el);
16290 }else{
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);
16295 layer.show();
16296 return layer;
16297 }else{
16298 return new Ext.Element(el);
16300 },
16302 doAutoLoad : function(){
16303 this.body.load(
16304 typeof this.autoLoad == 'object' ?
16305 this.autoLoad : {url: this.autoLoad});
16309 });
16310 Ext.reg('panel', Ext.Panel);
16313 Ext.Window = Ext.extend(Ext.Panel, {
16323 baseCls : 'x-window',
16325 resizable:true,
16327 draggable:true,
16329 closable : true,
16331 constrain:false,
16333 constrainHeader:false,
16335 plain:false,
16337 minimizable : false,
16339 maximizable : false,
16341 minHeight: 100,
16343 minWidth: 200,
16345 expandOnShow: true,
16347 closeAction: 'close',
16349 elements: 'header,body',
16351 collapsible:false,
16353 initHidden : true,
16355 monitorResize : true,
16357 frame:true,
16359 floating:true,
16361 initComponent : function(){
16362 Ext.Window.superclass.initComponent.call(this);
16363 this.addEvents(
16367 'resize',
16369 'maximize',
16371 'minimize',
16373 'restore'
16374 );
16375 },
16377 getState : function(){
16378 return Ext.apply(Ext.Window.superclass.getState.call(this) || {}, this.getBox());
16379 },
16381 onRender : function(ct, position){
16382 Ext.Window.superclass.onRender.call(this, ct, position);
16384 if(this.plain){
16385 this.el.addClass('x-window-plain');
16388 this.focusEl = this.el.createChild({
16389 tag: "a", href:"#", cls:"x-dlg-focus",
16390 tabIndex:"-1", html: "&#160;"});
16391 this.focusEl.swallowEvent('click', true);
16393 this.proxy = this.el.createProxy("x-window-proxy");
16394 this.proxy.enableDisplayMode('block');
16396 if(this.modal){
16397 this.mask = this.container.createChild({cls:"ext-el-mask"}, this.el.dom);
16398 this.mask.enableDisplayMode("block");
16399 this.mask.hide();
16401 },
16403 initEvents : function(){
16404 Ext.Window.superclass.initEvents.call(this);
16405 if(this.animateTarget){
16406 this.setAnimateTarget(this.animateTarget);
16409 if(this.resizable){
16410 this.resizer = new Ext.Resizable(this.el, {
16411 minWidth: this.minWidth,
16412 minHeight:this.minHeight,
16413 handles: this.resizeHandles || "all",
16414 pinned: true,
16415 resizeElement : this.resizerAction
16416 });
16417 this.resizer.window = this;
16418 this.resizer.on("beforeresize", this.beforeResize, this);
16421 if(this.draggable){
16422 this.header.addClass("x-window-draggable");
16424 this.initTools();
16426 this.el.on("mousedown", this.toFront, this);
16427 this.manager = this.manager || Ext.WindowMgr;
16428 this.manager.register(this);
16429 this.hidden = true;
16430 if(this.maximized){
16431 this.maximized = false;
16432 this.maximize();
16434 if(this.closable){
16435 var km = this.getKeyMap();
16436 km.on(27, this.onEsc, this);
16437 km.disable();
16439 },
16441 initDraggable : function(){
16443 this.dd = new Ext.Window.DD(this);
16444 },
16446 onEsc : function(){
16447 this[this.closeAction]();
16448 },
16450 beforeDestroy : function(){
16451 Ext.destroy(
16452 this.resizer,
16453 this.dd,
16454 this.proxy,
16455 this.mask
16456 );
16457 Ext.Window.superclass.beforeDestroy.call(this);
16458 },
16460 onDestroy : function(){
16461 if(this.manager){
16462 this.manager.unregister(this);
16464 Ext.Window.superclass.onDestroy.call(this);
16465 },
16467 initTools : function(){
16468 if(this.minimizable){
16469 this.addTool({
16470 id: 'minimize',
16471 handler: this.minimize.createDelegate(this, [])
16472 });
16474 if(this.maximizable){
16475 this.addTool({
16476 id: 'maximize',
16477 handler: this.maximize.createDelegate(this, [])
16478 });
16479 this.addTool({
16480 id: 'restore',
16481 handler: this.restore.createDelegate(this, []),
16482 hidden:true
16483 });
16484 this.header.on('dblclick', this.toggleMaximize, this);
16486 if(this.closable){
16487 this.addTool({
16488 id: 'close',
16489 handler: this[this.closeAction].createDelegate(this, [])
16490 });
16492 },
16494 resizerAction : function(){
16495 var box = this.proxy.getBox();
16496 this.proxy.hide();
16497 this.window.handleResize(box);
16498 return box;
16499 },
16501 beforeResize : function(){
16502 this.resizer.minHeight = Math.max(this.minHeight, this.getFrameHeight() + 40); this.resizer.minWidth = Math.max(this.minWidth, this.getFrameWidth() + 40);
16503 this.resizeBox = this.el.getBox();
16504 },
16506 updateHandles : function(){
16507 if(Ext.isIE && this.resizer){
16508 this.resizer.syncHandleHeight();
16509 this.el.repaint();
16511 },
16513 handleResize : function(box){
16514 var rz = this.resizeBox;
16515 if(rz.x != box.x || rz.y != box.y){
16516 this.updateBox(box);
16517 }else{
16518 this.setSize(box);
16520 this.focus();
16521 this.updateHandles();
16522 this.saveState();
16523 this.fireEvent("resize", this, box.width, box.height);
16524 },
16527 focus : function(){
16528 var f = this.focusEl, db = this.defaultButton, t = typeof db;
16529 if(t != 'undefined'){
16530 if(t == 'number'){
16531 f = this.buttons[db];
16532 }else if(t == 'string'){
16533 f = Ext.getCmp(db);
16534 }else{
16535 f = db;
16538 f.focus.defer(10, f);
16539 },
16542 setAnimateTarget : function(el){
16543 el = Ext.get(el);
16544 this.animateTarget = el;
16545 },
16547 beforeShow : function(){
16548 delete this.el.lastXY;
16549 delete this.el.lastLT;
16550 if(this.x === undefined || this.y === undefined){
16551 var xy = this.el.getAlignToXY(this.container, 'c-c');
16552 var pos = this.el.translatePoints(xy[0], xy[1]);
16553 this.x = this.x === undefined? pos.left : this.x;
16554 this.y = this.y === undefined? pos.top : this.y;
16556 this.el.setLeftTop(this.x, this.y);
16558 if(this.expandOnShow){
16559 this.expand(false);
16562 if(this.modal){
16563 Ext.getBody().addClass("x-body-masked");
16564 this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
16565 this.mask.show();
16567 },
16570 show : function(animateTarget, cb, scope){
16571 if(!this.rendered){
16572 this.render(Ext.getBody());
16574 if(this.hidden === false){
16575 this.toFront();
16576 return;
16578 if(this.fireEvent("beforeshow", this) === false){
16579 return;
16581 if(cb){
16582 this.on('show', cb, scope, {single:true});
16584 this.hidden = false;
16585 if(animateTarget !== undefined){
16586 this.setAnimateTarget(animateTarget);
16588 this.beforeShow();
16589 if(this.animateTarget){
16590 this.animShow();
16591 }else{
16592 this.afterShow();
16594 },
16596 afterShow : function(){
16597 this.proxy.hide();
16598 this.el.setStyle('display', 'block');
16599 this.el.show();
16600 if(this.maximized){
16601 this.fitContainer();
16603 if(Ext.isMac && Ext.isGecko){ this.cascade(this.setAutoScroll);
16606 if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
16607 Ext.EventManager.onWindowResize(this.onWindowResize, this);
16609 this.doConstrain();
16610 if(this.layout){
16611 this.doLayout();
16613 if(this.keyMap){
16614 this.keyMap.enable();
16616 this.toFront();
16617 this.updateHandles();
16618 this.fireEvent("show", this);
16619 },
16621 animShow : function(){
16622 this.proxy.show();
16623 this.proxy.setBox(this.animateTarget.getBox());
16624 this.proxy.setOpacity(0);
16625 var b = this.getBox(false);
16626 b.callback = this.afterShow;
16627 b.scope = this;
16628 b.duration = .25;
16629 b.easing = 'easeNone';
16630 b.opacity = .5;
16631 b.block = true;
16632 this.el.setStyle('display', 'none');
16633 this.proxy.shift(b);
16634 },
16637 hide : function(animateTarget, cb, scope){
16638 if(this.hidden || this.fireEvent("beforehide", this) === false){
16639 return;
16641 if(cb){
16642 this.on('hide', cb, scope, {single:true});
16644 this.hidden = true;
16645 if(animateTarget !== undefined){
16646 this.setAnimateTarget(animateTarget);
16648 if(this.animateTarget){
16649 this.animHide();
16650 }else{
16651 this.el.hide();
16652 this.afterHide();
16654 },
16656 afterHide : function(){
16657 this.proxy.hide();
16658 if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
16659 Ext.EventManager.removeResizeListener(this.onWindowResize, this);
16661 if(this.modal){
16662 this.mask.hide();
16663 Ext.getBody().removeClass("x-body-masked");
16665 if(this.keyMap){
16666 this.keyMap.disable();
16668 this.fireEvent("hide", this);
16669 },
16671 animHide : function(){
16672 this.proxy.setOpacity(.5);
16673 this.proxy.show();
16674 var tb = this.getBox(false);
16675 this.proxy.setBox(tb);
16676 this.el.hide();
16677 var b = this.animateTarget.getBox();
16678 b.callback = this.afterHide;
16679 b.scope = this;
16680 b.duration = .25;
16681 b.easing = 'easeNone';
16682 b.block = true;
16683 b.opacity = 0;
16684 this.proxy.shift(b);
16685 },
16687 onWindowResize : function(){
16688 if(this.maximized){
16689 this.fitContainer();
16691 if(this.modal){
16692 this.mask.setSize('100%', '100%');
16693 var force = this.mask.dom.offsetHeight;
16694 this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
16696 this.doConstrain();
16697 },
16699 doConstrain : function(){
16700 if(this.constrain || this.constrainHeader){
16701 var offsets;
16702 if(this.constrain){
16703 offsets = {
16704 right:this.el.shadowOffset,
16705 left:this.el.shadowOffset,
16706 bottom:this.el.shadowOffset
16707 };
16708 }else {
16709 var s = this.getSize();
16710 offsets = {
16711 right:-(s.width - 100),
16712 bottom:-(s.height - 25)
16713 };
16716 var xy = this.el.getConstrainToXY(this.container, true, offsets);
16717 if(xy){
16718 this.setPosition(xy[0], xy[1]);
16721 },
16723 ghost : function(cls){
16724 var ghost = this.createGhost(cls);
16725 var box = this.getBox(true);
16726 ghost.setLeftTop(box.x, box.y);
16727 ghost.setWidth(box.width);
16728 this.el.hide();
16729 this.activeGhost = ghost;
16730 return ghost;
16731 },
16733 unghost : function(show, matchPosition){
16734 if(show !== false){
16735 this.el.show();
16736 this.focus();
16737 if(Ext.isMac && Ext.isGecko){ this.cascade(this.setAutoScroll);
16740 if(matchPosition !== false){
16741 this.setPosition(this.activeGhost.getLeft(true), this.activeGhost.getTop(true));
16743 this.activeGhost.hide();
16744 this.activeGhost.remove();
16745 delete this.activeGhost;
16746 },
16749 minimize : function(){
16750 this.fireEvent('minimize', this);
16751 },
16754 close : function(){
16755 if(this.fireEvent("beforeclose", this) !== false){
16756 this.hide(null, function(){
16757 this.fireEvent('close', this);
16758 this.destroy();
16759 }, this);
16761 },
16764 maximize : function(){
16765 if(!this.maximized){
16766 this.expand(false);
16767 this.restoreSize = this.getSize();
16768 this.restorePos = this.getPosition(true);
16769 if (this.maximizable){
16770 this.tools.maximize.hide();
16771 this.tools.restore.show();
16773 this.maximized = true;
16774 this.el.disableShadow();
16776 if(this.dd){
16777 this.dd.lock();
16779 if(this.collapsible){
16780 this.tools.toggle.hide();
16782 this.el.addClass('x-window-maximized');
16783 this.container.addClass('x-window-maximized-ct');
16785 this.setPosition(0, 0);
16786 this.fitContainer();
16787 this.fireEvent('maximize', this);
16789 },
16792 restore : function(){
16793 if(this.maximized){
16794 this.el.removeClass('x-window-maximized');
16795 this.tools.restore.hide();
16796 this.tools.maximize.show();
16797 this.setPosition(this.restorePos[0], this.restorePos[1]);
16798 this.setSize(this.restoreSize.width, this.restoreSize.height);
16799 delete this.restorePos;
16800 delete this.restoreSize;
16801 this.maximized = false;
16802 this.el.enableShadow(true);
16804 if(this.dd){
16805 this.dd.unlock();
16807 if(this.collapsible){
16808 this.tools.toggle.show();
16810 this.container.removeClass('x-window-maximized-ct');
16812 this.doConstrain();
16813 this.fireEvent('restore', this);
16815 },
16818 toggleMaximize : function(){
16819 this[this.maximized ? 'restore' : 'maximize']();
16820 },
16822 fitContainer : function(){
16823 var vs = this.container.getViewSize();
16824 this.setSize(vs.width, vs.height);
16825 },
16827 setZIndex : function(index){
16828 if(this.modal){
16829 this.mask.setStyle("z-index", index);
16831 this.el.setZIndex(++index);
16832 index += 5;
16834 if(this.resizer){
16835 this.resizer.proxy.setStyle("z-index", ++index);
16838 this.lastZIndex = index;
16839 },
16842 alignTo : function(element, position, offsets){
16843 var xy = this.el.getAlignToXY(element, position, offsets);
16844 this.setPagePosition(xy[0], xy[1]);
16845 return this;
16846 },
16849 anchorTo : function(el, alignment, offsets, monitorScroll, _pname){
16850 var action = function(){
16851 this.alignTo(el, alignment, offsets);
16852 };
16853 Ext.EventManager.onWindowResize(action, this);
16854 var tm = typeof monitorScroll;
16855 if(tm != 'undefined'){
16856 Ext.EventManager.on(window, 'scroll', action, this,
16857 {buffer: tm == 'number' ? monitorScroll : 50});
16859 action.call(this);
16860 this[_pname] = action;
16861 return this;
16862 },
16865 toFront : function(){
16866 if(this.manager.bringToFront(this)){
16867 this.focus();
16869 return this;
16870 },
16873 setActive : function(active){
16874 if(active){
16875 if(!this.maximized){
16876 this.el.enableShadow(true);
16878 this.fireEvent('activate', this);
16879 }else{
16880 this.el.disableShadow();
16881 this.fireEvent('deactivate', this);
16883 },
16886 toBack : function(){
16887 this.manager.sendToBack(this);
16888 return this;
16889 },
16892 center : function(){
16893 var xy = this.el.getAlignToXY(this.container, 'c-c');
16894 this.setPagePosition(xy[0], xy[1]);
16895 return this;
16897 });
16898 Ext.reg('window', Ext.Window);
16900 Ext.Window.DD = function(win){
16901 this.win = win;
16902 Ext.Window.DD.superclass.constructor.call(this, win.el.id, 'WindowDD-'+win.id);
16903 this.setHandleElId(win.header.id);
16904 this.scroll = false;
16905 };
16907 Ext.extend(Ext.Window.DD, Ext.dd.DD, {
16908 moveOnly:true,
16909 headerOffsets:[100, 25],
16910 startDrag : function(){
16911 var w = this.win;
16912 this.proxy = w.ghost();
16913 if(w.constrain !== false){
16914 var so = w.el.shadowOffset;
16915 this.constrainTo(w.container, {right: so, left: so, bottom: so});
16916 }else if(w.constrainHeader !== false){
16917 var s = this.proxy.getSize();
16918 this.constrainTo(w.container, {right: -(s.width-this.headerOffsets[0]), bottom: -(s.height-this.headerOffsets[1])});
16920 },
16921 b4Drag : Ext.emptyFn,
16923 onDrag : function(e){
16924 this.alignElWithMouse(this.proxy, e.getPageX(), e.getPageY());
16925 },
16927 endDrag : function(e){
16928 this.win.unghost();
16929 this.win.saveState();
16931 });
16934 Ext.WindowGroup = function(){
16935 var list = {};
16936 var accessList = [];
16937 var front = null;
16939 var sortWindows = function(d1, d2){
16940 return (!d1._lastAccess || d1._lastAccess < d2._lastAccess) ? -1 : 1;
16941 };
16943 var orderWindows = function(){
16944 var a = accessList, len = a.length;
16945 if(len > 0){
16946 a.sort(sortWindows);
16947 var seed = a[0].manager.zseed;
16948 for(var i = 0; i < len; i++){
16949 var win = a[i];
16950 if(win && !win.hidden){
16951 win.setZIndex(seed + (i*10));
16955 activateLast();
16956 };
16958 var setActiveWin = function(win){
16959 if(win != front){
16960 if(front){
16961 front.setActive(false);
16963 front = win;
16964 if(win){
16965 win.setActive(true);
16968 };
16970 var activateLast = function(){
16971 for(var i = accessList.length-1; i >=0; --i) {
16972 if(!accessList[i].hidden){
16973 setActiveWin(accessList[i]);
16974 return;
16977 setActiveWin(null);
16978 };
16980 return {
16982 zseed : 9000,
16984 register : function(win){
16985 list[win.id] = win;
16986 accessList.push(win);
16987 win.on('hide', activateLast);
16988 },
16990 unregister : function(win){
16991 delete list[win.id];
16992 win.un('hide', activateLast);
16993 accessList.remove(win);
16994 },
16997 get : function(id){
16998 return typeof id == "object" ? id : list[id];
16999 },
17002 bringToFront : function(win){
17003 win = this.get(win);
17004 if(win != front){
17005 win._lastAccess = new Date().getTime();
17006 orderWindows();
17007 return true;
17009 return false;
17010 },
17013 sendToBack : function(win){
17014 win = this.get(win);
17015 win._lastAccess = -(new Date().getTime());
17016 orderWindows();
17017 return win;
17018 },
17021 hideAll : function(){
17022 for(var id in list){
17023 if(list[id] && typeof list[id] != "function" && list[id].isVisible()){
17024 list[id].hide();
17027 },
17030 getActive : function(){
17031 return front;
17032 },
17035 getBy : function(fn, scope){
17036 var r = [];
17037 for(var i = accessList.length-1; i >=0; --i) {
17038 var win = accessList[i];
17039 if(fn.call(scope||win, win) !== false){
17040 r.push(win);
17043 return r;
17044 },
17047 each : function(fn, scope){
17048 for(var id in list){
17049 if(list[id] && typeof list[id] != "function"){
17050 if(fn.call(scope || list[id], list[id]) === false){
17051 return;
17056 };
17057 };
17061 Ext.WindowMgr = new Ext.WindowGroup();
17063 Ext.dd.PanelProxy = function(panel, config){
17064 this.panel = panel;
17065 this.id = this.panel.id +'-ddproxy';
17066 Ext.apply(this, config);
17067 };
17069 Ext.dd.PanelProxy.prototype = {
17071 insertProxy : true,
17074 setStatus : Ext.emptyFn,
17075 reset : Ext.emptyFn,
17076 update : Ext.emptyFn,
17077 stop : Ext.emptyFn,
17078 sync: Ext.emptyFn,
17081 getEl : function(){
17082 return this.ghost;
17083 },
17086 getGhost : function(){
17087 return this.ghost;
17088 },
17091 getProxy : function(){
17092 return this.proxy;
17093 },
17096 hide : function(){
17097 if(this.ghost){
17098 if(this.proxy){
17099 this.proxy.remove();
17100 delete this.proxy;
17102 this.panel.el.dom.style.display = '';
17103 this.ghost.remove();
17104 delete this.ghost;
17106 },
17109 show : function(){
17110 if(!this.ghost){
17111 this.ghost = this.panel.createGhost(undefined, undefined, Ext.getBody());
17112 this.ghost.setXY(this.panel.el.getXY())
17113 if(this.insertProxy){
17114 this.proxy = this.panel.el.insertSibling({cls:'x-panel-dd-spacer'});
17115 this.proxy.setSize(this.panel.getSize());
17117 this.panel.el.dom.style.display = 'none';
17119 },
17122 repair : function(xy, callback, scope){
17123 this.hide();
17124 if(typeof callback == "function"){
17125 callback.call(scope || this);
17127 },
17130 moveProxy : function(parentNode, before){
17131 if(this.proxy){
17132 parentNode.insertBefore(this.proxy.dom, before);
17135 };
17138 Ext.Panel.DD = function(panel, cfg){
17139 this.panel = panel;
17140 this.dragData = {panel: panel};
17141 this.proxy = new Ext.dd.PanelProxy(panel, cfg);
17142 Ext.Panel.DD.superclass.constructor.call(this, panel.el, cfg);
17143 var h = panel.header;
17144 if(h){
17145 this.setHandleElId(h.id);
17147 (h ? h : this.panel.body).setStyle('cursor', 'move');
17148 this.scroll = false;
17149 };
17151 Ext.extend(Ext.Panel.DD, Ext.dd.DragSource, {
17152 showFrame: Ext.emptyFn,
17153 startDrag: Ext.emptyFn,
17154 b4StartDrag: function(x, y) {
17155 this.proxy.show();
17156 },
17157 b4MouseDown: function(e) {
17158 var x = e.getPageX();
17159 var y = e.getPageY();
17160 this.autoOffset(x, y);
17161 },
17162 onInitDrag : function(x, y){
17163 this.onStartDrag(x, y);
17164 return true;
17165 },
17166 createFrame : Ext.emptyFn,
17167 getDragEl : function(e){
17168 return this.proxy.ghost.dom;
17169 },
17170 endDrag : function(e){
17171 this.proxy.hide();
17172 this.panel.saveState();
17173 },
17175 autoOffset : function(x, y) {
17176 x -= this.startPageX;
17177 y -= this.startPageY;
17178 this.setDelta(x, y);
17180 });
17182 Ext.state.Provider = function(){
17184 this.addEvents("statechange");
17185 this.state = {};
17186 Ext.state.Provider.superclass.constructor.call(this);
17187 };
17188 Ext.extend(Ext.state.Provider, Ext.util.Observable, {
17190 get : function(name, defaultValue){
17191 return typeof this.state[name] == "undefined" ?
17192 defaultValue : this.state[name];
17193 },
17196 clear : function(name){
17197 delete this.state[name];
17198 this.fireEvent("statechange", this, name, null);
17199 },
17202 set : function(name, value){
17203 this.state[name] = value;
17204 this.fireEvent("statechange", this, name, value);
17205 },
17208 decodeValue : function(cookie){
17209 var re = /^(a|n|d|b|s|o)\:(.*)$/;
17210 var matches = re.exec(unescape(cookie));
17211 if(!matches || !matches[1]) return;
17212 var type = matches[1];
17213 var v = matches[2];
17214 switch(type){
17215 case "n":
17216 return parseFloat(v);
17217 case "d":
17218 return new Date(Date.parse(v));
17219 case "b":
17220 return (v == "1");
17221 case "a":
17222 var all = [];
17223 var values = v.split("^");
17224 for(var i = 0, len = values.length; i < len; i++){
17225 all.push(this.decodeValue(values[i]));
17227 return all;
17228 case "o":
17229 var all = {};
17230 var values = v.split("^");
17231 for(var i = 0, len = values.length; i < len; i++){
17232 var kv = values[i].split("=");
17233 all[kv[0]] = this.decodeValue(kv[1]);
17235 return all;
17236 default:
17237 return v;
17239 },
17242 encodeValue : function(v){
17243 var enc;
17244 if(typeof v == "number"){
17245 enc = "n:" + v;
17246 }else if(typeof v == "boolean"){
17247 enc = "b:" + (v ? "1" : "0");
17248 }else if(Ext.isDate(v)){
17249 enc = "d:" + v.toGMTString();
17250 }else if(Ext.isArray(v)){
17251 var flat = "";
17252 for(var i = 0, len = v.length; i < len; i++){
17253 flat += this.encodeValue(v[i]);
17254 if(i != len-1) flat += "^";
17256 enc = "a:" + flat;
17257 }else if(typeof v == "object"){
17258 var flat = "";
17259 for(var key in v){
17260 if(typeof v[key] != "function" && v[key] !== undefined){
17261 flat += key + "=" + this.encodeValue(v[key]) + "^";
17264 enc = "o:" + flat.substring(0, flat.length-1);
17265 }else{
17266 enc = "s:" + v;
17268 return escape(enc);
17270 });
17273 Ext.state.Manager = function(){
17274 var provider = new Ext.state.Provider();
17276 return {
17278 setProvider : function(stateProvider){
17279 provider = stateProvider;
17280 },
17283 get : function(key, defaultValue){
17284 return provider.get(key, defaultValue);
17285 },
17288 set : function(key, value){
17289 provider.set(key, value);
17290 },
17293 clear : function(key){
17294 provider.clear(key);
17295 },
17298 getProvider : function(){
17299 return provider;
17301 };
17302 }();
17305 Ext.state.CookieProvider = function(config){
17306 Ext.state.CookieProvider.superclass.constructor.call(this);
17307 this.path = "/";
17308 this.expires = new Date(new Date().getTime()+(1000*60*60*24*7));
17309 this.domain = null;
17310 this.secure = false;
17311 Ext.apply(this, config);
17312 this.state = this.readCookies();
17313 };
17315 Ext.extend(Ext.state.CookieProvider, Ext.state.Provider, {
17317 set : function(name, value){
17318 if(typeof value == "undefined" || value === null){
17319 this.clear(name);
17320 return;
17322 this.setCookie(name, value);
17323 Ext.state.CookieProvider.superclass.set.call(this, name, value);
17324 },
17327 clear : function(name){
17328 this.clearCookie(name);
17329 Ext.state.CookieProvider.superclass.clear.call(this, name);
17330 },
17333 readCookies : function(){
17334 var cookies = {};
17335 var c = document.cookie + ";";
17336 var re = /\s?(.*?)=(.*?);/g;
17337 var matches;
17338 while((matches = re.exec(c)) != null){
17339 var name = matches[1];
17340 var value = matches[2];
17341 if(name && name.substring(0,3) == "ys-"){
17342 cookies[name.substr(3)] = this.decodeValue(value);
17345 return cookies;
17346 },
17349 setCookie : function(name, value){
17350 document.cookie = "ys-"+ name + "=" + this.encodeValue(value) +
17351 ((this.expires == null) ? "" : ("; expires=" + this.expires.toGMTString())) +
17352 ((this.path == null) ? "" : ("; path=" + this.path)) +
17353 ((this.domain == null) ? "" : ("; domain=" + this.domain)) +
17354 ((this.secure == true) ? "; secure" : "");
17355 },
17358 clearCookie : function(name){
17359 document.cookie = "ys-" + name + "=null; expires=Thu, 01-Jan-70 00:00:01 GMT" +
17360 ((this.path == null) ? "" : ("; path=" + this.path)) +
17361 ((this.domain == null) ? "" : ("; domain=" + this.domain)) +
17362 ((this.secure == true) ? "; secure" : "");
17364 });
17366 Ext.DataView = Ext.extend(Ext.BoxComponent, {
17376 selectedClass : "x-view-selected",
17378 emptyText : "",
17381 deferEmptyText: true,
17383 last: false,
17385 initComponent : function(){
17386 Ext.DataView.superclass.initComponent.call(this);
17387 if(typeof this.tpl == "string"){
17388 this.tpl = new Ext.XTemplate(this.tpl);
17391 this.addEvents(
17393 "beforeclick",
17395 "click",
17397 "containerclick",
17399 "dblclick",
17401 "contextmenu",
17403 "selectionchange",
17406 "beforeselect"
17407 );
17409 this.all = new Ext.CompositeElementLite();
17410 this.selected = new Ext.CompositeElementLite();
17411 },
17413 onRender : function(){
17414 if(!this.el){
17415 this.el = document.createElement('div');
17416 this.el.id = this.id;
17418 Ext.DataView.superclass.onRender.apply(this, arguments);
17419 },
17421 afterRender : function(){
17422 Ext.DataView.superclass.afterRender.call(this);
17424 this.el.on({
17425 "click": this.onClick,
17426 "dblclick": this.onDblClick,
17427 "contextmenu": this.onContextMenu,
17428 scope:this
17429 });
17431 if(this.overClass){
17432 this.el.on({
17433 "mouseover": this.onMouseOver,
17434 "mouseout": this.onMouseOut,
17435 scope:this
17436 });
17439 if(this.store){
17440 this.setStore(this.store, true);
17442 },
17445 refresh : function(){
17446 this.clearSelections(false, true);
17447 this.el.update("");
17448 var html = [];
17449 var records = this.store.getRange();
17450 if(records.length < 1){
17451 if(!this.deferEmptyText || this.hasSkippedEmptyText){
17452 this.el.update(this.emptyText);
17454 this.hasSkippedEmptyText = true;
17455 this.all.clear();
17456 return;
17458 this.tpl.overwrite(this.el, this.collectData(records, 0));
17459 this.all.fill(Ext.query(this.itemSelector, this.el.dom));
17460 this.updateIndexes(0);
17461 },
17464 prepareData : function(data){
17465 return data;
17466 },
17468 collectData : function(records, startIndex){
17469 var r = [];
17470 for(var i = 0, len = records.length; i < len; i++){
17471 r[r.length] = this.prepareData(records[i].data, startIndex+i, records[i]);
17473 return r;
17474 },
17476 bufferRender : function(records){
17477 var div = document.createElement('div');
17478 this.tpl.overwrite(div, this.collectData(records));
17479 return Ext.query(this.itemSelector, div);
17480 },
17482 onUpdate : function(ds, record){
17483 var index = this.store.indexOf(record);
17484 var sel = this.isSelected(index);
17485 var original = this.all.elements[index];
17486 var node = this.bufferRender([record], index)[0];
17488 this.all.replaceElement(index, node, true);
17489 if(sel){
17490 this.selected.replaceElement(original, node);
17491 this.all.item(index).addClass(this.selectedClass);
17493 this.updateIndexes(index, index);
17494 },
17496 onAdd : function(ds, records, index){
17497 if(this.all.getCount() == 0){
17498 this.refresh();
17499 return;
17501 var nodes = this.bufferRender(records, index), n, a = this.all.elements;
17502 if(index < this.all.getCount()){
17503 n = this.all.item(index).insertSibling(nodes, 'before', true);
17504 a.splice.apply(a, [index, 0].concat(nodes));
17505 }else{
17506 n = this.all.last().insertSibling(nodes, 'after', true);
17507 a.push.apply(a, nodes);
17509 this.updateIndexes(index);
17510 },
17512 onRemove : function(ds, record, index){
17513 this.deselect(index);
17514 this.all.removeElement(index, true);
17515 this.updateIndexes(index);
17516 },
17519 refreshNode : function(index){
17520 this.onUpdate(this.store, this.store.getAt(index));
17521 },
17523 updateIndexes : function(startIndex, endIndex){
17524 var ns = this.all.elements;
17525 startIndex = startIndex || 0;
17526 endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length - 1));
17527 for(var i = startIndex; i <= endIndex; i++){
17528 ns[i].viewIndex = i;
17530 },
17533 setStore : function(store, initial){
17534 if(!initial && this.store){
17535 this.store.un("beforeload", this.onBeforeLoad, this);
17536 this.store.un("datachanged", this.refresh, this);
17537 this.store.un("add", this.onAdd, this);
17538 this.store.un("remove", this.onRemove, this);
17539 this.store.un("update", this.onUpdate, this);
17540 this.store.un("clear", this.refresh, this);
17542 if(store){
17543 store = Ext.StoreMgr.lookup(store);
17544 store.on("beforeload", this.onBeforeLoad, this);
17545 store.on("datachanged", this.refresh, this);
17546 store.on("add", this.onAdd, this);
17547 store.on("remove", this.onRemove, this);
17548 store.on("update", this.onUpdate, this);
17549 store.on("clear", this.refresh, this);
17551 this.store = store;
17552 if(store){
17553 this.refresh();
17555 },
17558 findItemFromChild : function(node){
17559 return Ext.fly(node).findParent(this.itemSelector, this.el);
17560 },
17562 onClick : function(e){
17563 var item = e.getTarget(this.itemSelector, this.el);
17564 if(item){
17565 var index = this.indexOf(item);
17566 if(this.onItemClick(item, index, e) !== false){
17567 this.fireEvent("click", this, index, item, e);
17569 }else{
17570 if(this.fireEvent("containerclick", this, e) !== false){
17571 this.clearSelections();
17574 },
17576 onContextMenu : function(e){
17577 var item = e.getTarget(this.itemSelector, this.el);
17578 if(item){
17579 this.fireEvent("contextmenu", this, this.indexOf(item), item, e);
17581 },
17583 onDblClick : function(e){
17584 var item = e.getTarget(this.itemSelector, this.el);
17585 if(item){
17586 this.fireEvent("dblclick", this, this.indexOf(item), item, e);
17588 },
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);
17596 },
17598 onMouseOut : function(e){
17599 if(this.lastItem){
17600 if(!e.within(this.lastItem, true)){
17601 Ext.fly(this.lastItem).removeClass(this.overClass);
17602 delete this.lastItem;
17605 },
17607 onItemClick : function(item, index, e){
17608 if(this.fireEvent("beforeclick", this, index, item, e) === false){
17609 return false;
17611 if(this.multiSelect){
17612 this.doMultiSelection(item, index, e);
17613 e.preventDefault();
17614 }else if(this.singleSelect){
17615 this.doSingleSelection(item, index, e);
17616 e.preventDefault();
17618 return true;
17619 },
17621 doSingleSelection : function(item, index, e){
17622 if(e.ctrlKey && this.isSelected(index)){
17623 this.deselect(index);
17624 }else{
17625 this.select(index, false);
17627 },
17629 doMultiSelection : function(item, index, e){
17630 if(e.shiftKey && this.last !== false){
17631 var last = this.last;
17632 this.selectRange(last, index, e.ctrlKey);
17633 this.last = last; }else{
17634 if((e.ctrlKey||this.simpleSelect) && this.isSelected(index)){
17635 this.deselect(index);
17636 }else{
17637 this.select(index, e.ctrlKey || e.shiftKey || this.simpleSelect);
17640 },
17643 getSelectionCount : function(){
17644 return this.selected.getCount()
17645 },
17648 getSelectedNodes : function(){
17649 return this.selected.elements;
17650 },
17653 getSelectedIndexes : function(){
17654 var indexes = [], s = this.selected.elements;
17655 for(var i = 0, len = s.length; i < len; i++){
17656 indexes.push(s[i].viewIndex);
17658 return indexes;
17659 },
17662 getSelectedRecords : function(){
17663 var r = [], s = this.selected.elements;
17664 for(var i = 0, len = s.length; i < len; i++){
17665 r[r.length] = this.store.getAt(s[i].viewIndex);
17667 return r;
17668 },
17671 getRecords : function(nodes){
17672 var r = [], s = nodes;
17673 for(var i = 0, len = s.length; i < len; i++){
17674 r[r.length] = this.store.getAt(s[i].viewIndex);
17676 return r;
17677 },
17680 getRecord : function(node){
17681 return this.store.getAt(node.viewIndex);
17682 },
17685 clearSelections : function(suppressEvent, skipUpdate){
17686 if((this.multiSelect || this.singleSelect) && this.selected.getCount() > 0){
17687 if(!skipUpdate){
17688 this.selected.removeClass(this.selectedClass);
17690 this.selected.clear();
17691 this.last = false;
17692 if(!suppressEvent){
17693 this.fireEvent("selectionchange", this, this.selected.elements);
17696 },
17699 isSelected : function(node){
17700 return this.selected.contains(this.getNode(node));
17701 },
17704 deselect : function(node){
17705 if(this.isSelected(node)){
17706 var node = this.getNode(node);
17707 this.selected.removeElement(node);
17708 if(this.last == node.viewIndex){
17709 this.last = false;
17711 Ext.fly(node).removeClass(this.selectedClass);
17712 this.fireEvent("selectionchange", this, this.selected.elements);
17714 },
17717 select : function(nodeInfo, keepExisting, suppressEvent){
17718 if(Ext.isArray(nodeInfo)){
17719 if(!keepExisting){
17720 this.clearSelections(true);
17722 for(var i = 0, len = nodeInfo.length; i < len; i++){
17723 this.select(nodeInfo[i], true, true);
17725 if(!suppressEvent){
17726 this.fireEvent("selectionchange", this, this.selected.elements);
17728 } else{
17729 var node = this.getNode(nodeInfo);
17730 if(!keepExisting){
17731 this.clearSelections(true);
17733 if(node && !this.isSelected(node)){
17734 if(this.fireEvent("beforeselect", this, node, this.selected.elements) !== false){
17735 Ext.fly(node).addClass(this.selectedClass);
17736 this.selected.add(node);
17737 this.last = node.viewIndex;
17738 if(!suppressEvent){
17739 this.fireEvent("selectionchange", this, this.selected.elements);
17744 },
17747 selectRange : function(start, end, keepExisting){
17748 if(!keepExisting){
17749 this.clearSelections(true);
17751 this.select(this.getNodes(start, end), true);
17752 },
17755 getNode : function(nodeInfo){
17756 if(typeof nodeInfo == "string"){
17757 return document.getElementById(nodeInfo);
17758 }else if(typeof nodeInfo == "number"){
17759 return this.all.elements[nodeInfo];
17761 return nodeInfo;
17762 },
17765 getNodes : function(start, end){
17766 var ns = this.all.elements;
17767 start = start || 0;
17768 end = typeof end == "undefined" ? ns.length - 1 : end;
17769 var nodes = [], i;
17770 if(start <= end){
17771 for(i = start; i <= end; i++){
17772 nodes.push(ns[i]);
17774 } else{
17775 for(i = start; i >= end; i--){
17776 nodes.push(ns[i]);
17779 return nodes;
17780 },
17783 indexOf : function(node){
17784 node = this.getNode(node);
17785 if(typeof node.viewIndex == "number"){
17786 return node.viewIndex;
17788 return this.all.indexOf(node);
17789 },
17791 onBeforeLoad : function(){
17792 if(this.loadingText){
17793 this.clearSelections(false, true);
17794 this.el.update('<div class="loading-indicator">'+this.loadingText+'</div>');
17795 this.all.clear();
17797 },
17799 onDestroy : function(){
17800 Ext.DataView.superclass.onDestroy.call(this);
17801 this.setStore(null);
17803 });
17805 Ext.reg('dataview', Ext.DataView);
17807 Ext.ColorPalette = function(config){
17808 Ext.ColorPalette.superclass.constructor.call(this, config);
17809 this.addEvents(
17811 'select'
17812 );
17814 if(this.handler){
17815 this.on("select", this.handler, this.scope, true);
17817 };
17818 Ext.extend(Ext.ColorPalette, Ext.Component, {
17821 itemCls : "x-color-palette",
17823 value : null,
17824 clickEvent:'click',
17825 ctype: "Ext.ColorPalette",
17828 allowReselect : false,
17831 colors : [
17832 "000000", "993300", "333300", "003300", "003366", "000080", "333399", "333333",
17833 "800000", "FF6600", "808000", "008000", "008080", "0000FF", "666699", "808080",
17834 "FF0000", "FF9900", "99CC00", "339966", "33CCCC", "3366FF", "800080", "969696",
17835 "FF00FF", "FFCC00", "FFFF00", "00FF00", "00FFFF", "00CCFF", "993366", "C0C0C0",
17836 "FF99CC", "FFCC99", "FFFF99", "CCFFCC", "CCFFFF", "99CCFF", "CC99FF", "FFFFFF"
17837 ],
17839 onRender : function(container, position){
17840 var t = this.tpl || new Ext.XTemplate(
17841 '<tpl for="."><a href="#" class="color-{.}" hidefocus="on"><em><span style="background:#{.}" unselectable="on">&#160;</span></em></a></tpl>'
17842 );
17843 var el = document.createElement("div");
17844 el.className = this.itemCls;
17845 t.overwrite(el, this.colors);
17846 container.dom.insertBefore(el, position);
17847 this.el = Ext.get(el);
17848 this.el.on(this.clickEvent, this.handleClick, this, {delegate: "a"});
17849 if(this.clickEvent != 'click'){
17850 this.el.on('click', Ext.emptyFn, this, {delegate: "a", preventDefault:true});
17852 },
17854 afterRender : function(){
17855 Ext.ColorPalette.superclass.afterRender.call(this);
17856 if(this.value){
17857 var s = this.value;
17858 this.value = null;
17859 this.select(s);
17861 },
17863 handleClick : function(e, t){
17864 e.preventDefault();
17865 if(!this.disabled){
17866 var c = t.className.match(/(?:^|\s)color-(.{6})(?:\s|$)/)[1];
17867 this.select(c.toUpperCase());
17869 },
17872 select : function(color){
17873 color = color.replace("#", "");
17874 if(color != this.value || this.allowReselect){
17875 var el = this.el;
17876 if(this.value){
17877 el.child("a.color-"+this.value).removeClass("x-color-palette-sel");
17879 el.child("a.color-"+color).addClass("x-color-palette-sel");
17880 this.value = color;
17881 this.fireEvent("select", this, color);
17886 });
17887 Ext.reg('colorpalette', Ext.ColorPalette);
17889 Ext.DatePicker = Ext.extend(Ext.Component, {
17891 todayText : "Today",
17893 okText : "&#160;OK&#160;",
17895 cancelText : "Cancel",
17897 todayTip : "{0} (Spacebar)",
17899 minDate : null,
17901 maxDate : null,
17903 minText : "This date is before the minimum date",
17905 maxText : "This date is after the maximum date",
17907 format : "m/d/y",
17909 disabledDays : null,
17911 disabledDaysText : "",
17913 disabledDatesRE : null,
17915 disabledDatesText : "",
17917 constrainToViewport : true,
17919 monthNames : Date.monthNames,
17921 dayNames : Date.dayNames,
17923 nextText: 'Next Month (Control+Right)',
17925 prevText: 'Previous Month (Control+Left)',
17927 monthYearText: 'Choose a month (Control+Up/Down to move years)',
17929 startDay : 0,
17931 initComponent : function(){
17932 Ext.DatePicker.superclass.initComponent.call(this);
17934 this.value = this.value ?
17935 this.value.clearTime() : new Date().clearTime();
17937 this.addEvents(
17939 'select'
17940 );
17942 if(this.handler){
17943 this.on("select", this.handler, this.scope || this);
17946 this.initDisabledDays();
17947 },
17950 initDisabledDays : function(){
17951 if(!this.disabledDatesRE && this.disabledDates){
17952 var dd = this.disabledDates;
17953 var re = "(?:";
17954 for(var i = 0; i < dd.length; i++){
17955 re += dd[i];
17956 if(i != dd.length-1) re += "|";
17958 this.disabledDatesRE = new RegExp(re + ")");
17960 },
17963 setValue : function(value){
17964 var old = this.value;
17965 this.value = value.clearTime(true);
17966 if(this.el){
17967 this.update(this.value);
17969 },
17972 getValue : function(){
17973 return this.value;
17974 },
17977 focus : function(){
17978 if(this.el){
17979 this.update(this.activeDate);
17981 },
17984 onRender : function(container, position){
17985 var m = [
17986 '<table cellspacing="0">',
17987 '<tr><td class="x-date-left"><a href="#" title="', this.prevText ,'">&#160;</a></td><td class="x-date-middle" align="center"></td><td class="x-date-right"><a href="#" title="', this.nextText ,'">&#160;</a></td></tr>',
17988 '<tr><td colspan="3"><table class="x-date-inner" cellspacing="0"><thead><tr>'];
17989 var dn = this.dayNames;
17990 for(var i = 0; i < 7; i++){
17991 var d = this.startDay+i;
17992 if(d > 6){
17993 d = d-7;
17995 m.push("<th><span>", dn[d].substr(0,1), "</span></th>");
17997 m[m.length] = "</tr></thead><tbody><tr>";
17998 for(var i = 0; i < 42; i++) {
17999 if(i % 7 == 0 && i != 0){
18000 m[m.length] = "</tr><tr>";
18002 m[m.length] = '<td><a href="#" hidefocus="on" class="x-date-date" tabIndex="1"><em><span></span></em></a></td>';
18004 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>';
18006 var el = document.createElement("div");
18007 el.className = "x-date-picker";
18008 el.innerHTML = m.join("");
18010 container.dom.insertBefore(el, position);
18012 this.el = Ext.get(el);
18013 this.eventEl = Ext.get(el.firstChild);
18015 new Ext.util.ClickRepeater(this.el.child("td.x-date-left a"), {
18016 handler: this.showPrevMonth,
18017 scope: this,
18018 preventDefault:true,
18019 stopDefault:true
18020 });
18022 new Ext.util.ClickRepeater(this.el.child("td.x-date-right a"), {
18023 handler: this.showNextMonth,
18024 scope: this,
18025 preventDefault:true,
18026 stopDefault:true
18027 });
18029 this.eventEl.on("mousewheel", this.handleMouseWheel, this);
18031 this.monthPicker = this.el.down('div.x-date-mp');
18032 this.monthPicker.enableDisplayMode('block');
18034 var kn = new Ext.KeyNav(this.eventEl, {
18035 "left" : function(e){
18036 e.ctrlKey ?
18037 this.showPrevMonth() :
18038 this.update(this.activeDate.add("d", -1));
18039 },
18041 "right" : function(e){
18042 e.ctrlKey ?
18043 this.showNextMonth() :
18044 this.update(this.activeDate.add("d", 1));
18045 },
18047 "up" : function(e){
18048 e.ctrlKey ?
18049 this.showNextYear() :
18050 this.update(this.activeDate.add("d", -7));
18051 },
18053 "down" : function(e){
18054 e.ctrlKey ?
18055 this.showPrevYear() :
18056 this.update(this.activeDate.add("d", 7));
18057 },
18059 "pageUp" : function(e){
18060 this.showNextMonth();
18061 },
18063 "pageDown" : function(e){
18064 this.showPrevMonth();
18065 },
18067 "enter" : function(e){
18068 e.stopPropagation();
18069 return true;
18070 },
18072 scope : this
18073 });
18075 this.eventEl.on("click", this.handleDateClick, this, {delegate: "a.x-date-date"});
18077 this.eventEl.addKeyListener(Ext.EventObject.SPACE, this.selectToday, this);
18079 this.el.unselectable();
18081 this.cells = this.el.select("table.x-date-inner tbody td");
18082 this.textNodes = this.el.query("table.x-date-inner tbody span");
18084 this.mbtn = new Ext.Button({
18085 text: "&#160;",
18086 tooltip: this.monthYearText,
18087 renderTo: this.el.child("td.x-date-middle", true)
18088 });
18090 this.mbtn.on('click', this.showMonthPicker, this);
18091 this.mbtn.el.child(this.mbtn.menuClassTarget).addClass("x-btn-with-menu");
18094 var today = (new Date()).dateFormat(this.format);
18095 this.todayBtn = new Ext.Button({
18096 renderTo: this.el.child("td.x-date-bottom", true),
18097 text: String.format(this.todayText, today),
18098 tooltip: String.format(this.todayTip, today),
18099 handler: this.selectToday,
18100 scope: this
18101 });
18103 if(Ext.isIE){
18104 this.el.repaint();
18106 this.update(this.value);
18107 },
18109 createMonthPicker : function(){
18110 if(!this.monthPicker.dom.firstChild){
18111 var buf = ['<table border="0" cellspacing="0">'];
18112 for(var i = 0; i < 6; i++){
18113 buf.push(
18114 '<tr><td class="x-date-mp-month"><a href="#">', this.monthNames[i].substr(0, 3), '</a></td>',
18115 '<td class="x-date-mp-month x-date-mp-sep"><a href="#">', this.monthNames[i+6].substr(0, 3), '</a></td>',
18116 i == 0 ?
18117 '<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>' :
18118 '<td class="x-date-mp-year"><a href="#"></a></td><td class="x-date-mp-year"><a href="#"></a></td></tr>'
18119 );
18121 buf.push(
18122 '<tr class="x-date-mp-btns"><td colspan="4"><button type="button" class="x-date-mp-ok">',
18123 this.okText,
18124 '</button><button type="button" class="x-date-mp-cancel">',
18125 this.cancelText,
18126 '</button></td></tr>',
18127 '</table>'
18128 );
18129 this.monthPicker.update(buf.join(''));
18130 this.monthPicker.on('click', this.onMonthClick, this);
18131 this.monthPicker.on('dblclick', this.onMonthDblClick, this);
18133 this.mpMonths = this.monthPicker.select('td.x-date-mp-month');
18134 this.mpYears = this.monthPicker.select('td.x-date-mp-year');
18136 this.mpMonths.each(function(m, a, i){
18137 i += 1;
18138 if((i%2) == 0){
18139 m.dom.xmonth = 5 + Math.round(i * .5);
18140 }else{
18141 m.dom.xmonth = Math.round((i-1) * .5);
18143 });
18145 },
18147 showMonthPicker : function(){
18148 this.createMonthPicker();
18149 var size = this.el.getSize();
18150 this.monthPicker.setSize(size);
18151 this.monthPicker.child('table').setSize(size);
18153 this.mpSelMonth = (this.activeDate || this.value).getMonth();
18154 this.updateMPMonth(this.mpSelMonth);
18155 this.mpSelYear = (this.activeDate || this.value).getFullYear();
18156 this.updateMPYear(this.mpSelYear);
18158 this.monthPicker.slideIn('t', {duration:.2});
18159 },
18161 updateMPYear : function(y){
18162 this.mpyear = y;
18163 var ys = this.mpYears.elements;
18164 for(var i = 1; i <= 10; i++){
18165 var td = ys[i-1], y2;
18166 if((i%2) == 0){
18167 y2 = y + Math.round(i * .5);
18168 td.firstChild.innerHTML = y2;
18169 td.xyear = y2;
18170 }else{
18171 y2 = y - (5-Math.round(i * .5));
18172 td.firstChild.innerHTML = y2;
18173 td.xyear = y2;
18175 this.mpYears.item(i-1)[y2 == this.mpSelYear ? 'addClass' : 'removeClass']('x-date-mp-sel');
18177 },
18179 updateMPMonth : function(sm){
18180 this.mpMonths.each(function(m, a, i){
18181 m[m.dom.xmonth == sm ? 'addClass' : 'removeClass']('x-date-mp-sel');
18182 });
18183 },
18185 selectMPMonth: function(m){
18187 },
18189 onMonthClick : function(e, t){
18190 e.stopEvent();
18191 var el = new Ext.Element(t), pn;
18192 if(el.is('button.x-date-mp-cancel')){
18193 this.hideMonthPicker();
18195 else if(el.is('button.x-date-mp-ok')){
18196 var d = new Date(this.mpSelYear, this.mpSelMonth, (this.activeDate || this.value).getDate());
18197 if(d.getMonth() != this.mpSelMonth){
18199 d = new Date(this.mpSelYear, this.mpSelMonth, 1).getLastDateOfMonth();
18201 this.update(d);
18202 this.hideMonthPicker();
18204 else if(pn = el.up('td.x-date-mp-month', 2)){
18205 this.mpMonths.removeClass('x-date-mp-sel');
18206 pn.addClass('x-date-mp-sel');
18207 this.mpSelMonth = pn.dom.xmonth;
18209 else if(pn = el.up('td.x-date-mp-year', 2)){
18210 this.mpYears.removeClass('x-date-mp-sel');
18211 pn.addClass('x-date-mp-sel');
18212 this.mpSelYear = pn.dom.xyear;
18214 else if(el.is('a.x-date-mp-prev')){
18215 this.updateMPYear(this.mpyear-10);
18217 else if(el.is('a.x-date-mp-next')){
18218 this.updateMPYear(this.mpyear+10);
18220 },
18222 onMonthDblClick : function(e, t){
18223 e.stopEvent();
18224 var el = new Ext.Element(t), pn;
18225 if(pn = el.up('td.x-date-mp-month', 2)){
18226 this.update(new Date(this.mpSelYear, pn.dom.xmonth, (this.activeDate || this.value).getDate()));
18227 this.hideMonthPicker();
18229 else if(pn = el.up('td.x-date-mp-year', 2)){
18230 this.update(new Date(pn.dom.xyear, this.mpSelMonth, (this.activeDate || this.value).getDate()));
18231 this.hideMonthPicker();
18233 },
18235 hideMonthPicker : function(disableAnim){
18236 if(this.monthPicker){
18237 if(disableAnim === true){
18238 this.monthPicker.hide();
18239 }else{
18240 this.monthPicker.slideOut('t', {duration:.2});
18243 },
18246 showPrevMonth : function(e){
18247 this.update(this.activeDate.add("mo", -1));
18248 },
18251 showNextMonth : function(e){
18252 this.update(this.activeDate.add("mo", 1));
18253 },
18256 showPrevYear : function(){
18257 this.update(this.activeDate.add("y", -1));
18258 },
18261 showNextYear : function(){
18262 this.update(this.activeDate.add("y", 1));
18263 },
18266 handleMouseWheel : function(e){
18267 var delta = e.getWheelDelta();
18268 if(delta > 0){
18269 this.showPrevMonth();
18270 e.stopEvent();
18271 } else if(delta < 0){
18272 this.showNextMonth();
18273 e.stopEvent();
18275 },
18278 handleDateClick : function(e, t){
18279 e.stopEvent();
18280 if(t.dateValue && !Ext.fly(t.parentNode).hasClass("x-date-disabled")){
18281 this.setValue(new Date(t.dateValue));
18282 this.fireEvent("select", this, this.value);
18284 },
18287 selectToday : function(){
18288 this.setValue(new Date().clearTime());
18289 this.fireEvent("select", this, this.value);
18290 },
18293 update : function(date){
18294 var vd = this.activeDate;
18295 this.activeDate = date;
18296 if(vd && this.el){
18297 var t = date.getTime();
18298 if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){
18299 this.cells.removeClass("x-date-selected");
18300 this.cells.each(function(c){
18301 if(c.dom.firstChild.dateValue == t){
18302 c.addClass("x-date-selected");
18303 setTimeout(function(){
18304 try{c.dom.firstChild.focus();}catch(e){}
18305 }, 50);
18306 return false;
18308 });
18309 return;
18312 var days = date.getDaysInMonth();
18313 var firstOfMonth = date.getFirstDateOfMonth();
18314 var startingPos = firstOfMonth.getDay()-this.startDay;
18316 if(startingPos <= this.startDay){
18317 startingPos += 7;
18320 var pm = date.add("mo", -1);
18321 var prevStart = pm.getDaysInMonth()-startingPos;
18323 var cells = this.cells.elements;
18324 var textEls = this.textNodes;
18325 days += startingPos;
18328 var day = 86400000;
18329 var d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart)).clearTime();
18330 var today = new Date().clearTime().getTime();
18331 var sel = date.clearTime().getTime();
18332 var min = this.minDate ? this.minDate.clearTime() : Number.NEGATIVE_INFINITY;
18333 var max = this.maxDate ? this.maxDate.clearTime() : Number.POSITIVE_INFINITY;
18334 var ddMatch = this.disabledDatesRE;
18335 var ddText = this.disabledDatesText;
18336 var ddays = this.disabledDays ? this.disabledDays.join("") : false;
18337 var ddaysText = this.disabledDaysText;
18338 var format = this.format;
18340 var setCellClass = function(cal, cell){
18341 cell.title = "";
18342 var t = d.getTime();
18343 cell.firstChild.dateValue = t;
18344 if(t == today){
18345 cell.className += " x-date-today";
18346 cell.title = cal.todayText;
18348 if(t == sel){
18349 cell.className += " x-date-selected";
18350 setTimeout(function(){
18351 try{cell.firstChild.focus();}catch(e){}
18352 }, 50);
18355 if(t < min) {
18356 cell.className = " x-date-disabled";
18357 cell.title = cal.minText;
18358 return;
18360 if(t > max) {
18361 cell.className = " x-date-disabled";
18362 cell.title = cal.maxText;
18363 return;
18365 if(ddays){
18366 if(ddays.indexOf(d.getDay()) != -1){
18367 cell.title = ddaysText;
18368 cell.className = " x-date-disabled";
18371 if(ddMatch && format){
18372 var fvalue = d.dateFormat(format);
18373 if(ddMatch.test(fvalue)){
18374 cell.title = ddText.replace("%0", fvalue);
18375 cell.className = " x-date-disabled";
18378 };
18380 var i = 0;
18381 for(; i < startingPos; i++) {
18382 textEls[i].innerHTML = (++prevStart);
18383 d.setDate(d.getDate()+1);
18384 cells[i].className = "x-date-prevday";
18385 setCellClass(this, cells[i]);
18387 for(; i < days; i++){
18388 intDay = i - startingPos + 1;
18389 textEls[i].innerHTML = (intDay);
18390 d.setDate(d.getDate()+1);
18391 cells[i].className = "x-date-active";
18392 setCellClass(this, cells[i]);
18394 var extraDays = 0;
18395 for(; i < 42; i++) {
18396 textEls[i].innerHTML = (++extraDays);
18397 d.setDate(d.getDate()+1);
18398 cells[i].className = "x-date-nextday";
18399 setCellClass(this, cells[i]);
18402 this.mbtn.setText(this.monthNames[date.getMonth()] + " " + date.getFullYear());
18404 if(!this.internalRender){
18405 var main = this.el.dom.firstChild;
18406 var w = main.offsetWidth;
18407 this.el.setWidth(w + this.el.getBorderWidth("lr"));
18408 Ext.fly(main).setWidth(w);
18409 this.internalRender = true;
18413 if(Ext.isOpera && !this.secondPass){
18414 main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + "px";
18415 this.secondPass = true;
18416 this.update.defer(10, this, [date]);
18419 },
18422 beforeDestroy : function() {
18423 if(this.rendered){
18424 this.mbtn.destroy();
18425 this.todayBtn.destroy();
18430 });
18431 Ext.reg('datepicker', Ext.DatePicker);
18433 Ext.TabPanel = Ext.extend(Ext.Panel, {
18436 monitorResize : true,
18438 deferredRender : true,
18440 tabWidth: 120,
18442 minTabWidth: 30,
18444 resizeTabs:false,
18446 enableTabScroll: false,
18448 scrollIncrement : 0,
18450 scrollRepeatInterval : 400,
18452 scrollDuration : .35,
18454 animScroll : true,
18456 tabPosition: 'top',
18458 baseCls: 'x-tab-panel',
18460 autoTabs : false,
18462 autoTabSelector:'div.x-tab',
18464 activeTab : null,
18466 tabMargin : 2,
18468 plain: false,
18470 wheelIncrement : 20,
18473 idDelimiter : '__',
18475 itemCls : 'x-tab-item',
18477 elements: 'body',
18478 headerAsText: false,
18479 frame: false,
18480 hideBorders:true,
18482 initComponent : function(){
18483 this.frame = false;
18484 Ext.TabPanel.superclass.initComponent.call(this);
18485 this.addEvents(
18487 'beforetabchange',
18489 'tabchange',
18491 'contextmenu'
18492 );
18493 this.setLayout(new Ext.layout.CardLayout({
18494 deferredRender: this.deferredRender
18495 }));
18496 if(this.tabPosition == 'top'){
18497 this.elements += ',header';
18498 this.stripTarget = 'header';
18499 }else {
18500 this.elements += ',footer';
18501 this.stripTarget = 'footer';
18503 if(!this.stack){
18504 this.stack = Ext.TabPanel.AccessStack();
18506 this.initItems();
18507 },
18509 render : function(){
18510 Ext.TabPanel.superclass.render.apply(this, arguments);
18511 if(this.activeTab !== undefined){
18512 var item = this.activeTab;
18513 delete this.activeTab;
18514 this.setActiveTab(item);
18516 },
18518 onRender : function(ct, position){
18519 Ext.TabPanel.superclass.onRender.call(this, ct, position);
18521 if(this.plain){
18522 var pos = this.tabPosition == 'top' ? 'header' : 'footer';
18523 this[pos].addClass('x-tab-panel-'+pos+'-plain');
18526 var st = this[this.stripTarget];
18528 this.stripWrap = st.createChild({cls:'x-tab-strip-wrap', cn:{
18529 tag:'ul', cls:'x-tab-strip x-tab-strip-'+this.tabPosition}});
18530 this.stripSpacer = st.createChild({cls:'x-tab-strip-spacer'});
18531 this.strip = new Ext.Element(this.stripWrap.dom.firstChild);
18533 this.edge = this.strip.createChild({tag:'li', cls:'x-tab-edge'});
18534 this.strip.createChild({cls:'x-clear'});
18536 this.body.addClass('x-tab-panel-body-'+this.tabPosition);
18538 if(!this.itemTpl){
18539 var tt = new Ext.Template(
18540 '<li class="{cls}" id="{id}"><a class="x-tab-strip-close" onclick="return false;"></a>',
18541 '<a class="x-tab-right" href="#" onclick="return false;"><em class="x-tab-left">',
18542 '<span class="x-tab-strip-inner"><span class="x-tab-strip-text {iconCls}">{text}</span></span>',
18543 '</em></a></li>'
18544 );
18545 tt.disableFormats = true;
18546 tt.compile();
18547 Ext.TabPanel.prototype.itemTpl = tt;
18550 this.items.each(this.initTab, this);
18551 },
18553 afterRender : function(){
18554 Ext.TabPanel.superclass.afterRender.call(this);
18555 if(this.autoTabs){
18556 this.readTabs(false);
18558 },
18560 initEvents : function(){
18561 Ext.TabPanel.superclass.initEvents.call(this);
18562 this.on('add', this.onAdd, this);
18563 this.on('remove', this.onRemove, this);
18565 this.strip.on('mousedown', this.onStripMouseDown, this);
18566 this.strip.on('click', this.onStripClick, this);
18567 this.strip.on('contextmenu', this.onStripContextMenu, this);
18568 if(this.enableTabScroll){
18569 this.strip.on('mousewheel', this.onWheel, this);
18571 },
18573 findTargets : function(e){
18574 var item = null;
18575 var itemEl = e.getTarget('li', this.strip);
18576 if(itemEl){
18577 item = this.getComponent(itemEl.id.split(this.idDelimiter)[1]);
18578 if(item.disabled){
18579 return {
18580 close : null,
18581 item : null,
18582 el : null
18583 };
18586 return {
18587 close : e.getTarget('.x-tab-strip-close', this.strip),
18588 item : item,
18589 el : itemEl
18590 };
18591 },
18593 onStripMouseDown : function(e){
18594 e.preventDefault();
18595 if(e.button != 0){
18596 return;
18598 var t = this.findTargets(e);
18599 if(t.close){
18600 this.remove(t.item);
18601 return;
18603 if(t.item && t.item != this.activeTab){
18604 this.setActiveTab(t.item);
18606 },
18608 onStripClick : function(e){
18609 var t = this.findTargets(e);
18610 if(!t.close && t.item && t.item != this.activeTab){
18611 this.setActiveTab(t.item);
18613 },
18615 onStripContextMenu : function(e){
18616 e.preventDefault();
18617 var t = this.findTargets(e);
18618 if(t.item){
18619 this.fireEvent('contextmenu', this, t.item, e);
18621 },
18624 readTabs : function(removeExisting){
18625 if(removeExisting === true){
18626 this.items.each(function(item){
18627 this.remove(item);
18628 }, this);
18630 var tabs = this.el.query(this.autoTabSelector);
18631 for(var i = 0, len = tabs.length; i < len; i++){
18632 var tab = tabs[i];
18633 var title = tab.getAttribute('title');
18634 tab.removeAttribute('title');
18635 this.add({
18636 title: title,
18637 el: tab
18638 });
18640 },
18642 initTab : function(item, index){
18643 var before = this.strip.dom.childNodes[index];
18644 var cls = item.closable ? 'x-tab-strip-closable' : '';
18645 if(item.disabled){
18646 cls += ' x-item-disabled';
18648 if(item.iconCls){
18649 cls += ' x-tab-with-icon';
18651 if(item.tabCls){
18652 cls += ' ' + item.tabCls;
18655 var p = {
18656 id: this.id + this.idDelimiter + item.getItemId(),
18657 text: item.title,
18658 cls: cls,
18659 iconCls: item.iconCls || ''
18660 };
18661 var el = before ?
18662 this.itemTpl.insertBefore(before, p) :
18663 this.itemTpl.append(this.strip, p);
18665 Ext.fly(el).addClassOnOver('x-tab-strip-over');
18667 if(item.tabTip){
18668 Ext.fly(el).child('span.x-tab-strip-text', true).qtip = item.tabTip;
18670 item.on('disable', this.onItemDisabled, this);
18671 item.on('enable', this.onItemEnabled, this);
18672 item.on('titlechange', this.onItemTitleChanged, this);
18673 item.on('beforeshow', this.onBeforeShowItem, this);
18674 },
18676 onAdd : function(tp, item, index){
18677 this.initTab(item, index);
18678 if(this.items.getCount() == 1){
18679 this.syncSize();
18681 this.delegateUpdates();
18682 },
18684 onBeforeAdd : function(item){
18685 var existing = item.events ? (this.items.containsKey(item.getItemId()) ? item : null) : this.items.get(item);
18686 if(existing){
18687 this.setActiveTab(item);
18688 return false;
18690 Ext.TabPanel.superclass.onBeforeAdd.apply(this, arguments);
18691 var es = item.elements;
18692 item.elements = es ? es.replace(',header', '') : es;
18693 item.border = (item.border === true);
18694 },
18696 onRemove : function(tp, item){
18697 Ext.removeNode(this.getTabEl(item));
18698 this.stack.remove(item);
18699 item.un('disable', this.onItemDisabled, this);
18700 item.un('enable', this.onItemEnabled, this);
18701 item.un('titlechange', this.onItemTitleChanged, this);
18702 item.un('beforeshow', this.onBeforeShowItem, this);
18703 if(item == this.activeTab){
18704 var next = this.stack.next();
18705 if(next){
18706 this.setActiveTab(next);
18707 }else{
18708 this.setActiveTab(0);
18711 this.delegateUpdates();
18712 },
18714 onBeforeShowItem : function(item){
18715 if(item != this.activeTab){
18716 this.setActiveTab(item);
18717 return false;
18719 },
18721 onItemDisabled : function(item){
18722 var el = this.getTabEl(item);
18723 if(el){
18724 Ext.fly(el).addClass('x-item-disabled');
18726 this.stack.remove(item);
18727 },
18729 onItemEnabled : function(item){
18730 var el = this.getTabEl(item);
18731 if(el){
18732 Ext.fly(el).removeClass('x-item-disabled');
18734 },
18736 onItemTitleChanged : function(item){
18737 var el = this.getTabEl(item);
18738 if(el){
18739 Ext.fly(el).child('span.x-tab-strip-text', true).innerHTML = item.title;
18741 },
18744 getTabEl : function(item){
18745 var itemId = (typeof item === 'number')?this.items.items[item].getItemId() : item.getItemId();
18746 return document.getElementById(this.id+this.idDelimiter+itemId);
18747 },
18749 onResize : function(){
18750 Ext.TabPanel.superclass.onResize.apply(this, arguments);
18751 this.delegateUpdates();
18752 },
18755 beginUpdate : function(){
18756 this.suspendUpdates = true;
18757 },
18760 endUpdate : function(){
18761 this.suspendUpdates = false;
18762 this.delegateUpdates();
18763 },
18766 hideTabStripItem : function(item){
18767 item = this.getComponent(item);
18768 var el = this.getTabEl(item);
18769 if(el){
18770 el.style.display = 'none';
18771 this.delegateUpdates();
18773 this.stack.remove(item);
18774 },
18777 unhideTabStripItem : function(item){
18778 item = this.getComponent(item);
18779 var el = this.getTabEl(item);
18780 if(el){
18781 el.style.display = '';
18782 this.delegateUpdates();
18784 },
18786 delegateUpdates : function(){
18787 if(this.suspendUpdates){
18788 return;
18790 if(this.resizeTabs && this.rendered){
18791 this.autoSizeTabs();
18793 if(this.enableTabScroll && this.rendered){
18794 this.autoScrollTabs();
18796 },
18798 autoSizeTabs : function(){
18799 var count = this.items.length;
18800 var ce = this.tabPosition != 'bottom' ? 'header' : 'footer';
18801 var ow = this[ce].dom.offsetWidth;
18802 var aw = this[ce].dom.clientWidth;
18804 if(!this.resizeTabs || count < 1 || !aw){ return;
18807 var each = Math.max(Math.min(Math.floor((aw-4) / count) - this.tabMargin, this.tabWidth), this.minTabWidth); this.lastTabWidth = each;
18808 var lis = this.stripWrap.dom.getElementsByTagName('li');
18809 for(var i = 0, len = lis.length-1; i < len; i++) { var li = lis[i];
18810 var inner = li.childNodes[1].firstChild.firstChild;
18811 var tw = li.offsetWidth;
18812 var iw = inner.offsetWidth;
18813 inner.style.width = (each - (tw-iw)) + 'px';
18815 },
18817 adjustBodyWidth : function(w){
18818 if(this.header){
18819 this.header.setWidth(w);
18821 if(this.footer){
18822 this.footer.setWidth(w);
18824 return w;
18825 },
18828 setActiveTab : function(item){
18829 item = this.getComponent(item);
18830 if(!item || this.fireEvent('beforetabchange', this, item, this.activeTab) === false){
18831 return;
18833 if(!this.rendered){
18834 this.activeTab = item;
18835 return;
18837 if(this.activeTab != item){
18838 if(this.activeTab){
18839 var oldEl = this.getTabEl(this.activeTab);
18840 if(oldEl){
18841 Ext.fly(oldEl).removeClass('x-tab-strip-active');
18843 this.activeTab.fireEvent('deactivate', this.activeTab);
18845 var el = this.getTabEl(item);
18846 Ext.fly(el).addClass('x-tab-strip-active');
18847 this.activeTab = item;
18848 this.stack.add(item);
18850 this.layout.setActiveItem(item);
18851 if(this.layoutOnTabChange && item.doLayout){
18852 item.doLayout();
18854 if(this.scrolling){
18855 this.scrollToTab(item, this.animScroll);
18858 item.fireEvent('activate', item);
18859 this.fireEvent('tabchange', this, item);
18861 },
18864 getActiveTab : function(){
18865 return this.activeTab || null;
18866 },
18869 getItem : function(item){
18870 return this.getComponent(item);
18871 },
18873 autoScrollTabs : function(){
18874 var count = this.items.length;
18875 var ow = this.header.dom.offsetWidth;
18876 var tw = this.header.dom.clientWidth;
18878 var wrap = this.stripWrap;
18879 var wd = wrap.dom;
18880 var cw = wd.offsetWidth;
18881 var pos = this.getScrollPos();
18882 var l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos;
18884 if(!this.enableTabScroll || count < 1 || cw < 20){ return;
18886 if(l <= tw){
18887 wd.scrollLeft = 0;
18888 wrap.setWidth(tw);
18889 if(this.scrolling){
18890 this.scrolling = false;
18891 this.header.removeClass('x-tab-scrolling');
18892 this.scrollLeft.hide();
18893 this.scrollRight.hide();
18894 if(Ext.isAir){
18895 wd.style.marginLeft = '';
18896 wd.style.marginRight = '';
18899 }else{
18900 if(!this.scrolling){
18901 this.header.addClass('x-tab-scrolling');
18902 if(Ext.isAir){
18903 wd.style.marginLeft = '18px';
18904 wd.style.marginRight = '18px';
18907 tw -= wrap.getMargins('lr');
18908 wrap.setWidth(tw > 20 ? tw : 20);
18909 if(!this.scrolling){
18910 if(!this.scrollLeft){
18911 this.createScrollers();
18912 }else{
18913 this.scrollLeft.show();
18914 this.scrollRight.show();
18917 this.scrolling = true;
18918 if(pos > (l-tw)){ wd.scrollLeft = l-tw;
18919 }else{ this.scrollToTab(this.activeTab, false);
18921 this.updateScrollButtons();
18923 },
18925 createScrollers : function(){
18926 var h = this.stripWrap.dom.offsetHeight;
18928 var sl = this.header.insertFirst({
18929 cls:'x-tab-scroller-left'
18930 });
18931 sl.setHeight(h);
18932 sl.addClassOnOver('x-tab-scroller-left-over');
18933 this.leftRepeater = new Ext.util.ClickRepeater(sl, {
18934 interval : this.scrollRepeatInterval,
18935 handler: this.onScrollLeft,
18936 scope: this
18937 });
18938 this.scrollLeft = sl;
18940 var sr = this.header.insertFirst({
18941 cls:'x-tab-scroller-right'
18942 });
18943 sr.setHeight(h);
18944 sr.addClassOnOver('x-tab-scroller-right-over');
18945 this.rightRepeater = new Ext.util.ClickRepeater(sr, {
18946 interval : this.scrollRepeatInterval,
18947 handler: this.onScrollRight,
18948 scope: this
18949 });
18950 this.scrollRight = sr;
18951 },
18953 getScrollWidth : function(){
18954 return this.edge.getOffsetsTo(this.stripWrap)[0] + this.getScrollPos();
18955 },
18957 getScrollPos : function(){
18958 return parseInt(this.stripWrap.dom.scrollLeft, 10) || 0;
18959 },
18961 getScrollArea : function(){
18962 return parseInt(this.stripWrap.dom.clientWidth, 10) || 0;
18963 },
18965 getScrollAnim : function(){
18966 return {duration:this.scrollDuration, callback: this.updateScrollButtons, scope: this};
18967 },
18969 getScrollIncrement : function(){
18970 return this.scrollIncrement || (this.resizeTabs ? this.lastTabWidth+2 : 100);
18971 },
18975 scrollToTab : function(item, animate){
18976 if(!item){ return; }
18977 var el = this.getTabEl(item);
18978 var pos = this.getScrollPos(), area = this.getScrollArea();
18979 var left = Ext.fly(el).getOffsetsTo(this.stripWrap)[0] + pos;
18980 var right = left + el.offsetWidth;
18981 if(left < pos){
18982 this.scrollTo(left, animate);
18983 }else if(right > (pos + area)){
18984 this.scrollTo(right - area, animate);
18986 },
18988 scrollTo : function(pos, animate){
18989 this.stripWrap.scrollTo('left', pos, animate ? this.getScrollAnim() : false);
18990 if(!animate){
18991 this.updateScrollButtons();
18993 },
18995 onWheel : function(e){
18996 var d = e.getWheelDelta()*this.wheelIncrement*-1;
18997 e.stopEvent();
18999 var pos = this.getScrollPos();
19000 var newpos = pos + d;
19001 var sw = this.getScrollWidth()-this.getScrollArea();
19003 var s = Math.max(0, Math.min(sw, newpos));
19004 if(s != pos){
19005 this.scrollTo(s, false);
19007 },
19009 onScrollRight : function(){
19010 var sw = this.getScrollWidth()-this.getScrollArea();
19011 var pos = this.getScrollPos();
19012 var s = Math.min(sw, pos + this.getScrollIncrement());
19013 if(s != pos){
19014 this.scrollTo(s, this.animScroll);
19016 },
19018 onScrollLeft : function(){
19019 var pos = this.getScrollPos();
19020 var s = Math.max(0, pos - this.getScrollIncrement());
19021 if(s != pos){
19022 this.scrollTo(s, this.animScroll);
19024 },
19026 updateScrollButtons : function(){
19027 var pos = this.getScrollPos();
19028 this.scrollLeft[pos == 0 ? 'addClass' : 'removeClass']('x-tab-scroller-left-disabled');
19029 this.scrollRight[pos >= (this.getScrollWidth()-this.getScrollArea()) ? 'addClass' : 'removeClass']('x-tab-scroller-right-disabled');
19044 });
19045 Ext.reg('tabpanel', Ext.TabPanel);
19048 Ext.TabPanel.prototype.activate = Ext.TabPanel.prototype.setActiveTab;
19050 Ext.TabPanel.AccessStack = function(){
19051 var items = [];
19052 return {
19053 add : function(item){
19054 items.push(item);
19055 if(items.length > 10){
19056 items.shift();
19058 },
19060 remove : function(item){
19061 var s = [];
19062 for(var i = 0, len = items.length; i < len; i++) {
19063 if(items[i] != item){
19064 s.push(items[i]);
19067 items = s;
19068 },
19070 next : function(){
19071 return items.pop();
19073 };
19074 };
19079 Ext.Button = Ext.extend(Ext.Component, {
19081 hidden : false,
19083 disabled : false,
19085 pressed : false,
19093 enableToggle: false,
19097 menuAlign : "tl-bl?",
19101 type : 'button',
19103 menuClassTarget: 'tr',
19106 clickEvent : 'click',
19109 handleMouseEvents : true,
19112 tooltipType : 'qtip',
19114 buttonSelector : "button:first",
19119 initComponent : function(){
19120 Ext.Button.superclass.initComponent.call(this);
19122 this.addEvents(
19124 "click",
19126 "toggle",
19128 'mouseover',
19130 'mouseout',
19132 'menushow',
19134 'menuhide',
19136 'menutriggerover',
19138 'menutriggerout'
19139 );
19140 if(this.menu){
19141 this.menu = Ext.menu.MenuMgr.get(this.menu);
19143 if(typeof this.toggleGroup === 'string'){
19144 this.enableToggle = true;
19146 },
19148 onRender : function(ct, position){
19149 if(!this.template){
19150 if(!Ext.Button.buttonTemplate){
19151 Ext.Button.buttonTemplate = new Ext.Template(
19152 '<table border="0" cellpadding="0" cellspacing="0" class="x-btn-wrap"><tbody><tr>',
19153 '<td class="x-btn-left"><i>&#160;</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>&#160;</i></td>',
19154 "</tr></tbody></table>");
19156 this.template = Ext.Button.buttonTemplate;
19158 var btn, targs = [this.text || '&#160;', this.type];
19160 if(position){
19161 btn = this.template.insertBefore(position, targs, true);
19162 }else{
19163 btn = this.template.append(ct, targs, true);
19165 var btnEl = btn.child(this.buttonSelector);
19166 btnEl.on('focus', this.onFocus, this);
19167 btnEl.on('blur', this.onBlur, this);
19169 this.initButtonEl(btn, btnEl);
19171 if(this.menu){
19172 this.el.child(this.menuClassTarget).addClass("x-btn-with-menu");
19174 Ext.ButtonToggleMgr.register(this);
19175 },
19177 initButtonEl : function(btn, btnEl){
19179 this.el = btn;
19180 btn.addClass("x-btn");
19182 if(this.icon){
19183 btnEl.setStyle('background-image', 'url(' +this.icon +')');
19185 if(this.iconCls){
19186 btnEl.addClass(this.iconCls);
19187 if(!this.cls){
19188 btn.addClass(this.text ? 'x-btn-text-icon' : 'x-btn-icon');
19191 if(this.tabIndex !== undefined){
19192 btnEl.dom.tabIndex = this.tabIndex;
19194 if(this.tooltip){
19195 if(typeof this.tooltip == 'object'){
19196 Ext.QuickTips.register(Ext.apply({
19197 target: btnEl.id
19198 }, this.tooltip));
19199 } else {
19200 btnEl.dom[this.tooltipType] = this.tooltip;
19204 if(this.pressed){
19205 this.el.addClass("x-btn-pressed");
19208 if(this.handleMouseEvents){
19209 btn.on("mouseover", this.onMouseOver, this);
19210 btn.on("mousedown", this.onMouseDown, this);
19213 if(this.menu){
19214 this.menu.on("show", this.onMenuShow, this);
19215 this.menu.on("hide", this.onMenuHide, this);
19218 if(this.id){
19219 this.el.dom.id = this.el.id = this.id;
19222 if(this.repeat){
19223 var repeater = new Ext.util.ClickRepeater(btn,
19224 typeof this.repeat == "object" ? this.repeat : {}
19225 );
19226 repeater.on("click", this.onClick, this);
19229 btn.on(this.clickEvent, this.onClick, this);
19230 },
19232 afterRender : function(){
19233 Ext.Button.superclass.afterRender.call(this);
19234 if(Ext.isIE6){
19235 this.autoWidth.defer(1, this);
19236 }else{
19237 this.autoWidth();
19239 },
19242 setIconClass : function(cls){
19243 if(this.el){
19244 this.el.child(this.buttonSelector).replaceClass(this.iconCls, cls);
19246 this.iconCls = cls;
19247 },
19249 beforeDestroy: function(){
19250 if(this.rendered){
19251 var btn = this.el.child(this.buttonSelector);
19252 if(btn){
19253 btn.removeAllListeners();
19256 if(this.menu){
19257 Ext.destroy(this.menu);
19259 },
19261 onDestroy : function(){
19262 if(this.rendered){
19263 Ext.ButtonToggleMgr.unregister(this);
19265 },
19267 autoWidth : function(){
19268 if(this.el){
19269 this.el.setWidth("auto");
19270 if(Ext.isIE7 && Ext.isStrict){
19271 var ib = this.el.child(this.buttonSelector);
19272 if(ib && ib.getWidth() > 20){
19273 ib.clip();
19274 ib.setWidth(Ext.util.TextMetrics.measure(ib, this.text).width+ib.getFrameWidth('lr'));
19277 if(this.minWidth){
19278 if(this.el.getWidth() < this.minWidth){
19279 this.el.setWidth(this.minWidth);
19283 },
19286 setHandler : function(handler, scope){
19287 this.handler = handler;
19288 this.scope = scope;
19289 },
19292 setText : function(text){
19293 this.text = text;
19294 if(this.el){
19295 this.el.child("td.x-btn-center " + this.buttonSelector).update(text);
19297 this.autoWidth();
19298 },
19301 getText : function(){
19302 return this.text;
19303 },
19306 toggle : function(state){
19307 state = state === undefined ? !this.pressed : state;
19308 if(state != this.pressed){
19309 if(state){
19310 this.el.addClass("x-btn-pressed");
19311 this.pressed = true;
19312 this.fireEvent("toggle", this, true);
19313 }else{
19314 this.el.removeClass("x-btn-pressed");
19315 this.pressed = false;
19316 this.fireEvent("toggle", this, false);
19318 if(this.toggleHandler){
19319 this.toggleHandler.call(this.scope || this, this, state);
19322 },
19325 focus : function(){
19326 this.el.child(this.buttonSelector).focus();
19327 },
19329 onDisable : function(){
19330 if(this.el){
19331 if(!Ext.isIE6 || !this.text){
19332 this.el.addClass(this.disabledClass);
19334 this.el.dom.disabled = true;
19336 this.disabled = true;
19337 },
19339 onEnable : function(){
19340 if(this.el){
19341 if(!Ext.isIE6 || !this.text){
19342 this.el.removeClass(this.disabledClass);
19344 this.el.dom.disabled = false;
19346 this.disabled = false;
19347 },
19350 showMenu : function(){
19351 if(this.menu){
19352 this.menu.show(this.el, this.menuAlign);
19354 return this;
19355 },
19358 hideMenu : function(){
19359 if(this.menu){
19360 this.menu.hide();
19362 return this;
19363 },
19366 hasVisibleMenu : function(){
19367 return this.menu && this.menu.isVisible();
19368 },
19370 onClick : function(e){
19371 if(e){
19372 e.preventDefault();
19374 if(e.button != 0){
19375 return;
19377 if(!this.disabled){
19378 if(this.enableToggle && (this.allowDepress !== false || !this.pressed)){
19379 this.toggle();
19381 if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
19382 this.showMenu();
19384 this.fireEvent("click", this, e);
19385 if(this.handler){
19386 this.handler.call(this.scope || this, this, e);
19389 },
19391 isMenuTriggerOver : function(e, internal){
19392 return this.menu && !internal;
19393 },
19395 isMenuTriggerOut : function(e, internal){
19396 return this.menu && !internal;
19397 },
19399 onMouseOver : function(e){
19400 if(!this.disabled){
19401 var internal = e.within(this.el, true);
19402 if(!internal){
19403 this.el.addClass("x-btn-over");
19404 Ext.getDoc().on('mouseover', this.monitorMouseOver, this);
19405 this.fireEvent('mouseover', this, e);
19407 if(this.isMenuTriggerOver(e, internal)){
19408 this.fireEvent('menutriggerover', this, this.menu, e);
19411 },
19413 monitorMouseOver : function(e){
19414 if(e.target != this.el.dom && !e.within(this.el)){
19415 Ext.getDoc().un('mouseover', this.monitorMouseOver, this);
19416 this.onMouseOut(e);
19418 },
19420 onMouseOut : function(e){
19421 var internal = e.within(this.el) && e.target != this.el.dom;
19422 this.el.removeClass("x-btn-over");
19423 this.fireEvent('mouseout', this, e);
19424 if(this.isMenuTriggerOut(e, internal)){
19425 this.fireEvent('menutriggerout', this, this.menu, e);
19427 },
19428 onFocus : function(e){
19429 if(!this.disabled){
19430 this.el.addClass("x-btn-focus");
19432 },
19433 onBlur : function(e){
19434 this.el.removeClass("x-btn-focus");
19435 },
19437 getClickEl : function(e, isUp){
19438 return this.el;
19439 },
19441 onMouseDown : function(e){
19442 if(!this.disabled && e.button == 0){
19443 this.getClickEl(e).addClass("x-btn-click");
19444 Ext.getDoc().on('mouseup', this.onMouseUp, this);
19446 },
19447 onMouseUp : function(e){
19448 if(e.button == 0){
19449 this.getClickEl(e, true).removeClass("x-btn-click");
19450 Ext.getDoc().un('mouseup', this.onMouseUp, this);
19452 },
19453 onMenuShow : function(e){
19454 this.ignoreNextClick = 0;
19455 this.el.addClass("x-btn-menu-active");
19456 this.fireEvent('menushow', this, this.menu);
19457 },
19458 onMenuHide : function(e){
19459 this.el.removeClass("x-btn-menu-active");
19460 this.ignoreNextClick = this.restoreClick.defer(250, this);
19461 this.fireEvent('menuhide', this, this.menu);
19462 },
19464 restoreClick : function(){
19465 this.ignoreNextClick = 0;
19471 });
19472 Ext.reg('button', Ext.Button);
19474 Ext.ButtonToggleMgr = function(){
19475 var groups = {};
19477 function toggleGroup(btn, state){
19478 if(state){
19479 var g = groups[btn.toggleGroup];
19480 for(var i = 0, l = g.length; i < l; i++){
19481 if(g[i] != btn){
19482 g[i].toggle(false);
19488 return {
19489 register : function(btn){
19490 if(!btn.toggleGroup){
19491 return;
19493 var g = groups[btn.toggleGroup];
19494 if(!g){
19495 g = groups[btn.toggleGroup] = [];
19497 g.push(btn);
19498 btn.on("toggle", toggleGroup);
19499 },
19501 unregister : function(btn){
19502 if(!btn.toggleGroup){
19503 return;
19505 var g = groups[btn.toggleGroup];
19506 if(g){
19507 g.remove(btn);
19508 btn.un("toggle", toggleGroup);
19511 };
19512 }();
19514 Ext.SplitButton = Ext.extend(Ext.Button, {
19516 arrowSelector : 'button:last',
19519 initComponent : function(){
19520 Ext.SplitButton.superclass.initComponent.call(this);
19522 this.addEvents("arrowclick");
19523 },
19526 onRender : function(ct, position){
19528 var tpl = new Ext.Template(
19529 '<table cellspacing="0" class="x-btn-menu-wrap x-btn"><tr><td>',
19530 '<table cellspacing="0" class="x-btn-wrap x-btn-menu-text-wrap"><tbody>',
19531 '<tr><td class="x-btn-left"><i>&#160;</i></td><td class="x-btn-center"><button class="x-btn-text" type="{1}">{0}</button></td></tr>',
19532 "</tbody></table></td><td>",
19533 '<table cellspacing="0" class="x-btn-wrap x-btn-menu-arrow-wrap"><tbody>',
19534 '<tr><td class="x-btn-center"><button class="x-btn-menu-arrow-el" type="button">&#160;</button></td><td class="x-btn-right"><i>&#160;</i></td></tr>',
19535 "</tbody></table></td></tr></table>"
19536 );
19537 var btn, targs = [this.text || '&#160;', this.type];
19538 if(position){
19539 btn = tpl.insertBefore(position, targs, true);
19540 }else{
19541 btn = tpl.append(ct, targs, true);
19543 var btnEl = btn.child(this.buttonSelector);
19545 this.initButtonEl(btn, btnEl);
19546 this.arrowBtnTable = btn.child("table:last");
19547 if(this.arrowTooltip){
19548 btn.child(this.arrowSelector).dom[this.tooltipType] = this.arrowTooltip;
19550 },
19553 autoWidth : function(){
19554 if(this.el){
19555 var tbl = this.el.child("table:first");
19556 var tbl2 = this.el.child("table:last");
19557 this.el.setWidth("auto");
19558 tbl.setWidth("auto");
19559 if(Ext.isIE7 && Ext.isStrict){
19560 var ib = this.el.child(this.buttonSelector);
19561 if(ib && ib.getWidth() > 20){
19562 ib.clip();
19563 ib.setWidth(Ext.util.TextMetrics.measure(ib, this.text).width+ib.getFrameWidth('lr'));
19566 if(this.minWidth){
19567 if((tbl.getWidth()+tbl2.getWidth()) < this.minWidth){
19568 tbl.setWidth(this.minWidth-tbl2.getWidth());
19571 this.el.setWidth(tbl.getWidth()+tbl2.getWidth());
19573 },
19576 setArrowHandler : function(handler, scope){
19577 this.arrowHandler = handler;
19578 this.scope = scope;
19579 },
19582 onClick : function(e){
19583 e.preventDefault();
19584 if(!this.disabled){
19585 if(e.getTarget(".x-btn-menu-arrow-wrap")){
19586 if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
19587 this.showMenu();
19589 this.fireEvent("arrowclick", this, e);
19590 if(this.arrowHandler){
19591 this.arrowHandler.call(this.scope || this, this, e);
19593 }else{
19594 if(this.enableToggle){
19595 this.toggle();
19597 this.fireEvent("click", this, e);
19598 if(this.handler){
19599 this.handler.call(this.scope || this, this, e);
19603 },
19606 getClickEl : function(e, isUp){
19607 if(!isUp){
19608 return (this.lastClickEl = e.getTarget("table", 10, true));
19610 return this.lastClickEl;
19611 },
19614 onDisable : function(){
19615 if(this.el){
19616 if(!Ext.isIE6){
19617 this.el.addClass("x-item-disabled");
19619 this.el.child(this.buttonSelector).dom.disabled = true;
19620 this.el.child(this.arrowSelector).dom.disabled = true;
19622 this.disabled = true;
19623 },
19626 onEnable : function(){
19627 if(this.el){
19628 if(!Ext.isIE6){
19629 this.el.removeClass("x-item-disabled");
19631 this.el.child(this.buttonSelector).dom.disabled = false;
19632 this.el.child(this.arrowSelector).dom.disabled = false;
19634 this.disabled = false;
19635 },
19638 isMenuTriggerOver : function(e){
19639 return this.menu && e.within(this.arrowBtnTable) && !e.within(this.arrowBtnTable, true);
19640 },
19643 isMenuTriggerOut : function(e, internal){
19644 return this.menu && !e.within(this.arrowBtnTable);
19645 },
19648 onDestroy : function(){
19649 Ext.destroy(this.arrowBtnTable);
19650 Ext.SplitButton.superclass.onDestroy.call(this);
19652 });
19655 Ext.MenuButton = Ext.SplitButton;
19658 Ext.reg('splitbutton', Ext.SplitButton);
19660 Ext.CycleButton = Ext.extend(Ext.SplitButton, {
19668 getItemText : function(item){
19669 if(item && this.showText === true){
19670 var text = '';
19671 if(this.prependText){
19672 text += this.prependText;
19674 text += item.text;
19675 return text;
19677 return undefined;
19678 },
19681 setActiveItem : function(item, suppressEvent){
19682 if(typeof item != 'object'){
19683 item = this.menu.items.get(item);
19685 if(item){
19686 if(!this.rendered){
19687 this.text = this.getItemText(item);
19688 this.iconCls = item.iconCls;
19689 }else{
19690 var t = this.getItemText(item);
19691 if(t){
19692 this.setText(t);
19694 this.setIconClass(item.iconCls);
19696 this.activeItem = item;
19697 if(!item.checked){
19698 item.setChecked(true, true);
19700 if(this.forceIcon){
19701 this.setIconClass(this.forceIcon);
19703 if(!suppressEvent){
19704 this.fireEvent('change', this, item);
19707 },
19710 getActiveItem : function(){
19711 return this.activeItem;
19712 },
19715 initComponent : function(){
19716 this.addEvents(
19718 "change"
19719 );
19721 if(this.changeHandler){
19722 this.on('change', this.changeHandler, this.scope||this);
19723 delete this.changeHandler;
19726 this.itemCount = this.items.length;
19728 this.menu = {cls:'x-cycle-menu', items:[]};
19729 var checked;
19730 for(var i = 0, len = this.itemCount; i < len; i++){
19731 var item = this.items[i];
19732 item.group = item.group || this.id;
19733 item.itemIndex = i;
19734 item.checkHandler = this.checkHandler;
19735 item.scope = this;
19736 item.checked = item.checked || false;
19737 this.menu.items.push(item);
19738 if(item.checked){
19739 checked = item;
19742 this.setActiveItem(checked, true);
19743 Ext.CycleButton.superclass.initComponent.call(this);
19745 this.on('click', this.toggleSelected, this);
19746 },
19749 checkHandler : function(item, pressed){
19750 if(pressed){
19751 this.setActiveItem(item);
19753 },
19756 toggleSelected : function(){
19757 this.menu.render();
19759 var nextIdx, checkItem;
19760 for (var i = 1; i < this.itemCount; i++) {
19761 nextIdx = (this.activeItem.itemIndex + i) % this.itemCount;
19763 checkItem = this.menu.items.itemAt(nextIdx);
19765 if (!checkItem.disabled) {
19766 checkItem.setChecked(true);
19767 break;
19771 });
19772 Ext.reg('cycle', Ext.CycleButton);
19774 Ext.Toolbar = function(config){
19775 if(Ext.isArray(config)){
19776 config = {buttons:config};
19778 Ext.Toolbar.superclass.constructor.call(this, config);
19779 };
19781 (function(){
19783 var T = Ext.Toolbar;
19785 Ext.extend(T, Ext.BoxComponent, {
19787 trackMenus : true,
19790 initComponent : function(){
19791 T.superclass.initComponent.call(this);
19793 if(this.items){
19794 this.buttons = this.items;
19797 this.items = new Ext.util.MixedCollection(false, function(o){
19798 return o.itemId || o.id || Ext.id();
19799 });
19800 },
19803 autoCreate: {
19804 cls:'x-toolbar x-small-editor',
19805 html:'<table cellspacing="0"><tr></tr></table>'
19806 },
19809 onRender : function(ct, position){
19810 this.el = ct.createChild(Ext.apply({ id: this.id },this.autoCreate), position);
19811 this.tr = this.el.child("tr", true);
19812 },
19815 afterRender : function(){
19816 T.superclass.afterRender.call(this);
19817 if(this.buttons){
19818 this.add.apply(this, this.buttons);
19819 delete this.buttons;
19821 },
19824 add : function(){
19825 var a = arguments, l = a.length;
19826 for(var i = 0; i < l; i++){
19827 var el = a[i];
19828 if(el.isFormField){
19829 this.addField(el);
19830 }else if(el.render){
19831 this.addItem(el);
19832 }else if(typeof el == "string"){
19833 if(el == "separator" || el == "-"){
19834 this.addSeparator();
19835 }else if(el == " "){
19836 this.addSpacer();
19837 }else if(el == "->"){
19838 this.addFill();
19839 }else{
19840 this.addText(el);
19842 }else if(el.tagName){
19843 this.addElement(el);
19844 }else if(typeof el == "object"){
19845 if(el.xtype){
19846 this.addField(Ext.ComponentMgr.create(el, 'button'));
19847 }else{
19848 this.addButton(el);
19852 },
19855 addSeparator : function(){
19856 return this.addItem(new T.Separator());
19857 },
19860 addSpacer : function(){
19861 return this.addItem(new T.Spacer());
19862 },
19865 addFill : function(){
19866 return this.addItem(new T.Fill());
19867 },
19870 addElement : function(el){
19871 return this.addItem(new T.Item(el));
19872 },
19875 addItem : function(item){
19876 var td = this.nextBlock();
19877 this.initMenuTracking(item);
19878 item.render(td);
19879 this.items.add(item);
19880 return item;
19881 },
19884 addButton : function(config){
19885 if(Ext.isArray(config)){
19886 var buttons = [];
19887 for(var i = 0, len = config.length; i < len; i++) {
19888 buttons.push(this.addButton(config[i]));
19890 return buttons;
19892 var b = config;
19893 if(!(config instanceof T.Button)){
19894 b = config.split ?
19895 new T.SplitButton(config) :
19896 new T.Button(config);
19898 var td = this.nextBlock();
19899 this.initMenuTracking(b);
19900 b.render(td);
19901 this.items.add(b);
19902 return b;
19903 },
19906 initMenuTracking : function(item){
19907 if(this.trackMenus && item.menu){
19908 item.on({
19909 'menutriggerover' : this.onButtonTriggerOver,
19910 'menushow' : this.onButtonMenuShow,
19911 'menuhide' : this.onButtonMenuHide,
19912 scope: this
19913 })
19915 },
19918 addText : function(text){
19919 return this.addItem(new T.TextItem(text));
19920 },
19923 insertButton : function(index, item){
19924 if(Ext.isArray(item)){
19925 var buttons = [];
19926 for(var i = 0, len = item.length; i < len; i++) {
19927 buttons.push(this.insertButton(index + i, item[i]));
19929 return buttons;
19931 if (!(item instanceof T.Button)){
19932 item = new T.Button(item);
19934 var td = document.createElement("td");
19935 this.tr.insertBefore(td, this.tr.childNodes[index]);
19936 this.initMenuTracking(item);
19937 item.render(td);
19938 this.items.insert(index, item);
19939 return item;
19940 },
19943 addDom : function(config, returnEl){
19944 var td = this.nextBlock();
19945 Ext.DomHelper.overwrite(td, config);
19946 var ti = new T.Item(td.firstChild);
19947 ti.render(td);
19948 this.items.add(ti);
19949 return ti;
19950 },
19953 addField : function(field){
19954 var td = this.nextBlock();
19955 field.render(td);
19956 var ti = new T.Item(td.firstChild);
19957 ti.render(td);
19958 this.items.add(ti);
19959 return ti;
19960 },
19963 nextBlock : function(){
19964 var td = document.createElement("td");
19965 this.tr.appendChild(td);
19966 return td;
19967 },
19970 onDestroy : function(){
19971 Ext.Toolbar.superclass.onDestroy.call(this);
19972 if(this.rendered){
19973 if(this.items){
19974 Ext.destroy.apply(Ext, this.items.items);
19976 Ext.Element.uncache(this.tr);
19978 },
19981 onDisable : function(){
19982 this.items.each(function(item){
19983 if(item.disable){
19984 item.disable();
19986 });
19987 },
19990 onEnable : function(){
19991 this.items.each(function(item){
19992 if(item.enable){
19993 item.enable();
19995 });
19996 },
19999 onButtonTriggerOver : function(btn){
20000 if(this.activeMenuBtn && this.activeMenuBtn != btn){
20001 this.activeMenuBtn.hideMenu();
20002 btn.showMenu();
20003 this.activeMenuBtn = btn;
20005 },
20008 onButtonMenuShow : function(btn){
20009 this.activeMenuBtn = btn;
20010 },
20013 onButtonMenuHide : function(btn){
20014 delete this.activeMenuBtn;
20018 });
20019 Ext.reg('toolbar', Ext.Toolbar);
20022 T.Item = function(el){
20023 this.el = Ext.getDom(el);
20024 this.id = Ext.id(this.el);
20025 this.hidden = false;
20026 };
20028 T.Item.prototype = {
20031 getEl : function(){
20032 return this.el;
20033 },
20036 render : function(td){
20037 this.td = td;
20038 td.appendChild(this.el);
20039 },
20042 destroy : function(){
20043 if(this.td && this.td.parentNode){
20044 this.td.parentNode.removeChild(this.td);
20046 },
20049 show: function(){
20050 this.hidden = false;
20051 this.td.style.display = "";
20052 },
20055 hide: function(){
20056 this.hidden = true;
20057 this.td.style.display = "none";
20058 },
20061 setVisible: function(visible){
20062 if(visible) {
20063 this.show();
20064 }else{
20065 this.hide();
20067 },
20070 focus : function(){
20071 Ext.fly(this.el).focus();
20072 },
20075 disable : function(){
20076 Ext.fly(this.td).addClass("x-item-disabled");
20077 this.disabled = true;
20078 this.el.disabled = true;
20079 },
20082 enable : function(){
20083 Ext.fly(this.td).removeClass("x-item-disabled");
20084 this.disabled = false;
20085 this.el.disabled = false;
20087 };
20088 Ext.reg('tbitem', T.Item);
20092 T.Separator = function(){
20093 var s = document.createElement("span");
20094 s.className = "ytb-sep";
20095 T.Separator.superclass.constructor.call(this, s);
20096 };
20097 Ext.extend(T.Separator, T.Item, {
20098 enable:Ext.emptyFn,
20099 disable:Ext.emptyFn,
20100 focus:Ext.emptyFn
20101 });
20102 Ext.reg('tbseparator', T.Separator);
20105 T.Spacer = function(){
20106 var s = document.createElement("div");
20107 s.className = "ytb-spacer";
20108 T.Spacer.superclass.constructor.call(this, s);
20109 };
20110 Ext.extend(T.Spacer, T.Item, {
20111 enable:Ext.emptyFn,
20112 disable:Ext.emptyFn,
20113 focus:Ext.emptyFn
20114 });
20116 Ext.reg('tbspacer', T.Spacer);
20119 T.Fill = Ext.extend(T.Spacer, {
20121 render : function(td){
20122 td.style.width = '100%';
20123 T.Fill.superclass.render.call(this, td);
20125 });
20126 Ext.reg('tbfill', T.Fill);
20129 T.TextItem = function(t){
20130 var s = document.createElement("span");
20131 s.className = "ytb-text";
20132 s.innerHTML = t.text ? t.text : t;
20133 T.TextItem.superclass.constructor.call(this, s);
20134 };
20135 Ext.extend(T.TextItem, T.Item, {
20136 enable:Ext.emptyFn,
20137 disable:Ext.emptyFn,
20138 focus:Ext.emptyFn
20139 });
20140 Ext.reg('tbtext', T.TextItem);
20144 T.Button = Ext.extend(Ext.Button, {
20145 hideParent : true,
20147 onDestroy : function(){
20148 T.Button.superclass.onDestroy.call(this);
20149 if(this.container){
20150 this.container.remove();
20153 });
20154 Ext.reg('tbbutton', T.Button);
20157 T.SplitButton = Ext.extend(Ext.SplitButton, {
20158 hideParent : true,
20160 onDestroy : function(){
20161 T.SplitButton.superclass.onDestroy.call(this);
20162 if(this.container){
20163 this.container.remove();
20166 });
20168 Ext.reg('tbsplit', T.SplitButton);
20170 T.MenuButton = T.SplitButton;
20172 })();
20175 Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {
20179 pageSize: 20,
20181 displayMsg : 'Displaying {0} - {1} of {2}',
20183 emptyMsg : 'No data to display',
20185 beforePageText : "Page",
20187 afterPageText : "of {0}",
20189 firstText : "First Page",
20191 prevText : "Previous Page",
20193 nextText : "Next Page",
20195 lastText : "Last Page",
20197 refreshText : "Refresh",
20200 paramNames : {start: 'start', limit: 'limit'},
20202 initComponent : function(){
20203 Ext.PagingToolbar.superclass.initComponent.call(this);
20204 this.cursor = 0;
20205 this.bind(this.store);
20206 },
20208 onRender : function(ct, position){
20209 Ext.PagingToolbar.superclass.onRender.call(this, ct, position);
20210 this.first = this.addButton({
20211 tooltip: this.firstText,
20212 iconCls: "x-tbar-page-first",
20213 disabled: true,
20214 handler: this.onClick.createDelegate(this, ["first"])
20215 });
20216 this.prev = this.addButton({
20217 tooltip: this.prevText,
20218 iconCls: "x-tbar-page-prev",
20219 disabled: true,
20220 handler: this.onClick.createDelegate(this, ["prev"])
20221 });
20222 this.addSeparator();
20223 this.add(this.beforePageText);
20224 this.field = Ext.get(this.addDom({
20225 tag: "input",
20226 type: "text",
20227 size: "3",
20228 value: "1",
20229 cls: "x-tbar-page-number"
20230 }).el);
20231 this.field.on("keydown", this.onPagingKeydown, this);
20232 this.field.on("focus", function(){this.dom.select();});
20233 this.afterTextEl = this.addText(String.format(this.afterPageText, 1));
20234 this.field.setHeight(18);
20235 this.addSeparator();
20236 this.next = this.addButton({
20237 tooltip: this.nextText,
20238 iconCls: "x-tbar-page-next",
20239 disabled: true,
20240 handler: this.onClick.createDelegate(this, ["next"])
20241 });
20242 this.last = this.addButton({
20243 tooltip: this.lastText,
20244 iconCls: "x-tbar-page-last",
20245 disabled: true,
20246 handler: this.onClick.createDelegate(this, ["last"])
20247 });
20248 this.addSeparator();
20249 this.loading = this.addButton({
20250 tooltip: this.refreshText,
20251 iconCls: "x-tbar-loading",
20252 handler: this.onClick.createDelegate(this, ["refresh"])
20253 });
20255 if(this.displayInfo){
20256 this.displayEl = Ext.fly(this.el.dom).createChild({cls:'x-paging-info'});
20258 if(this.dsLoaded){
20259 this.onLoad.apply(this, this.dsLoaded);
20261 },
20263 updateInfo : function(){
20264 if(this.displayEl){
20265 var count = this.store.getCount();
20266 var msg = count == 0 ?
20267 this.emptyMsg :
20268 String.format(
20269 this.displayMsg,
20270 this.cursor+1, this.cursor+count, this.store.getTotalCount()
20271 );
20272 this.displayEl.update(msg);
20274 },
20276 onLoad : function(store, r, o){
20277 if(!this.rendered){
20278 this.dsLoaded = [store, r, o];
20279 return;
20281 this.cursor = o.params ? o.params[this.paramNames.start] : 0;
20282 var d = this.getPageData(), ap = d.activePage, ps = d.pages;
20284 this.afterTextEl.el.innerHTML = String.format(this.afterPageText, d.pages);
20285 this.field.dom.value = ap;
20286 this.first.setDisabled(ap == 1);
20287 this.prev.setDisabled(ap == 1);
20288 this.next.setDisabled(ap == ps);
20289 this.last.setDisabled(ap == ps);
20290 this.loading.enable();
20291 this.updateInfo();
20292 },
20294 getPageData : function(){
20295 var total = this.store.getTotalCount();
20296 return {
20297 total : total,
20298 activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize),
20299 pages : total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)
20300 };
20301 },
20303 onLoadError : function(){
20304 if(!this.rendered){
20305 return;
20307 this.loading.enable();
20308 },
20310 readPage : function(d){
20311 var v = this.field.dom.value, pageNum;
20312 if (!v || isNaN(pageNum = parseInt(v, 10))) {
20313 this.field.dom.value = d.activePage;
20314 return false;
20316 return pageNum;
20317 },
20319 onPagingKeydown : function(e){
20320 var k = e.getKey(), d = this.getPageData(), pageNum;
20321 if (k == e.RETURN) {
20322 e.stopEvent();
20323 if(pageNum = this.readPage(d)){
20324 pageNum = Math.min(Math.max(1, pageNum), d.pages) - 1;
20325 this.doLoad(pageNum * this.pageSize);
20327 }else if (k == e.HOME || k == e.END){
20328 e.stopEvent();
20329 pageNum = k == e.HOME ? 1 : d.pages;
20330 this.field.dom.value = pageNum;
20331 }else if (k == e.UP || k == e.PAGEUP || k == e.DOWN || k == e.PAGEDOWN){
20332 e.stopEvent();
20333 if(pageNum = this.readPage(d)){
20334 var increment = e.shiftKey ? 10 : 1;
20335 if(k == e.DOWN || k == e.PAGEDOWN){
20336 increment *= -1;
20338 pageNum += increment;
20339 if(pageNum >= 1 & pageNum <= d.pages){
20340 this.field.dom.value = pageNum;
20344 },
20346 beforeLoad : function(){
20347 if(this.rendered && this.loading){
20348 this.loading.disable();
20350 },
20352 doLoad : function(start){
20353 var o = {}, pn = this.paramNames;
20354 o[pn.start] = start;
20355 o[pn.limit] = this.pageSize;
20356 this.store.load({params:o});
20357 },
20359 onClick : function(which){
20360 var store = this.store;
20361 switch(which){
20362 case "first":
20363 this.doLoad(0);
20364 break;
20365 case "prev":
20366 this.doLoad(Math.max(0, this.cursor-this.pageSize));
20367 break;
20368 case "next":
20369 this.doLoad(this.cursor+this.pageSize);
20370 break;
20371 case "last":
20372 var total = store.getTotalCount();
20373 var extra = total % this.pageSize;
20374 var lastStart = extra ? (total - extra) : total-this.pageSize;
20375 this.doLoad(lastStart);
20376 break;
20377 case "refresh":
20378 this.doLoad(this.cursor);
20379 break;
20381 },
20384 unbind : function(store){
20385 store = Ext.StoreMgr.lookup(store);
20386 store.un("beforeload", this.beforeLoad, this);
20387 store.un("load", this.onLoad, this);
20388 store.un("loadexception", this.onLoadError, this);
20389 this.store = undefined;
20390 },
20393 bind : function(store){
20394 store = Ext.StoreMgr.lookup(store);
20395 store.on("beforeload", this.beforeLoad, this);
20396 store.on("load", this.onLoad, this);
20397 store.on("loadexception", this.onLoadError, this);
20398 this.store = store;
20400 });
20401 Ext.reg('paging', Ext.PagingToolbar);
20403 Ext.Resizable = function(el, config){
20404 this.el = Ext.get(el);
20406 if(config && config.wrap){
20407 config.resizeChild = this.el;
20408 this.el = this.el.wrap(typeof config.wrap == "object" ? config.wrap : {cls:"xresizable-wrap"});
20409 this.el.id = this.el.dom.id = config.resizeChild.id + "-rzwrap";
20410 this.el.setStyle("overflow", "hidden");
20411 this.el.setPositioning(config.resizeChild.getPositioning());
20412 config.resizeChild.clearPositioning();
20413 if(!config.width || !config.height){
20414 var csize = config.resizeChild.getSize();
20415 this.el.setSize(csize.width, csize.height);
20417 if(config.pinned && !config.adjustments){
20418 config.adjustments = "auto";
20423 this.proxy = this.el.createProxy({tag: "div", cls: "x-resizable-proxy", id: this.el.id + "-rzproxy"});
20424 this.proxy.unselectable();
20425 this.proxy.enableDisplayMode('block');
20427 Ext.apply(this, config);
20429 if(this.pinned){
20430 this.disableTrackOver = true;
20431 this.el.addClass("x-resizable-pinned");
20434 var position = this.el.getStyle("position");
20435 if(position != "absolute" && position != "fixed"){
20436 this.el.setStyle("position", "relative");
20438 if(!this.handles){
20439 this.handles = 's,e,se';
20440 if(this.multiDirectional){
20441 this.handles += ',n,w';
20444 if(this.handles == "all"){
20445 this.handles = "n s e w ne nw se sw";
20447 var hs = this.handles.split(/\s*?[,;]\s*?| /);
20448 var ps = Ext.Resizable.positions;
20449 for(var i = 0, len = hs.length; i < len; i++){
20450 if(hs[i] && ps[hs[i]]){
20451 var pos = ps[hs[i]];
20452 this[pos] = new Ext.Resizable.Handle(this, pos, this.disableTrackOver, this.transparent);
20456 this.corner = this.southeast;
20458 if(this.handles.indexOf("n") != -1 || this.handles.indexOf("w") != -1){
20459 this.updateBox = true;
20462 this.activeHandle = null;
20464 if(this.resizeChild){
20465 if(typeof this.resizeChild == "boolean"){
20466 this.resizeChild = Ext.get(this.el.dom.firstChild, true);
20467 }else{
20468 this.resizeChild = Ext.get(this.resizeChild, true);
20472 if(this.adjustments == "auto"){
20473 var rc = this.resizeChild;
20474 var hw = this.west, he = this.east, hn = this.north, hs = this.south;
20475 if(rc && (hw || hn)){
20476 rc.position("relative");
20477 rc.setLeft(hw ? hw.el.getWidth() : 0);
20478 rc.setTop(hn ? hn.el.getHeight() : 0);
20480 this.adjustments = [
20481 (he ? -he.el.getWidth() : 0) + (hw ? -hw.el.getWidth() : 0),
20482 (hn ? -hn.el.getHeight() : 0) + (hs ? -hs.el.getHeight() : 0) -1
20483 ];
20486 if(this.draggable){
20487 this.dd = this.dynamic ?
20488 this.el.initDD(null) : this.el.initDDProxy(null, {dragElId: this.proxy.id});
20489 this.dd.setHandleElId(this.resizeChild ? this.resizeChild.id : this.el.id);
20493 this.addEvents(
20494 "beforeresize",
20495 "resize"
20496 );
20498 if(this.width !== null && this.height !== null){
20499 this.resizeTo(this.width, this.height);
20500 }else{
20501 this.updateChildSize();
20503 if(Ext.isIE){
20504 this.el.dom.style.zoom = 1;
20506 Ext.Resizable.superclass.constructor.call(this);
20507 };
20509 Ext.extend(Ext.Resizable, Ext.util.Observable, {
20510 resizeChild : false,
20511 adjustments : [0, 0],
20512 minWidth : 5,
20513 minHeight : 5,
20514 maxWidth : 10000,
20515 maxHeight : 10000,
20516 enabled : true,
20517 animate : false,
20518 duration : .35,
20519 dynamic : false,
20520 handles : false,
20521 multiDirectional : false,
20522 disableTrackOver : false,
20523 easing : 'easeOutStrong',
20524 widthIncrement : 0,
20525 heightIncrement : 0,
20526 pinned : false,
20527 width : null,
20528 height : null,
20529 preserveRatio : false,
20530 transparent: false,
20531 minX: 0,
20532 minY: 0,
20533 draggable: false,
20542 resizeTo : function(width, height){
20543 this.el.setSize(width, height);
20544 this.updateChildSize();
20545 this.fireEvent("resize", this, width, height, null);
20546 },
20549 startSizing : function(e, handle){
20550 this.fireEvent("beforeresize", this, e);
20551 if(this.enabled){
20553 if(!this.overlay){
20554 this.overlay = this.el.createProxy({tag: "div", cls: "x-resizable-overlay", html: "&#160;"}, Ext.getBody());
20555 this.overlay.unselectable();
20556 this.overlay.enableDisplayMode("block");
20557 this.overlay.on("mousemove", this.onMouseMove, this);
20558 this.overlay.on("mouseup", this.onMouseUp, this);
20560 this.overlay.setStyle("cursor", handle.el.getStyle("cursor"));
20562 this.resizing = true;
20563 this.startBox = this.el.getBox();
20564 this.startPoint = e.getXY();
20565 this.offsets = [(this.startBox.x + this.startBox.width) - this.startPoint[0],
20566 (this.startBox.y + this.startBox.height) - this.startPoint[1]];
20568 this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
20569 this.overlay.show();
20571 if(this.constrainTo) {
20572 var ct = Ext.get(this.constrainTo);
20573 this.resizeRegion = ct.getRegion().adjust(
20574 ct.getFrameWidth('t'),
20575 ct.getFrameWidth('l'),
20576 -ct.getFrameWidth('b'),
20577 -ct.getFrameWidth('r')
20578 );
20581 this.proxy.setStyle('visibility', 'hidden');
20582 this.proxy.show();
20583 this.proxy.setBox(this.startBox);
20584 if(!this.dynamic){
20585 this.proxy.setStyle('visibility', 'visible');
20588 },
20591 onMouseDown : function(handle, e){
20592 if(this.enabled){
20593 e.stopEvent();
20594 this.activeHandle = handle;
20595 this.startSizing(e, handle);
20597 },
20600 onMouseUp : function(e){
20601 var size = this.resizeElement();
20602 this.resizing = false;
20603 this.handleOut();
20604 this.overlay.hide();
20605 this.proxy.hide();
20606 this.fireEvent("resize", this, size.width, size.height, e);
20607 },
20610 updateChildSize : function(){
20611 if(this.resizeChild){
20612 var el = this.el;
20613 var child = this.resizeChild;
20614 var adj = this.adjustments;
20615 if(el.dom.offsetWidth){
20616 var b = el.getSize(true);
20617 child.setSize(b.width+adj[0], b.height+adj[1]);
20623 if(Ext.isIE){
20624 setTimeout(function(){
20625 if(el.dom.offsetWidth){
20626 var b = el.getSize(true);
20627 child.setSize(b.width+adj[0], b.height+adj[1]);
20629 }, 10);
20632 },
20635 snap : function(value, inc, min){
20636 if(!inc || !value) return value;
20637 var newValue = value;
20638 var m = value % inc;
20639 if(m > 0){
20640 if(m > (inc/2)){
20641 newValue = value + (inc-m);
20642 }else{
20643 newValue = value - m;
20646 return Math.max(min, newValue);
20647 },
20650 resizeElement : function(){
20651 var box = this.proxy.getBox();
20652 if(this.updateBox){
20653 this.el.setBox(box, false, this.animate, this.duration, null, this.easing);
20654 }else{
20655 this.el.setSize(box.width, box.height, this.animate, this.duration, null, this.easing);
20657 this.updateChildSize();
20658 if(!this.dynamic){
20659 this.proxy.hide();
20661 return box;
20662 },
20665 constrain : function(v, diff, m, mx){
20666 if(v - diff < m){
20667 diff = v - m;
20668 }else if(v - diff > mx){
20669 diff = mx - v;
20671 return diff;
20672 },
20675 onMouseMove : function(e){
20676 if(this.enabled){
20677 try{
20679 if(this.resizeRegion && !this.resizeRegion.contains(e.getPoint())) {
20680 return;
20684 var curSize = this.curSize || this.startBox;
20685 var x = this.startBox.x, y = this.startBox.y;
20686 var ox = x, oy = y;
20687 var w = curSize.width, h = curSize.height;
20688 var ow = w, oh = h;
20689 var mw = this.minWidth, mh = this.minHeight;
20690 var mxw = this.maxWidth, mxh = this.maxHeight;
20691 var wi = this.widthIncrement;
20692 var hi = this.heightIncrement;
20694 var eventXY = e.getXY();
20695 var diffX = -(this.startPoint[0] - Math.max(this.minX, eventXY[0]));
20696 var diffY = -(this.startPoint[1] - Math.max(this.minY, eventXY[1]));
20698 var pos = this.activeHandle.position;
20700 switch(pos){
20701 case "east":
20702 w += diffX;
20703 w = Math.min(Math.max(mw, w), mxw);
20704 break;
20705 case "south":
20706 h += diffY;
20707 h = Math.min(Math.max(mh, h), mxh);
20708 break;
20709 case "southeast":
20710 w += diffX;
20711 h += diffY;
20712 w = Math.min(Math.max(mw, w), mxw);
20713 h = Math.min(Math.max(mh, h), mxh);
20714 break;
20715 case "north":
20716 diffY = this.constrain(h, diffY, mh, mxh);
20717 y += diffY;
20718 h -= diffY;
20719 break;
20720 case "west":
20721 diffX = this.constrain(w, diffX, mw, mxw);
20722 x += diffX;
20723 w -= diffX;
20724 break;
20725 case "northeast":
20726 w += diffX;
20727 w = Math.min(Math.max(mw, w), mxw);
20728 diffY = this.constrain(h, diffY, mh, mxh);
20729 y += diffY;
20730 h -= diffY;
20731 break;
20732 case "northwest":
20733 diffX = this.constrain(w, diffX, mw, mxw);
20734 diffY = this.constrain(h, diffY, mh, mxh);
20735 y += diffY;
20736 h -= diffY;
20737 x += diffX;
20738 w -= diffX;
20739 break;
20740 case "southwest":
20741 diffX = this.constrain(w, diffX, mw, mxw);
20742 h += diffY;
20743 h = Math.min(Math.max(mh, h), mxh);
20744 x += diffX;
20745 w -= diffX;
20746 break;
20749 var sw = this.snap(w, wi, mw);
20750 var sh = this.snap(h, hi, mh);
20751 if(sw != w || sh != h){
20752 switch(pos){
20753 case "northeast":
20754 y -= sh - h;
20755 break;
20756 case "north":
20757 y -= sh - h;
20758 break;
20759 case "southwest":
20760 x -= sw - w;
20761 break;
20762 case "west":
20763 x -= sw - w;
20764 break;
20765 case "northwest":
20766 x -= sw - w;
20767 y -= sh - h;
20768 break;
20770 w = sw;
20771 h = sh;
20774 if(this.preserveRatio){
20775 switch(pos){
20776 case "southeast":
20777 case "east":
20778 h = oh * (w/ow);
20779 h = Math.min(Math.max(mh, h), mxh);
20780 w = ow * (h/oh);
20781 break;
20782 case "south":
20783 w = ow * (h/oh);
20784 w = Math.min(Math.max(mw, w), mxw);
20785 h = oh * (w/ow);
20786 break;
20787 case "northeast":
20788 w = ow * (h/oh);
20789 w = Math.min(Math.max(mw, w), mxw);
20790 h = oh * (w/ow);
20791 break;
20792 case "north":
20793 var tw = w;
20794 w = ow * (h/oh);
20795 w = Math.min(Math.max(mw, w), mxw);
20796 h = oh * (w/ow);
20797 x += (tw - w) / 2;
20798 break;
20799 case "southwest":
20800 h = oh * (w/ow);
20801 h = Math.min(Math.max(mh, h), mxh);
20802 var tw = w;
20803 w = ow * (h/oh);
20804 x += tw - w;
20805 break;
20806 case "west":
20807 var th = h;
20808 h = oh * (w/ow);
20809 h = Math.min(Math.max(mh, h), mxh);
20810 y += (th - h) / 2;
20811 var tw = w;
20812 w = ow * (h/oh);
20813 x += tw - w;
20814 break;
20815 case "northwest":
20816 var tw = w;
20817 var th = h;
20818 h = oh * (w/ow);
20819 h = Math.min(Math.max(mh, h), mxh);
20820 w = ow * (h/oh);
20821 y += th - h;
20822 x += tw - w;
20823 break;
20827 this.proxy.setBounds(x, y, w, h);
20828 if(this.dynamic){
20829 this.resizeElement();
20831 }catch(e){}
20833 },
20836 handleOver : function(){
20837 if(this.enabled){
20838 this.el.addClass("x-resizable-over");
20840 },
20843 handleOut : function(){
20844 if(!this.resizing){
20845 this.el.removeClass("x-resizable-over");
20847 },
20850 getEl : function(){
20851 return this.el;
20852 },
20855 getResizeChild : function(){
20856 return this.resizeChild;
20857 },
20860 destroy : function(removeEl){
20861 this.proxy.remove();
20862 if(this.overlay){
20863 this.overlay.removeAllListeners();
20864 this.overlay.remove();
20866 var ps = Ext.Resizable.positions;
20867 for(var k in ps){
20868 if(typeof ps[k] != "function" && this[ps[k]]){
20869 var h = this[ps[k]];
20870 h.el.removeAllListeners();
20871 h.el.remove();
20874 if(removeEl){
20875 this.el.update("");
20876 this.el.remove();
20878 },
20880 syncHandleHeight : function(){
20881 var h = this.el.getHeight(true);
20882 if(this.west){
20883 this.west.el.setHeight(h);
20885 if(this.east){
20886 this.east.el.setHeight(h);
20889 });
20893 Ext.Resizable.positions = {
20894 n: "north", s: "south", e: "east", w: "west", se: "southeast", sw: "southwest", nw: "northwest", ne: "northeast"
20895 };
20898 Ext.Resizable.Handle = function(rz, pos, disableTrackOver, transparent){
20899 if(!this.tpl){
20901 var tpl = Ext.DomHelper.createTemplate(
20902 {tag: "div", cls: "x-resizable-handle x-resizable-handle-{0}"}
20903 );
20904 tpl.compile();
20905 Ext.Resizable.Handle.prototype.tpl = tpl;
20907 this.position = pos;
20908 this.rz = rz;
20909 this.el = this.tpl.append(rz.el.dom, [this.position], true);
20910 this.el.unselectable();
20911 if(transparent){
20912 this.el.setOpacity(0);
20914 this.el.on("mousedown", this.onMouseDown, this);
20915 if(!disableTrackOver){
20916 this.el.on("mouseover", this.onMouseOver, this);
20917 this.el.on("mouseout", this.onMouseOut, this);
20919 };
20922 Ext.Resizable.Handle.prototype = {
20923 afterResize : function(rz){
20925 },
20927 onMouseDown : function(e){
20928 this.rz.onMouseDown(this, e);
20929 },
20931 onMouseOver : function(e){
20932 this.rz.handleOver(this, e);
20933 },
20935 onMouseOut : function(e){
20936 this.rz.handleOut(this, e);
20938 };
20944 Ext.Editor = function(field, config){
20945 this.field = field;
20946 Ext.Editor.superclass.constructor.call(this, config);
20947 };
20949 Ext.extend(Ext.Editor, Ext.Component, {
20955 value : "",
20957 alignment: "c-c?",
20959 shadow : "frame",
20961 constrain : false,
20963 swallowKeys : true,
20965 completeOnEnter : false,
20967 cancelOnEsc : false,
20969 updateEl : false,
20971 initComponent : function(){
20972 Ext.Editor.superclass.initComponent.call(this);
20973 this.addEvents(
20975 "beforestartedit",
20977 "startedit",
20979 "beforecomplete",
20981 "complete",
20983 "specialkey"
20984 );
20985 },
20987 onRender : function(ct, position){
20988 this.el = new Ext.Layer({
20989 shadow: this.shadow,
20990 cls: "x-editor",
20991 parentEl : ct,
20992 shim : this.shim,
20993 shadowOffset:4,
20994 id: this.id,
20995 constrain: this.constrain
20996 });
20997 this.el.setStyle("overflow", Ext.isGecko ? "auto" : "hidden");
20998 if(this.field.msgTarget != 'title'){
20999 this.field.msgTarget = 'qtip';
21001 this.field.inEditor = true;
21002 this.field.render(this.el);
21003 if(Ext.isGecko){
21004 this.field.el.dom.setAttribute('autocomplete', 'off');
21006 this.field.on("specialkey", this.onSpecialKey, this);
21007 if(this.swallowKeys){
21008 this.field.el.swallowEvent(['keydown','keypress']);
21010 this.field.show();
21011 this.field.on("blur", this.onBlur, this);
21012 if(this.field.grow){
21013 this.field.on("autosize", this.el.sync, this.el, {delay:1});
21015 },
21017 onSpecialKey : function(field, e){
21018 if(this.completeOnEnter && e.getKey() == e.ENTER){
21019 e.stopEvent();
21020 this.completeEdit();
21021 }else if(this.cancelOnEsc && e.getKey() == e.ESC){
21022 this.cancelEdit();
21023 }else{
21024 this.fireEvent('specialkey', field, e);
21026 },
21029 startEdit : function(el, value){
21030 if(this.editing){
21031 this.completeEdit();
21033 this.boundEl = Ext.get(el);
21034 var v = value !== undefined ? value : this.boundEl.dom.innerHTML;
21035 if(!this.rendered){
21036 this.render(this.parentEl || document.body);
21038 if(this.fireEvent("beforestartedit", this, this.boundEl, v) === false){
21039 return;
21041 this.startValue = v;
21042 this.field.setValue(v);
21043 this.doAutoSize();
21044 this.el.alignTo(this.boundEl, this.alignment);
21045 this.editing = true;
21046 this.show();
21047 },
21049 doAutoSize : function(){
21050 if(this.autoSize){
21051 var sz = this.boundEl.getSize();
21052 switch(this.autoSize){
21053 case "width":
21054 this.setSize(sz.width, "");
21055 break;
21056 case "height":
21057 this.setSize("", sz.height);
21058 break;
21059 default:
21060 this.setSize(sz.width, sz.height);
21063 },
21066 setSize : function(w, h){
21067 delete this.field.lastSize;
21068 this.field.setSize(w, h);
21069 if(this.el){
21070 this.el.sync();
21072 },
21075 realign : function(){
21076 this.el.alignTo(this.boundEl, this.alignment);
21077 },
21080 completeEdit : function(remainVisible){
21081 if(!this.editing){
21082 return;
21084 var v = this.getValue();
21085 if(this.revertInvalid !== false && !this.field.isValid()){
21086 v = this.startValue;
21087 this.cancelEdit(true);
21089 if(String(v) === String(this.startValue) && this.ignoreNoChange){
21090 this.editing = false;
21091 this.hide();
21092 return;
21094 if(this.fireEvent("beforecomplete", this, v, this.startValue) !== false){
21095 this.editing = false;
21096 if(this.updateEl && this.boundEl){
21097 this.boundEl.update(v);
21099 if(remainVisible !== true){
21100 this.hide();
21102 this.fireEvent("complete", this, v, this.startValue);
21104 },
21106 onShow : function(){
21107 this.el.show();
21108 if(this.hideEl !== false){
21109 this.boundEl.hide();
21111 this.field.show();
21112 if(Ext.isIE && !this.fixIEFocus){ this.fixIEFocus = true;
21113 this.deferredFocus.defer(50, this);
21114 }else{
21115 this.field.focus();
21117 this.fireEvent("startedit", this.boundEl, this.startValue);
21118 },
21120 deferredFocus : function(){
21121 if(this.editing){
21122 this.field.focus();
21124 },
21127 cancelEdit : function(remainVisible){
21128 if(this.editing){
21129 this.setValue(this.startValue);
21130 if(remainVisible !== true){
21131 this.hide();
21134 },
21136 onBlur : function(){
21137 if(this.allowBlur !== true && this.editing){
21138 this.completeEdit();
21140 },
21142 onHide : function(){
21143 if(this.editing){
21144 this.completeEdit();
21145 return;
21147 this.field.blur();
21148 if(this.field.collapse){
21149 this.field.collapse();
21151 this.el.hide();
21152 if(this.hideEl !== false){
21153 this.boundEl.show();
21155 },
21158 setValue : function(v){
21159 this.field.setValue(v);
21160 },
21163 getValue : function(){
21164 return this.field.getValue();
21165 },
21167 beforeDestroy : function(){
21168 this.field.destroy();
21169 this.field = null;
21171 });
21172 Ext.reg('editor', Ext.Editor);
21174 Ext.MessageBox = function(){
21175 var dlg, opt, mask, waitTimer;
21176 var bodyEl, msgEl, textboxEl, textareaEl, progressBar, pp, iconEl, spacerEl;
21177 var buttons, activeTextEl, bwidth, iconCls = '';
21180 var handleButton = function(button){
21181 if(dlg.isVisible()){
21182 dlg.hide();
21183 Ext.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value], 1);
21185 };
21188 var handleHide = function(){
21189 if(opt && opt.cls){
21190 dlg.el.removeClass(opt.cls);
21192 progressBar.reset();
21193 };
21196 var handleEsc = function(d, k, e){
21197 if(opt && opt.closable !== false){
21198 dlg.hide();
21200 if(e){
21201 e.stopEvent();
21203 };
21206 var updateButtons = function(b){
21207 var width = 0;
21208 if(!b){
21209 buttons["ok"].hide();
21210 buttons["cancel"].hide();
21211 buttons["yes"].hide();
21212 buttons["no"].hide();
21213 return width;
21215 dlg.footer.dom.style.display = '';
21216 for(var k in buttons){
21217 if(typeof buttons[k] != "function"){
21218 if(b[k]){
21219 buttons[k].show();
21220 buttons[k].setText(typeof b[k] == "string" ? b[k] : Ext.MessageBox.buttonText[k]);
21221 width += buttons[k].el.getWidth()+15;
21222 }else{
21223 buttons[k].hide();
21227 return width;
21228 };
21230 return {
21232 getDialog : function(titleText){
21233 if(!dlg){
21234 dlg = new Ext.Window({
21235 autoCreate : true,
21236 title:titleText,
21237 resizable:false,
21238 constrain:true,
21239 constrainHeader:true,
21240 minimizable : false,
21241 maximizable : false,
21242 stateful: false,
21243 modal: true,
21244 shim:true,
21245 buttonAlign:"center",
21246 width:400,
21247 height:100,
21248 minHeight: 80,
21249 plain:true,
21250 footer:true,
21251 closable:true,
21252 close : function(){
21253 if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){
21254 handleButton("no");
21255 }else{
21256 handleButton("cancel");
21259 });
21260 buttons = {};
21261 var bt = this.buttonText;
21263 buttons["ok"] = dlg.addButton(bt["ok"], handleButton.createCallback("ok"));
21264 buttons["yes"] = dlg.addButton(bt["yes"], handleButton.createCallback("yes"));
21265 buttons["no"] = dlg.addButton(bt["no"], handleButton.createCallback("no"));
21266 buttons["cancel"] = dlg.addButton(bt["cancel"], handleButton.createCallback("cancel"));
21267 buttons["ok"].hideMode = buttons["yes"].hideMode = buttons["no"].hideMode = buttons["cancel"].hideMode = 'offsets';
21268 dlg.render(document.body);
21269 dlg.getEl().addClass('x-window-dlg');
21270 mask = dlg.mask;
21271 bodyEl = dlg.body.createChild({
21272 html:'<div class="ext-mb-icon"></div><div class="ext-mb-content"><span class="ext-mb-text"></span><br /><div class="ext-mb-fix-cursor"><input type="text" class="ext-mb-input" /><textarea class="ext-mb-textarea"></textarea></div></div>'
21273 });
21274 iconEl = Ext.get(bodyEl.dom.firstChild);
21275 var contentEl = bodyEl.dom.childNodes[1];
21276 msgEl = Ext.get(contentEl.firstChild);
21277 textboxEl = Ext.get(contentEl.childNodes[2].firstChild);
21278 textboxEl.enableDisplayMode();
21279 textboxEl.addKeyListener([10,13], function(){
21280 if(dlg.isVisible() && opt && opt.buttons){
21281 if(opt.buttons.ok){
21282 handleButton("ok");
21283 }else if(opt.buttons.yes){
21284 handleButton("yes");
21287 });
21288 textareaEl = Ext.get(contentEl.childNodes[2].childNodes[1]);
21289 textareaEl.enableDisplayMode();
21290 progressBar = new Ext.ProgressBar({
21291 renderTo:bodyEl
21292 });
21293 bodyEl.createChild({cls:'x-clear'});
21295 return dlg;
21296 },
21299 updateText : function(text){
21300 if(!dlg.isVisible() && !opt.width){
21301 dlg.setSize(this.maxWidth, 100);
21303 msgEl.update(text || '&#160;');
21305 var iw = iconCls != '' ? (iconEl.getWidth() + iconEl.getMargins('lr')) : 0;
21306 var mw = msgEl.getWidth() + msgEl.getMargins('lr');
21307 var fw = dlg.getFrameWidth('lr');
21308 var bw = dlg.body.getFrameWidth('lr');
21309 if (Ext.isIE && iw > 0){
21312 iw += 3;
21314 var w = Math.max(Math.min(opt.width || iw+mw+fw+bw, this.maxWidth),
21315 Math.max(opt.minWidth || this.minWidth, bwidth || 0));
21317 if(opt.prompt === true){
21318 activeTextEl.setWidth(w-iw-fw-bw);
21320 if(opt.progress === true || opt.wait === true){
21321 progressBar.setSize(w-iw-fw-bw);
21323 dlg.setSize(w, 'auto').center();
21324 return this;
21325 },
21328 updateProgress : function(value, progressText, msg){
21329 progressBar.updateProgress(value, progressText);
21330 if(msg){
21331 this.updateText(msg);
21333 return this;
21334 },
21337 isVisible : function(){
21338 return dlg && dlg.isVisible();
21339 },
21342 hide : function(){
21343 if(this.isVisible()){
21344 dlg.hide();
21345 handleHide();
21347 return this;
21348 },
21351 show : function(options){
21352 if(this.isVisible()){
21353 this.hide();
21355 opt = options;
21356 var d = this.getDialog(opt.title || "&#160;");
21358 d.setTitle(opt.title || "&#160;");
21359 var allowClose = (opt.closable !== false && opt.progress !== true && opt.wait !== true);
21360 d.tools.close.setDisplayed(allowClose);
21361 activeTextEl = textboxEl;
21362 opt.prompt = opt.prompt || (opt.multiline ? true : false);
21363 if(opt.prompt){
21364 if(opt.multiline){
21365 textboxEl.hide();
21366 textareaEl.show();
21367 textareaEl.setHeight(typeof opt.multiline == "number" ?
21368 opt.multiline : this.defaultTextHeight);
21369 activeTextEl = textareaEl;
21370 }else{
21371 textboxEl.show();
21372 textareaEl.hide();
21374 }else{
21375 textboxEl.hide();
21376 textareaEl.hide();
21378 activeTextEl.dom.value = opt.value || "";
21379 if(opt.prompt){
21380 d.focusEl = activeTextEl;
21381 }else{
21382 var bs = opt.buttons;
21383 var db = null;
21384 if(bs && bs.ok){
21385 db = buttons["ok"];
21386 }else if(bs && bs.yes){
21387 db = buttons["yes"];
21389 if (db){
21390 d.focusEl = db;
21393 if(opt.iconCls){
21394 d.setIconClass(opt.iconCls);
21396 this.setIcon(opt.icon);
21397 bwidth = updateButtons(opt.buttons);
21398 progressBar.setVisible(opt.progress === true || opt.wait === true);
21399 this.updateProgress(0, opt.progressText);
21400 this.updateText(opt.msg);
21401 if(opt.cls){
21402 d.el.addClass(opt.cls);
21404 d.proxyDrag = opt.proxyDrag === true;
21405 d.modal = opt.modal !== false;
21406 d.mask = opt.modal !== false ? mask : false;
21407 if(!d.isVisible()){
21409 document.body.appendChild(dlg.el.dom);
21410 d.setAnimateTarget(opt.animEl);
21411 d.show(opt.animEl);
21415 d.on('show', function(){
21416 if(allowClose === true){
21417 d.keyMap.enable();
21418 }else{
21419 d.keyMap.disable();
21421 }, this, {single:true});
21423 if(opt.wait === true){
21424 progressBar.wait(opt.waitConfig);
21426 return this;
21427 },
21430 setIcon : function(icon){
21431 if(icon && icon != ''){
21432 iconEl.removeClass('x-hidden');
21433 iconEl.replaceClass(iconCls, icon);
21434 iconCls = icon;
21435 }else{
21436 iconEl.replaceClass(iconCls, 'x-hidden');
21437 iconCls = '';
21439 return this;
21440 },
21443 progress : function(title, msg, progressText){
21444 this.show({
21445 title : title,
21446 msg : msg,
21447 buttons: false,
21448 progress:true,
21449 closable:false,
21450 minWidth: this.minProgressWidth,
21451 progressText: progressText
21452 });
21453 return this;
21454 },
21457 wait : function(msg, title, config){
21458 this.show({
21459 title : title,
21460 msg : msg,
21461 buttons: false,
21462 closable:false,
21463 wait:true,
21464 modal:true,
21465 minWidth: this.minProgressWidth,
21466 waitConfig: config
21467 });
21468 return this;
21469 },
21472 alert : function(title, msg, fn, scope){
21473 this.show({
21474 title : title,
21475 msg : msg,
21476 buttons: this.OK,
21477 fn: fn,
21478 scope : scope
21479 });
21480 return this;
21481 },
21484 confirm : function(title, msg, fn, scope){
21485 this.show({
21486 title : title,
21487 msg : msg,
21488 buttons: this.YESNO,
21489 fn: fn,
21490 scope : scope,
21491 icon: this.QUESTION
21492 });
21493 return this;
21494 },
21497 prompt : function(title, msg, fn, scope, multiline, value){
21498 this.show({
21499 title : title,
21500 msg : msg,
21501 buttons: this.OKCANCEL,
21502 fn: fn,
21503 minWidth:250,
21504 scope : scope,
21505 prompt:true,
21506 multiline: multiline,
21507 value: value
21508 });
21509 return this;
21510 },
21513 OK : {ok:true},
21515 CANCEL : {cancel:true},
21517 OKCANCEL : {ok:true, cancel:true},
21519 YESNO : {yes:true, no:true},
21521 YESNOCANCEL : {yes:true, no:true, cancel:true},
21523 INFO : 'ext-mb-info',
21525 WARNING : 'ext-mb-warning',
21527 QUESTION : 'ext-mb-question',
21529 ERROR : 'ext-mb-error',
21532 defaultTextHeight : 75,
21534 maxWidth : 600,
21536 minWidth : 100,
21538 minProgressWidth : 250,
21540 buttonText : {
21541 ok : "OK",
21542 cancel : "Cancel",
21543 yes : "Yes",
21544 no : "No"
21546 };
21547 }();
21550 Ext.Msg = Ext.MessageBox;
21552 Ext.Tip = Ext.extend(Ext.Panel, {
21556 minWidth : 40,
21558 maxWidth : 300,
21560 shadow : "sides",
21562 defaultAlign : "tl-bl?",
21563 autoRender: true,
21564 quickShowInterval : 250,
21567 frame:true,
21568 hidden:true,
21569 baseCls: 'x-tip',
21570 floating:{shadow:true,shim:true,useDisplay:true,constrain:false},
21571 autoHeight:true,
21574 initComponent : function(){
21575 Ext.Tip.superclass.initComponent.call(this);
21576 if(this.closable && !this.title){
21577 this.elements += ',header';
21579 },
21582 afterRender : function(){
21583 Ext.Tip.superclass.afterRender.call(this);
21584 if(this.closable){
21585 this.addTool({
21586 id: 'close',
21587 handler: this.hide,
21588 scope: this
21589 });
21591 },
21594 showAt : function(xy){
21595 Ext.Tip.superclass.show.call(this);
21596 if(this.measureWidth !== false && (!this.initialConfig || typeof this.initialConfig.width != 'number')){
21597 this.doAutoWidth();
21599 if(this.constrainPosition){
21600 xy = this.el.adjustForConstraints(xy);
21602 this.setPagePosition(xy[0], xy[1]);
21603 },
21606 doAutoWidth : function(){
21607 var bw = this.body.getTextWidth();
21608 if(this.title){
21609 bw = Math.max(bw, this.header.child('span').getTextWidth(this.title));
21611 bw += this.getFrameWidth() + (this.closable ? 20 : 0) + this.body.getPadding("lr");
21612 this.setWidth(bw.constrain(this.minWidth, this.maxWidth));
21613 },
21616 showBy : function(el, pos){
21617 if(!this.rendered){
21618 this.render(Ext.getBody());
21620 this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign));
21621 },
21623 initDraggable : function(){
21624 this.dd = new Ext.Tip.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);
21625 this.header.addClass('x-tip-draggable');
21627 });
21630 Ext.Tip.DD = function(tip, config){
21631 Ext.apply(this, config);
21632 this.tip = tip;
21633 Ext.Tip.DD.superclass.constructor.call(this, tip.el.id, 'WindowDD-'+tip.id);
21634 this.setHandleElId(tip.header.id);
21635 this.scroll = false;
21636 };
21638 Ext.extend(Ext.Tip.DD, Ext.dd.DD, {
21639 moveOnly:true,
21640 scroll:false,
21641 headerOffsets:[100, 25],
21642 startDrag : function(){
21643 this.tip.el.disableShadow();
21644 },
21645 endDrag : function(e){
21646 this.tip.el.enableShadow(true);
21648 });
21650 Ext.ToolTip = Ext.extend(Ext.Tip, {
21654 showDelay: 500,
21656 hideDelay: 200,
21658 dismissDelay: 5000,
21660 mouseOffset: [15,18],
21662 trackMouse : false,
21663 constrainPosition: true,
21666 initComponent: function(){
21667 Ext.ToolTip.superclass.initComponent.call(this);
21668 this.lastActive = new Date();
21669 this.initTarget();
21670 },
21673 initTarget : function(){
21674 if(this.target){
21675 this.target = Ext.get(this.target);
21676 this.target.on('mouseover', this.onTargetOver, this);
21677 this.target.on('mouseout', this.onTargetOut, this);
21678 this.target.on('mousemove', this.onMouseMove, this);
21680 },
21683 onMouseMove : function(e){
21684 this.targetXY = e.getXY();
21685 if(!this.hidden && this.trackMouse){
21686 this.setPagePosition(this.getTargetXY());
21688 },
21691 getTargetXY : function(){
21692 return [this.targetXY[0]+this.mouseOffset[0], this.targetXY[1]+this.mouseOffset[1]];
21693 },
21696 onTargetOver : function(e){
21697 if(this.disabled || e.within(this.target.dom, true)){
21698 return;
21700 this.clearTimer('hide');
21701 this.targetXY = e.getXY();
21702 this.delayShow();
21703 },
21706 delayShow : function(){
21707 if(this.hidden && !this.showTimer){
21708 if(this.lastActive.getElapsed() < this.quickShowInterval){
21709 this.show();
21710 }else{
21711 this.showTimer = this.show.defer(this.showDelay, this);
21713 }else if(!this.hidden && this.autoHide !== false){
21714 this.show();
21716 },
21719 onTargetOut : function(e){
21720 if(this.disabled || e.within(this.target.dom, true)){
21721 return;
21723 this.clearTimer('show');
21724 if(this.autoHide !== false){
21725 this.delayHide();
21727 },
21730 delayHide : function(){
21731 if(!this.hidden && !this.hideTimer){
21732 this.hideTimer = this.hide.defer(this.hideDelay, this);
21734 },
21737 hide: function(){
21738 this.clearTimer('dismiss');
21739 this.lastActive = new Date();
21740 Ext.ToolTip.superclass.hide.call(this);
21741 },
21744 show : function(){
21745 this.showAt(this.getTargetXY());
21746 },
21749 showAt : function(xy){
21750 this.lastActive = new Date();
21751 this.clearTimers();
21752 Ext.ToolTip.superclass.showAt.call(this, xy);
21753 if(this.dismissDelay && this.autoHide !== false){
21754 this.dismissTimer = this.hide.defer(this.dismissDelay, this);
21756 },
21759 clearTimer : function(name){
21760 name = name + 'Timer';
21761 clearTimeout(this[name]);
21762 delete this[name];
21763 },
21766 clearTimers : function(){
21767 this.clearTimer('show');
21768 this.clearTimer('dismiss');
21769 this.clearTimer('hide');
21770 },
21773 onShow : function(){
21774 Ext.ToolTip.superclass.onShow.call(this);
21775 Ext.getDoc().on('mousedown', this.onDocMouseDown, this);
21776 },
21779 onHide : function(){
21780 Ext.ToolTip.superclass.onHide.call(this);
21781 Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
21782 },
21785 onDocMouseDown : function(e){
21786 if(this.autoHide !== false && !e.within(this.el.dom)){
21787 this.disable();
21788 this.enable.defer(100, this);
21790 },
21793 onDisable : function(){
21794 this.clearTimers();
21795 this.hide();
21796 },
21799 adjustPosition : function(x, y){
21801 var ay = this.targetXY[1], h = this.getSize().height;
21802 if(this.constrainPosition && y <= ay && (y+h) >= ay){
21803 y = ay-h-5;
21805 return {x : x, y: y};
21806 },
21809 onDestroy : function(){
21810 Ext.ToolTip.superclass.onDestroy.call(this);
21811 if(this.target){
21812 this.target.un('mouseover', this.onTargetOver, this);
21813 this.target.un('mouseout', this.onTargetOut, this);
21814 this.target.un('mousemove', this.onMouseMove, this);
21817 });
21819 Ext.QuickTip = Ext.extend(Ext.ToolTip, {
21822 interceptTitles : false,
21825 tagConfig : {
21826 namespace : "ext",
21827 attribute : "qtip",
21828 width : "qwidth",
21829 target : "target",
21830 title : "qtitle",
21831 hide : "hide",
21832 cls : "qclass",
21833 align : "qalign"
21834 },
21837 initComponent : function(){
21838 this.target = this.target || Ext.getDoc();
21839 this.targets = this.targets || {};
21840 Ext.QuickTip.superclass.initComponent.call(this);
21841 },
21844 register : function(config){
21845 var cs = Ext.isArray(config) ? config : arguments;
21846 for(var i = 0, len = cs.length; i < len; i++){
21847 var c = cs[i];
21848 var target = c.target;
21849 if(target){
21850 if(Ext.isArray(target)){
21851 for(var j = 0, jlen = target.length; j < jlen; j++){
21852 this.targets[Ext.id(target[j])] = c;
21854 } else{
21855 this.targets[Ext.id(target)] = c;
21859 },
21862 unregister : function(el){
21863 delete this.targets[Ext.id(el)];
21864 },
21867 onTargetOver : function(e){
21868 if(this.disabled){
21869 return;
21871 this.targetXY = e.getXY();
21872 var t = e.getTarget();
21873 if(!t || t.nodeType !== 1 || t == document || t == document.body){
21874 return;
21876 if(this.activeTarget && t == this.activeTarget.el){
21877 this.clearTimer('hide');
21878 this.show();
21879 return;
21881 if(t && this.targets[t.id]){
21882 this.activeTarget = this.targets[t.id];
21883 this.activeTarget.el = t;
21884 this.delayShow();
21885 return;
21887 var ttp, et = Ext.fly(t), cfg = this.tagConfig;
21888 var ns = cfg.namespace;
21889 if(this.interceptTitles && t.title){
21890 ttp = t.title;
21891 t.qtip = ttp;
21892 t.removeAttribute("title");
21893 e.preventDefault();
21894 } else{
21895 ttp = t.qtip || et.getAttributeNS(ns, cfg.attribute);
21897 if(ttp){
21898 var autoHide = et.getAttributeNS(ns, cfg.hide);
21899 this.activeTarget = {
21900 el: t,
21901 text: ttp,
21902 width: et.getAttributeNS(ns, cfg.width),
21903 autoHide: autoHide != "user" && autoHide !== 'false',
21904 title: et.getAttributeNS(ns, cfg.title),
21905 cls: et.getAttributeNS(ns, cfg.cls),
21906 align: et.getAttributeNS(ns, cfg.align)
21907 };
21908 this.delayShow();
21910 },
21913 onTargetOut : function(e){
21914 this.clearTimer('show');
21915 if(this.autoHide !== false){
21916 this.delayHide();
21918 },
21921 showAt : function(xy){
21922 var t = this.activeTarget;
21923 if(t){
21924 if(!this.rendered){
21925 this.render(Ext.getBody());
21926 this.activeTarget = t;
21928 if(t.width){
21929 this.setWidth(t.width);
21930 this.body.setWidth(this.adjustBodyWidth(t.width - this.getFrameWidth()));
21931 this.measureWidth = false;
21932 } else{
21933 this.measureWidth = true;
21935 this.setTitle(t.title || '');
21936 this.body.update(t.text);
21937 this.autoHide = t.autoHide;
21938 this.dismissDelay = t.dismissDelay || this.dismissDelay;
21939 if(this.lastCls){
21940 this.el.removeClass(this.lastCls);
21941 delete this.lastCls;
21943 if(t.cls){
21944 this.el.addClass(t.cls);
21945 this.lastCls = t.cls;
21947 if(t.align){
21948 xy = this.el.getAlignToXY(t.el, t.align);
21949 this.constrainPosition = false;
21950 } else{
21951 this.constrainPosition = true;
21954 Ext.QuickTip.superclass.showAt.call(this, xy);
21955 },
21958 hide: function(){
21959 delete this.activeTarget;
21960 Ext.QuickTip.superclass.hide.call(this);
21962 });
21964 Ext.QuickTips = function(){
21965 var tip, locks = [];
21966 return {
21968 init : function(){
21969 if(!tip){
21970 tip = new Ext.QuickTip({elements:'header,body'});
21972 },
21975 enable : function(){
21976 if(tip){
21977 locks.pop();
21978 if(locks.length < 1){
21979 tip.enable();
21982 },
21985 disable : function(){
21986 if(tip){
21987 tip.disable();
21989 locks.push(1);
21990 },
21993 isEnabled : function(){
21994 return tip !== undefined && !tip.disabled;
21995 },
21998 getQuickTip : function(){
21999 return tip;
22000 },
22003 register : function(){
22004 tip.register.apply(tip, arguments);
22005 },
22008 unregister : function(){
22009 tip.unregister.apply(tip, arguments);
22010 },
22013 tips :function(){
22014 tip.register.apply(tip, arguments);
22017 }();
22019 Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
22020 rootVisible : true,
22021 animate: Ext.enableFx,
22022 lines : true,
22023 enableDD : false,
22024 hlDrop : Ext.enableFx,
22025 pathSeparator: "/",
22027 initComponent : function(){
22028 Ext.tree.TreePanel.superclass.initComponent.call(this);
22030 if(!this.eventModel){
22031 this.eventModel = new Ext.tree.TreeEventModel(this);
22034 this.nodeHash = {};
22037 if(this.root){
22038 this.setRootNode(this.root);
22041 this.addEvents(
22044 "append",
22046 "remove",
22048 "movenode",
22050 "insert",
22052 "beforeappend",
22054 "beforeremove",
22056 "beforemovenode",
22058 "beforeinsert",
22061 "beforeload",
22063 "load",
22065 "textchange",
22067 "beforeexpandnode",
22069 "beforecollapsenode",
22071 "expandnode",
22073 "disabledchange",
22075 "collapsenode",
22077 "beforeclick",
22079 "click",
22081 "checkchange",
22083 "dblclick",
22085 "contextmenu",
22087 "beforechildrenrendered",
22089 "startdrag",
22091 "enddrag",
22093 "dragdrop",
22095 "beforenodedrop",
22097 "nodedrop",
22099 "nodedragover"
22100 );
22101 if(this.singleExpand){
22102 this.on("beforeexpandnode", this.restrictExpand, this);
22104 },
22107 proxyNodeEvent : function(ename, a1, a2, a3, a4, a5, a6){
22108 if(ename == 'collapse' || ename == 'expand' || ename == 'beforecollapse' || ename == 'beforeexpand' || ename == 'move' || ename == 'beforemove'){
22109 ename = ename+'node';
22112 return this.fireEvent(ename, a1, a2, a3, a4, a5, a6);
22113 },
22117 getRootNode : function(){
22118 return this.root;
22119 },
22122 setRootNode : function(node){
22123 this.root = node;
22124 node.ownerTree = this;
22125 node.isRoot = true;
22126 this.registerNode(node);
22127 if(!this.rootVisible){
22128 var uiP = node.attributes.uiProvider;
22129 node.ui = uiP ? new uiP(node) : new Ext.tree.RootTreeNodeUI(node);
22131 return node;
22132 },
22135 getNodeById : function(id){
22136 return this.nodeHash[id];
22137 },
22140 registerNode : function(node){
22141 this.nodeHash[node.id] = node;
22142 },
22145 unregisterNode : function(node){
22146 delete this.nodeHash[node.id];
22147 },
22150 toString : function(){
22151 return "[Tree"+(this.id?" "+this.id:"")+"]";
22152 },
22155 restrictExpand : function(node){
22156 var p = node.parentNode;
22157 if(p){
22158 if(p.expandedChild && p.expandedChild.parentNode == p){
22159 p.expandedChild.collapse();
22161 p.expandedChild = node;
22163 },
22166 getChecked : function(a, startNode){
22167 startNode = startNode || this.root;
22168 var r = [];
22169 var f = function(){
22170 if(this.attributes.checked){
22171 r.push(!a ? this : (a == 'id' ? this.id : this.attributes[a]));
22174 startNode.cascade(f);
22175 return r;
22176 },
22179 getEl : function(){
22180 return this.el;
22181 },
22184 getLoader : function(){
22185 return this.loader;
22186 },
22189 expandAll : function(){
22190 this.root.expand(true);
22191 },
22194 collapseAll : function(){
22195 this.root.collapse(true);
22196 },
22199 getSelectionModel : function(){
22200 if(!this.selModel){
22201 this.selModel = new Ext.tree.DefaultSelectionModel();
22203 return this.selModel;
22204 },
22207 expandPath : function(path, attr, callback){
22208 attr = attr || "id";
22209 var keys = path.split(this.pathSeparator);
22210 var curNode = this.root;
22211 if(curNode.attributes[attr] != keys[1]){
22212 if(callback){
22213 callback(false, null);
22215 return;
22217 var index = 1;
22218 var f = function(){
22219 if(++index == keys.length){
22220 if(callback){
22221 callback(true, curNode);
22223 return;
22225 var c = curNode.findChild(attr, keys[index]);
22226 if(!c){
22227 if(callback){
22228 callback(false, curNode);
22230 return;
22232 curNode = c;
22233 c.expand(false, false, f);
22234 };
22235 curNode.expand(false, false, f);
22236 },
22239 selectPath : function(path, attr, callback){
22240 attr = attr || "id";
22241 var keys = path.split(this.pathSeparator);
22242 var v = keys.pop();
22243 if(keys.length > 0){
22244 var f = function(success, node){
22245 if(success && node){
22246 var n = node.findChild(attr, v);
22247 if(n){
22248 n.select();
22249 if(callback){
22250 callback(true, n);
22252 }else if(callback){
22253 callback(false, n);
22255 }else{
22256 if(callback){
22257 callback(false, n);
22260 };
22261 this.expandPath(keys.join(this.pathSeparator), attr, f);
22262 }else{
22263 this.root.select();
22264 if(callback){
22265 callback(true, this.root);
22268 },
22271 getTreeEl : function(){
22272 return this.body;
22273 },
22276 onRender : function(ct, position){
22277 Ext.tree.TreePanel.superclass.onRender.call(this, ct, position);
22278 this.el.addClass('x-tree');
22279 this.innerCt = this.body.createChild({tag:"ul",
22280 cls:"x-tree-root-ct " +
22281 (this.useArrows ? 'x-tree-arrows' : this.lines ? "x-tree-lines" : "x-tree-no-lines")});
22282 },
22285 initEvents : function(){
22286 Ext.tree.TreePanel.superclass.initEvents.call(this);
22288 if(this.containerScroll){
22289 Ext.dd.ScrollManager.register(this.body);
22291 if((this.enableDD || this.enableDrop) && !this.dropZone){
22293 this.dropZone = new Ext.tree.TreeDropZone(this, this.dropConfig || {
22294 ddGroup: this.ddGroup || "TreeDD", appendOnly: this.ddAppendOnly === true
22295 });
22297 if((this.enableDD || this.enableDrag) && !this.dragZone){
22299 this.dragZone = new Ext.tree.TreeDragZone(this, this.dragConfig || {
22300 ddGroup: this.ddGroup || "TreeDD",
22301 scroll: this.ddScroll
22302 });
22304 this.getSelectionModel().init(this);
22305 },
22308 afterRender : function(){
22309 Ext.tree.TreePanel.superclass.afterRender.call(this);
22310 this.root.render();
22311 if(!this.rootVisible){
22312 this.root.renderChildren();
22314 },
22316 onDestroy : function(){
22317 if(this.rendered){
22318 this.body.removeAllListeners();
22319 Ext.dd.ScrollManager.unregister(this.body);
22320 if(this.dropZone){
22321 this.dropZone.unreg();
22323 if(this.dragZone){
22324 this.dragZone.unreg();
22327 this.root.destroy();
22328 this.nodeHash = null;
22329 Ext.tree.TreePanel.superclass.onDestroy.call(this);
22378 });
22379 Ext.reg('treepanel', Ext.tree.TreePanel);
22380 Ext.tree.TreeEventModel = function(tree){
22381 this.tree = tree;
22382 this.tree.on('render', this.initEvents, this);
22385 Ext.tree.TreeEventModel.prototype = {
22386 initEvents : function(){
22387 var el = this.tree.getTreeEl();
22388 el.on('click', this.delegateClick, this);
22389 if(this.tree.trackMouseOver !== false){
22390 el.on('mouseover', this.delegateOver, this);
22391 el.on('mouseout', this.delegateOut, this);
22393 el.on('dblclick', this.delegateDblClick, this);
22394 el.on('contextmenu', this.delegateContextMenu, this);
22395 },
22397 getNode : function(e){
22398 var t;
22399 if(t = e.getTarget('.x-tree-node-el', 10)){
22400 var id = Ext.fly(t, '_treeEvents').getAttributeNS('ext', 'tree-node-id');
22401 if(id){
22402 return this.tree.getNodeById(id);
22405 return null;
22406 },
22408 getNodeTarget : function(e){
22409 var t = e.getTarget('.x-tree-node-icon', 1);
22410 if(!t){
22411 t = e.getTarget('.x-tree-node-el', 6);
22413 return t;
22414 },
22416 delegateOut : function(e, t){
22417 if(!this.beforeEvent(e)){
22418 return;
22420 if(e.getTarget('.x-tree-ec-icon', 1)){
22421 var n = this.getNode(e);
22422 this.onIconOut(e, n);
22423 if(n == this.lastEcOver){
22424 delete this.lastEcOver;
22427 if((t = this.getNodeTarget(e)) && !e.within(t, true)){
22428 this.onNodeOut(e, this.getNode(e));
22430 },
22432 delegateOver : function(e, t){
22433 if(!this.beforeEvent(e)){
22434 return;
22436 if(this.lastEcOver){
22437 this.onIconOut(e, this.lastEcOver);
22438 delete this.lastEcOver;
22440 if(e.getTarget('.x-tree-ec-icon', 1)){
22441 this.lastEcOver = this.getNode(e);
22442 this.onIconOver(e, this.lastEcOver);
22444 if(t = this.getNodeTarget(e)){
22445 this.onNodeOver(e, this.getNode(e));
22447 },
22449 delegateClick : function(e, t){
22450 if(!this.beforeEvent(e)){
22451 return;
22454 if(e.getTarget('input[type=checkbox]', 1)){
22455 this.onCheckboxClick(e, this.getNode(e));
22457 else if(e.getTarget('.x-tree-ec-icon', 1)){
22458 this.onIconClick(e, this.getNode(e));
22460 else if(this.getNodeTarget(e)){
22461 this.onNodeClick(e, this.getNode(e));
22463 },
22465 delegateDblClick : function(e, t){
22466 if(this.beforeEvent(e) && this.getNodeTarget(e)){
22467 this.onNodeDblClick(e, this.getNode(e));
22469 },
22471 delegateContextMenu : function(e, t){
22472 if(this.beforeEvent(e) && this.getNodeTarget(e)){
22473 this.onNodeContextMenu(e, this.getNode(e));
22475 },
22477 onNodeClick : function(e, node){
22478 node.ui.onClick(e);
22479 },
22481 onNodeOver : function(e, node){
22482 node.ui.onOver(e);
22483 },
22485 onNodeOut : function(e, node){
22486 node.ui.onOut(e);
22487 },
22489 onIconOver : function(e, node){
22490 node.ui.addClass('x-tree-ec-over');
22491 },
22493 onIconOut : function(e, node){
22494 node.ui.removeClass('x-tree-ec-over');
22495 },
22497 onIconClick : function(e, node){
22498 node.ui.ecClick(e);
22499 },
22501 onCheckboxClick : function(e, node){
22502 node.ui.onCheckChange(e);
22503 },
22505 onNodeDblClick : function(e, node){
22506 node.ui.onDblClick(e);
22507 },
22509 onNodeContextMenu : function(e, node){
22510 node.ui.onContextMenu(e);
22511 },
22513 beforeEvent : function(e){
22514 if(this.disabled){
22515 e.stopEvent();
22516 return false;
22518 return true;
22519 },
22521 disable: function(){
22522 this.disabled = true;
22523 },
22525 enable: function(){
22526 this.disabled = false;
22528 };
22530 Ext.tree.DefaultSelectionModel = function(config){
22531 this.selNode = null;
22533 this.addEvents(
22535 "selectionchange",
22538 "beforeselect"
22539 );
22541 Ext.apply(this, config);
22542 Ext.tree.DefaultSelectionModel.superclass.constructor.call(this);
22543 };
22545 Ext.extend(Ext.tree.DefaultSelectionModel, Ext.util.Observable, {
22546 init : function(tree){
22547 this.tree = tree;
22548 tree.getTreeEl().on("keydown", this.onKeyDown, this);
22549 tree.on("click", this.onNodeClick, this);
22550 },
22552 onNodeClick : function(node, e){
22553 this.select(node);
22554 },
22557 select : function(node){
22558 var last = this.selNode;
22559 if(last != node && this.fireEvent('beforeselect', this, node, last) !== false){
22560 if(last){
22561 last.ui.onSelectedChange(false);
22563 this.selNode = node;
22564 node.ui.onSelectedChange(true);
22565 this.fireEvent("selectionchange", this, node, last);
22567 return node;
22568 },
22571 unselect : function(node){
22572 if(this.selNode == node){
22573 this.clearSelections();
22575 },
22578 clearSelections : function(){
22579 var n = this.selNode;
22580 if(n){
22581 n.ui.onSelectedChange(false);
22582 this.selNode = null;
22583 this.fireEvent("selectionchange", this, null);
22585 return n;
22586 },
22589 getSelectedNode : function(){
22590 return this.selNode;
22591 },
22594 isSelected : function(node){
22595 return this.selNode == node;
22596 },
22599 selectPrevious : function(){
22600 var s = this.selNode || this.lastSelNode;
22601 if(!s){
22602 return null;
22604 var ps = s.previousSibling;
22605 if(ps){
22606 if(!ps.isExpanded() || ps.childNodes.length < 1){
22607 return this.select(ps);
22608 } else{
22609 var lc = ps.lastChild;
22610 while(lc && lc.isExpanded() && lc.childNodes.length > 0){
22611 lc = lc.lastChild;
22613 return this.select(lc);
22615 } else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){
22616 return this.select(s.parentNode);
22618 return null;
22619 },
22622 selectNext : function(){
22623 var s = this.selNode || this.lastSelNode;
22624 if(!s){
22625 return null;
22627 if(s.firstChild && s.isExpanded()){
22628 return this.select(s.firstChild);
22629 }else if(s.nextSibling){
22630 return this.select(s.nextSibling);
22631 }else if(s.parentNode){
22632 var newS = null;
22633 s.parentNode.bubble(function(){
22634 if(this.nextSibling){
22635 newS = this.getOwnerTree().selModel.select(this.nextSibling);
22636 return false;
22638 });
22639 return newS;
22641 return null;
22642 },
22644 onKeyDown : function(e){
22645 var s = this.selNode || this.lastSelNode;
22647 var sm = this;
22648 if(!s){
22649 return;
22651 var k = e.getKey();
22652 switch(k){
22653 case e.DOWN:
22654 e.stopEvent();
22655 this.selectNext();
22656 break;
22657 case e.UP:
22658 e.stopEvent();
22659 this.selectPrevious();
22660 break;
22661 case e.RIGHT:
22662 e.preventDefault();
22663 if(s.hasChildNodes()){
22664 if(!s.isExpanded()){
22665 s.expand();
22666 }else if(s.firstChild){
22667 this.select(s.firstChild, e);
22670 break;
22671 case e.LEFT:
22672 e.preventDefault();
22673 if(s.hasChildNodes() && s.isExpanded()){
22674 s.collapse();
22675 }else if(s.parentNode && (this.tree.rootVisible || s.parentNode != this.tree.getRootNode())){
22676 this.select(s.parentNode, e);
22678 break;
22679 };
22681 });
22684 Ext.tree.MultiSelectionModel = function(config){
22685 this.selNodes = [];
22686 this.selMap = {};
22687 this.addEvents(
22689 "selectionchange"
22690 );
22691 Ext.apply(this, config);
22692 Ext.tree.MultiSelectionModel.superclass.constructor.call(this);
22693 };
22695 Ext.extend(Ext.tree.MultiSelectionModel, Ext.util.Observable, {
22696 init : function(tree){
22697 this.tree = tree;
22698 tree.getTreeEl().on("keydown", this.onKeyDown, this);
22699 tree.on("click", this.onNodeClick, this);
22700 },
22702 onNodeClick : function(node, e){
22703 this.select(node, e, e.ctrlKey);
22704 },
22707 select : function(node, e, keepExisting){
22708 if(keepExisting !== true){
22709 this.clearSelections(true);
22711 if(this.isSelected(node)){
22712 this.lastSelNode = node;
22713 return node;
22715 this.selNodes.push(node);
22716 this.selMap[node.id] = node;
22717 this.lastSelNode = node;
22718 node.ui.onSelectedChange(true);
22719 this.fireEvent("selectionchange", this, this.selNodes);
22720 return node;
22721 },
22724 unselect : function(node){
22725 if(this.selMap[node.id]){
22726 node.ui.onSelectedChange(false);
22727 var sn = this.selNodes;
22728 var index = sn.indexOf(node);
22729 if(index != -1){
22730 this.selNodes.splice(index, 1);
22732 delete this.selMap[node.id];
22733 this.fireEvent("selectionchange", this, this.selNodes);
22735 },
22738 clearSelections : function(suppressEvent){
22739 var sn = this.selNodes;
22740 if(sn.length > 0){
22741 for(var i = 0, len = sn.length; i < len; i++){
22742 sn[i].ui.onSelectedChange(false);
22744 this.selNodes = [];
22745 this.selMap = {};
22746 if(suppressEvent !== true){
22747 this.fireEvent("selectionchange", this, this.selNodes);
22750 },
22753 isSelected : function(node){
22754 return this.selMap[node.id] ? true : false;
22755 },
22758 getSelectedNodes : function(){
22759 return this.selNodes;
22760 },
22762 onKeyDown : Ext.tree.DefaultSelectionModel.prototype.onKeyDown,
22764 selectNext : Ext.tree.DefaultSelectionModel.prototype.selectNext,
22766 selectPrevious : Ext.tree.DefaultSelectionModel.prototype.selectPrevious
22767 });
22769 Ext.tree.TreeNode = function(attributes){
22770 attributes = attributes || {};
22771 if(typeof attributes == "string"){
22772 attributes = {text: attributes};
22774 this.childrenRendered = false;
22775 this.rendered = false;
22776 Ext.tree.TreeNode.superclass.constructor.call(this, attributes);
22777 this.expanded = attributes.expanded === true;
22778 this.isTarget = attributes.isTarget !== false;
22779 this.draggable = attributes.draggable !== false && attributes.allowDrag !== false;
22780 this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false;
22783 this.text = attributes.text;
22785 this.disabled = attributes.disabled === true;
22787 this.addEvents(
22789 "textchange",
22791 "beforeexpand",
22793 "beforecollapse",
22795 "expand",
22797 "disabledchange",
22799 "collapse",
22801 "beforeclick",
22803 "click",
22805 "checkchange",
22807 "dblclick",
22809 "contextmenu",
22811 "beforechildrenrendered"
22812 );
22814 var uiClass = this.attributes.uiProvider || this.defaultUI || Ext.tree.TreeNodeUI;
22817 this.ui = new uiClass(this);
22818 };
22819 Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
22820 preventHScroll: true,
22822 isExpanded : function(){
22823 return this.expanded;
22824 },
22827 getUI : function(){
22828 return this.ui;
22829 },
22832 setFirstChild : function(node){
22833 var of = this.firstChild;
22834 Ext.tree.TreeNode.superclass.setFirstChild.call(this, node);
22835 if(this.childrenRendered && of && node != of){
22836 of.renderIndent(true, true);
22838 if(this.rendered){
22839 this.renderIndent(true, true);
22841 },
22844 setLastChild : function(node){
22845 var ol = this.lastChild;
22846 Ext.tree.TreeNode.superclass.setLastChild.call(this, node);
22847 if(this.childrenRendered && ol && node != ol){
22848 ol.renderIndent(true, true);
22850 if(this.rendered){
22851 this.renderIndent(true, true);
22853 },
22857 appendChild : function(){
22858 var node = Ext.tree.TreeNode.superclass.appendChild.apply(this, arguments);
22859 if(node && this.childrenRendered){
22860 node.render();
22862 this.ui.updateExpandIcon();
22863 return node;
22864 },
22867 removeChild : function(node){
22868 this.ownerTree.getSelectionModel().unselect(node);
22869 Ext.tree.TreeNode.superclass.removeChild.apply(this, arguments);
22871 if(this.childrenRendered){
22872 node.ui.remove();
22874 if(this.childNodes.length < 1){
22875 this.collapse(false, false);
22876 }else{
22877 this.ui.updateExpandIcon();
22879 if(!this.firstChild && !this.isHiddenRoot()) {
22880 this.childrenRendered = false;
22882 return node;
22883 },
22886 insertBefore : function(node, refNode){
22887 var newNode = Ext.tree.TreeNode.superclass.insertBefore.apply(this, arguments);
22888 if(newNode && refNode && this.childrenRendered){
22889 node.render();
22891 this.ui.updateExpandIcon();
22892 return newNode;
22893 },
22896 setText : function(text){
22897 var oldText = this.text;
22898 this.text = text;
22899 this.attributes.text = text;
22900 if(this.rendered){
22901 this.ui.onTextChange(this, text, oldText);
22903 this.fireEvent("textchange", this, text, oldText);
22904 },
22907 select : function(){
22908 this.getOwnerTree().getSelectionModel().select(this);
22909 },
22912 unselect : function(){
22913 this.getOwnerTree().getSelectionModel().unselect(this);
22914 },
22917 isSelected : function(){
22918 return this.getOwnerTree().getSelectionModel().isSelected(this);
22919 },
22922 expand : function(deep, anim, callback){
22923 if(!this.expanded){
22924 if(this.fireEvent("beforeexpand", this, deep, anim) === false){
22925 return;
22927 if(!this.childrenRendered){
22928 this.renderChildren();
22930 this.expanded = true;
22931 if(!this.isHiddenRoot() && (this.getOwnerTree().animate && anim !== false) || anim){
22932 this.ui.animExpand(function(){
22933 this.fireEvent("expand", this);
22934 if(typeof callback == "function"){
22935 callback(this);
22937 if(deep === true){
22938 this.expandChildNodes(true);
22940 }.createDelegate(this));
22941 return;
22942 }else{
22943 this.ui.expand();
22944 this.fireEvent("expand", this);
22945 if(typeof callback == "function"){
22946 callback(this);
22949 }else{
22950 if(typeof callback == "function"){
22951 callback(this);
22954 if(deep === true){
22955 this.expandChildNodes(true);
22957 },
22959 isHiddenRoot : function(){
22960 return this.isRoot && !this.getOwnerTree().rootVisible;
22961 },
22964 collapse : function(deep, anim){
22965 if(this.expanded && !this.isHiddenRoot()){
22966 if(this.fireEvent("beforecollapse", this, deep, anim) === false){
22967 return;
22969 this.expanded = false;
22970 if((this.getOwnerTree().animate && anim !== false) || anim){
22971 this.ui.animCollapse(function(){
22972 this.fireEvent("collapse", this);
22973 if(deep === true){
22974 this.collapseChildNodes(true);
22976 }.createDelegate(this));
22977 return;
22978 }else{
22979 this.ui.collapse();
22980 this.fireEvent("collapse", this);
22983 if(deep === true){
22984 var cs = this.childNodes;
22985 for(var i = 0, len = cs.length; i < len; i++) {
22986 cs[i].collapse(true, false);
22989 },
22992 delayedExpand : function(delay){
22993 if(!this.expandProcId){
22994 this.expandProcId = this.expand.defer(delay, this);
22996 },
22999 cancelExpand : function(){
23000 if(this.expandProcId){
23001 clearTimeout(this.expandProcId);
23003 this.expandProcId = false;
23004 },
23007 toggle : function(){
23008 if(this.expanded){
23009 this.collapse();
23010 }else{
23011 this.expand();
23013 },
23016 ensureVisible : function(callback){
23017 var tree = this.getOwnerTree();
23018 tree.expandPath(this.parentNode.getPath(), false, function(){
23019 var node = tree.getNodeById(this.id);
23020 tree.getTreeEl().scrollChildIntoView(node.ui.anchor);
23021 Ext.callback(callback);
23022 }.createDelegate(this));
23023 },
23026 expandChildNodes : function(deep){
23027 var cs = this.childNodes;
23028 for(var i = 0, len = cs.length; i < len; i++) {
23029 cs[i].expand(deep);
23031 },
23034 collapseChildNodes : function(deep){
23035 var cs = this.childNodes;
23036 for(var i = 0, len = cs.length; i < len; i++) {
23037 cs[i].collapse(deep);
23039 },
23042 disable : function(){
23043 this.disabled = true;
23044 this.unselect();
23045 if(this.rendered && this.ui.onDisableChange){
23046 this.ui.onDisableChange(this, true);
23048 this.fireEvent("disabledchange", this, true);
23049 },
23052 enable : function(){
23053 this.disabled = false;
23054 if(this.rendered && this.ui.onDisableChange){
23055 this.ui.onDisableChange(this, false);
23057 this.fireEvent("disabledchange", this, false);
23058 },
23061 renderChildren : function(suppressEvent){
23062 if(suppressEvent !== false){
23063 this.fireEvent("beforechildrenrendered", this);
23065 var cs = this.childNodes;
23066 for(var i = 0, len = cs.length; i < len; i++){
23067 cs[i].render(true);
23069 this.childrenRendered = true;
23070 },
23073 sort : function(fn, scope){
23074 Ext.tree.TreeNode.superclass.sort.apply(this, arguments);
23075 if(this.childrenRendered){
23076 var cs = this.childNodes;
23077 for(var i = 0, len = cs.length; i < len; i++){
23078 cs[i].render(true);
23081 },
23084 render : function(bulkRender){
23085 this.ui.render(bulkRender);
23086 if(!this.rendered){
23088 this.getOwnerTree().registerNode(this);
23089 this.rendered = true;
23090 if(this.expanded){
23091 this.expanded = false;
23092 this.expand(false, false);
23095 },
23098 renderIndent : function(deep, refresh){
23099 if(refresh){
23100 this.ui.childIndent = null;
23102 this.ui.renderIndent();
23103 if(deep === true && this.childrenRendered){
23104 var cs = this.childNodes;
23105 for(var i = 0, len = cs.length; i < len; i++){
23106 cs[i].renderIndent(true, refresh);
23109 },
23111 beginUpdate : function(){
23112 this.childrenRendered = false;
23113 },
23115 endUpdate : function(){
23116 if(this.expanded && this.rendered){
23117 this.renderChildren();
23119 },
23121 destroy : function(){
23122 for(var i = 0,l = this.childNodes.length; i < l; i++){
23123 this.childNodes[i].destroy();
23125 this.childNodes = null;
23126 if(this.ui.destroy){
23127 this.ui.destroy();
23130 });
23132 Ext.tree.AsyncTreeNode = function(config){
23133 this.loaded = false;
23134 this.loading = false;
23135 Ext.tree.AsyncTreeNode.superclass.constructor.apply(this, arguments);
23137 this.addEvents('beforeload', 'load');
23140 };
23141 Ext.extend(Ext.tree.AsyncTreeNode, Ext.tree.TreeNode, {
23142 expand : function(deep, anim, callback){
23143 if(this.loading){
23144 var timer;
23145 var f = function(){
23146 if(!this.loading){
23147 clearInterval(timer);
23148 this.expand(deep, anim, callback);
23150 }.createDelegate(this);
23151 timer = setInterval(f, 200);
23152 return;
23154 if(!this.loaded){
23155 if(this.fireEvent("beforeload", this) === false){
23156 return;
23158 this.loading = true;
23159 this.ui.beforeLoad(this);
23160 var loader = this.loader || this.attributes.loader || this.getOwnerTree().getLoader();
23161 if(loader){
23162 loader.load(this, this.loadComplete.createDelegate(this, [deep, anim, callback]));
23163 return;
23166 Ext.tree.AsyncTreeNode.superclass.expand.call(this, deep, anim, callback);
23167 },
23170 isLoading : function(){
23171 return this.loading;
23172 },
23174 loadComplete : function(deep, anim, callback){
23175 this.loading = false;
23176 this.loaded = true;
23177 this.ui.afterLoad(this);
23178 this.fireEvent("load", this);
23179 this.expand(deep, anim, callback);
23180 },
23183 isLoaded : function(){
23184 return this.loaded;
23185 },
23187 hasChildNodes : function(){
23188 if(!this.isLeaf() && !this.loaded){
23189 return true;
23190 }else{
23191 return Ext.tree.AsyncTreeNode.superclass.hasChildNodes.call(this);
23193 },
23196 reload : function(callback){
23197 this.collapse(false, false);
23198 while(this.firstChild){
23199 this.removeChild(this.firstChild);
23201 this.childrenRendered = false;
23202 this.loaded = false;
23203 if(this.isHiddenRoot()){
23204 this.expanded = false;
23206 this.expand(false, false, callback);
23208 });
23210 Ext.tree.TreeNodeUI = function(node){
23211 this.node = node;
23212 this.rendered = false;
23213 this.animating = false;
23214 this.wasLeaf = true;
23215 this.ecc = 'x-tree-ec-icon x-tree-elbow';
23216 this.emptyIcon = Ext.BLANK_IMAGE_URL;
23217 };
23219 Ext.tree.TreeNodeUI.prototype = {
23221 removeChild : function(node){
23222 if(this.rendered){
23223 this.ctNode.removeChild(node.ui.getEl());
23225 },
23228 beforeLoad : function(){
23229 this.addClass("x-tree-node-loading");
23230 },
23233 afterLoad : function(){
23234 this.removeClass("x-tree-node-loading");
23235 },
23238 onTextChange : function(node, text, oldText){
23239 if(this.rendered){
23240 this.textNode.innerHTML = text;
23242 },
23245 onDisableChange : function(node, state){
23246 this.disabled = state;
23247 if (this.checkbox) {
23248 this.checkbox.disabled = state;
23250 if(state){
23251 this.addClass("x-tree-node-disabled");
23252 }else{
23253 this.removeClass("x-tree-node-disabled");
23255 },
23258 onSelectedChange : function(state){
23259 if(state){
23260 this.focus();
23261 this.addClass("x-tree-selected");
23262 }else{
23264 this.removeClass("x-tree-selected");
23266 },
23269 onMove : function(tree, node, oldParent, newParent, index, refNode){
23270 this.childIndent = null;
23271 if(this.rendered){
23272 var targetNode = newParent.ui.getContainer();
23273 if(!targetNode){
23274 this.holder = document.createElement("div");
23275 this.holder.appendChild(this.wrap);
23276 return;
23278 var insertBefore = refNode ? refNode.ui.getEl() : null;
23279 if(insertBefore){
23280 targetNode.insertBefore(this.wrap, insertBefore);
23281 }else{
23282 targetNode.appendChild(this.wrap);
23284 this.node.renderIndent(true);
23286 },
23289 addClass : function(cls){
23290 if(this.elNode){
23291 Ext.fly(this.elNode).addClass(cls);
23293 },
23296 removeClass : function(cls){
23297 if(this.elNode){
23298 Ext.fly(this.elNode).removeClass(cls);
23300 },
23303 remove : function(){
23304 if(this.rendered){
23305 this.holder = document.createElement("div");
23306 this.holder.appendChild(this.wrap);
23308 },
23311 fireEvent : function(){
23312 return this.node.fireEvent.apply(this.node, arguments);
23313 },
23316 initEvents : function(){
23317 this.node.on("move", this.onMove, this);
23319 if(this.node.disabled){
23320 this.addClass("x-tree-node-disabled");
23321 if (this.checkbox) {
23322 this.checkbox.disabled = true;
23325 if(this.node.hidden){
23326 this.hide();
23328 var ot = this.node.getOwnerTree();
23329 var dd = ot.enableDD || ot.enableDrag || ot.enableDrop;
23330 if(dd && (!this.node.isRoot || ot.rootVisible)){
23331 Ext.dd.Registry.register(this.elNode, {
23332 node: this.node,
23333 handles: this.getDDHandles(),
23334 isHandle: false
23335 });
23337 },
23340 getDDHandles : function(){
23341 return [this.iconNode, this.textNode, this.elNode];
23342 },
23345 hide : function(){
23346 this.node.hidden = true;
23347 if(this.wrap){
23348 this.wrap.style.display = "none";
23350 },
23353 show : function(){
23354 this.node.hidden = false;
23355 if(this.wrap){
23356 this.wrap.style.display = "";
23358 },
23361 onContextMenu : function(e){
23362 if (this.node.hasListener("contextmenu") || this.node.getOwnerTree().hasListener("contextmenu")) {
23363 e.preventDefault();
23364 this.focus();
23365 this.fireEvent("contextmenu", this.node, e);
23367 },
23370 onClick : function(e){
23371 if(this.dropping){
23372 e.stopEvent();
23373 return;
23375 if(this.fireEvent("beforeclick", this.node, e) !== false){
23376 var a = e.getTarget('a');
23377 if(!this.disabled && this.node.attributes.href && a){
23378 this.fireEvent("click", this.node, e);
23379 return;
23380 }else if(a && e.ctrlKey){
23381 e.stopEvent();
23383 e.preventDefault();
23384 if(this.disabled){
23385 return;
23388 if(this.node.attributes.singleClickExpand && !this.animating && this.node.hasChildNodes()){
23389 this.node.toggle();
23392 this.fireEvent("click", this.node, e);
23393 }else{
23394 e.stopEvent();
23396 },
23399 onDblClick : function(e){
23400 e.preventDefault();
23401 if(this.disabled){
23402 return;
23404 if(this.checkbox){
23405 this.toggleCheck();
23407 if(!this.animating && this.node.hasChildNodes()){
23408 this.node.toggle();
23410 this.fireEvent("dblclick", this.node, e);
23411 },
23413 onOver : function(e){
23414 this.addClass('x-tree-node-over');
23415 },
23417 onOut : function(e){
23418 this.removeClass('x-tree-node-over');
23419 },
23422 onCheckChange : function(){
23423 var checked = this.checkbox.checked;
23425 this.checkbox.defaultChecked = checked;
23426 this.node.attributes.checked = checked;
23427 this.fireEvent('checkchange', this.node, checked);
23428 },
23431 ecClick : function(e){
23432 if(!this.animating && (this.node.hasChildNodes() || this.node.attributes.expandable)){
23433 this.node.toggle();
23435 },
23438 startDrop : function(){
23439 this.dropping = true;
23440 },
23443 endDrop : function(){
23444 setTimeout(function(){
23445 this.dropping = false;
23446 }.createDelegate(this), 50);
23447 },
23450 expand : function(){
23451 this.updateExpandIcon();
23452 this.ctNode.style.display = "";
23453 },
23456 focus : function(){
23457 if(!this.node.preventHScroll){
23458 try{this.anchor.focus();
23459 }catch(e){}
23460 }else if(!Ext.isIE){
23461 try{
23462 var noscroll = this.node.getOwnerTree().getTreeEl().dom;
23463 var l = noscroll.scrollLeft;
23464 this.anchor.focus();
23465 noscroll.scrollLeft = l;
23466 }catch(e){}
23468 },
23471 toggleCheck : function(value){
23472 var cb = this.checkbox;
23473 if(cb){
23474 cb.checked = (value === undefined ? !cb.checked : value);
23475 this.onCheckChange();
23477 },
23480 blur : function(){
23481 try{
23482 this.anchor.blur();
23483 }catch(e){}
23484 },
23487 animExpand : function(callback){
23488 var ct = Ext.get(this.ctNode);
23489 ct.stopFx();
23490 if(!this.node.hasChildNodes()){
23491 this.updateExpandIcon();
23492 this.ctNode.style.display = "";
23493 Ext.callback(callback);
23494 return;
23496 this.animating = true;
23497 this.updateExpandIcon();
23499 ct.slideIn('t', {
23500 callback : function(){
23501 this.animating = false;
23502 Ext.callback(callback);
23503 },
23504 scope: this,
23505 duration: this.node.ownerTree.duration || .25
23506 });
23507 },
23510 highlight : function(){
23511 var tree = this.node.getOwnerTree();
23512 Ext.fly(this.wrap).highlight(
23513 tree.hlColor || "C3DAF9",
23514 {endColor: tree.hlBaseColor}
23515 );
23516 },
23519 collapse : function(){
23520 this.updateExpandIcon();
23521 this.ctNode.style.display = "none";
23522 },
23525 animCollapse : function(callback){
23526 var ct = Ext.get(this.ctNode);
23527 ct.enableDisplayMode('block');
23528 ct.stopFx();
23530 this.animating = true;
23531 this.updateExpandIcon();
23533 ct.slideOut('t', {
23534 callback : function(){
23535 this.animating = false;
23536 Ext.callback(callback);
23537 },
23538 scope: this,
23539 duration: this.node.ownerTree.duration || .25
23540 });
23541 },
23544 getContainer : function(){
23545 return this.ctNode;
23546 },
23549 getEl : function(){
23550 return this.wrap;
23551 },
23554 appendDDGhost : function(ghostNode){
23555 ghostNode.appendChild(this.elNode.cloneNode(true));
23556 },
23559 getDDRepairXY : function(){
23560 return Ext.lib.Dom.getXY(this.iconNode);
23561 },
23564 onRender : function(){
23565 this.render();
23566 },
23569 render : function(bulkRender){
23570 var n = this.node, a = n.attributes;
23571 var targetNode = n.parentNode ?
23572 n.parentNode.ui.getContainer() : n.ownerTree.innerCt.dom;
23574 if(!this.rendered){
23575 this.rendered = true;
23577 this.renderElements(n, a, targetNode, bulkRender);
23579 if(a.qtip){
23580 if(this.textNode.setAttributeNS){
23581 this.textNode.setAttributeNS("ext", "qtip", a.qtip);
23582 if(a.qtipTitle){
23583 this.textNode.setAttributeNS("ext", "qtitle", a.qtipTitle);
23585 }else{
23586 this.textNode.setAttribute("ext:qtip", a.qtip);
23587 if(a.qtipTitle){
23588 this.textNode.setAttribute("ext:qtitle", a.qtipTitle);
23591 }else if(a.qtipCfg){
23592 a.qtipCfg.target = Ext.id(this.textNode);
23593 Ext.QuickTips.register(a.qtipCfg);
23595 this.initEvents();
23596 if(!this.node.expanded){
23597 this.updateExpandIcon(true);
23599 }else{
23600 if(bulkRender === true) {
23601 targetNode.appendChild(this.wrap);
23604 },
23607 renderElements : function(n, a, targetNode, bulkRender){
23609 this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
23611 var cb = typeof a.checked == 'boolean';
23613 var href = a.href ? a.href : Ext.isGecko ? "" : "#";
23614 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">',
23615 '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
23616 '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
23617 '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />',
23618 cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
23619 '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
23620 a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span unselectable="on">',n.text,"</span></a></div>",
23621 '<ul class="x-tree-node-ct" style="display:none;"></ul>',
23622 "</li>"].join('');
23624 var nel;
23625 if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){
23626 this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
23627 }else{
23628 this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
23631 this.elNode = this.wrap.childNodes[0];
23632 this.ctNode = this.wrap.childNodes[1];
23633 var cs = this.elNode.childNodes;
23634 this.indentNode = cs[0];
23635 this.ecNode = cs[1];
23636 this.iconNode = cs[2];
23637 var index = 3;
23638 if(cb){
23639 this.checkbox = cs[3];
23641 this.checkbox.defaultChecked = this.checkbox.checked;
23642 index++;
23644 this.anchor = cs[index];
23645 this.textNode = cs[index].firstChild;
23646 },
23649 getAnchor : function(){
23650 return this.anchor;
23651 },
23654 getTextEl : function(){
23655 return this.textNode;
23656 },
23659 getIconEl : function(){
23660 return this.iconNode;
23661 },
23664 isChecked : function(){
23665 return this.checkbox ? this.checkbox.checked : false;
23666 },
23669 updateExpandIcon : function(){
23670 if(this.rendered){
23671 var n = this.node, c1, c2;
23672 var cls = n.isLast() ? "x-tree-elbow-end" : "x-tree-elbow";
23673 var hasChild = n.hasChildNodes();
23674 if(hasChild || n.attributes.expandable){
23675 if(n.expanded){
23676 cls += "-minus";
23677 c1 = "x-tree-node-collapsed";
23678 c2 = "x-tree-node-expanded";
23679 }else{
23680 cls += "-plus";
23681 c1 = "x-tree-node-expanded";
23682 c2 = "x-tree-node-collapsed";
23684 if(this.wasLeaf){
23685 this.removeClass("x-tree-node-leaf");
23686 this.wasLeaf = false;
23688 if(this.c1 != c1 || this.c2 != c2){
23689 Ext.fly(this.elNode).replaceClass(c1, c2);
23690 this.c1 = c1; this.c2 = c2;
23692 }else{
23693 if(!this.wasLeaf){
23694 Ext.fly(this.elNode).replaceClass("x-tree-node-expanded", "x-tree-node-leaf");
23695 delete this.c1;
23696 delete this.c2;
23697 this.wasLeaf = true;
23700 var ecc = "x-tree-ec-icon "+cls;
23701 if(this.ecc != ecc){
23702 this.ecNode.className = ecc;
23703 this.ecc = ecc;
23706 },
23709 getChildIndent : function(){
23710 if(!this.childIndent){
23711 var buf = [];
23712 var p = this.node;
23713 while(p){
23714 if(!p.isRoot || (p.isRoot && p.ownerTree.rootVisible)){
23715 if(!p.isLast()) {
23716 buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-elbow-line" />');
23717 } else {
23718 buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-icon" />');
23721 p = p.parentNode;
23723 this.childIndent = buf.join("");
23725 return this.childIndent;
23726 },
23729 renderIndent : function(){
23730 if(this.rendered){
23731 var indent = "";
23732 var p = this.node.parentNode;
23733 if(p){
23734 indent = p.ui.getChildIndent();
23736 if(this.indentMarkup != indent){
23737 this.indentNode.innerHTML = indent;
23738 this.indentMarkup = indent;
23740 this.updateExpandIcon();
23742 },
23744 destroy : function(){
23745 if(this.elNode){
23746 Ext.dd.Registry.unregister(this.elNode.id);
23748 delete this.elNode;
23749 delete this.ctNode;
23750 delete this.indentNode;
23751 delete this.ecNode;
23752 delete this.iconNode;
23753 delete this.checkbox;
23754 delete this.anchor;
23755 delete this.textNode;
23756 Ext.removeNode(this.ctNode);
23758 };
23761 Ext.tree.RootTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
23763 render : function(){
23764 if(!this.rendered){
23765 var targetNode = this.node.ownerTree.innerCt.dom;
23766 this.node.expanded = true;
23767 targetNode.innerHTML = '<div class="x-tree-root-node"></div>';
23768 this.wrap = this.ctNode = targetNode.firstChild;
23770 },
23771 collapse : Ext.emptyFn,
23772 expand : Ext.emptyFn
23773 });
23775 Ext.tree.TreeLoader = function(config){
23776 this.baseParams = {};
23777 Ext.apply(this, config);
23779 this.addEvents(
23781 "beforeload",
23783 "load",
23785 "loadexception"
23786 );
23788 Ext.tree.TreeLoader.superclass.constructor.call(this);
23789 };
23791 Ext.extend(Ext.tree.TreeLoader, Ext.util.Observable, {
23799 uiProviders : {},
23802 clearOnLoad : true,
23805 load : function(node, callback){
23806 if(this.clearOnLoad){
23807 while(node.firstChild){
23808 node.removeChild(node.firstChild);
23811 if(this.doPreload(node)){
23812 if(typeof callback == "function"){
23813 callback();
23815 }else if(this.dataUrl||this.url){
23816 this.requestData(node, callback);
23818 },
23820 doPreload : function(node){
23821 if(node.attributes.children){
23822 if(node.childNodes.length < 1){
23823 var cs = node.attributes.children;
23824 node.beginUpdate();
23825 for(var i = 0, len = cs.length; i < len; i++){
23826 var cn = node.appendChild(this.createNode(cs[i]));
23827 if(this.preloadChildren){
23828 this.doPreload(cn);
23831 node.endUpdate();
23833 return true;
23834 }else {
23835 return false;
23837 },
23839 getParams: function(node){
23840 var buf = [], bp = this.baseParams;
23841 for(var key in bp){
23842 if(typeof bp[key] != "function"){
23843 buf.push(encodeURIComponent(key), "=", encodeURIComponent(bp[key]), "&");
23846 buf.push("node=", encodeURIComponent(node.id));
23847 return buf.join("");
23848 },
23850 requestData : function(node, callback){
23851 if(this.fireEvent("beforeload", this, node, callback) !== false){
23852 this.transId = Ext.Ajax.request({
23853 method:this.requestMethod,
23854 url: this.dataUrl||this.url,
23855 success: this.handleResponse,
23856 failure: this.handleFailure,
23857 scope: this,
23858 argument: {callback: callback, node: node},
23859 params: this.getParams(node)
23860 });
23861 }else{
23864 if(typeof callback == "function"){
23865 callback();
23868 },
23870 isLoading : function(){
23871 return this.transId ? true : false;
23872 },
23874 abort : function(){
23875 if(this.isLoading()){
23876 Ext.Ajax.abort(this.transId);
23878 },
23881 createNode : function(attr){
23883 if(this.baseAttrs){
23884 Ext.applyIf(attr, this.baseAttrs);
23886 if(this.applyLoader !== false){
23887 attr.loader = this;
23889 if(typeof attr.uiProvider == 'string'){
23890 attr.uiProvider = this.uiProviders[attr.uiProvider] || eval(attr.uiProvider);
23892 return(attr.leaf ?
23893 new Ext.tree.TreeNode(attr) :
23894 new Ext.tree.AsyncTreeNode(attr));
23895 },
23897 processResponse : function(response, node, callback){
23898 var json = response.responseText;
23899 try {
23900 var o = eval("("+json+")");
23901 node.beginUpdate();
23902 for(var i = 0, len = o.length; i < len; i++){
23903 var n = this.createNode(o[i]);
23904 if(n){
23905 node.appendChild(n);
23908 node.endUpdate();
23909 if(typeof callback == "function"){
23910 callback(this, node);
23912 }catch(e){
23913 this.handleFailure(response);
23915 },
23917 handleResponse : function(response){
23918 this.transId = false;
23919 var a = response.argument;
23920 this.processResponse(response, a.node, a.callback);
23921 this.fireEvent("load", this, a.node, response);
23922 },
23924 handleFailure : function(response){
23925 this.transId = false;
23926 var a = response.argument;
23927 this.fireEvent("loadexception", this, a.node, response);
23928 if(typeof a.callback == "function"){
23929 a.callback(this, a.node);
23932 });
23934 Ext.tree.TreeFilter = function(tree, config){
23935 this.tree = tree;
23936 this.filtered = {};
23937 Ext.apply(this, config);
23938 };
23940 Ext.tree.TreeFilter.prototype = {
23941 clearBlank:false,
23942 reverse:false,
23943 autoClear:false,
23944 remove:false,
23947 filter : function(value, attr, startNode){
23948 attr = attr || "text";
23949 var f;
23950 if(typeof value == "string"){
23951 var vlen = value.length;
23953 if(vlen == 0 && this.clearBlank){
23954 this.clear();
23955 return;
23957 value = value.toLowerCase();
23958 f = function(n){
23959 return n.attributes[attr].substr(0, vlen).toLowerCase() == value;
23960 };
23961 }else if(value.exec){
23962 f = function(n){
23963 return value.test(n.attributes[attr]);
23964 };
23965 }else{
23966 throw 'Illegal filter type, must be string or regex';
23968 this.filterBy(f, null, startNode);
23969 },
23972 filterBy : function(fn, scope, startNode){
23973 startNode = startNode || this.tree.root;
23974 if(this.autoClear){
23975 this.clear();
23977 var af = this.filtered, rv = this.reverse;
23978 var f = function(n){
23979 if(n == startNode){
23980 return true;
23982 if(af[n.id]){
23983 return false;
23985 var m = fn.call(scope || n, n);
23986 if(!m || rv){
23987 af[n.id] = n;
23988 n.ui.hide();
23989 return false;
23991 return true;
23992 };
23993 startNode.cascade(f);
23994 if(this.remove){
23995 for(var id in af){
23996 if(typeof id != "function"){
23997 var n = af[id];
23998 if(n && n.parentNode){
23999 n.parentNode.removeChild(n);
24004 },
24007 clear : function(){
24008 var t = this.tree;
24009 var af = this.filtered;
24010 for(var id in af){
24011 if(typeof id != "function"){
24012 var n = af[id];
24013 if(n){
24014 n.ui.show();
24018 this.filtered = {};
24020 };
24023 Ext.tree.TreeSorter = function(tree, config){
24031 Ext.apply(this, config);
24032 tree.on("beforechildrenrendered", this.doSort, this);
24033 tree.on("append", this.updateSort, this);
24034 tree.on("insert", this.updateSort, this);
24035 tree.on("textchange", this.updateSortParent, this);
24037 var dsc = this.dir && this.dir.toLowerCase() == "desc";
24038 var p = this.property || "text";
24039 var sortType = this.sortType;
24040 var fs = this.folderSort;
24041 var cs = this.caseSensitive === true;
24042 var leafAttr = this.leafAttr || 'leaf';
24044 this.sortFn = function(n1, n2){
24045 if(fs){
24046 if(n1.attributes[leafAttr] && !n2.attributes[leafAttr]){
24047 return 1;
24049 if(!n1.attributes[leafAttr] && n2.attributes[leafAttr]){
24050 return -1;
24053 var v1 = sortType ? sortType(n1) : (cs ? n1.attributes[p] : n1.attributes[p].toUpperCase());
24054 var v2 = sortType ? sortType(n2) : (cs ? n2.attributes[p] : n2.attributes[p].toUpperCase());
24055 if(v1 < v2){
24056 return dsc ? +1 : -1;
24057 }else if(v1 > v2){
24058 return dsc ? -1 : +1;
24059 }else{
24060 return 0;
24062 };
24063 };
24065 Ext.tree.TreeSorter.prototype = {
24066 doSort : function(node){
24067 node.sort(this.sortFn);
24068 },
24070 compareNodes : function(n1, n2){
24071 return (n1.text.toUpperCase() > n2.text.toUpperCase() ? 1 : -1);
24072 },
24074 updateSort : function(tree, node){
24075 if(node.childrenRendered){
24076 this.doSort.defer(1, this, [node]);
24078 },
24080 updateSortParent : function(node){
24081 var p = node.parentNode;
24082 if(p && p.childrenRendered){
24083 this.doSort.defer(1, this, [p]);
24086 };
24088 if(Ext.dd.DropZone){
24090 Ext.tree.TreeDropZone = function(tree, config){
24092 this.allowParentInsert = false;
24094 this.allowContainerDrop = false;
24096 this.appendOnly = false;
24097 Ext.tree.TreeDropZone.superclass.constructor.call(this, tree.innerCt, config);
24099 this.tree = tree;
24101 this.dragOverData = {};
24103 this.lastInsertClass = "x-tree-no-status";
24104 };
24106 Ext.extend(Ext.tree.TreeDropZone, Ext.dd.DropZone, {
24108 ddGroup : "TreeDD",
24111 expandDelay : 1000,
24114 expandNode : function(node){
24115 if(node.hasChildNodes() && !node.isExpanded()){
24116 node.expand(false, null, this.triggerCacheRefresh.createDelegate(this));
24118 },
24121 queueExpand : function(node){
24122 this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]);
24123 },
24126 cancelExpand : function(){
24127 if(this.expandProcId){
24128 clearTimeout(this.expandProcId);
24129 this.expandProcId = false;
24131 },
24134 isValidDropPoint : function(n, pt, dd, e, data){
24135 if(!n || !data){ return false; }
24136 var targetNode = n.node;
24137 var dropNode = data.node;
24139 if(!(targetNode && targetNode.isTarget && pt)){
24140 return false;
24142 if(pt == "append" && targetNode.allowChildren === false){
24143 return false;
24145 if((pt == "above" || pt == "below") && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){
24146 return false;
24148 if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){
24149 return false;
24152 var overEvent = this.dragOverData;
24153 overEvent.tree = this.tree;
24154 overEvent.target = targetNode;
24155 overEvent.data = data;
24156 overEvent.point = pt;
24157 overEvent.source = dd;
24158 overEvent.rawEvent = e;
24159 overEvent.dropNode = dropNode;
24160 overEvent.cancel = false;
24161 var result = this.tree.fireEvent("nodedragover", overEvent);
24162 return overEvent.cancel === false && result !== false;
24163 },
24166 getDropPoint : function(e, n, dd){
24167 var tn = n.node;
24168 if(tn.isRoot){
24169 return tn.allowChildren !== false ? "append" : false;
24171 var dragEl = n.ddel;
24172 var t = Ext.lib.Dom.getY(dragEl), b = t + dragEl.offsetHeight;
24173 var y = Ext.lib.Event.getPageY(e);
24174 var noAppend = tn.allowChildren === false || tn.isLeaf();
24175 if(this.appendOnly || tn.parentNode.allowChildren === false){
24176 return noAppend ? false : "append";
24178 var noBelow = false;
24179 if(!this.allowParentInsert){
24180 noBelow = tn.hasChildNodes() && tn.isExpanded();
24182 var q = (b - t) / (noAppend ? 2 : 3);
24183 if(y >= t && y < (t + q)){
24184 return "above";
24185 }else if(!noBelow && (noAppend || y >= b-q && y <= b)){
24186 return "below";
24187 }else{
24188 return "append";
24190 },
24193 onNodeEnter : function(n, dd, e, data){
24194 this.cancelExpand();
24195 },
24198 onNodeOver : function(n, dd, e, data){
24199 var pt = this.getDropPoint(e, n, dd);
24200 var node = n.node;
24203 if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){
24204 this.queueExpand(node);
24205 }else if(pt != "append"){
24206 this.cancelExpand();
24210 var returnCls = this.dropNotAllowed;
24211 if(this.isValidDropPoint(n, pt, dd, e, data)){
24212 if(pt){
24213 var el = n.ddel;
24214 var cls;
24215 if(pt == "above"){
24216 returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between";
24217 cls = "x-tree-drag-insert-above";
24218 }else if(pt == "below"){
24219 returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between";
24220 cls = "x-tree-drag-insert-below";
24221 }else{
24222 returnCls = "x-tree-drop-ok-append";
24223 cls = "x-tree-drag-append";
24225 if(this.lastInsertClass != cls){
24226 Ext.fly(el).replaceClass(this.lastInsertClass, cls);
24227 this.lastInsertClass = cls;
24231 return returnCls;
24232 },
24235 onNodeOut : function(n, dd, e, data){
24236 this.cancelExpand();
24237 this.removeDropIndicators(n);
24238 },
24241 onNodeDrop : function(n, dd, e, data){
24242 var point = this.getDropPoint(e, n, dd);
24243 var targetNode = n.node;
24244 targetNode.ui.startDrop();
24245 if(!this.isValidDropPoint(n, point, dd, e, data)){
24246 targetNode.ui.endDrop();
24247 return false;
24250 var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
24251 var dropEvent = {
24252 tree : this.tree,
24253 target: targetNode,
24254 data: data,
24255 point: point,
24256 source: dd,
24257 rawEvent: e,
24258 dropNode: dropNode,
24259 cancel: !dropNode,
24260 dropStatus: false
24261 };
24262 var retval = this.tree.fireEvent("beforenodedrop", dropEvent);
24263 if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
24264 targetNode.ui.endDrop();
24265 return dropEvent.dropStatus;
24268 targetNode = dropEvent.target;
24269 if(point == "append" && !targetNode.isExpanded()){
24270 targetNode.expand(false, null, function(){
24271 this.completeDrop(dropEvent);
24272 }.createDelegate(this));
24273 }else{
24274 this.completeDrop(dropEvent);
24276 return true;
24277 },
24280 completeDrop : function(de){
24281 var ns = de.dropNode, p = de.point, t = de.target;
24282 if(!Ext.isArray(ns)){
24283 ns = [ns];
24285 var n;
24286 for(var i = 0, len = ns.length; i < len; i++){
24287 n = ns[i];
24288 if(p == "above"){
24289 t.parentNode.insertBefore(n, t);
24290 }else if(p == "below"){
24291 t.parentNode.insertBefore(n, t.nextSibling);
24292 }else{
24293 t.appendChild(n);
24296 n.ui.focus();
24297 if(this.tree.hlDrop){
24298 n.ui.highlight();
24300 t.ui.endDrop();
24301 this.tree.fireEvent("nodedrop", de);
24302 },
24305 afterNodeMoved : function(dd, data, e, targetNode, dropNode){
24306 if(this.tree.hlDrop){
24307 dropNode.ui.focus();
24308 dropNode.ui.highlight();
24310 this.tree.fireEvent("nodedrop", this.tree, targetNode, data, dd, e);
24311 },
24314 getTree : function(){
24315 return this.tree;
24316 },
24319 removeDropIndicators : function(n){
24320 if(n && n.ddel){
24321 var el = n.ddel;
24322 Ext.fly(el).removeClass([
24323 "x-tree-drag-insert-above",
24324 "x-tree-drag-insert-below",
24325 "x-tree-drag-append"]);
24326 this.lastInsertClass = "_noclass";
24328 },
24331 beforeDragDrop : function(target, e, id){
24332 this.cancelExpand();
24333 return true;
24334 },
24337 afterRepair : function(data){
24338 if(data && Ext.enableFx){
24339 data.node.ui.highlight();
24341 this.hideProxy();
24343 });
24347 if(Ext.dd.DragZone){
24348 Ext.tree.TreeDragZone = function(tree, config){
24349 Ext.tree.TreeDragZone.superclass.constructor.call(this, tree.getTreeEl(), config);
24351 this.tree = tree;
24352 };
24354 Ext.extend(Ext.tree.TreeDragZone, Ext.dd.DragZone, {
24356 ddGroup : "TreeDD",
24359 onBeforeDrag : function(data, e){
24360 var n = data.node;
24361 return n && n.draggable && !n.disabled;
24362 },
24365 onInitDrag : function(e){
24366 var data = this.dragData;
24367 this.tree.getSelectionModel().select(data.node);
24368 this.tree.eventModel.disable();
24369 this.proxy.update("");
24370 data.node.ui.appendDDGhost(this.proxy.ghost.dom);
24371 this.tree.fireEvent("startdrag", this.tree, data.node, e);
24372 },
24375 getRepairXY : function(e, data){
24376 return data.node.ui.getDDRepairXY();
24377 },
24380 onEndDrag : function(data, e){
24381 this.tree.eventModel.enable.defer(100, this.tree.eventModel);
24382 this.tree.fireEvent("enddrag", this.tree, data.node, e);
24383 },
24386 onValidDrop : function(dd, e, id){
24387 this.tree.fireEvent("dragdrop", this.tree, this.dragData.node, dd, e);
24388 this.hideProxy();
24389 },
24392 beforeInvalidDrop : function(e, id){
24394 var sm = this.tree.getSelectionModel();
24395 sm.clearSelections();
24396 sm.select(this.dragData.node);
24398 });
24401 Ext.tree.TreeEditor = function(tree, fc, config){
24402 fc = fc || {};
24403 var field = fc.events ? fc : new Ext.form.TextField(fc);
24404 Ext.tree.TreeEditor.superclass.constructor.call(this, field, config);
24406 this.tree = tree;
24408 if(!tree.rendered){
24409 tree.on('render', this.initEditor, this);
24410 }else{
24411 this.initEditor(tree);
24413 };
24415 Ext.extend(Ext.tree.TreeEditor, Ext.Editor, {
24417 alignment: "l-l",
24418 autoSize: false,
24420 hideEl : false,
24422 cls: "x-small-editor x-tree-editor",
24424 shim:false,
24425 shadow:"frame",
24427 maxWidth: 250,
24429 editDelay : 350,
24431 initEditor : function(tree){
24432 tree.on('beforeclick', this.beforeNodeClick, this);
24433 tree.on('dblclick', this.onNodeDblClick, this);
24434 this.on('complete', this.updateNode, this);
24435 this.on('beforestartedit', this.fitToTree, this);
24436 this.on('startedit', this.bindScroll, this, {delay:10});
24437 this.on('specialkey', this.onSpecialKey, this);
24438 },
24440 fitToTree : function(ed, el){
24441 var td = this.tree.getTreeEl().dom, nd = el.dom;
24442 if(td.scrollLeft > nd.offsetLeft){ td.scrollLeft = nd.offsetLeft;
24444 var w = Math.min(
24445 this.maxWidth,
24446 (td.clientWidth > 20 ? td.clientWidth : td.offsetWidth) - Math.max(0, nd.offsetLeft-td.scrollLeft) - 5);
24447 this.setSize(w, '');
24448 },
24450 triggerEdit : function(node, defer){
24451 this.completeEdit();
24452 if(node.attributes.editable !== false){
24453 this.editNode = node;
24454 this.autoEditTimer = this.startEdit.defer(this.editDelay, this, [node.ui.textNode, node.text]);
24455 return false;
24457 },
24459 bindScroll : function(){
24460 this.tree.getTreeEl().on('scroll', this.cancelEdit, this);
24461 },
24463 beforeNodeClick : function(node, e){
24464 clearTimeout(this.autoEditTimer);
24465 if(this.tree.getSelectionModel().isSelected(node)){
24466 e.stopEvent();
24467 return this.triggerEdit(node);
24469 },
24471 onNodeDblClick : function(node, e){
24472 clearTimeout(this.autoEditTimer);
24473 },
24475 updateNode : function(ed, value){
24476 this.tree.getTreeEl().un('scroll', this.cancelEdit, this);
24477 this.editNode.setText(value);
24478 },
24480 onHide : function(){
24481 Ext.tree.TreeEditor.superclass.onHide.call(this);
24482 if(this.editNode){
24483 this.editNode.ui.focus.defer(50, this.editNode.ui);
24485 },
24487 onSpecialKey : function(field, e){
24488 var k = e.getKey();
24489 if(k == e.ESC){
24490 e.stopEvent();
24491 this.cancelEdit();
24492 }else if(k == e.ENTER && !e.hasModifier()){
24493 e.stopEvent();
24494 this.completeEdit();
24497 });
24499 Ext.menu.Menu = function(config){
24500 if(Ext.isArray(config)){
24501 config = {items:config};
24503 Ext.apply(this, config);
24504 this.id = this.id || Ext.id();
24505 this.addEvents(
24507 'beforeshow',
24509 'beforehide',
24511 'show',
24513 'hide',
24515 'click',
24517 'mouseover',
24519 'mouseout',
24521 'itemclick'
24522 );
24523 Ext.menu.MenuMgr.register(this);
24524 Ext.menu.Menu.superclass.constructor.call(this);
24525 var mis = this.items;
24528 this.items = new Ext.util.MixedCollection();
24529 if(mis){
24530 this.add.apply(this, mis);
24532 };
24534 Ext.extend(Ext.menu.Menu, Ext.util.Observable, {
24538 minWidth : 120,
24540 shadow : "sides",
24542 subMenuAlign : "tl-tr?",
24544 defaultAlign : "tl-bl?",
24546 allowOtherMenus : false,
24548 hidden:true,
24550 createEl : function(){
24551 return new Ext.Layer({
24552 cls: "x-menu",
24553 shadow:this.shadow,
24554 constrain: false,
24555 parentEl: this.parentEl || document.body,
24556 zindex:15000
24557 });
24558 },
24560 render : function(){
24561 if(this.el){
24562 return;
24564 var el = this.el = this.createEl();
24566 if(!this.keyNav){
24567 this.keyNav = new Ext.menu.MenuNav(this);
24569 if(this.plain){
24570 el.addClass("x-menu-plain");
24572 if(this.cls){
24573 el.addClass(this.cls);
24575 this.focusEl = el.createChild({
24576 tag: "a", cls: "x-menu-focus", href: "#", onclick: "return false;", tabIndex:"-1"
24577 });
24578 var ul = el.createChild({tag: "ul", cls: "x-menu-list"});
24579 ul.on("click", this.onClick, this);
24580 ul.on("mouseover", this.onMouseOver, this);
24581 ul.on("mouseout", this.onMouseOut, this);
24582 this.items.each(function(item){
24583 var li = document.createElement("li");
24584 li.className = "x-menu-list-item";
24585 ul.dom.appendChild(li);
24586 item.render(li, this);
24587 }, this);
24588 this.ul = ul;
24589 this.autoWidth();
24590 },
24592 autoWidth : function(){
24593 var el = this.el, ul = this.ul;
24594 if(!el){
24595 return;
24597 var w = this.width;
24598 if(w){
24599 el.setWidth(w);
24600 }else if(Ext.isIE){
24601 el.setWidth(this.minWidth);
24602 var t = el.dom.offsetWidth; el.setWidth(ul.getWidth()+el.getFrameWidth("lr"));
24604 },
24606 delayAutoWidth : function(){
24607 if(this.el){
24608 if(!this.awTask){
24609 this.awTask = new Ext.util.DelayedTask(this.autoWidth, this);
24611 this.awTask.delay(20);
24613 },
24615 findTargetItem : function(e){
24616 var t = e.getTarget(".x-menu-list-item", this.ul, true);
24617 if(t && t.menuItemId){
24618 return this.items.get(t.menuItemId);
24620 },
24622 onClick : function(e){
24623 var t;
24624 if(t = this.findTargetItem(e)){
24625 t.onClick(e);
24626 this.fireEvent("click", this, t, e);
24628 },
24630 setActiveItem : function(item, autoExpand){
24631 if(item != this.activeItem){
24632 if(this.activeItem){
24633 this.activeItem.deactivate();
24635 this.activeItem = item;
24636 item.activate(autoExpand);
24637 }else if(autoExpand){
24638 item.expandMenu();
24640 },
24642 tryActivate : function(start, step){
24643 var items = this.items;
24644 for(var i = start, len = items.length; i >= 0 && i < len; i+= step){
24645 var item = items.get(i);
24646 if(!item.disabled && item.canActivate){
24647 this.setActiveItem(item, false);
24648 return item;
24651 return false;
24652 },
24654 onMouseOver : function(e){
24655 var t;
24656 if(t = this.findTargetItem(e)){
24657 if(t.canActivate && !t.disabled){
24658 this.setActiveItem(t, true);
24661 this.fireEvent("mouseover", this, e, t);
24662 },
24664 onMouseOut : function(e){
24665 var t;
24666 if(t = this.findTargetItem(e)){
24667 if(t == this.activeItem && t.shouldDeactivate(e)){
24668 this.activeItem.deactivate();
24669 delete this.activeItem;
24672 this.fireEvent("mouseout", this, e, t);
24673 },
24676 isVisible : function(){
24677 return this.el && !this.hidden;
24678 },
24681 show : function(el, pos, parentMenu){
24682 this.parentMenu = parentMenu;
24683 if(!this.el){
24684 this.render();
24686 this.fireEvent("beforeshow", this);
24687 this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign), parentMenu, false);
24688 },
24691 showAt : function(xy, parentMenu, _e){
24692 this.parentMenu = parentMenu;
24693 if(!this.el){
24694 this.render();
24696 if(_e !== false){
24697 this.fireEvent("beforeshow", this);
24698 xy = this.el.adjustForConstraints(xy);
24700 this.el.setXY(xy);
24701 this.el.show();
24702 this.hidden = false;
24703 this.focus();
24704 this.fireEvent("show", this);
24705 },
24709 focus : function(){
24710 if(!this.hidden){
24711 this.doFocus.defer(50, this);
24713 },
24715 doFocus : function(){
24716 if(!this.hidden){
24717 this.focusEl.focus();
24719 },
24722 hide : function(deep){
24723 if(this.el && this.isVisible()){
24724 this.fireEvent("beforehide", this);
24725 if(this.activeItem){
24726 this.activeItem.deactivate();
24727 this.activeItem = null;
24729 this.el.hide();
24730 this.hidden = true;
24731 this.fireEvent("hide", this);
24733 if(deep === true && this.parentMenu){
24734 this.parentMenu.hide(true);
24736 },
24739 add : function(){
24740 var a = arguments, l = a.length, item;
24741 for(var i = 0; i < l; i++){
24742 var el = a[i];
24743 if(el.render){ item = this.addItem(el);
24744 }else if(typeof el == "string"){ if(el == "separator" || el == "-"){
24745 item = this.addSeparator();
24746 }else{
24747 item = this.addText(el);
24749 }else if(el.tagName || el.el){ item = this.addElement(el);
24750 }else if(typeof el == "object"){ Ext.applyIf(el, this.defaults);
24751 item = this.addMenuItem(el);
24754 return item;
24755 },
24758 getEl : function(){
24759 if(!this.el){
24760 this.render();
24762 return this.el;
24763 },
24766 addSeparator : function(){
24767 return this.addItem(new Ext.menu.Separator());
24768 },
24771 addElement : function(el){
24772 return this.addItem(new Ext.menu.BaseItem(el));
24773 },
24776 addItem : function(item){
24777 this.items.add(item);
24778 if(this.ul){
24779 var li = document.createElement("li");
24780 li.className = "x-menu-list-item";
24781 this.ul.dom.appendChild(li);
24782 item.render(li, this);
24783 this.delayAutoWidth();
24785 return item;
24786 },
24789 addMenuItem : function(config){
24790 if(!(config instanceof Ext.menu.Item)){
24791 if(typeof config.checked == "boolean"){ config = new Ext.menu.CheckItem(config);
24792 }else{
24793 config = new Ext.menu.Item(config);
24796 return this.addItem(config);
24797 },
24800 addText : function(text){
24801 return this.addItem(new Ext.menu.TextItem(text));
24802 },
24805 insert : function(index, item){
24806 this.items.insert(index, item);
24807 if(this.ul){
24808 var li = document.createElement("li");
24809 li.className = "x-menu-list-item";
24810 this.ul.dom.insertBefore(li, this.ul.dom.childNodes[index]);
24811 item.render(li, this);
24812 this.delayAutoWidth();
24814 return item;
24815 },
24818 remove : function(item){
24819 this.items.removeKey(item.id);
24820 item.destroy();
24821 },
24824 removeAll : function(){
24825 if(this.items){
24826 var f;
24827 while(f = this.items.first()){
24828 this.remove(f);
24831 },
24834 destroy : function(){
24835 this.beforeDestroy();
24836 Ext.menu.MenuMgr.unregister(this);
24837 if (this.keyNav) {
24838 this.keyNav.disable();
24840 this.removeAll();
24841 if (this.ul) {
24842 this.ul.removeAllListeners();
24844 if (this.el) {
24845 this.el.destroy();
24847 },
24849 beforeDestroy : Ext.emptyFn
24851 });
24853 Ext.menu.MenuNav = function(menu){
24854 Ext.menu.MenuNav.superclass.constructor.call(this, menu.el);
24855 this.scope = this.menu = menu;
24856 };
24858 Ext.extend(Ext.menu.MenuNav, Ext.KeyNav, {
24859 doRelay : function(e, h){
24860 var k = e.getKey();
24861 if(!this.menu.activeItem && e.isNavKeyPress() && k != e.SPACE && k != e.RETURN){
24862 this.menu.tryActivate(0, 1);
24863 return false;
24865 return h.call(this.scope || this, e, this.menu);
24866 },
24868 up : function(e, m){
24869 if(!m.tryActivate(m.items.indexOf(m.activeItem)-1, -1)){
24870 m.tryActivate(m.items.length-1, -1);
24872 },
24874 down : function(e, m){
24875 if(!m.tryActivate(m.items.indexOf(m.activeItem)+1, 1)){
24876 m.tryActivate(0, 1);
24878 },
24880 right : function(e, m){
24881 if(m.activeItem){
24882 m.activeItem.expandMenu(true);
24884 },
24886 left : function(e, m){
24887 m.hide();
24888 if(m.parentMenu && m.parentMenu.activeItem){
24889 m.parentMenu.activeItem.activate();
24891 },
24893 enter : function(e, m){
24894 if(m.activeItem){
24895 e.stopPropagation();
24896 m.activeItem.onClick(e);
24897 m.fireEvent("click", this, m.activeItem);
24898 return true;
24901 });
24903 Ext.menu.MenuMgr = function(){
24904 var menus, active, groups = {}, attached = false, lastShow = new Date();
24906 function init(){
24907 menus = {};
24908 active = new Ext.util.MixedCollection();
24909 Ext.getDoc().addKeyListener(27, function(){
24910 if(active.length > 0){
24911 hideAll();
24913 });
24916 function hideAll(){
24917 if(active && active.length > 0){
24918 var c = active.clone();
24919 c.each(function(m){
24920 m.hide();
24921 });
24925 function onHide(m){
24926 active.remove(m);
24927 if(active.length < 1){
24928 Ext.getDoc().un("mousedown", onMouseDown);
24929 attached = false;
24933 function onShow(m){
24934 var last = active.last();
24935 lastShow = new Date();
24936 active.add(m);
24937 if(!attached){
24938 Ext.getDoc().on("mousedown", onMouseDown);
24939 attached = true;
24941 if(m.parentMenu){
24942 m.getEl().setZIndex(parseInt(m.parentMenu.getEl().getStyle("z-index"), 10) + 3);
24943 m.parentMenu.activeChild = m;
24944 }else if(last && last.isVisible()){
24945 m.getEl().setZIndex(parseInt(last.getEl().getStyle("z-index"), 10) + 3);
24949 function onBeforeHide(m){
24950 if(m.activeChild){
24951 m.activeChild.hide();
24953 if(m.autoHideTimer){
24954 clearTimeout(m.autoHideTimer);
24955 delete m.autoHideTimer;
24959 function onBeforeShow(m){
24960 var pm = m.parentMenu;
24961 if(!pm && !m.allowOtherMenus){
24962 hideAll();
24963 }else if(pm && pm.activeChild){
24964 pm.activeChild.hide();
24968 function onMouseDown(e){
24969 if(lastShow.getElapsed() > 50 && active.length > 0 && !e.getTarget(".x-menu")){
24970 hideAll();
24974 function onBeforeCheck(mi, state){
24975 if(state){
24976 var g = groups[mi.group];
24977 for(var i = 0, l = g.length; i < l; i++){
24978 if(g[i] != mi){
24979 g[i].setChecked(false);
24985 return {
24988 hideAll : function(){
24989 hideAll();
24990 },
24992 register : function(menu){
24993 if(!menus){
24994 init();
24996 menus[menu.id] = menu;
24997 menu.on("beforehide", onBeforeHide);
24998 menu.on("hide", onHide);
24999 menu.on("beforeshow", onBeforeShow);
25000 menu.on("show", onShow);
25001 var g = menu.group;
25002 if(g && menu.events["checkchange"]){
25003 if(!groups[g]){
25004 groups[g] = [];
25006 groups[g].push(menu);
25007 menu.on("checkchange", onCheck);
25009 },
25012 get : function(menu){
25013 if(typeof menu == "string"){ if(!menus){ return null;
25015 return menus[menu];
25016 }else if(menu.events){ return menu;
25017 }else if(typeof menu.length == 'number'){ return new Ext.menu.Menu({items:menu});
25018 }else{ return new Ext.menu.Menu(menu);
25020 },
25022 unregister : function(menu){
25023 delete menus[menu.id];
25024 menu.un("beforehide", onBeforeHide);
25025 menu.un("hide", onHide);
25026 menu.un("beforeshow", onBeforeShow);
25027 menu.un("show", onShow);
25028 var g = menu.group;
25029 if(g && menu.events["checkchange"]){
25030 groups[g].remove(menu);
25031 menu.un("checkchange", onCheck);
25033 },
25035 registerCheckable : function(menuItem){
25036 var g = menuItem.group;
25037 if(g){
25038 if(!groups[g]){
25039 groups[g] = [];
25041 groups[g].push(menuItem);
25042 menuItem.on("beforecheckchange", onBeforeCheck);
25044 },
25046 unregisterCheckable : function(menuItem){
25047 var g = menuItem.group;
25048 if(g){
25049 groups[g].remove(menuItem);
25050 menuItem.un("beforecheckchange", onBeforeCheck);
25052 },
25054 getCheckedItem : function(groupId){
25055 var g = groups[groupId];
25056 if(g){
25057 for(var i = 0, l = g.length; i < l; i++){
25058 if(g[i].checked){
25059 return g[i];
25063 return null;
25064 },
25066 setCheckedItem : function(groupId, itemId){
25067 var g = groups[groupId];
25068 if(g){
25069 for(var i = 0, l = g.length; i < l; i++){
25070 if(g[i].id == itemId){
25071 g[i].setChecked(true);
25075 return null;
25077 };
25078 }();
25081 Ext.menu.BaseItem = function(config){
25082 Ext.menu.BaseItem.superclass.constructor.call(this, config);
25084 this.addEvents(
25086 'click',
25088 'activate',
25090 'deactivate'
25091 );
25093 if(this.handler){
25094 this.on("click", this.handler, this.scope);
25096 };
25098 Ext.extend(Ext.menu.BaseItem, Ext.Component, {
25102 canActivate : false,
25104 activeClass : "x-menu-item-active",
25106 hideOnClick : true,
25108 hideDelay : 100,
25110 ctype: "Ext.menu.BaseItem",
25112 actionMode : "container",
25114 render : function(container, parentMenu){
25115 this.parentMenu = parentMenu;
25116 Ext.menu.BaseItem.superclass.render.call(this, container);
25117 this.container.menuItemId = this.id;
25118 },
25120 onRender : function(container, position){
25121 this.el = Ext.get(this.el);
25122 container.dom.appendChild(this.el.dom);
25123 },
25126 setHandler : function(handler, scope){
25127 if(this.handler){
25128 this.un("click", this.handler, this.scope);
25130 this.on("click", this.handler = handler, this.scope = scope);
25131 },
25133 onClick : function(e){
25134 if(!this.disabled && this.fireEvent("click", this, e) !== false
25135 && this.parentMenu.fireEvent("itemclick", this, e) !== false){
25136 this.handleClick(e);
25137 }else{
25138 e.stopEvent();
25140 },
25142 activate : function(){
25143 if(this.disabled){
25144 return false;
25146 var li = this.container;
25147 li.addClass(this.activeClass);
25148 this.region = li.getRegion().adjust(2, 2, -2, -2);
25149 this.fireEvent("activate", this);
25150 return true;
25151 },
25153 deactivate : function(){
25154 this.container.removeClass(this.activeClass);
25155 this.fireEvent("deactivate", this);
25156 },
25158 shouldDeactivate : function(e){
25159 return !this.region || !this.region.contains(e.getPoint());
25160 },
25162 handleClick : function(e){
25163 if(this.hideOnClick){
25164 this.parentMenu.hide.defer(this.hideDelay, this.parentMenu, [true]);
25166 },
25168 expandMenu : function(autoActivate){
25169 },
25171 hideMenu : function(){
25173 });
25175 Ext.menu.TextItem = function(text){
25176 this.text = text;
25177 Ext.menu.TextItem.superclass.constructor.call(this);
25178 };
25180 Ext.extend(Ext.menu.TextItem, Ext.menu.BaseItem, {
25183 hideOnClick : false,
25185 itemCls : "x-menu-text",
25187 onRender : function(){
25188 var s = document.createElement("span");
25189 s.className = this.itemCls;
25190 s.innerHTML = this.text;
25191 this.el = s;
25192 Ext.menu.TextItem.superclass.onRender.apply(this, arguments);
25194 });
25196 Ext.menu.Separator = function(config){
25197 Ext.menu.Separator.superclass.constructor.call(this, config);
25198 };
25200 Ext.extend(Ext.menu.Separator, Ext.menu.BaseItem, {
25202 itemCls : "x-menu-sep",
25204 hideOnClick : false,
25206 onRender : function(li){
25207 var s = document.createElement("span");
25208 s.className = this.itemCls;
25209 s.innerHTML = "&#160;";
25210 this.el = s;
25211 li.addClass("x-menu-sep-li");
25212 Ext.menu.Separator.superclass.onRender.apply(this, arguments);
25214 });
25216 Ext.menu.Item = function(config){
25217 Ext.menu.Item.superclass.constructor.call(this, config);
25218 if(this.menu){
25219 this.menu = Ext.menu.MenuMgr.get(this.menu);
25221 };
25222 Ext.extend(Ext.menu.Item, Ext.menu.BaseItem, {
25230 itemCls : "x-menu-item",
25232 canActivate : true,
25234 showDelay: 200,
25235 hideDelay: 200,
25237 ctype: "Ext.menu.Item",
25239 onRender : function(container, position){
25240 var el = document.createElement("a");
25241 el.hideFocus = true;
25242 el.unselectable = "on";
25243 el.href = this.href || "#";
25244 if(this.hrefTarget){
25245 el.target = this.hrefTarget;
25247 el.className = this.itemCls + (this.menu ? " x-menu-item-arrow" : "") + (this.cls ? " " + this.cls : "");
25248 el.innerHTML = String.format(
25249 '<img src="{0}" class="x-menu-item-icon {2}" />{1}',
25250 this.icon || Ext.BLANK_IMAGE_URL, this.itemText||this.text, this.iconCls || '');
25251 this.el = el;
25252 Ext.menu.Item.superclass.onRender.call(this, container, position);
25253 },
25256 setText : function(text){
25257 this.text = text;
25258 if(this.rendered){
25259 this.el.update(String.format(
25260 '<img src="{0}" class="x-menu-item-icon {2}">{1}',
25261 this.icon || Ext.BLANK_IMAGE_URL, this.text, this.iconCls || ''));
25262 this.parentMenu.autoWidth();
25264 },
25267 setIconClass : function(cls){
25268 var oldCls = this.iconCls;
25269 this.iconCls = cls;
25270 if(this.rendered){
25271 this.el.child('img.x-menu-item-icon').replaceClass(oldCls, this.iconCls);
25273 },
25275 handleClick : function(e){
25276 if(!this.href){ e.stopEvent();
25278 Ext.menu.Item.superclass.handleClick.apply(this, arguments);
25279 },
25281 activate : function(autoExpand){
25282 if(Ext.menu.Item.superclass.activate.apply(this, arguments)){
25283 this.focus();
25284 if(autoExpand){
25285 this.expandMenu();
25288 return true;
25289 },
25291 shouldDeactivate : function(e){
25292 if(Ext.menu.Item.superclass.shouldDeactivate.call(this, e)){
25293 if(this.menu && this.menu.isVisible()){
25294 return !this.menu.getEl().getRegion().contains(e.getPoint());
25296 return true;
25298 return false;
25299 },
25301 deactivate : function(){
25302 Ext.menu.Item.superclass.deactivate.apply(this, arguments);
25303 this.hideMenu();
25304 },
25306 expandMenu : function(autoActivate){
25307 if(!this.disabled && this.menu){
25308 clearTimeout(this.hideTimer);
25309 delete this.hideTimer;
25310 if(!this.menu.isVisible() && !this.showTimer){
25311 this.showTimer = this.deferExpand.defer(this.showDelay, this, [autoActivate]);
25312 }else if (this.menu.isVisible() && autoActivate){
25313 this.menu.tryActivate(0, 1);
25316 },
25318 deferExpand : function(autoActivate){
25319 delete this.showTimer;
25320 this.menu.show(this.container, this.parentMenu.subMenuAlign || "tl-tr?", this.parentMenu);
25321 if(autoActivate){
25322 this.menu.tryActivate(0, 1);
25324 },
25326 hideMenu : function(){
25327 clearTimeout(this.showTimer);
25328 delete this.showTimer;
25329 if(!this.hideTimer && this.menu && this.menu.isVisible()){
25330 this.hideTimer = this.deferHide.defer(this.hideDelay, this);
25332 },
25334 deferHide : function(){
25335 delete this.hideTimer;
25336 this.menu.hide();
25338 });
25340 Ext.menu.CheckItem = function(config){
25341 Ext.menu.CheckItem.superclass.constructor.call(this, config);
25342 this.addEvents(
25344 "beforecheckchange" ,
25346 "checkchange"
25347 );
25349 if(this.checkHandler){
25350 this.on('checkchange', this.checkHandler, this.scope);
25352 Ext.menu.MenuMgr.registerCheckable(this);
25353 };
25354 Ext.extend(Ext.menu.CheckItem, Ext.menu.Item, {
25357 itemCls : "x-menu-item x-menu-check-item",
25359 groupClass : "x-menu-group-item",
25362 checked: false,
25364 ctype: "Ext.menu.CheckItem",
25366 onRender : function(c){
25367 Ext.menu.CheckItem.superclass.onRender.apply(this, arguments);
25368 if(this.group){
25369 this.el.addClass(this.groupClass);
25371 if(this.checked){
25372 this.checked = false;
25373 this.setChecked(true, true);
25375 },
25377 destroy : function(){
25378 Ext.menu.MenuMgr.unregisterCheckable(this);
25379 Ext.menu.CheckItem.superclass.destroy.apply(this, arguments);
25380 },
25383 setChecked : function(state, suppressEvent){
25384 if(this.checked != state && this.fireEvent("beforecheckchange", this, state) !== false){
25385 if(this.container){
25386 this.container[state ? "addClass" : "removeClass"]("x-menu-item-checked");
25388 this.checked = state;
25389 if(suppressEvent !== true){
25390 this.fireEvent("checkchange", this, state);
25393 },
25395 handleClick : function(e){
25396 if(!this.disabled && !(this.checked && this.group)){ this.setChecked(!this.checked);
25398 Ext.menu.CheckItem.superclass.handleClick.apply(this, arguments);
25400 });
25402 Ext.menu.Adapter = function(component, config){
25403 Ext.menu.Adapter.superclass.constructor.call(this, config);
25404 this.component = component;
25405 };
25406 Ext.extend(Ext.menu.Adapter, Ext.menu.BaseItem, {
25407 canActivate : true,
25409 onRender : function(container, position){
25410 this.component.render(container);
25411 this.el = this.component.getEl();
25412 },
25414 activate : function(){
25415 if(this.disabled){
25416 return false;
25418 this.component.focus();
25419 this.fireEvent("activate", this);
25420 return true;
25421 },
25423 deactivate : function(){
25424 this.fireEvent("deactivate", this);
25425 },
25427 disable : function(){
25428 this.component.disable();
25429 Ext.menu.Adapter.superclass.disable.call(this);
25430 },
25432 enable : function(){
25433 this.component.enable();
25434 Ext.menu.Adapter.superclass.enable.call(this);
25436 });
25438 Ext.menu.DateItem = function(config){
25439 Ext.menu.DateItem.superclass.constructor.call(this, new Ext.DatePicker(config), config);
25441 this.picker = this.component;
25442 this.addEvents('select');
25444 this.picker.on("render", function(picker){
25445 picker.getEl().swallowEvent("click");
25446 picker.container.addClass("x-menu-date-item");
25447 });
25449 this.picker.on("select", this.onSelect, this);
25450 };
25452 Ext.extend(Ext.menu.DateItem, Ext.menu.Adapter, {
25453 onSelect : function(picker, date){
25454 this.fireEvent("select", this, date, picker);
25455 Ext.menu.DateItem.superclass.handleClick.call(this);
25457 });
25459 Ext.menu.ColorItem = function(config){
25460 Ext.menu.ColorItem.superclass.constructor.call(this, new Ext.ColorPalette(config), config);
25462 this.palette = this.component;
25463 this.relayEvents(this.palette, ["select"]);
25464 if(this.selectHandler){
25465 this.on('select', this.selectHandler, this.scope);
25467 };
25468 Ext.extend(Ext.menu.ColorItem, Ext.menu.Adapter);
25470 Ext.menu.DateMenu = function(config){
25471 Ext.menu.DateMenu.superclass.constructor.call(this, config);
25472 this.plain = true;
25473 var di = new Ext.menu.DateItem(config);
25474 this.add(di);
25476 this.picker = di.picker;
25478 this.relayEvents(di, ["select"]);
25480 this.on('beforeshow', function(){
25481 if(this.picker){
25482 this.picker.hideMonthPicker(true);
25484 }, this);
25485 };
25486 Ext.extend(Ext.menu.DateMenu, Ext.menu.Menu, {
25487 cls:'x-date-menu',
25489 beforeDestroy : function() {
25490 this.picker.destroy();
25492 });
25494 Ext.menu.ColorMenu = function(config){
25495 Ext.menu.ColorMenu.superclass.constructor.call(this, config);
25496 this.plain = true;
25497 var ci = new Ext.menu.ColorItem(config);
25498 this.add(ci);
25500 this.palette = ci.palette;
25502 this.relayEvents(ci, ["select"]);
25503 };
25504 Ext.extend(Ext.menu.ColorMenu, Ext.menu.Menu);
25506 Ext.form.Field = Ext.extend(Ext.BoxComponent, {
25520 invalidClass : "x-form-invalid",
25522 invalidText : "The value in this field is invalid",
25524 focusClass : "x-form-focus",
25526 validationEvent : "keyup",
25528 validateOnBlur : true,
25530 validationDelay : 250,
25532 defaultAutoCreate : {tag: "input", type: "text", size: "20", autocomplete: "off"},
25534 fieldClass : "x-form-field",
25536 msgTarget : 'qtip',
25538 msgFx : 'normal',
25540 readOnly : false,
25542 disabled : false,
25544 isFormField : true,
25546 hasFocus : false,
25548 initComponent : function(){
25549 Ext.form.Field.superclass.initComponent.call(this);
25550 this.addEvents(
25552 'focus',
25554 'blur',
25556 'specialkey',
25558 'change',
25560 'invalid',
25562 'valid'
25563 );
25564 },
25567 getName: function(){
25568 return this.rendered && this.el.dom.name ? this.el.dom.name : (this.hiddenName || '');
25569 },
25571 onRender : function(ct, position){
25572 Ext.form.Field.superclass.onRender.call(this, ct, position);
25573 if(!this.el){
25574 var cfg = this.getAutoCreate();
25575 if(!cfg.name){
25576 cfg.name = this.name || this.id;
25578 if(this.inputType){
25579 cfg.type = this.inputType;
25581 this.el = ct.createChild(cfg, position);
25583 var type = this.el.dom.type;
25584 if(type){
25585 if(type == 'password'){
25586 type = 'text';
25588 this.el.addClass('x-form-'+type);
25590 if(this.readOnly){
25591 this.el.dom.readOnly = true;
25593 if(this.tabIndex !== undefined){
25594 this.el.dom.setAttribute('tabIndex', this.tabIndex);
25597 this.el.addClass([this.fieldClass, this.cls]);
25598 this.initValue();
25599 },
25601 initValue : function(){
25602 if(this.value !== undefined){
25603 this.setValue(this.value);
25604 }else if(this.el.dom.value.length > 0){
25605 this.setValue(this.el.dom.value);
25607 },
25610 isDirty : function() {
25611 if(this.disabled) {
25612 return false;
25614 return String(this.getValue()) !== String(this.originalValue);
25615 },
25617 afterRender : function(){
25618 Ext.form.Field.superclass.afterRender.call(this);
25619 this.initEvents();
25620 },
25622 fireKey : function(e){
25623 if(e.isSpecialKey()){
25624 this.fireEvent("specialkey", this, e);
25626 },
25629 reset : function(){
25630 this.setValue(this.originalValue);
25631 this.clearInvalid();
25632 },
25634 initEvents : function(){
25635 this.el.on(Ext.isIE || Ext.isSafari3 ? "keydown" : "keypress", this.fireKey, this);
25636 this.el.on("focus", this.onFocus, this);
25637 this.el.on("blur", this.onBlur, this);
25639 this.originalValue = this.getValue();
25640 },
25642 onFocus : function(){
25643 if(!Ext.isOpera && this.focusClass){ this.el.addClass(this.focusClass);
25645 if(!this.hasFocus){
25646 this.hasFocus = true;
25647 this.startValue = this.getValue();
25648 this.fireEvent("focus", this);
25650 },
25652 beforeBlur : Ext.emptyFn,
25654 onBlur : function(){
25655 this.beforeBlur();
25656 if(!Ext.isOpera && this.focusClass){ this.el.removeClass(this.focusClass);
25658 this.hasFocus = false;
25659 if(this.validationEvent !== false && this.validateOnBlur && this.validationEvent != "blur"){
25660 this.validate();
25662 var v = this.getValue();
25663 if(String(v) !== String(this.startValue)){
25664 this.fireEvent('change', this, v, this.startValue);
25666 this.fireEvent("blur", this);
25667 },
25670 isValid : function(preventMark){
25671 if(this.disabled){
25672 return true;
25674 var restore = this.preventMark;
25675 this.preventMark = preventMark === true;
25676 var v = this.validateValue(this.processValue(this.getRawValue()));
25677 this.preventMark = restore;
25678 return v;
25679 },
25682 validate : function(){
25683 if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
25684 this.clearInvalid();
25685 return true;
25687 return false;
25688 },
25690 processValue : function(value){
25691 return value;
25692 },
25694 validateValue : function(value){
25695 return true;
25696 },
25699 markInvalid : function(msg){
25700 if(!this.rendered || this.preventMark){ return;
25702 this.el.addClass(this.invalidClass);
25703 msg = msg || this.invalidText;
25704 switch(this.msgTarget){
25705 case 'qtip':
25706 this.el.dom.qtip = msg;
25707 this.el.dom.qclass = 'x-form-invalid-tip';
25708 if(Ext.QuickTips){ Ext.QuickTips.enable();
25710 break;
25711 case 'title':
25712 this.el.dom.title = msg;
25713 break;
25714 case 'under':
25715 if(!this.errorEl){
25716 var elp = this.getErrorCt();
25717 this.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
25718 this.errorEl.setWidth(elp.getWidth(true)-20);
25720 this.errorEl.update(msg);
25721 Ext.form.Field.msgFx[this.msgFx].show(this.errorEl, this);
25722 break;
25723 case 'side':
25724 if(!this.errorIcon){
25725 var elp = this.getErrorCt();
25726 this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
25728 this.alignErrorIcon();
25729 this.errorIcon.dom.qtip = msg;
25730 this.errorIcon.dom.qclass = 'x-form-invalid-tip';
25731 this.errorIcon.show();
25732 this.on('resize', this.alignErrorIcon, this);
25733 break;
25734 default:
25735 var t = Ext.getDom(this.msgTarget);
25736 t.innerHTML = msg;
25737 t.style.display = this.msgDisplay;
25738 break;
25740 this.fireEvent('invalid', this, msg);
25741 },
25743 getErrorCt : function(){
25744 return this.el.findParent('.x-form-element', 5, true) || this.el.findParent('.x-form-field-wrap', 5, true); },
25746 alignErrorIcon : function(){
25747 this.errorIcon.alignTo(this.el, 'tl-tr', [2, 0]);
25748 },
25751 clearInvalid : function(){
25752 if(!this.rendered || this.preventMark){ return;
25754 this.el.removeClass(this.invalidClass);
25755 switch(this.msgTarget){
25756 case 'qtip':
25757 this.el.dom.qtip = '';
25758 break;
25759 case 'title':
25760 this.el.dom.title = '';
25761 break;
25762 case 'under':
25763 if(this.errorEl){
25764 Ext.form.Field.msgFx[this.msgFx].hide(this.errorEl, this);
25766 break;
25767 case 'side':
25768 if(this.errorIcon){
25769 this.errorIcon.dom.qtip = '';
25770 this.errorIcon.hide();
25771 this.un('resize', this.alignErrorIcon, this);
25773 break;
25774 default:
25775 var t = Ext.getDom(this.msgTarget);
25776 t.innerHTML = '';
25777 t.style.display = 'none';
25778 break;
25780 this.fireEvent('valid', this);
25781 },
25784 getRawValue : function(){
25785 var v = this.rendered ? this.el.getValue() : Ext.value(this.value, '');
25786 if(v === this.emptyText){
25787 v = '';
25789 return v;
25790 },
25793 getValue : function(){
25794 if(!this.rendered) {
25795 return this.value;
25797 var v = this.el.getValue();
25798 if(v === this.emptyText || v === undefined){
25799 v = '';
25801 return v;
25802 },
25805 setRawValue : function(v){
25806 return this.el.dom.value = (v === null || v === undefined ? '' : v);
25807 },
25810 setValue : function(v){
25811 this.value = v;
25812 if(this.rendered){
25813 this.el.dom.value = (v === null || v === undefined ? '' : v);
25814 this.validate();
25816 },
25818 adjustSize : function(w, h){
25819 var s = Ext.form.Field.superclass.adjustSize.call(this, w, h);
25820 s.width = this.adjustWidth(this.el.dom.tagName, s.width);
25821 return s;
25822 },
25824 adjustWidth : function(tag, w){
25825 tag = tag.toLowerCase();
25826 if(typeof w == 'number' && !Ext.isSafari){
25827 if(Ext.isIE && (tag == 'input' || tag == 'textarea')){
25828 if(tag == 'input' && !Ext.isStrict){
25829 return this.inEditor ? w : w - 3;
25831 if(tag == 'input' && Ext.isStrict){
25832 return w - (Ext.isIE6 ? 4 : 1);
25834 if(tag == 'textarea' && Ext.isStrict){
25835 return w-2;
25837 }else if(Ext.isOpera && Ext.isStrict){
25838 if(tag == 'input'){
25839 return w + 2;
25841 if(tag == 'textarea'){
25842 return w-2;
25846 return w;
25853 });
25856 Ext.form.Field.msgFx = {
25857 normal : {
25858 show: function(msgEl, f){
25859 msgEl.setDisplayed('block');
25860 },
25862 hide : function(msgEl, f){
25863 msgEl.setDisplayed(false).update('');
25865 },
25867 slide : {
25868 show: function(msgEl, f){
25869 msgEl.slideIn('t', {stopFx:true});
25870 },
25872 hide : function(msgEl, f){
25873 msgEl.slideOut('t', {stopFx:true,useDisplay:true});
25875 },
25877 slideRight : {
25878 show: function(msgEl, f){
25879 msgEl.fixDisplay();
25880 msgEl.alignTo(f.el, 'tl-tr');
25881 msgEl.slideIn('l', {stopFx:true});
25882 },
25884 hide : function(msgEl, f){
25885 msgEl.slideOut('l', {stopFx:true,useDisplay:true});
25888 };
25889 Ext.reg('field', Ext.form.Field);
25892 Ext.form.TextField = Ext.extend(Ext.form.Field, {
25895 grow : false,
25897 growMin : 30,
25899 growMax : 800,
25901 vtype : null,
25903 maskRe : null,
25905 disableKeyFilter : false,
25907 allowBlank : true,
25909 minLength : 0,
25911 maxLength : Number.MAX_VALUE,
25913 minLengthText : "The minimum length for this field is {0}",
25915 maxLengthText : "The maximum length for this field is {0}",
25917 selectOnFocus : false,
25919 blankText : "This field is required",
25921 validator : null,
25923 regex : null,
25925 regexText : "",
25927 emptyText : null,
25929 emptyClass : 'x-form-empty-field',
25933 initComponent : function(){
25934 Ext.form.TextField.superclass.initComponent.call(this);
25935 this.addEvents(
25937 'autosize',
25940 'keydown',
25942 'keyup',
25944 'keypress'
25945 );
25946 },
25948 initEvents : function(){
25949 Ext.form.TextField.superclass.initEvents.call(this);
25950 if(this.validationEvent == 'keyup'){
25951 this.validationTask = new Ext.util.DelayedTask(this.validate, this);
25952 this.el.on('keyup', this.filterValidation, this);
25954 else if(this.validationEvent !== false){
25955 this.el.on(this.validationEvent, this.validate, this, {buffer: this.validationDelay});
25957 if(this.selectOnFocus || this.emptyText){
25958 this.on("focus", this.preFocus, this);
25959 if(this.emptyText){
25960 this.on('blur', this.postBlur, this);
25961 this.applyEmptyText();
25964 if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Ext.form.VTypes[this.vtype+'Mask']))){
25965 this.el.on("keypress", this.filterKeys, this);
25967 if(this.grow){
25968 this.el.on("keyup", this.onKeyUpBuffered, this, {buffer:50});
25969 this.el.on("click", this.autoSize, this);
25972 if(this.enableKeyEvents){
25973 this.el.on("keyup", this.onKeyUp, this);
25974 this.el.on("keydown", this.onKeyDown, this);
25975 this.el.on("keypress", this.onKeyPress, this);
25977 },
25979 processValue : function(value){
25980 if(this.stripCharsRe){
25981 var newValue = value.replace(this.stripCharsRe, '');
25982 if(newValue !== value){
25983 this.setRawValue(newValue);
25984 return newValue;
25987 return value;
25988 },
25990 filterValidation : function(e){
25991 if(!e.isNavKeyPress()){
25992 this.validationTask.delay(this.validationDelay);
25994 },
25996 onKeyUpBuffered : function(e){
25997 if(!e.isNavKeyPress()){
25998 this.autoSize();
26000 },
26002 onKeyUp : function(e){
26003 this.fireEvent('keyup', this, e);
26004 },
26006 onKeyDown : function(e){
26007 this.fireEvent('keydown', this, e);
26008 },
26010 onKeyPress : function(e){
26011 this.fireEvent('keypress', this, e);
26012 },
26015 reset : function(){
26016 Ext.form.TextField.superclass.reset.call(this);
26017 this.applyEmptyText();
26018 },
26020 applyEmptyText : function(){
26021 if(this.rendered && this.emptyText && this.getRawValue().length < 1){
26022 this.setRawValue(this.emptyText);
26023 this.el.addClass(this.emptyClass);
26025 },
26027 preFocus : function(){
26028 if(this.emptyText){
26029 if(this.el.dom.value == this.emptyText){
26030 this.setRawValue('');
26032 this.el.removeClass(this.emptyClass);
26034 if(this.selectOnFocus){
26035 this.el.dom.select();
26037 },
26039 postBlur : function(){
26040 this.applyEmptyText();
26041 },
26043 filterKeys : function(e){
26044 var k = e.getKey();
26045 if(!Ext.isIE && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
26046 return;
26048 var c = e.getCharCode(), cc = String.fromCharCode(c);
26049 if(Ext.isIE && (e.isSpecialKey() || !cc)){
26050 return;
26052 if(!this.maskRe.test(cc)){
26053 e.stopEvent();
26055 },
26057 setValue : function(v){
26058 if(this.emptyText && this.el && v !== undefined && v !== null && v !== ''){
26059 this.el.removeClass(this.emptyClass);
26061 Ext.form.TextField.superclass.setValue.apply(this, arguments);
26062 this.applyEmptyText();
26063 this.autoSize();
26064 },
26067 validateValue : function(value){
26068 if(value.length < 1 || value === this.emptyText){ if(this.allowBlank){
26069 this.clearInvalid();
26070 return true;
26071 }else{
26072 this.markInvalid(this.blankText);
26073 return false;
26076 if(value.length < this.minLength){
26077 this.markInvalid(String.format(this.minLengthText, this.minLength));
26078 return false;
26080 if(value.length > this.maxLength){
26081 this.markInvalid(String.format(this.maxLengthText, this.maxLength));
26082 return false;
26084 if(this.vtype){
26085 var vt = Ext.form.VTypes;
26086 if(!vt[this.vtype](value, this)){
26087 this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
26088 return false;
26091 if(typeof this.validator == "function"){
26092 var msg = this.validator(value);
26093 if(msg !== true){
26094 this.markInvalid(msg);
26095 return false;
26098 if(this.regex && !this.regex.test(value)){
26099 this.markInvalid(this.regexText);
26100 return false;
26102 return true;
26103 },
26106 selectText : function(start, end){
26107 var v = this.getRawValue();
26108 if(v.length > 0){
26109 start = start === undefined ? 0 : start;
26110 end = end === undefined ? v.length : end;
26111 var d = this.el.dom;
26112 if(d.setSelectionRange){
26113 d.setSelectionRange(start, end);
26114 }else if(d.createTextRange){
26115 var range = d.createTextRange();
26116 range.moveStart("character", start);
26117 range.moveEnd("character", end-v.length);
26118 range.select();
26121 },
26124 autoSize : function(){
26125 if(!this.grow || !this.rendered){
26126 return;
26128 if(!this.metrics){
26129 this.metrics = Ext.util.TextMetrics.createInstance(this.el);
26131 var el = this.el;
26132 var v = el.dom.value;
26133 var d = document.createElement('div');
26134 d.appendChild(document.createTextNode(v));
26135 v = d.innerHTML;
26136 d = null;
26137 v += "&#160;";
26138 var w = Math.min(this.growMax, Math.max(this.metrics.getWidth(v) + 10, this.growMin));
26139 this.el.setWidth(w);
26140 this.fireEvent("autosize", this, w);
26142 });
26143 Ext.reg('textfield', Ext.form.TextField);
26146 Ext.form.TriggerField = Ext.extend(Ext.form.TextField, {
26149 defaultAutoCreate : {tag: "input", type: "text", size: "16", autocomplete: "off"},
26151 hideTrigger:false,
26154 autoSize: Ext.emptyFn,
26155 monitorTab : true,
26156 deferHeight : true,
26157 mimicing : false,
26159 onResize : function(w, h){
26160 Ext.form.TriggerField.superclass.onResize.call(this, w, h);
26161 if(typeof w == 'number'){
26162 this.el.setWidth(this.adjustWidth('input', w - this.trigger.getWidth()));
26164 this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
26165 },
26167 adjustSize : Ext.BoxComponent.prototype.adjustSize,
26169 getResizeEl : function(){
26170 return this.wrap;
26171 },
26173 getPositionEl : function(){
26174 return this.wrap;
26175 },
26177 alignErrorIcon : function(){
26178 this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
26179 },
26181 onRender : function(ct, position){
26182 Ext.form.TriggerField.superclass.onRender.call(this, ct, position);
26183 this.wrap = this.el.wrap({cls: "x-form-field-wrap"});
26184 this.trigger = this.wrap.createChild(this.triggerConfig ||
26185 {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.triggerClass});
26186 if(this.hideTrigger){
26187 this.trigger.setDisplayed(false);
26189 this.initTrigger();
26190 if(!this.width){
26191 this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
26193 },
26195 initTrigger : function(){
26196 this.trigger.on("click", this.onTriggerClick, this, {preventDefault:true});
26197 this.trigger.addClassOnOver('x-form-trigger-over');
26198 this.trigger.addClassOnClick('x-form-trigger-click');
26199 },
26201 onDestroy : function(){
26202 if(this.trigger){
26203 this.trigger.removeAllListeners();
26204 this.trigger.remove();
26206 if(this.wrap){
26207 this.wrap.remove();
26209 Ext.form.TriggerField.superclass.onDestroy.call(this);
26210 },
26212 onFocus : function(){
26213 Ext.form.TriggerField.superclass.onFocus.call(this);
26214 if(!this.mimicing){
26215 this.wrap.addClass('x-trigger-wrap-focus');
26216 this.mimicing = true;
26217 Ext.get(Ext.isIE ? document.body : document).on("mousedown", this.mimicBlur, this, {delay: 10});
26218 if(this.monitorTab){
26219 this.el.on("keydown", this.checkTab, this);
26222 },
26224 checkTab : function(e){
26225 if(e.getKey() == e.TAB){
26226 this.triggerBlur();
26228 },
26230 onBlur : function(){
26231 },
26233 mimicBlur : function(e){
26234 if(!this.wrap.contains(e.target) && this.validateBlur(e)){
26235 this.triggerBlur();
26237 },
26239 triggerBlur : function(){
26240 this.mimicing = false;
26241 Ext.get(Ext.isIE ? document.body : document).un("mousedown", this.mimicBlur);
26242 if(this.monitorTab){
26243 this.el.un("keydown", this.checkTab, this);
26245 this.beforeBlur();
26246 this.wrap.removeClass('x-trigger-wrap-focus');
26247 Ext.form.TriggerField.superclass.onBlur.call(this);
26248 },
26250 beforeBlur : Ext.emptyFn,
26252 validateBlur : function(e){
26253 return true;
26254 },
26256 onDisable : function(){
26257 Ext.form.TriggerField.superclass.onDisable.call(this);
26258 if(this.wrap){
26259 this.wrap.addClass('x-item-disabled');
26261 },
26263 onEnable : function(){
26264 Ext.form.TriggerField.superclass.onEnable.call(this);
26265 if(this.wrap){
26266 this.wrap.removeClass('x-item-disabled');
26268 },
26271 onShow : function(){
26272 if(this.wrap){
26273 this.wrap.dom.style.display = '';
26274 this.wrap.dom.style.visibility = 'visible';
26276 },
26278 onHide : function(){
26279 this.wrap.dom.style.display = 'none';
26280 },
26283 onTriggerClick : Ext.emptyFn
26288 });
26290 Ext.form.TwinTriggerField = Ext.extend(Ext.form.TriggerField, {
26291 initComponent : function(){
26292 Ext.form.TwinTriggerField.superclass.initComponent.call(this);
26294 this.triggerConfig = {
26295 tag:'span', cls:'x-form-twin-triggers', cn:[
26296 {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger1Class},
26297 {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger2Class}
26298 ]};
26299 },
26301 getTrigger : function(index){
26302 return this.triggers[index];
26303 },
26305 initTrigger : function(){
26306 var ts = this.trigger.select('.x-form-trigger', true);
26307 this.wrap.setStyle('overflow', 'hidden');
26308 var triggerField = this;
26309 ts.each(function(t, all, index){
26310 t.hide = function(){
26311 var w = triggerField.wrap.getWidth();
26312 this.dom.style.display = 'none';
26313 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
26314 };
26315 t.show = function(){
26316 var w = triggerField.wrap.getWidth();
26317 this.dom.style.display = '';
26318 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
26319 };
26320 var triggerIndex = 'Trigger'+(index+1);
26322 if(this['hide'+triggerIndex]){
26323 t.dom.style.display = 'none';
26325 t.on("click", this['on'+triggerIndex+'Click'], this, {preventDefault:true});
26326 t.addClassOnOver('x-form-trigger-over');
26327 t.addClassOnClick('x-form-trigger-click');
26328 }, this);
26329 this.triggers = ts.elements;
26330 },
26332 onTrigger1Click : Ext.emptyFn,
26333 onTrigger2Click : Ext.emptyFn
26334 });
26335 Ext.reg('trigger', Ext.form.TriggerField);
26337 Ext.form.TextArea = Ext.extend(Ext.form.TextField, {
26339 growMin : 60,
26341 growMax: 1000,
26342 growAppend : '&#160;\n&#160;',
26343 growPad : 0,
26345 enterIsSpecial : false,
26348 preventScrollbars: false,
26351 onRender : function(ct, position){
26352 if(!this.el){
26353 this.defaultAutoCreate = {
26354 tag: "textarea",
26355 style:"width:100px;height:60px;",
26356 autocomplete: "off"
26357 };
26359 Ext.form.TextArea.superclass.onRender.call(this, ct, position);
26360 if(this.grow){
26361 this.textSizeEl = Ext.DomHelper.append(document.body, {
26362 tag: "pre", cls: "x-form-grow-sizer"
26363 });
26364 if(this.preventScrollbars){
26365 this.el.setStyle("overflow", "hidden");
26367 this.el.setHeight(this.growMin);
26369 },
26371 onDestroy : function(){
26372 if(this.textSizeEl){
26373 Ext.removeNode(this.textSizeEl);
26375 Ext.form.TextArea.superclass.onDestroy.call(this);
26376 },
26378 fireKey : function(e){
26379 if(e.isSpecialKey() && (this.enterIsSpecial || (e.getKey() != e.ENTER || e.hasModifier()))){
26380 this.fireEvent("specialkey", this, e);
26382 },
26384 onKeyUp : function(e){
26385 if(!e.isNavKeyPress() || e.getKey() == e.ENTER){
26386 this.autoSize();
26388 },
26391 autoSize : function(){
26392 if(!this.grow || !this.textSizeEl){
26393 return;
26395 var el = this.el;
26396 var v = el.dom.value;
26397 var ts = this.textSizeEl;
26398 ts.innerHTML = '';
26399 ts.appendChild(document.createTextNode(v));
26400 v = ts.innerHTML;
26402 Ext.fly(ts).setWidth(this.el.getWidth());
26403 if(v.length < 1){
26404 v = "&#160;&#160;";
26405 }else{
26406 if(Ext.isIE){
26407 v = v.replace(/\n/g, '<p>&#160;</p>');
26409 v += this.growAppend;
26411 ts.innerHTML = v;
26412 var h = Math.min(this.growMax, Math.max(ts.offsetHeight, this.growMin)+this.growPad);
26413 if(h != this.lastHeight){
26414 this.lastHeight = h;
26415 this.el.setHeight(h);
26416 this.fireEvent("autosize", this, h);
26419 });
26420 Ext.reg('textarea', Ext.form.TextArea);
26422 Ext.form.NumberField = Ext.extend(Ext.form.TextField, {
26424 fieldClass: "x-form-field x-form-num-field",
26426 allowDecimals : true,
26428 decimalSeparator : ".",
26430 decimalPrecision : 2,
26432 allowNegative : true,
26434 minValue : Number.NEGATIVE_INFINITY,
26436 maxValue : Number.MAX_VALUE,
26438 minText : "The minimum value for this field is {0}",
26440 maxText : "The maximum value for this field is {0}",
26442 nanText : "{0} is not a valid number",
26444 baseChars : "0123456789",
26446 initEvents : function(){
26447 Ext.form.NumberField.superclass.initEvents.call(this);
26448 var allowed = this.baseChars+'';
26449 if(this.allowDecimals){
26450 allowed += this.decimalSeparator;
26452 if(this.allowNegative){
26453 allowed += "-";
26455 this.stripCharsRe = new RegExp('[^'+allowed+']', 'gi');
26456 var keyPress = function(e){
26457 var k = e.getKey();
26458 if(!Ext.isIE && (e.isSpecialKey() || k == e.BACKSPACE || k == e.DELETE)){
26459 return;
26461 var c = e.getCharCode();
26462 if(allowed.indexOf(String.fromCharCode(c)) === -1){
26463 e.stopEvent();
26465 };
26466 this.el.on("keypress", keyPress, this);
26467 },
26469 validateValue : function(value){
26470 if(!Ext.form.NumberField.superclass.validateValue.call(this, value)){
26471 return false;
26473 if(value.length < 1){ return true;
26475 value = String(value).replace(this.decimalSeparator, ".");
26476 if(isNaN(value)){
26477 this.markInvalid(String.format(this.nanText, value));
26478 return false;
26480 var num = this.parseValue(value);
26481 if(num < this.minValue){
26482 this.markInvalid(String.format(this.minText, this.minValue));
26483 return false;
26485 if(num > this.maxValue){
26486 this.markInvalid(String.format(this.maxText, this.maxValue));
26487 return false;
26489 return true;
26490 },
26492 getValue : function(){
26493 return this.fixPrecision(this.parseValue(Ext.form.NumberField.superclass.getValue.call(this)));
26494 },
26496 setValue : function(v){
26497 v = typeof v == 'number' ? v : parseFloat(String(v).replace(this.decimalSeparator, "."));
26498 v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator);
26499 Ext.form.NumberField.superclass.setValue.call(this, v);
26500 },
26502 parseValue : function(value){
26503 value = parseFloat(String(value).replace(this.decimalSeparator, "."));
26504 return isNaN(value) ? '' : value;
26505 },
26507 fixPrecision : function(value){
26508 var nan = isNaN(value);
26509 if(!this.allowDecimals || this.decimalPrecision == -1 || nan || !value){
26510 return nan ? '' : value;
26512 return parseFloat(parseFloat(value).toFixed(this.decimalPrecision));
26513 },
26515 beforeBlur : function(){
26516 var v = this.parseValue(this.getRawValue());
26517 if(v){
26518 this.setValue(this.fixPrecision(v));
26521 });
26522 Ext.reg('numberfield', Ext.form.NumberField);
26524 Ext.form.DateField = Ext.extend(Ext.form.TriggerField, {
26526 format : "m/d/Y",
26528 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",
26530 disabledDays : null,
26532 disabledDaysText : "Disabled",
26534 disabledDates : null,
26536 disabledDatesText : "Disabled",
26538 minValue : null,
26540 maxValue : null,
26542 minText : "The date in this field must be equal to or after {0}",
26544 maxText : "The date in this field must be equal to or before {0}",
26546 invalidText : "{0} is not a valid date - it must be in the format {1}",
26548 triggerClass : 'x-form-date-trigger',
26551 defaultAutoCreate : {tag: "input", type: "text", size: "10", autocomplete: "off"},
26553 initComponent : function(){
26554 Ext.form.DateField.superclass.initComponent.call(this);
26555 if(typeof this.minValue == "string"){
26556 this.minValue = this.parseDate(this.minValue);
26558 if(typeof this.maxValue == "string"){
26559 this.maxValue = this.parseDate(this.maxValue);
26561 this.ddMatch = null;
26562 if(this.disabledDates){
26563 var dd = this.disabledDates;
26564 var re = "(?:";
26565 for(var i = 0; i < dd.length; i++){
26566 re += dd[i];
26567 if(i != dd.length-1) re += "|";
26569 this.ddMatch = new RegExp(re + ")");
26571 },
26573 validateValue : function(value){
26574 value = this.formatDate(value);
26575 if(!Ext.form.DateField.superclass.validateValue.call(this, value)){
26576 return false;
26578 if(value.length < 1){ return true;
26580 var svalue = value;
26581 value = this.parseDate(value);
26582 if(!value){
26583 this.markInvalid(String.format(this.invalidText, svalue, this.format));
26584 return false;
26586 var time = value.getTime();
26587 if(this.minValue && time < this.minValue.getTime()){
26588 this.markInvalid(String.format(this.minText, this.formatDate(this.minValue)));
26589 return false;
26591 if(this.maxValue && time > this.maxValue.getTime()){
26592 this.markInvalid(String.format(this.maxText, this.formatDate(this.maxValue)));
26593 return false;
26595 if(this.disabledDays){
26596 var day = value.getDay();
26597 for(var i = 0; i < this.disabledDays.length; i++) {
26598 if(day === this.disabledDays[i]){
26599 this.markInvalid(this.disabledDaysText);
26600 return false;
26604 var fvalue = this.formatDate(value);
26605 if(this.ddMatch && this.ddMatch.test(fvalue)){
26606 this.markInvalid(String.format(this.disabledDatesText, fvalue));
26607 return false;
26609 return true;
26610 },
26612 validateBlur : function(){
26613 return !this.menu || !this.menu.isVisible();
26614 },
26617 getValue : function(){
26618 return this.parseDate(Ext.form.DateField.superclass.getValue.call(this)) || "";
26619 },
26622 setValue : function(date){
26623 Ext.form.DateField.superclass.setValue.call(this, this.formatDate(this.parseDate(date)));
26624 },
26626 parseDate : function(value){
26627 if(!value || Ext.isDate(value)){
26628 return value;
26630 var v = Date.parseDate(value, this.format);
26631 if(!v && this.altFormats){
26632 if(!this.altFormatsArray){
26633 this.altFormatsArray = this.altFormats.split("|");
26635 for(var i = 0, len = this.altFormatsArray.length; i < len && !v; i++){
26636 v = Date.parseDate(value, this.altFormatsArray[i]);
26639 return v;
26640 },
26642 onDestroy : function(){
26643 if(this.menu) {
26644 this.menu.destroy();
26646 if(this.wrap){
26647 this.wrap.remove();
26649 Ext.form.DateField.superclass.onDestroy.call(this);
26650 },
26652 formatDate : function(date){
26653 return Ext.isDate(date) ? date.dateFormat(this.format) : date;
26654 },
26656 menuListeners : {
26657 select: function(m, d){
26658 this.setValue(d);
26659 },
26660 show : function(){ this.onFocus();
26661 },
26662 hide : function(){
26663 this.focus.defer(10, this);
26664 var ml = this.menuListeners;
26665 this.menu.un("select", ml.select, this);
26666 this.menu.un("show", ml.show, this);
26667 this.menu.un("hide", ml.hide, this);
26669 },
26671 onTriggerClick : function(){
26672 if(this.disabled){
26673 return;
26675 if(this.menu == null){
26676 this.menu = new Ext.menu.DateMenu();
26678 Ext.apply(this.menu.picker, {
26679 minDate : this.minValue,
26680 maxDate : this.maxValue,
26681 disabledDatesRE : this.ddMatch,
26682 disabledDatesText : this.disabledDatesText,
26683 disabledDays : this.disabledDays,
26684 disabledDaysText : this.disabledDaysText,
26685 format : this.format,
26686 minText : String.format(this.minText, this.formatDate(this.minValue)),
26687 maxText : String.format(this.maxText, this.formatDate(this.maxValue))
26688 });
26689 this.menu.on(Ext.apply({}, this.menuListeners, {
26690 scope:this
26691 }));
26692 this.menu.picker.setValue(this.getValue() || new Date());
26693 this.menu.show(this.el, "tl-bl?");
26694 },
26696 beforeBlur : function(){
26697 var v = this.parseDate(this.getRawValue());
26698 if(v){
26699 this.setValue(v);
26707 });
26708 Ext.reg('datefield', Ext.form.DateField);
26710 Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
26717 defaultAutoCreate : {tag: "input", type: "text", size: "24", autocomplete: "off"},
26724 listClass: '',
26726 selectedClass: 'x-combo-selected',
26728 triggerClass : 'x-form-arrow-trigger',
26730 shadow:'sides',
26732 listAlign: 'tl-bl?',
26734 maxHeight: 300,
26736 minHeight: 90,
26738 triggerAction: 'query',
26740 minChars : 4,
26742 typeAhead: false,
26744 queryDelay: 500,
26746 pageSize: 0,
26748 selectOnFocus:false,
26750 queryParam: 'query',
26752 loadingText: 'Loading...',
26754 resizable: false,
26756 handleHeight : 8,
26758 editable: true,
26760 allQuery: '',
26762 mode: 'remote',
26764 minListWidth : 70,
26766 forceSelection:false,
26768 typeAheadDelay : 250,
26772 lazyInit : true,
26774 initComponent : function(){
26775 Ext.form.ComboBox.superclass.initComponent.call(this);
26776 this.addEvents(
26778 'expand',
26780 'collapse',
26782 'beforeselect',
26784 'select',
26786 'beforequery'
26787 );
26788 if(this.transform){
26789 this.allowDomMove = false;
26790 var s = Ext.getDom(this.transform);
26791 if(!this.hiddenName){
26792 this.hiddenName = s.name;
26794 if(!this.store){
26795 this.mode = 'local';
26796 var d = [], opts = s.options;
26797 for(var i = 0, len = opts.length;i < len; i++){
26798 var o = opts[i];
26799 var value = (Ext.isIE ? o.getAttributeNode('value').specified : o.hasAttribute('value')) ? o.value : o.text;
26800 if(o.selected) {
26801 this.value = value;
26803 d.push([value, o.text]);
26805 this.store = new Ext.data.SimpleStore({
26806 'id': 0,
26807 fields: ['value', 'text'],
26808 data : d
26809 });
26810 this.valueField = 'value';
26811 this.displayField = 'text';
26813 s.name = Ext.id(); if(!this.lazyRender){
26814 this.target = true;
26815 this.el = Ext.DomHelper.insertBefore(s, this.autoCreate || this.defaultAutoCreate);
26816 Ext.removeNode(s); this.render(this.el.parentNode);
26817 }else{
26818 Ext.removeNode(s); }
26820 else if(Ext.isArray(this.store)){
26821 if (Ext.isArray(this.store[0])){
26822 this.store = new Ext.data.SimpleStore({
26823 fields: ['value','text'],
26824 data: this.store
26825 });
26826 this.valueField = 'value';
26827 }else{
26828 this.store = new Ext.data.SimpleStore({
26829 fields: ['text'],
26830 data: this.store,
26831 expandData: true
26832 });
26833 this.valueField = 'text';
26835 this.displayField = 'text';
26836 this.mode = 'local';
26839 this.selectedIndex = -1;
26840 if(this.mode == 'local'){
26841 if(this.initialConfig.queryDelay === undefined){
26842 this.queryDelay = 10;
26844 if(this.initialConfig.minChars === undefined){
26845 this.minChars = 0;
26848 },
26850 onRender : function(ct, position){
26851 Ext.form.ComboBox.superclass.onRender.call(this, ct, position);
26852 if(this.hiddenName){
26853 this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName, id: (this.hiddenId||this.hiddenName)},
26854 'before', true);
26855 this.hiddenField.value =
26856 this.hiddenValue !== undefined ? this.hiddenValue :
26857 this.value !== undefined ? this.value : '';
26859 this.el.dom.removeAttribute('name');
26861 if(Ext.isGecko){
26862 this.el.dom.setAttribute('autocomplete', 'off');
26865 if(!this.lazyInit){
26866 this.initList();
26867 }else{
26868 this.on('focus', this.initList, this, {single: true});
26871 if(!this.editable){
26872 this.editable = true;
26873 this.setEditable(false);
26875 },
26877 initList : function(){
26878 if(!this.list){
26879 var cls = 'x-combo-list';
26881 this.list = new Ext.Layer({
26882 shadow: this.shadow, cls: [cls, this.listClass].join(' '), constrain:false
26883 });
26885 var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
26886 this.list.setWidth(lw);
26887 this.list.swallowEvent('mousewheel');
26888 this.assetHeight = 0;
26890 if(this.title){
26891 this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
26892 this.assetHeight += this.header.getHeight();
26895 this.innerList = this.list.createChild({cls:cls+'-inner'});
26896 this.innerList.on('mouseover', this.onViewOver, this);
26897 this.innerList.on('mousemove', this.onViewMove, this);
26898 this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
26900 if(this.pageSize){
26901 this.footer = this.list.createChild({cls:cls+'-ft'});
26902 this.pageTb = new Ext.PagingToolbar({
26903 store:this.store,
26904 pageSize: this.pageSize,
26905 renderTo:this.footer
26906 });
26907 this.assetHeight += this.footer.getHeight();
26910 if(!this.tpl){
26912 this.tpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';
26917 this.view = new Ext.DataView({
26918 applyTo: this.innerList,
26919 tpl: this.tpl,
26920 singleSelect: true,
26921 selectedClass: this.selectedClass,
26922 itemSelector: this.itemSelector || '.' + cls + '-item'
26923 });
26925 this.view.on('click', this.onViewClick, this);
26927 this.bindStore(this.store, true);
26929 if(this.resizable){
26930 this.resizer = new Ext.Resizable(this.list, {
26931 pinned:true, handles:'se'
26932 });
26933 this.resizer.on('resize', function(r, w, h){
26934 this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
26935 this.listWidth = w;
26936 this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
26937 this.restrictHeight();
26938 }, this);
26939 this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
26942 },
26945 bindStore : function(store, initial){
26946 if(this.store && !initial){
26947 this.store.un('beforeload', this.onBeforeLoad, this);
26948 this.store.un('load', this.onLoad, this);
26949 this.store.un('loadexception', this.collapse, this);
26950 if(!store){
26951 this.store = null;
26952 if(this.view){
26953 this.view.setStore(null);
26957 if(store){
26958 this.store = Ext.StoreMgr.lookup(store);
26960 this.store.on('beforeload', this.onBeforeLoad, this);
26961 this.store.on('load', this.onLoad, this);
26962 this.store.on('loadexception', this.collapse, this);
26964 if(this.view){
26965 this.view.setStore(store);
26968 },
26970 initEvents : function(){
26971 Ext.form.ComboBox.superclass.initEvents.call(this);
26973 this.keyNav = new Ext.KeyNav(this.el, {
26974 "up" : function(e){
26975 this.inKeyMode = true;
26976 this.selectPrev();
26977 },
26979 "down" : function(e){
26980 if(!this.isExpanded()){
26981 this.onTriggerClick();
26982 }else{
26983 this.inKeyMode = true;
26984 this.selectNext();
26986 },
26988 "enter" : function(e){
26989 this.onViewClick();
26990 this.delayedCheck = true;
26991 this.unsetDelayCheck.defer(10, this);
26992 },
26994 "esc" : function(e){
26995 this.collapse();
26996 },
26998 "tab" : function(e){
26999 this.onViewClick(false);
27000 return true;
27001 },
27003 scope : this,
27005 doRelay : function(foo, bar, hname){
27006 if(hname == 'down' || this.scope.isExpanded()){
27007 return Ext.KeyNav.prototype.doRelay.apply(this, arguments);
27009 return true;
27010 },
27012 forceKeyDown : true
27013 });
27014 this.queryDelay = Math.max(this.queryDelay || 10,
27015 this.mode == 'local' ? 10 : 250);
27016 this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);
27017 if(this.typeAhead){
27018 this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
27020 if(this.editable !== false){
27021 this.el.on("keyup", this.onKeyUp, this);
27023 if(this.forceSelection){
27024 this.on('blur', this.doForce, this);
27026 },
27028 onDestroy : function(){
27029 if(this.view){
27030 this.view.el.removeAllListeners();
27031 this.view.el.remove();
27032 this.view.purgeListeners();
27034 if(this.list){
27035 this.list.destroy();
27037 this.bindStore(null);
27038 Ext.form.ComboBox.superclass.onDestroy.call(this);
27039 },
27041 unsetDelayCheck : function(){
27042 delete this.delayedCheck;
27043 },
27044 fireKey : function(e){
27045 if(e.isNavKeyPress() && !this.isExpanded() && !this.delayedCheck){
27046 this.fireEvent("specialkey", this, e);
27048 },
27050 onResize: function(w, h){
27051 Ext.form.ComboBox.superclass.onResize.apply(this, arguments);
27052 if(this.list && this.listWidth === undefined){
27053 var lw = Math.max(w, this.minListWidth);
27054 this.list.setWidth(lw);
27055 this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
27057 },
27059 onEnable: function(){
27060 Ext.form.ComboBox.superclass.onEnable.apply(this, arguments);
27061 if(this.hiddenField){
27062 this.hiddenField.disabled = false;
27064 },
27066 onDisable: function(){
27067 Ext.form.ComboBox.superclass.onDisable.apply(this, arguments);
27068 if(this.hiddenField){
27069 this.hiddenField.disabled = true;
27071 },
27074 setEditable : function(value){
27075 if(value == this.editable){
27076 return;
27078 this.editable = value;
27079 if(!value){
27080 this.el.dom.setAttribute('readOnly', true);
27081 this.el.on('mousedown', this.onTriggerClick, this);
27082 this.el.addClass('x-combo-noedit');
27083 }else{
27084 this.el.dom.setAttribute('readOnly', false);
27085 this.el.un('mousedown', this.onTriggerClick, this);
27086 this.el.removeClass('x-combo-noedit');
27088 },
27090 onBeforeLoad : function(){
27091 if(!this.hasFocus){
27092 return;
27094 this.innerList.update(this.loadingText ?
27095 '<div class="loading-indicator">'+this.loadingText+'</div>' : '');
27096 this.restrictHeight();
27097 this.selectedIndex = -1;
27098 },
27100 onLoad : function(){
27101 if(!this.hasFocus){
27102 return;
27104 if(this.store.getCount() > 0){
27105 this.expand();
27106 this.restrictHeight();
27107 if(this.lastQuery == this.allQuery){
27108 if(this.editable){
27109 this.el.dom.select();
27111 if(!this.selectByValue(this.value, true)){
27112 this.select(0, true);
27114 }else{
27115 this.selectNext();
27116 if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){
27117 this.taTask.delay(this.typeAheadDelay);
27120 }else{
27121 this.onEmptyResults();
27123 },
27125 onTypeAhead : function(){
27126 if(this.store.getCount() > 0){
27127 var r = this.store.getAt(0);
27128 var newValue = r.data[this.displayField];
27129 var len = newValue.length;
27130 var selStart = this.getRawValue().length;
27131 if(selStart != len){
27132 this.setRawValue(newValue);
27133 this.selectText(selStart, newValue.length);
27136 },
27138 onSelect : function(record, index){
27139 if(this.fireEvent('beforeselect', this, record, index) !== false){
27140 this.setValue(record.data[this.valueField || this.displayField]);
27141 this.collapse();
27142 this.fireEvent('select', this, record, index);
27144 },
27147 getValue : function(){
27148 if(this.valueField){
27149 return typeof this.value != 'undefined' ? this.value : '';
27150 }else{
27151 return Ext.form.ComboBox.superclass.getValue.call(this);
27153 },
27156 clearValue : function(){
27157 if(this.hiddenField){
27158 this.hiddenField.value = '';
27160 this.setRawValue('');
27161 this.lastSelectionText = '';
27162 this.applyEmptyText();
27163 this.value = '';
27164 },
27167 setValue : function(v){
27168 var text = v;
27169 if(this.valueField){
27170 var r = this.findRecord(this.valueField, v);
27171 if(r){
27172 text = r.data[this.displayField];
27173 }else if(this.valueNotFoundText !== undefined){
27174 text = this.valueNotFoundText;
27177 this.lastSelectionText = text;
27178 if(this.hiddenField){
27179 this.hiddenField.value = v;
27181 Ext.form.ComboBox.superclass.setValue.call(this, text);
27182 this.value = v;
27183 },
27185 findRecord : function(prop, value){
27186 var record;
27187 if(this.store.getCount() > 0){
27188 this.store.each(function(r){
27189 if(r.data[prop] == value){
27190 record = r;
27191 return false;
27193 });
27195 return record;
27196 },
27198 onViewMove : function(e, t){
27199 this.inKeyMode = false;
27200 },
27202 onViewOver : function(e, t){
27203 if(this.inKeyMode){ return;
27205 var item = this.view.findItemFromChild(t);
27206 if(item){
27207 var index = this.view.indexOf(item);
27208 this.select(index, false);
27210 },
27212 onViewClick : function(doFocus){
27213 var index = this.view.getSelectedIndexes()[0];
27214 var r = this.store.getAt(index);
27215 if(r){
27216 this.onSelect(r, index);
27218 if(doFocus !== false){
27219 this.el.focus();
27221 },
27223 restrictHeight : function(){
27224 this.innerList.dom.style.height = '';
27225 var inner = this.innerList.dom;
27226 var pad = this.list.getFrameWidth('tb')+(this.resizable?this.handleHeight:0)+this.assetHeight;
27227 var h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight);
27228 var ha = this.getPosition()[1]-Ext.getBody().getScroll().top;
27229 var hb = Ext.lib.Dom.getViewHeight()-ha-this.getSize().height;
27230 var space = Math.max(ha, hb, this.minHeight || 0)-this.list.shadowOffset-pad-5;
27231 h = Math.min(h, space, this.maxHeight);
27233 this.innerList.setHeight(h);
27234 this.list.beginUpdate();
27235 this.list.setHeight(h+pad);
27236 this.list.alignTo(this.wrap, this.listAlign);
27237 this.list.endUpdate();
27238 },
27240 onEmptyResults : function(){
27241 this.collapse();
27242 },
27245 isExpanded : function(){
27246 return this.list && this.list.isVisible();
27247 },
27250 selectByValue : function(v, scrollIntoView){
27251 if(v !== undefined && v !== null){
27252 var r = this.findRecord(this.valueField || this.displayField, v);
27253 if(r){
27254 this.select(this.store.indexOf(r), scrollIntoView);
27255 return true;
27258 return false;
27259 },
27262 select : function(index, scrollIntoView){
27263 this.selectedIndex = index;
27264 this.view.select(index);
27265 if(scrollIntoView !== false){
27266 var el = this.view.getNode(index);
27267 if(el){
27268 this.innerList.scrollChildIntoView(el, false);
27271 },
27273 selectNext : function(){
27274 var ct = this.store.getCount();
27275 if(ct > 0){
27276 if(this.selectedIndex == -1){
27277 this.select(0);
27278 }else if(this.selectedIndex < ct-1){
27279 this.select(this.selectedIndex+1);
27282 },
27284 selectPrev : function(){
27285 var ct = this.store.getCount();
27286 if(ct > 0){
27287 if(this.selectedIndex == -1){
27288 this.select(0);
27289 }else if(this.selectedIndex != 0){
27290 this.select(this.selectedIndex-1);
27293 },
27295 onKeyUp : function(e){
27296 if(this.editable !== false && !e.isSpecialKey()){
27297 this.lastKey = e.getKey();
27298 this.dqTask.delay(this.queryDelay);
27300 },
27302 validateBlur : function(){
27303 return !this.list || !this.list.isVisible();
27304 },
27306 initQuery : function(){
27307 this.doQuery(this.getRawValue());
27308 },
27310 doForce : function(){
27311 if(this.el.dom.value.length > 0){
27312 this.el.dom.value =
27313 this.lastSelectionText === undefined ? '' : this.lastSelectionText;
27314 this.applyEmptyText();
27316 },
27319 doQuery : function(q, forceAll){
27320 if(q === undefined || q === null){
27321 q = '';
27323 var qe = {
27324 query: q,
27325 forceAll: forceAll,
27326 combo: this,
27327 cancel:false
27328 };
27329 if(this.fireEvent('beforequery', qe)===false || qe.cancel){
27330 return false;
27332 q = qe.query;
27333 forceAll = qe.forceAll;
27334 if(forceAll === true || (q.length >= this.minChars)){
27335 if(this.lastQuery !== q){
27336 this.lastQuery = q;
27337 if(this.mode == 'local'){
27338 this.selectedIndex = -1;
27339 if(forceAll){
27340 this.store.clearFilter();
27341 }else{
27342 this.store.filter(this.displayField, q);
27344 this.onLoad();
27345 }else{
27346 this.store.baseParams[this.queryParam] = q;
27347 this.store.load({
27348 params: this.getParams(q)
27349 });
27350 this.expand();
27352 }else{
27353 this.selectedIndex = -1;
27354 this.onLoad();
27357 },
27359 getParams : function(q){
27360 var p = {};
27361 if(this.pageSize){
27362 p.start = 0;
27363 p.limit = this.pageSize;
27365 return p;
27366 },
27369 collapse : function(){
27370 if(!this.isExpanded()){
27371 return;
27373 this.list.hide();
27374 Ext.getDoc().un('mousewheel', this.collapseIf, this);
27375 Ext.getDoc().un('mousedown', this.collapseIf, this);
27376 this.fireEvent('collapse', this);
27377 },
27379 collapseIf : function(e){
27380 if(!e.within(this.wrap) && !e.within(this.list)){
27381 this.collapse();
27383 },
27386 expand : function(){
27387 if(this.isExpanded() || !this.hasFocus){
27388 return;
27390 this.list.alignTo(this.wrap, this.listAlign);
27391 this.list.show();
27392 this.innerList.setOverflow('auto'); Ext.getDoc().on('mousewheel', this.collapseIf, this);
27393 Ext.getDoc().on('mousedown', this.collapseIf, this);
27394 this.fireEvent('expand', this);
27395 },
27397 onTriggerClick : function(){
27398 if(this.disabled){
27399 return;
27401 if(this.isExpanded()){
27402 this.collapse();
27403 this.el.focus();
27404 }else {
27405 this.onFocus({});
27406 if(this.triggerAction == 'all') {
27407 this.doQuery(this.allQuery, true);
27408 } else {
27409 this.doQuery(this.getRawValue());
27411 this.el.focus();
27420 });
27421 Ext.reg('combo', Ext.form.ComboBox);
27423 Ext.form.Checkbox = Ext.extend(Ext.form.Field, {
27425 focusClass : undefined,
27427 fieldClass: "x-form-field",
27429 checked: false,
27431 defaultAutoCreate : { tag: "input", type: 'checkbox', autocomplete: "off"},
27435 initComponent : function(){
27436 Ext.form.Checkbox.superclass.initComponent.call(this);
27437 this.addEvents(
27439 'check'
27440 );
27441 },
27443 onResize : function(){
27444 Ext.form.Checkbox.superclass.onResize.apply(this, arguments);
27445 if(!this.boxLabel){
27446 this.el.alignTo(this.wrap, 'c-c');
27448 },
27450 initEvents : function(){
27451 Ext.form.Checkbox.superclass.initEvents.call(this);
27452 this.el.on("click", this.onClick, this);
27453 this.el.on("change", this.onClick, this);
27454 },
27456 getResizeEl : function(){
27457 return this.wrap;
27458 },
27460 getPositionEl : function(){
27461 return this.wrap;
27462 },
27465 markInvalid : Ext.emptyFn,
27467 clearInvalid : Ext.emptyFn,
27469 onRender : function(ct, position){
27470 Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
27471 if(this.inputValue !== undefined){
27472 this.el.dom.value = this.inputValue;
27474 this.wrap = this.el.wrap({cls: "x-form-check-wrap"});
27475 if(this.boxLabel){
27476 this.wrap.createChild({tag: 'label', htmlFor: this.el.id, cls: 'x-form-cb-label', html: this.boxLabel});
27478 if(this.checked){
27479 this.setValue(true);
27480 }else{
27481 this.checked = this.el.dom.checked;
27483 },
27485 onDestroy : function(){
27486 if(this.wrap){
27487 this.wrap.remove();
27489 Ext.form.Checkbox.superclass.onDestroy.call(this);
27490 },
27492 initValue : Ext.emptyFn,
27495 getValue : function(){
27496 if(this.rendered){
27497 return this.el.dom.checked;
27499 return false;
27500 },
27502 onClick : function(){
27503 if(this.el.dom.checked != this.checked){
27504 this.setValue(this.el.dom.checked);
27506 },
27509 setValue : function(v){
27510 this.checked = (v === true || v === 'true' || v == '1' || String(v).toLowerCase() == 'on');
27511 if(this.el && this.el.dom){
27512 this.el.dom.checked = this.checked;
27513 this.el.dom.defaultChecked = this.checked;
27515 this.fireEvent("check", this, this.checked);
27517 });
27518 Ext.reg('checkbox', Ext.form.Checkbox);
27520 Ext.form.Radio = Ext.extend(Ext.form.Checkbox, {
27521 inputType: 'radio',
27524 markInvalid : Ext.emptyFn,
27526 clearInvalid : Ext.emptyFn,
27529 getGroupValue : function(){
27530 var p = this.el.up('form') || Ext.getBody();
27531 var c = p.child('input[name='+this.el.dom.name+']:checked', true);
27532 return c ? c.value : null;
27533 },
27535 onClick : function(){
27536 if(this.el.dom.checked != this.checked){
27537 var p = this.el.up('form') || Ext.getBody();
27538 var els = p.select('input[name='+this.el.dom.name+']');
27539 els.each(function(el){
27540 if(el.dom.id == this.id){
27541 this.setValue(true);
27542 }else{
27543 Ext.getCmp(el.dom.id).setValue(false);
27545 }, this);
27547 },
27550 setValue : function(v){
27551 if (typeof v == 'boolean') {
27552 Ext.form.Radio.superclass.setValue.call(this, v);
27553 } else {
27554 var r = this.el.up('form').child('input[name='+this.el.dom.name+'][value='+v+']', true);
27555 if (r){
27556 r.checked = true;
27557 };
27560 });
27561 Ext.reg('radio', Ext.form.Radio);
27563 Ext.form.Hidden = Ext.extend(Ext.form.Field, {
27565 inputType : 'hidden',
27568 onRender : function(){
27569 Ext.form.Hidden.superclass.onRender.apply(this, arguments);
27570 },
27573 initEvents : function(){
27574 this.originalValue = this.getValue();
27575 },
27578 setSize : Ext.emptyFn,
27579 setWidth : Ext.emptyFn,
27580 setHeight : Ext.emptyFn,
27581 setPosition : Ext.emptyFn,
27582 setPagePosition : Ext.emptyFn,
27583 markInvalid : Ext.emptyFn,
27584 clearInvalid : Ext.emptyFn
27585 });
27586 Ext.reg('hidden', Ext.form.Hidden);
27588 Ext.form.BasicForm = function(el, config){
27589 Ext.apply(this, config);
27591 this.items = new Ext.util.MixedCollection(false, function(o){
27592 return o.id || (o.id = Ext.id());
27593 });
27594 this.addEvents(
27596 'beforeaction',
27598 'actionfailed',
27600 'actioncomplete'
27601 );
27603 if(el){
27604 this.initEl(el);
27606 Ext.form.BasicForm.superclass.constructor.call(this);
27607 };
27609 Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
27617 timeout: 30,
27619 activeAction : null,
27622 trackResetOnLoad : false,
27627 initEl : function(el){
27628 this.el = Ext.get(el);
27629 this.id = this.el.id || Ext.id();
27630 if(!this.standardSubmit){
27631 this.el.on('submit', this.onSubmit, this);
27633 this.el.addClass('x-form');
27634 },
27637 getEl: function(){
27638 return this.el;
27639 },
27641 onSubmit : function(e){
27642 e.stopEvent();
27643 },
27645 destroy: function() {
27646 this.items.each(function(f){
27647 Ext.destroy(f);
27648 });
27649 if(this.el){
27650 this.el.removeAllListeners();
27651 this.el.remove();
27653 this.purgeListeners();
27654 },
27657 isValid : function(){
27658 var valid = true;
27659 this.items.each(function(f){
27660 if(!f.validate()){
27661 valid = false;
27663 });
27664 return valid;
27665 },
27668 isDirty : function(){
27669 var dirty = false;
27670 this.items.each(function(f){
27671 if(f.isDirty()){
27672 dirty = true;
27673 return false;
27675 });
27676 return dirty;
27677 },
27680 doAction : function(action, options){
27681 if(typeof action == 'string'){
27682 action = new Ext.form.Action.ACTION_TYPES[action](this, options);
27684 if(this.fireEvent('beforeaction', this, action) !== false){
27685 this.beforeAction(action);
27686 action.run.defer(100, action);
27688 return this;
27689 },
27692 submit : function(options){
27693 if(this.standardSubmit){
27694 var v = this.isValid();
27695 if(v){
27696 this.el.dom.submit();
27698 return v;
27700 this.doAction('submit', options);
27701 return this;
27702 },
27705 load : function(options){
27706 this.doAction('load', options);
27707 return this;
27708 },
27711 updateRecord : function(record){
27712 record.beginEdit();
27713 var fs = record.fields;
27714 fs.each(function(f){
27715 var field = this.findField(f.name);
27716 if(field){
27717 record.set(f.name, field.getValue());
27719 }, this);
27720 record.endEdit();
27721 return this;
27722 },
27725 loadRecord : function(record){
27726 this.setValues(record.data);
27727 return this;
27728 },
27730 beforeAction : function(action){
27731 var o = action.options;
27732 if(o.waitMsg){
27733 if(this.waitMsgTarget === true){
27734 this.el.mask(o.waitMsg, 'x-mask-loading');
27735 }else if(this.waitMsgTarget){
27736 this.waitMsgTarget = Ext.get(this.waitMsgTarget);
27737 this.waitMsgTarget.mask(o.waitMsg, 'x-mask-loading');
27738 }else{
27739 Ext.MessageBox.wait(o.waitMsg, o.waitTitle || this.waitTitle || 'Please Wait...');
27742 },
27744 afterAction : function(action, success){
27745 this.activeAction = null;
27746 var o = action.options;
27747 if(o.waitMsg){
27748 if(this.waitMsgTarget === true){
27749 this.el.unmask();
27750 }else if(this.waitMsgTarget){
27751 this.waitMsgTarget.unmask();
27752 }else{
27753 Ext.MessageBox.updateProgress(1);
27754 Ext.MessageBox.hide();
27757 if(success){
27758 if(o.reset){
27759 this.reset();
27761 Ext.callback(o.success, o.scope, [this, action]);
27762 this.fireEvent('actioncomplete', this, action);
27763 }else{
27764 Ext.callback(o.failure, o.scope, [this, action]);
27765 this.fireEvent('actionfailed', this, action);
27767 },
27770 findField : function(id){
27771 var field = this.items.get(id);
27772 if(!field){
27773 this.items.each(function(f){
27774 if(f.isFormField && (f.dataIndex == id || f.id == id || f.getName() == id)){
27775 field = f;
27776 return false;
27778 });
27780 return field || null;
27781 },
27785 markInvalid : function(errors){
27786 if(Ext.isArray(errors)){
27787 for(var i = 0, len = errors.length; i < len; i++){
27788 var fieldError = errors[i];
27789 var f = this.findField(fieldError.id);
27790 if(f){
27791 f.markInvalid(fieldError.msg);
27794 }else{
27795 var field, id;
27796 for(id in errors){
27797 if(typeof errors[id] != 'function' && (field = this.findField(id))){
27798 field.markInvalid(errors[id]);
27802 return this;
27803 },
27806 setValues : function(values){
27807 if(Ext.isArray(values)){ for(var i = 0, len = values.length; i < len; i++){
27808 var v = values[i];
27809 var f = this.findField(v.id);
27810 if(f){
27811 f.setValue(v.value);
27812 if(this.trackResetOnLoad){
27813 f.originalValue = f.getValue();
27817 }else{ var field, id;
27818 for(id in values){
27819 if(typeof values[id] != 'function' && (field = this.findField(id))){
27820 field.setValue(values[id]);
27821 if(this.trackResetOnLoad){
27822 field.originalValue = field.getValue();
27827 return this;
27828 },
27831 getValues : function(asString){
27832 var fs = Ext.lib.Ajax.serializeForm(this.el.dom);
27833 if(asString === true){
27834 return fs;
27836 return Ext.urlDecode(fs);
27837 },
27840 clearInvalid : function(){
27841 this.items.each(function(f){
27842 f.clearInvalid();
27843 });
27844 return this;
27845 },
27848 reset : function(){
27849 this.items.each(function(f){
27850 f.reset();
27851 });
27852 return this;
27853 },
27856 add : function(){
27857 this.items.addAll(Array.prototype.slice.call(arguments, 0));
27858 return this;
27859 },
27863 remove : function(field){
27864 this.items.remove(field);
27865 return this;
27866 },
27869 render : function(){
27870 this.items.each(function(f){
27871 if(f.isFormField && !f.rendered && document.getElementById(f.id)){ f.applyToMarkup(f.id);
27873 });
27874 return this;
27875 },
27878 applyToFields : function(o){
27879 this.items.each(function(f){
27880 Ext.apply(f, o);
27881 });
27882 return this;
27883 },
27886 applyIfToFields : function(o){
27887 this.items.each(function(f){
27888 Ext.applyIf(f, o);
27889 });
27890 return this;
27892 });
27894 Ext.BasicForm = Ext.form.BasicForm;
27896 Ext.FormPanel = Ext.extend(Ext.Panel, {
27901 buttonAlign:'center',
27904 minButtonWidth:75,
27907 labelAlign:'left',
27910 monitorValid : false,
27913 monitorPoll : 200,
27916 layout: 'form',
27918 initComponent :function(){
27919 this.form = this.createForm();
27921 Ext.FormPanel.superclass.initComponent.call(this);
27923 this.addEvents(
27925 'clientvalidation'
27926 );
27928 this.relayEvents(this.form, ['beforeaction', 'actionfailed', 'actioncomplete']);
27929 },
27931 createForm: function(){
27932 delete this.initialConfig.listeners;
27933 return new Ext.form.BasicForm(null, this.initialConfig);
27934 },
27936 initFields : function(){
27937 var f = this.form;
27938 var formPanel = this;
27939 var fn = function(c){
27940 if(c.doLayout && c != formPanel){
27941 Ext.applyIf(c, {
27942 labelAlign: c.ownerCt.labelAlign,
27943 labelWidth: c.ownerCt.labelWidth,
27944 itemCls: c.ownerCt.itemCls
27945 });
27946 if(c.items){
27947 c.items.each(fn);
27949 }else if(c.isFormField){
27950 f.add(c);
27953 this.items.each(fn);
27954 },
27956 getLayoutTarget : function(){
27957 return this.form.el;
27958 },
27961 getForm : function(){
27962 return this.form;
27963 },
27965 onRender : function(ct, position){
27966 this.initFields();
27968 Ext.FormPanel.superclass.onRender.call(this, ct, position);
27969 var o = {
27970 tag: 'form',
27971 method : this.method || 'POST',
27972 id : this.formId || Ext.id()
27973 };
27974 if(this.fileUpload) {
27975 o.enctype = 'multipart/form-data';
27977 this.form.initEl(this.body.createChild(o));
27978 },
27980 beforeDestroy: function(){
27981 Ext.FormPanel.superclass.beforeDestroy.call(this);
27982 Ext.destroy(this.form);
27983 },
27985 initEvents : function(){
27986 Ext.FormPanel.superclass.initEvents.call(this);
27987 this.items.on('remove', this.onRemove, this);
27988 this.items.on('add', this.onAdd, this);
27989 if(this.monitorValid){ this.startMonitoring();
27991 },
27993 onAdd : function(ct, c) {
27994 if (c.isFormField) {
27995 this.form.add(c);
27997 },
27999 onRemove : function(c) {
28000 if (c.isFormField) {
28001 Ext.destroy(c.container.up('.x-form-item'));
28002 this.form.remove(c);
28004 },
28007 startMonitoring : function(){
28008 if(!this.bound){
28009 this.bound = true;
28010 Ext.TaskMgr.start({
28011 run : this.bindHandler,
28012 interval : this.monitorPoll || 200,
28013 scope: this
28014 });
28016 },
28019 stopMonitoring : function(){
28020 this.bound = false;
28021 },
28024 load : function(){
28025 this.form.load.apply(this.form, arguments);
28026 },
28028 onDisable : function(){
28029 Ext.FormPanel.superclass.onDisable.call(this);
28030 if(this.form){
28031 this.form.items.each(function(){
28032 this.disable();
28033 });
28035 },
28037 onEnable : function(){
28038 Ext.FormPanel.superclass.onEnable.call(this);
28039 if(this.form){
28040 this.form.items.each(function(){
28041 this.enable();
28042 });
28044 },
28046 bindHandler : function(){
28047 if(!this.bound){
28048 return false; }
28049 var valid = true;
28050 this.form.items.each(function(f){
28051 if(!f.isValid(true)){
28052 valid = false;
28053 return false;
28055 });
28056 if(this.buttons){
28057 for(var i = 0, len = this.buttons.length; i < len; i++){
28058 var btn = this.buttons[i];
28059 if(btn.formBind === true && btn.disabled === valid){
28060 btn.setDisabled(!valid);
28064 this.fireEvent('clientvalidation', this, valid);
28066 });
28067 Ext.reg('form', Ext.FormPanel);
28069 Ext.form.FormPanel = Ext.FormPanel;
28073 Ext.form.FieldSet = Ext.extend(Ext.Panel, {
28079 baseCls:'x-fieldset',
28081 layout: 'form',
28084 onRender : function(ct, position){
28085 if(!this.el){
28086 this.el = document.createElement('fieldset');
28087 this.el.id = this.id;
28088 if (this.title || this.header || this.checkboxToggle) {
28089 this.el.appendChild(document.createElement('legend')).className = 'x-fieldset-header';
28093 Ext.form.FieldSet.superclass.onRender.call(this, ct, position);
28095 if(this.checkboxToggle){
28096 var o = typeof this.checkboxToggle == 'object' ?
28097 this.checkboxToggle :
28098 {tag: 'input', type: 'checkbox', name: this.checkboxName || this.id+'-checkbox'};
28099 this.checkbox = this.header.insertFirst(o);
28100 this.checkbox.dom.checked = !this.collapsed;
28101 this.checkbox.on('click', this.onCheckClick, this);
28103 },
28106 onCollapse : function(doAnim, animArg){
28107 if(this.checkbox){
28108 this.checkbox.dom.checked = false;
28110 this.afterCollapse();
28112 },
28115 onExpand : function(doAnim, animArg){
28116 if(this.checkbox){
28117 this.checkbox.dom.checked = true;
28119 this.afterExpand();
28120 },
28123 onCheckClick : function(){
28124 this[this.checkbox.dom.checked ? 'expand' : 'collapse']();
28164 });
28165 Ext.reg('fieldset', Ext.form.FieldSet);
28170 Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
28172 enableFormat : true,
28174 enableFontSize : true,
28176 enableColors : true,
28178 enableAlignments : true,
28180 enableLists : true,
28182 enableSourceEdit : true,
28184 enableLinks : true,
28186 enableFont : true,
28188 createLinkText : 'Please enter the URL for the link:',
28190 defaultLinkValue : 'http:/'+'/',
28192 fontFamilies : [
28193 'Arial',
28194 'Courier New',
28195 'Tahoma',
28196 'Times New Roman',
28197 'Verdana'
28198 ],
28199 defaultFont: 'tahoma',
28202 validationEvent : false,
28203 deferHeight: true,
28204 initialized : false,
28205 activated : false,
28206 sourceEditMode : false,
28207 onFocus : Ext.emptyFn,
28208 iframePad:3,
28209 hideMode:'offsets',
28210 defaultAutoCreate : {
28211 tag: "textarea",
28212 style:"width:500px;height:300px;",
28213 autocomplete: "off"
28214 },
28217 initComponent : function(){
28218 this.addEvents(
28220 'initialize',
28222 'activate',
28224 'beforesync',
28226 'beforepush',
28228 'sync',
28230 'push',
28232 'editmodechange'
28234 },
28237 createFontOptions : function(){
28238 var buf = [], fs = this.fontFamilies, ff, lc;
28239 for(var i = 0, len = fs.length; i< len; i++){
28240 ff = fs[i];
28241 lc = ff.toLowerCase();
28242 buf.push(
28243 '<option value="',lc,'" style="font-family:',ff,';"',
28244 (this.defaultFont == lc ? ' selected="true">' : '>'),
28245 ff,
28246 '</option>'
28247 );
28249 return buf.join('');
28250 },
28253 createToolbar : function(editor){
28255 var tipsEnabled = Ext.QuickTips && Ext.QuickTips.isEnabled();
28257 function btn(id, toggle, handler){
28258 return {
28259 itemId : id,
28260 cls : 'x-btn-icon x-edit-'+id,
28261 enableToggle:toggle !== false,
28262 scope: editor,
28263 handler:handler||editor.relayBtnCmd,
28264 clickEvent:'mousedown',
28265 tooltip: tipsEnabled ? editor.buttonTips[id] || undefined : undefined,
28266 tabIndex:-1
28267 };
28271 var tb = new Ext.Toolbar({
28272 renderTo:this.wrap.dom.firstChild
28273 });
28276 tb.el.on('click', function(e){
28277 e.preventDefault();
28278 });
28280 if(this.enableFont && !Ext.isSafari){
28281 this.fontSelect = tb.el.createChild({
28282 tag:'select',
28283 cls:'x-font-select',
28284 html: this.createFontOptions()
28285 });
28286 this.fontSelect.on('change', function(){
28287 var font = this.fontSelect.dom.value;
28288 this.relayCmd('fontname', font);
28289 this.deferFocus();
28290 }, this);
28291 tb.add(
28292 this.fontSelect.dom,
28293 '-'
28294 );
28295 };
28297 if(this.enableFormat){
28298 tb.add(
28299 btn('bold'),
28300 btn('italic'),
28301 btn('underline')
28302 );
28303 };
28305 if(this.enableFontSize){
28306 tb.add(
28307 '-',
28308 btn('increasefontsize', false, this.adjustFont),
28309 btn('decreasefontsize', false, this.adjustFont)
28310 );
28311 };
28313 if(this.enableColors){
28314 tb.add(
28315 '-', {
28316 itemId:'forecolor',
28317 cls:'x-btn-icon x-edit-forecolor',
28318 clickEvent:'mousedown',
28319 tooltip: tipsEnabled ? editor.buttonTips['forecolor'] || undefined : undefined,
28320 tabIndex:-1,
28321 menu : new Ext.menu.ColorMenu({
28322 allowReselect: true,
28323 focus: Ext.emptyFn,
28324 value:'000000',
28325 plain:true,
28326 selectHandler: function(cp, color){
28327 this.execCmd('forecolor', Ext.isSafari || Ext.isIE ? '#'+color : color);
28328 this.deferFocus();
28329 },
28330 scope: this,
28331 clickEvent:'mousedown'
28332 })
28333 }, {
28334 itemId:'backcolor',
28335 cls:'x-btn-icon x-edit-backcolor',
28336 clickEvent:'mousedown',
28337 tooltip: tipsEnabled ? editor.buttonTips['backcolor'] || undefined : undefined,
28338 tabIndex:-1,
28339 menu : new Ext.menu.ColorMenu({
28340 focus: Ext.emptyFn,
28341 value:'FFFFFF',
28342 plain:true,
28343 allowReselect: true,
28344 selectHandler: function(cp, color){
28345 if(Ext.isGecko){
28346 this.execCmd('useCSS', false);
28347 this.execCmd('hilitecolor', color);
28348 this.execCmd('useCSS', true);
28349 this.deferFocus();
28350 }else{
28351 this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isSafari || Ext.isIE ? '#'+color : color);
28352 this.deferFocus();
28354 },
28355 scope:this,
28356 clickEvent:'mousedown'
28357 })
28359 );
28360 };
28362 if(this.enableAlignments){
28363 tb.add(
28364 '-',
28365 btn('justifyleft'),
28366 btn('justifycenter'),
28367 btn('justifyright')
28368 );
28369 };
28371 if(!Ext.isSafari){
28372 if(this.enableLinks){
28373 tb.add(
28374 '-',
28375 btn('createlink', false, this.createLink)
28376 );
28377 };
28379 if(this.enableLists){
28380 tb.add(
28381 '-',
28382 btn('insertorderedlist'),
28383 btn('insertunorderedlist')
28384 );
28386 if(this.enableSourceEdit){
28387 tb.add(
28388 '-',
28389 btn('sourceedit', true, function(btn){
28390 this.toggleSourceEdit(btn.pressed);
28391 })
28392 );
28396 this.tb = tb;
28397 },
28400 getDocMarkup : function(){
28401 return '<html><head><style type="text/css">body{border:0;margin:0;padding:3px;height:98%;cursor:text;}</style></head><body></body></html>';
28402 },
28405 getEditorBody : function(){
28406 return this.doc.body || this.doc.documentElement;
28407 },
28410 onRender : function(ct, position){
28411 Ext.form.HtmlEditor.superclass.onRender.call(this, ct, position);
28412 this.el.dom.style.border = '0 none';
28413 this.el.dom.setAttribute('tabIndex', -1);
28414 this.el.addClass('x-hidden');
28415 if(Ext.isIE){
28416 this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;')
28418 this.wrap = this.el.wrap({
28419 cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
28420 });
28422 this.createToolbar(this);
28424 this.tb.items.each(function(item){
28425 if(item.itemId != 'sourceedit'){
28426 item.disable();
28428 });
28430 var iframe = document.createElement('iframe');
28431 iframe.name = Ext.id();
28432 iframe.frameBorder = 'no';
28434 iframe.src=(Ext.SSL_SECURE_URL || "javascript:false");
28436 this.wrap.dom.appendChild(iframe);
28438 this.iframe = iframe;
28440 if(Ext.isIE){
28441 iframe.contentWindow.document.designMode = 'on';
28442 this.doc = iframe.contentWindow.document;
28443 this.win = iframe.contentWindow;
28444 } else {
28445 this.doc = (iframe.contentDocument || window.frames[iframe.name].document);
28446 this.win = window.frames[iframe.name];
28447 this.doc.designMode = 'on';
28449 this.doc.open();
28450 this.doc.write(this.getDocMarkup())
28451 this.doc.close();
28453 var task = {
28454 run : function(){
28455 if(this.doc.body || this.doc.readyState == 'complete'){
28456 Ext.TaskMgr.stop(task);
28457 this.doc.designMode="on";
28458 this.initEditor.defer(10, this);
28460 },
28461 interval : 10,
28462 duration:10000,
28463 scope: this
28464 };
28465 Ext.TaskMgr.start(task);
28467 if(!this.width){
28468 this.setSize(this.el.getSize());
28470 },
28473 onResize : function(w, h){
28474 Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments);
28475 if(this.el && this.iframe){
28476 if(typeof w == 'number'){
28477 var aw = w - this.wrap.getFrameWidth('lr');
28478 this.el.setWidth(this.adjustWidth('textarea', aw));
28479 this.iframe.style.width = aw + 'px';
28481 if(typeof h == 'number'){
28482 var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight();
28483 this.el.setHeight(this.adjustWidth('textarea', ah));
28484 this.iframe.style.height = ah + 'px';
28485 if(this.doc){
28486 this.getEditorBody().style.height = (ah - (this.iframePad*2)) + 'px';
28490 },
28493 toggleSourceEdit : function(sourceEditMode){
28494 if(sourceEditMode === undefined){
28495 sourceEditMode = !this.sourceEditMode;
28497 this.sourceEditMode = sourceEditMode === true;
28498 var btn = this.tb.items.get('sourceedit');
28499 if(btn.pressed !== this.sourceEditMode){
28500 btn.toggle(this.sourceEditMode);
28501 return;
28503 if(this.sourceEditMode){
28504 this.tb.items.each(function(item){
28505 if(item.itemId != 'sourceedit'){
28506 item.disable();
28508 });
28509 this.syncValue();
28510 this.iframe.className = 'x-hidden';
28511 this.el.removeClass('x-hidden');
28512 this.el.dom.removeAttribute('tabIndex');
28513 this.el.focus();
28514 }else{
28515 if(this.initialized){
28516 this.tb.items.each(function(item){
28517 item.enable();
28518 });
28520 this.pushValue();
28521 this.iframe.className = '';
28522 this.el.addClass('x-hidden');
28523 this.el.dom.setAttribute('tabIndex', -1);
28524 this.deferFocus();
28526 var lastSize = this.lastSize;
28527 if(lastSize){
28528 delete this.lastSize;
28529 this.setSize(lastSize);
28531 this.fireEvent('editmodechange', this, this.sourceEditMode);
28532 },
28535 createLink : function(){
28536 var url = prompt(this.createLinkText, this.defaultLinkValue);
28537 if(url && url != 'http:/'+'/'){
28538 this.relayCmd('createlink', url);
28540 },
28543 adjustSize : Ext.BoxComponent.prototype.adjustSize,
28546 getResizeEl : function(){
28547 return this.wrap;
28548 },
28551 getPositionEl : function(){
28552 return this.wrap;
28553 },
28556 initEvents : function(){
28557 this.originalValue = this.getValue();
28558 },
28561 markInvalid : Ext.emptyFn,
28564 clearInvalid : Ext.emptyFn,
28567 setValue : function(v){
28568 Ext.form.HtmlEditor.superclass.setValue.call(this, v);
28569 this.pushValue();
28570 },
28573 cleanHtml : function(html){
28574 html = String(html);
28575 if(html.length > 5){
28576 if(Ext.isSafari){
28577 html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');
28580 if(html == '&nbsp;'){
28581 html = '';
28583 return html;
28584 },
28587 syncValue : function(){
28588 if(this.initialized){
28589 var bd = this.getEditorBody();
28590 var html = bd.innerHTML;
28591 if(Ext.isSafari){
28592 var bs = bd.getAttribute('style');
28593 var m = bs.match(/text-align:(.*?);/i);
28594 if(m && m[1]){
28595 html = '<div style="'+m[0]+'">' + html + '</div>';
28598 html = this.cleanHtml(html);
28599 if(this.fireEvent('beforesync', this, html) !== false){
28600 this.el.dom.value = html;
28601 this.fireEvent('sync', this, html);
28604 },
28607 pushValue : function(){
28608 if(this.initialized){
28609 var v = this.el.dom.value;
28610 if(!this.activated && v.length < 1){
28611 v = '&nbsp;';
28613 if(this.fireEvent('beforepush', this, v) !== false){
28614 this.getEditorBody().innerHTML = v;
28615 this.fireEvent('push', this, v);
28618 },
28621 deferFocus : function(){
28622 this.focus.defer(10, this);
28623 },
28626 focus : function(){
28627 if(this.win && !this.sourceEditMode){
28628 this.win.focus();
28629 }else{
28630 this.el.focus();
28632 },
28635 initEditor : function(){
28636 var dbody = this.getEditorBody();
28637 var ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat');
28638 ss['background-attachment'] = 'fixed';
28639 dbody.bgProperties = 'fixed';
28640 Ext.DomHelper.applyStyles(dbody, ss);
28641 Ext.EventManager.on(this.doc, {
28642 'mousedown': this.onEditorEvent,
28643 'dblclick': this.onEditorEvent,
28644 'click': this.onEditorEvent,
28645 'keyup': this.onEditorEvent,
28646 buffer:100,
28647 scope: this
28648 });
28649 if(Ext.isGecko){
28650 Ext.EventManager.on(this.doc, 'keypress', this.applyCommand, this);
28652 if(Ext.isIE || Ext.isSafari || Ext.isOpera){
28653 Ext.EventManager.on(this.doc, 'keydown', this.fixKeys, this);
28655 this.initialized = true;
28657 this.fireEvent('initialize', this);
28658 this.pushValue();
28659 },
28662 onDestroy : function(){
28663 if(this.rendered){
28664 this.tb.items.each(function(item){
28665 if(item.menu){
28666 item.menu.removeAll();
28667 if(item.menu.el){
28668 item.menu.el.destroy();
28671 item.destroy();
28672 });
28673 this.wrap.dom.innerHTML = '';
28674 this.wrap.remove();
28676 },
28679 onFirstFocus : function(){
28680 this.activated = true;
28681 this.tb.items.each(function(item){
28682 item.enable();
28683 });
28684 if(Ext.isGecko){
28685 this.win.focus();
28686 var s = this.win.getSelection();
28687 if(!s.focusNode || s.focusNode.nodeType != 3){
28688 var r = s.getRangeAt(0);
28689 r.selectNodeContents(this.getEditorBody());
28690 r.collapse(true);
28691 this.deferFocus();
28693 try{
28694 this.execCmd('useCSS', true);
28695 this.execCmd('styleWithCSS', false);
28696 }catch(e){}
28698 this.fireEvent('activate', this);
28699 },
28702 adjustFont: function(btn){
28703 var adjust = btn.itemId == 'increasefontsize' ? 1 : -1;
28705 var v = parseInt(this.doc.queryCommandValue('FontSize') || 2, 10);
28706 if(Ext.isSafari3 || Ext.isAir){
28709 if(v <= 10){
28710 v = 1 + adjust;
28711 }else if(v <= 13){
28712 v = 2 + adjust;
28713 }else if(v <= 16){
28714 v = 3 + adjust;
28715 }else if(v <= 18){
28716 v = 4 + adjust;
28717 }else if(v <= 24){
28718 v = 5 + adjust;
28719 }else {
28720 v = 6 + adjust;
28722 v = v.constrain(1, 6);
28723 }else{
28724 if(Ext.isSafari){
28725 adjust *= 2;
28727 v = Math.max(1, v+adjust) + (Ext.isSafari ? 'px' : 0);
28729 this.execCmd('FontSize', v);
28730 },
28733 onEditorEvent : function(e){
28734 this.updateToolbar();
28735 },
28739 updateToolbar: function(){
28741 if(!this.activated){
28742 this.onFirstFocus();
28743 return;
28746 var btns = this.tb.items.map, doc = this.doc;
28748 if(this.enableFont && !Ext.isSafari){
28749 var name = (this.doc.queryCommandValue('FontName')||this.defaultFont).toLowerCase();
28750 if(name != this.fontSelect.dom.value){
28751 this.fontSelect.dom.value = name;
28754 if(this.enableFormat){
28755 btns.bold.toggle(doc.queryCommandState('bold'));
28756 btns.italic.toggle(doc.queryCommandState('italic'));
28757 btns.underline.toggle(doc.queryCommandState('underline'));
28759 if(this.enableAlignments){
28760 btns.justifyleft.toggle(doc.queryCommandState('justifyleft'));
28761 btns.justifycenter.toggle(doc.queryCommandState('justifycenter'));
28762 btns.justifyright.toggle(doc.queryCommandState('justifyright'));
28764 if(!Ext.isSafari && this.enableLists){
28765 btns.insertorderedlist.toggle(doc.queryCommandState('insertorderedlist'));
28766 btns.insertunorderedlist.toggle(doc.queryCommandState('insertunorderedlist'));
28769 Ext.menu.MenuMgr.hideAll();
28771 this.syncValue();
28772 },
28775 relayBtnCmd : function(btn){
28776 this.relayCmd(btn.itemId);
28777 },
28780 relayCmd : function(cmd, value){
28781 this.win.focus();
28782 this.execCmd(cmd, value);
28783 this.updateToolbar();
28784 this.deferFocus();
28785 },
28788 execCmd : function(cmd, value){
28789 this.doc.execCommand(cmd, false, value === undefined ? null : value);
28790 this.syncValue();
28791 },
28794 applyCommand : function(e){
28795 if(e.ctrlKey){
28796 var c = e.getCharCode(), cmd;
28797 if(c > 0){
28798 c = String.fromCharCode(c);
28799 switch(c){
28800 case 'b':
28801 cmd = 'bold';
28802 break;
28803 case 'i':
28804 cmd = 'italic';
28805 break;
28806 case 'u':
28807 cmd = 'underline';
28808 break;
28810 if(cmd){
28811 this.win.focus();
28812 this.execCmd(cmd);
28813 this.deferFocus();
28814 e.preventDefault();
28818 },
28821 insertAtCursor : function(text){
28822 if(!this.activated){
28823 return;
28825 if(Ext.isIE){
28826 this.win.focus();
28827 var r = this.doc.selection.createRange();
28828 if(r){
28829 r.collapse(true);
28830 r.pasteHTML(text);
28831 this.syncValue();
28832 this.deferFocus();
28834 }else if(Ext.isGecko || Ext.isOpera){
28835 this.win.focus();
28836 this.execCmd('InsertHTML', text);
28837 this.deferFocus();
28838 }else if(Ext.isSafari){
28839 this.execCmd('InsertText', text);
28840 this.deferFocus();
28842 },
28845 fixKeys : function(){
28846 if(Ext.isIE){
28847 return function(e){
28848 var k = e.getKey(), r;
28849 if(k == e.TAB){
28850 e.stopEvent();
28851 r = this.doc.selection.createRange();
28852 if(r){
28853 r.collapse(true);
28854 r.pasteHTML('&nbsp;&nbsp;&nbsp;&nbsp;');
28855 this.deferFocus();
28857 }else if(k == e.ENTER){
28858 r = this.doc.selection.createRange();
28859 if(r){
28860 var target = r.parentElement();
28861 if(!target || target.tagName.toLowerCase() != 'li'){
28862 e.stopEvent();
28863 r.pasteHTML('<br />');
28864 r.collapse(false);
28865 r.select();
28869 };
28870 }else if(Ext.isOpera){
28871 return function(e){
28872 var k = e.getKey();
28873 if(k == e.TAB){
28874 e.stopEvent();
28875 this.win.focus();
28876 this.execCmd('InsertHTML','&nbsp;&nbsp;&nbsp;&nbsp;');
28877 this.deferFocus();
28879 };
28880 }else if(Ext.isSafari){
28881 return function(e){
28882 var k = e.getKey();
28883 if(k == e.TAB){
28884 e.stopEvent();
28885 this.execCmd('InsertText','\t');
28886 this.deferFocus();
28888 };
28890 }(),
28893 getToolbar : function(){
28894 return this.tb;
28895 },
28898 buttonTips : {
28899 bold : {
28900 title: 'Bold (Ctrl+B)',
28901 text: 'Make the selected text bold.',
28902 cls: 'x-html-editor-tip'
28903 },
28904 italic : {
28905 title: 'Italic (Ctrl+I)',
28906 text: 'Make the selected text italic.',
28907 cls: 'x-html-editor-tip'
28908 },
28909 underline : {
28910 title: 'Underline (Ctrl+U)',
28911 text: 'Underline the selected text.',
28912 cls: 'x-html-editor-tip'
28913 },
28914 increasefontsize : {
28915 title: 'Grow Text',
28916 text: 'Increase the font size.',
28917 cls: 'x-html-editor-tip'
28918 },
28919 decreasefontsize : {
28920 title: 'Shrink Text',
28921 text: 'Decrease the font size.',
28922 cls: 'x-html-editor-tip'
28923 },
28924 backcolor : {
28925 title: 'Text Highlight Color',
28926 text: 'Change the background color of the selected text.',
28927 cls: 'x-html-editor-tip'
28928 },
28929 forecolor : {
28930 title: 'Font Color',
28931 text: 'Change the color of the selected text.',
28932 cls: 'x-html-editor-tip'
28933 },
28934 justifyleft : {
28935 title: 'Align Text Left',
28936 text: 'Align text to the left.',
28937 cls: 'x-html-editor-tip'
28938 },
28939 justifycenter : {
28940 title: 'Center Text',
28941 text: 'Center text in the editor.',
28942 cls: 'x-html-editor-tip'
28943 },
28944 justifyright : {
28945 title: 'Align Text Right',
28946 text: 'Align text to the right.',
28947 cls: 'x-html-editor-tip'
28948 },
28949 insertunorderedlist : {
28950 title: 'Bullet List',
28951 text: 'Start a bulleted list.',
28952 cls: 'x-html-editor-tip'
28953 },
28954 insertorderedlist : {
28955 title: 'Numbered List',
28956 text: 'Start a numbered list.',
28957 cls: 'x-html-editor-tip'
28958 },
28959 createlink : {
28960 title: 'Hyperlink',
28961 text: 'Make the selected text a hyperlink.',
28962 cls: 'x-html-editor-tip'
28963 },
28964 sourceedit : {
28965 title: 'Source Edit',
28966 text: 'Switch to source editing mode.',
28967 cls: 'x-html-editor-tip'
29005 });
29006 Ext.reg('htmleditor', Ext.form.HtmlEditor);
29008 Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {
29010 minValue : null,
29012 maxValue : null,
29014 minText : "The time in this field must be equal to or after {0}",
29016 maxText : "The time in this field must be equal to or before {0}",
29018 invalidText : "{0} is not a valid time",
29020 format : "g:i A",
29022 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",
29024 increment: 15,
29027 mode: 'local',
29029 triggerAction: 'all',
29031 typeAhead: false,
29034 initComponent : function(){
29035 Ext.form.TimeField.superclass.initComponent.call(this);
29037 if(typeof this.minValue == "string"){
29038 this.minValue = this.parseDate(this.minValue);
29040 if(typeof this.maxValue == "string"){
29041 this.maxValue = this.parseDate(this.maxValue);
29044 if(!this.store){
29045 var min = this.parseDate(this.minValue);
29046 if(!min){
29047 min = new Date().clearTime();
29049 var max = this.parseDate(this.maxValue);
29050 if(!max){
29051 max = new Date().clearTime().add('mi', (24 * 60) - 1);
29053 var times = [];
29054 while(min <= max){
29055 times.push([min.dateFormat(this.format)]);
29056 min = min.add('mi', this.increment);
29058 this.store = new Ext.data.SimpleStore({
29059 fields: ['text'],
29060 data : times
29061 });
29062 this.displayField = 'text';
29064 },
29067 getValue : function(){
29068 var v = Ext.form.TimeField.superclass.getValue.call(this);
29069 return this.formatDate(this.parseDate(v)) || '';
29070 },
29073 setValue : function(value){
29074 Ext.form.TimeField.superclass.setValue.call(this, this.formatDate(this.parseDate(value)));
29075 },
29078 validateValue : Ext.form.DateField.prototype.validateValue,
29079 parseDate : Ext.form.DateField.prototype.parseDate,
29080 formatDate : Ext.form.DateField.prototype.formatDate,
29083 beforeBlur : function(){
29084 var v = this.parseDate(this.getRawValue());
29085 if(v){
29086 this.setValue(v.dateFormat(this.format));
29094 });
29095 Ext.reg('timefield', Ext.form.TimeField);
29097 Ext.form.Label = Ext.extend(Ext.BoxComponent, {
29101 onRender : function(ct, position){
29102 if(!this.el){
29103 this.el = document.createElement('label');
29104 this.el.id = this.getId();
29105 this.el.innerHTML = this.text ? Ext.util.Format.htmlEncode(this.text) : (this.html || '');
29106 if(this.forId){
29107 this.el.setAttribute('htmlFor', this.forId);
29110 Ext.form.Label.superclass.onRender.call(this, ct, position);
29112 });
29114 Ext.reg('label', Ext.form.Label);
29116 Ext.form.Action = function(form, options){
29117 this.form = form;
29118 this.options = options || {};
29119 };
29122 Ext.form.Action.CLIENT_INVALID = 'client';
29124 Ext.form.Action.SERVER_INVALID = 'server';
29126 Ext.form.Action.CONNECT_FAILURE = 'connect';
29128 Ext.form.Action.LOAD_FAILURE = 'load';
29130 Ext.form.Action.prototype = {
29142 type : 'default',
29145 run : function(options){
29147 },
29149 success : function(response){
29151 },
29153 handleResponse : function(response){
29155 },
29157 failure : function(response){
29158 this.response = response;
29159 this.failureType = Ext.form.Action.CONNECT_FAILURE;
29160 this.form.afterAction(this, false);
29161 },
29163 processResponse : function(response){
29164 this.response = response;
29165 if(!response.responseText){
29166 return true;
29168 this.result = this.handleResponse(response);
29169 return this.result;
29170 },
29172 getUrl : function(appendParams){
29173 var url = this.options.url || this.form.url || this.form.el.dom.action;
29174 if(appendParams){
29175 var p = this.getParams();
29176 if(p){
29177 url += (url.indexOf('?') != -1 ? '&' : '?') + p;
29180 return url;
29181 },
29183 getMethod : function(){
29184 return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();
29185 },
29187 getParams : function(){
29188 var bp = this.form.baseParams;
29189 var p = this.options.params;
29190 if(p){
29191 if(typeof p == "object"){
29192 p = Ext.urlEncode(Ext.applyIf(p, bp));
29193 }else if(typeof p == 'string' && bp){
29194 p += '&' + Ext.urlEncode(bp);
29196 }else if(bp){
29197 p = Ext.urlEncode(bp);
29199 return p;
29200 },
29202 createCallback : function(opts){
29203 var opts = opts || {};
29204 return {
29205 success: this.success,
29206 failure: this.failure,
29207 scope: this,
29208 timeout: (opts.timeout*1000) || (this.form.timeout*1000),
29209 upload: this.form.fileUpload ? this.success : undefined
29210 };
29212 };
29215 Ext.form.Action.Submit = function(form, options){
29216 Ext.form.Action.Submit.superclass.constructor.call(this, form, options);
29217 };
29219 Ext.extend(Ext.form.Action.Submit, Ext.form.Action, {
29221 type : 'submit',
29223 run : function(){
29224 var o = this.options;
29225 var method = this.getMethod();
29226 var isGet = method == 'GET';
29227 if(o.clientValidation === false || this.form.isValid()){
29228 Ext.Ajax.request(Ext.apply(this.createCallback(o), {
29229 form:this.form.el.dom,
29230 url:this.getUrl(isGet),
29231 method: method,
29232 headers: o.headers,
29233 params:!isGet ? this.getParams() : null,
29234 isUpload: this.form.fileUpload
29235 }));
29236 }else if (o.clientValidation !== false){ this.failureType = Ext.form.Action.CLIENT_INVALID;
29237 this.form.afterAction(this, false);
29239 },
29241 success : function(response){
29242 var result = this.processResponse(response);
29243 if(result === true || result.success){
29244 this.form.afterAction(this, true);
29245 return;
29247 if(result.errors){
29248 this.form.markInvalid(result.errors);
29249 this.failureType = Ext.form.Action.SERVER_INVALID;
29251 this.form.afterAction(this, false);
29252 },
29254 handleResponse : function(response){
29255 if(this.form.errorReader){
29256 var rs = this.form.errorReader.read(response);
29257 var errors = [];
29258 if(rs.records){
29259 for(var i = 0, len = rs.records.length; i < len; i++) {
29260 var r = rs.records[i];
29261 errors[i] = r.data;
29264 if(errors.length < 1){
29265 errors = null;
29267 return {
29268 success : rs.success,
29269 errors : errors
29270 };
29272 return Ext.decode(response.responseText);
29274 });
29278 Ext.form.Action.Load = function(form, options){
29279 Ext.form.Action.Load.superclass.constructor.call(this, form, options);
29280 this.reader = this.form.reader;
29281 };
29283 Ext.extend(Ext.form.Action.Load, Ext.form.Action, {
29284 type : 'load',
29286 run : function(){
29287 Ext.Ajax.request(Ext.apply(
29288 this.createCallback(this.options), {
29289 method:this.getMethod(),
29290 url:this.getUrl(false),
29291 headers: this.options.headers,
29292 params:this.getParams()
29293 }));
29294 },
29296 success : function(response){
29297 var result = this.processResponse(response);
29298 if(result === true || !result.success || !result.data){
29299 this.failureType = Ext.form.Action.LOAD_FAILURE;
29300 this.form.afterAction(this, false);
29301 return;
29303 this.form.clearInvalid();
29304 this.form.setValues(result.data);
29305 this.form.afterAction(this, true);
29306 },
29308 handleResponse : function(response){
29309 if(this.form.reader){
29310 var rs = this.form.reader.read(response);
29311 var data = rs.records && rs.records[0] ? rs.records[0].data : null;
29312 return {
29313 success : rs.success,
29314 data : data
29315 };
29317 return Ext.decode(response.responseText);
29319 });
29321 Ext.form.Action.ACTION_TYPES = {
29322 'load' : Ext.form.Action.Load,
29323 'submit' : Ext.form.Action.Submit
29324 };
29327 Ext.form.VTypes = function(){
29328 var alpha = /^[a-zA-Z_]+$/;
29329 var alphanum = /^[a-zA-Z0-9_]+$/;
29330 var email = /^([\w]+)(.[\w]+)*@([\w-]+\.){1,5}([A-Za-z]){2,4}$/;
29331 var url = /(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
29333 return {
29335 'email' : function(v){
29336 return email.test(v);
29337 },
29339 'emailText' : 'This field should be an e-mail address in the format "user@domain.com"',
29341 'emailMask' : /[a-z0-9_\.\-@]/i,
29344 'url' : function(v){
29345 return url.test(v);
29346 },
29348 'urlText' : 'This field should be a URL in the format "http:/'+'/www.domain.com"',
29351 'alpha' : function(v){
29352 return alpha.test(v);
29353 },
29355 'alphaText' : 'This field should only contain letters and _',
29357 'alphaMask' : /[a-z_]/i,
29360 'alphanum' : function(v){
29361 return alphanum.test(v);
29362 },
29364 'alphanumText' : 'This field should only contain letters, numbers and _',
29366 'alphanumMask' : /[a-z0-9_]/i
29367 };
29368 }();
29370 Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
29385 ddText : "{0} selected row{1}",
29387 minColumnWidth : 25,
29389 trackMouseOver : true,
29391 enableDragDrop : false,
29393 enableColumnMove : true,
29395 enableColumnHide : true,
29397 enableHdMenu : true,
29399 stripeRows : false,
29401 autoExpandColumn : false,
29403 autoExpandMin : 50,
29405 autoExpandMax : 1000,
29407 view : null,
29409 loadMask : false,
29412 rendered : false,
29414 viewReady: false,
29416 stateEvents: ["columnmove", "columnresize", "sortchange"],
29419 initComponent : function(){
29420 Ext.grid.GridPanel.superclass.initComponent.call(this);
29424 this.autoScroll = false;
29425 this.autoWidth = false;
29427 if(Ext.isArray(this.columns)){
29428 this.colModel = new Ext.grid.ColumnModel(this.columns);
29429 delete this.columns;
29433 if(this.ds){
29434 this.store = this.ds;
29435 delete this.ds;
29437 if(this.cm){
29438 this.colModel = this.cm;
29439 delete this.cm;
29441 if(this.sm){
29442 this.selModel = this.sm;
29443 delete this.sm;
29445 this.store = Ext.StoreMgr.lookup(this.store);
29447 this.addEvents(
29450 "click",
29452 "dblclick",
29454 "contextmenu",
29456 "mousedown",
29458 "mouseup",
29460 "mouseover",
29462 "mouseout",
29464 "keypress",
29466 "keydown",
29470 "cellmousedown",
29472 "rowmousedown",
29474 "headermousedown",
29477 "cellclick",
29479 "celldblclick",
29481 "rowclick",
29483 "rowdblclick",
29485 "headerclick",
29487 "headerdblclick",
29489 "rowcontextmenu",
29491 "cellcontextmenu",
29493 "headercontextmenu",
29495 "bodyscroll",
29497 "columnresize",
29499 "columnmove",
29501 "sortchange"
29502 );
29503 },
29506 onRender : function(ct, position){
29507 Ext.grid.GridPanel.superclass.onRender.apply(this, arguments);
29509 var c = this.body;
29511 this.el.addClass('x-grid-panel');
29513 var view = this.getView();
29514 view.init(this);
29516 c.on("mousedown", this.onMouseDown, this);
29517 c.on("click", this.onClick, this);
29518 c.on("dblclick", this.onDblClick, this);
29519 c.on("contextmenu", this.onContextMenu, this);
29520 c.on("keydown", this.onKeyDown, this);
29522 this.relayEvents(c, ["mousedown","mouseup","mouseover","mouseout","keypress"]);
29524 this.getSelectionModel().init(this);
29525 this.view.render();
29526 },
29529 initEvents : function(){
29530 Ext.grid.GridPanel.superclass.initEvents.call(this);
29532 if(this.loadMask){
29533 this.loadMask = new Ext.LoadMask(this.bwrap,
29534 Ext.apply({store:this.store}, this.loadMask));
29536 },
29538 initStateEvents : function(){
29539 Ext.grid.GridPanel.superclass.initStateEvents.call(this);
29540 this.colModel.on('hiddenchange', this.saveState, this, {delay: 100});
29541 },
29543 applyState : function(state){
29544 var cm = this.colModel;
29545 var cs = state.columns;
29546 if(cs){
29547 for(var i = 0, len = cs.length; i < len; i++){
29548 var s = cs[i];
29549 var c = cm.getColumnById(s.id);
29550 if(c){
29551 c.hidden = s.hidden;
29552 c.width = s.width;
29553 var oldIndex = cm.getIndexById(s.id);
29554 if(oldIndex != i){
29555 cm.moveColumn(oldIndex, i);
29560 if(state.sort){
29561 this.store[this.store.remoteSort ? 'setDefaultSort' : 'sort'](state.sort.field, state.sort.direction);
29563 },
29565 getState : function(){
29566 var o = {columns: []};
29567 for(var i = 0, c; c = this.colModel.config[i]; i++){
29568 o.columns[i] = {
29569 id: c.id,
29570 width: c.width
29571 };
29572 if(c.hidden){
29573 o.columns[i].hidden = true;
29576 var ss = this.store.getSortState();
29577 if(ss){
29578 o.sort = ss;
29580 return o;
29581 },
29584 afterRender : function(){
29585 Ext.grid.GridPanel.superclass.afterRender.call(this);
29586 this.view.layout();
29587 this.viewReady = true;
29588 },
29591 reconfigure : function(store, colModel){
29592 if(this.loadMask){
29593 this.loadMask.destroy();
29594 this.loadMask = new Ext.LoadMask(this.bwrap,
29595 Ext.apply({store:store}, this.initialConfig.loadMask));
29597 this.view.bind(store, colModel);
29598 this.store = store;
29599 this.colModel = colModel;
29600 if(this.rendered){
29601 this.view.refresh(true);
29603 },
29606 onKeyDown : function(e){
29607 this.fireEvent("keydown", e);
29608 },
29611 onDestroy : function(){
29612 if(this.rendered){
29613 if(this.loadMask){
29614 this.loadMask.destroy();
29616 var c = this.body;
29617 c.removeAllListeners();
29618 this.view.destroy();
29619 c.update("");
29621 this.colModel.purgeListeners();
29622 Ext.grid.GridPanel.superclass.onDestroy.call(this);
29623 },
29626 processEvent : function(name, e){
29627 this.fireEvent(name, e);
29628 var t = e.getTarget();
29629 var v = this.view;
29630 var header = v.findHeaderIndex(t);
29631 if(header !== false){
29632 this.fireEvent("header" + name, this, header, e);
29633 }else{
29634 var row = v.findRowIndex(t);
29635 var cell = v.findCellIndex(t);
29636 if(row !== false){
29637 this.fireEvent("row" + name, this, row, e);
29638 if(cell !== false){
29639 this.fireEvent("cell" + name, this, row, cell, e);
29643 },
29646 onClick : function(e){
29647 this.processEvent("click", e);
29648 },
29651 onMouseDown : function(e){
29652 this.processEvent("mousedown", e);
29653 },
29656 onContextMenu : function(e, t){
29657 this.processEvent("contextmenu", e);
29658 },
29661 onDblClick : function(e){
29662 this.processEvent("dblclick", e);
29663 },
29666 walkCells : function(row, col, step, fn, scope){
29667 var cm = this.colModel, clen = cm.getColumnCount();
29668 var ds = this.store, rlen = ds.getCount(), first = true;
29669 if(step < 0){
29670 if(col < 0){
29671 row--;
29672 first = false;
29674 while(row >= 0){
29675 if(!first){
29676 col = clen-1;
29678 first = false;
29679 while(col >= 0){
29680 if(fn.call(scope || this, row, col, cm) === true){
29681 return [row, col];
29683 col--;
29685 row--;
29687 } else {
29688 if(col >= clen){
29689 row++;
29690 first = false;
29692 while(row < rlen){
29693 if(!first){
29694 col = 0;
29696 first = false;
29697 while(col < clen){
29698 if(fn.call(scope || this, row, col, cm) === true){
29699 return [row, col];
29701 col++;
29703 row++;
29706 return null;
29707 },
29710 getSelections : function(){
29711 return this.selModel.getSelections();
29712 },
29715 onResize : function(){
29716 Ext.grid.GridPanel.superclass.onResize.apply(this, arguments);
29717 if(this.viewReady){
29718 this.view.layout();
29720 },
29723 getGridEl : function(){
29724 return this.body;
29725 },
29728 stopEditing : function(){},
29731 getSelectionModel : function(){
29732 if(!this.selModel){
29733 this.selModel = new Ext.grid.RowSelectionModel(
29734 this.disableSelection ? {selectRow: Ext.emptyFn} : null);
29736 return this.selModel;
29737 },
29740 getStore : function(){
29741 return this.store;
29742 },
29745 getColumnModel : function(){
29746 return this.colModel;
29747 },
29750 getView : function(){
29751 if(!this.view){
29752 this.view = new Ext.grid.GridView(this.viewConfig);
29754 return this.view;
29755 },
29757 getDragDropText : function(){
29758 var count = this.selModel.getCount();
29759 return String.format(this.ddText, count, count == 1 ? '' : 's');
29811 });
29812 Ext.reg('grid', Ext.grid.GridPanel);
29814 Ext.grid.GridView = function(config){
29815 Ext.apply(this, config);
29816 this.addEvents(
29818 "beforerowremoved",
29820 "beforerowsinserted",
29822 "beforerefresh",
29824 "rowremoved",
29826 "rowsinserted",
29828 "rowupdated",
29830 "refresh"
29831 );
29832 Ext.grid.GridView.superclass.constructor.call(this);
29833 };
29835 Ext.extend(Ext.grid.GridView, Ext.util.Observable, {
29840 deferEmptyText: true,
29842 scrollOffset: 19,
29844 autoFill: false,
29846 forceFit: false,
29848 sortClasses : ["sort-asc", "sort-desc"],
29850 sortAscText : "Sort Ascending",
29852 sortDescText : "Sort Descending",
29854 columnsText : "Columns",
29856 borderWidth: 2,
29860 initTemplates : function(){
29861 var ts = this.templates || {};
29862 if(!ts.master){
29863 ts.master = new Ext.Template(
29864 '<div class="x-grid3" hidefocus="true">',
29865 '<div class="x-grid3-viewport">',
29866 '<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>',
29867 '<div class="x-grid3-scroller"><div class="x-grid3-body">{body}</div><a href="#" class="x-grid3-focus" tabIndex="-1"></a></div>',
29868 "</div>",
29869 '<div class="x-grid3-resize-marker">&#160;</div>',
29870 '<div class="x-grid3-resize-proxy">&#160;</div>',
29871 "</div>"
29872 );
29875 if(!ts.header){
29876 ts.header = new Ext.Template(
29877 '<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
29878 '<thead><tr class="x-grid3-hd-row">{cells}</tr></thead>',
29879 "</table>"
29880 );
29883 if(!ts.hcell){
29884 ts.hcell = new Ext.Template(
29885 '<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>' : '',
29886 '{value}<img class="x-grid3-sort-icon" src="', Ext.BLANK_IMAGE_URL, '" />',
29887 "</div></td>"
29888 );
29891 if(!ts.body){
29892 ts.body = new Ext.Template('{rows}');
29895 if(!ts.row){
29896 ts.row = new Ext.Template(
29897 '<div class="x-grid3-row {alt}" style="{tstyle}"><table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
29898 '<tbody><tr>{cells}</tr>',
29899 (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>' : ''),
29900 '</tbody></table></div>'
29901 );
29904 if(!ts.cell){
29905 ts.cell = new Ext.Template(
29906 '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}" tabIndex="0" {cellAttr}>',
29907 '<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr}>{value}</div>',
29908 "</td>"
29909 );
29912 for(var k in ts){
29913 var t = ts[k];
29914 if(t && typeof t.compile == 'function' && !t.compiled){
29915 t.disableFormats = true;
29916 t.compile();
29920 this.templates = ts;
29922 this.tdClass = 'x-grid3-cell';
29923 this.cellSelector = 'td.x-grid3-cell';
29924 this.hdCls = 'x-grid3-hd';
29925 this.rowSelector = 'div.x-grid3-row';
29926 this.colRe = new RegExp("x-grid3-td-([^\\s]+)", "");
29927 },
29929 fly : function(el){
29930 if(!this._flyweight){
29931 this._flyweight = new Ext.Element.Flyweight(document.body);
29933 this._flyweight.dom = el;
29934 return this._flyweight;
29935 },
29937 getEditorParent : function(ed){
29938 return this.scroller.dom;
29939 },
29941 initElements : function(){
29942 var E = Ext.Element;
29944 var el = this.grid.getGridEl().dom.firstChild;
29945 var cs = el.childNodes;
29947 this.el = new E(el);
29949 this.mainWrap = new E(cs[0]);
29950 this.mainHd = new E(this.mainWrap.dom.firstChild);
29952 if(this.grid.hideHeaders){
29953 this.mainHd.setDisplayed(false);
29956 this.innerHd = this.mainHd.dom.firstChild;
29957 this.scroller = new E(this.mainWrap.dom.childNodes[1]);
29958 if(this.forceFit){
29959 this.scroller.setStyle('overflow-x', 'hidden');
29961 this.mainBody = new E(this.scroller.dom.firstChild);
29963 this.focusEl = new E(this.scroller.dom.childNodes[1]);
29964 this.focusEl.swallowEvent("click", true);
29966 this.resizeMarker = new E(cs[1]);
29967 this.resizeProxy = new E(cs[2]);
29968 },
29970 getRows : function(){
29971 return this.hasRows() ? this.mainBody.dom.childNodes : [];
29972 },
29975 findCell : function(el){
29976 if(!el){
29977 return false;
29979 return this.fly(el).findParent(this.cellSelector, 3);
29980 },
29982 findCellIndex : function(el, requiredCls){
29983 var cell = this.findCell(el);
29984 if(cell && (!requiredCls || this.fly(cell).hasClass(requiredCls))){
29985 return this.getCellIndex(cell);
29987 return false;
29988 },
29990 getCellIndex : function(el){
29991 if(el){
29992 var m = el.className.match(this.colRe);
29993 if(m && m[1]){
29994 return this.cm.getIndexById(m[1]);
29997 return false;
29998 },
30000 findHeaderCell : function(el){
30001 var cell = this.findCell(el);
30002 return cell && this.fly(cell).hasClass(this.hdCls) ? cell : null;
30003 },
30005 findHeaderIndex : function(el){
30006 return this.findCellIndex(el, this.hdCls);
30007 },
30009 findRow : function(el){
30010 if(!el){
30011 return false;
30013 return this.fly(el).findParent(this.rowSelector, 10);
30014 },
30016 findRowIndex : function(el){
30017 var r = this.findRow(el);
30018 return r ? r.rowIndex : false;
30019 },
30023 getRow : function(row){
30024 return this.getRows()[row];
30025 },
30028 getCell : function(row, col){
30029 return this.getRow(row).getElementsByTagName('td')[col];
30030 },
30033 getHeaderCell : function(index){
30034 return this.mainHd.dom.getElementsByTagName('td')[index];
30035 },
30038 addRowClass : function(row, cls){
30039 var r = this.getRow(row);
30040 if(r){
30041 this.fly(r).addClass(cls);
30043 },
30045 removeRowClass : function(row, cls){
30046 var r = this.getRow(row);
30047 if(r){
30048 this.fly(r).removeClass(cls);
30050 },
30052 removeRow : function(row){
30053 Ext.removeNode(this.getRow(row));
30054 },
30056 removeRows : function(firstRow, lastRow){
30057 var bd = this.mainBody.dom;
30058 for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
30059 Ext.removeNode(bd.childNodes[firstRow]);
30061 },
30064 getScrollState : function(){
30065 var sb = this.scroller.dom;
30066 return {left: sb.scrollLeft, top: sb.scrollTop};
30067 },
30069 restoreScroll : function(state){
30070 var sb = this.scroller.dom;
30071 sb.scrollLeft = state.left;
30072 sb.scrollTop = state.top;
30073 },
30076 scrollToTop : function(){
30077 this.scroller.dom.scrollTop = 0;
30078 this.scroller.dom.scrollLeft = 0;
30079 },
30081 syncScroll : function(){
30082 this.syncHeaderScroll();
30083 var mb = this.scroller.dom;
30084 this.grid.fireEvent("bodyscroll", mb.scrollLeft, mb.scrollTop);
30085 },
30087 syncHeaderScroll : function(){
30088 var mb = this.scroller.dom;
30089 this.innerHd.scrollLeft = mb.scrollLeft;
30090 this.innerHd.scrollLeft = mb.scrollLeft; },
30092 updateSortIcon : function(col, dir){
30093 var sc = this.sortClasses;
30094 var hds = this.mainHd.select('td').removeClass(sc);
30095 hds.item(col).addClass(sc[dir == "DESC" ? 1 : 0]);
30096 },
30098 updateAllColumnWidths : function(){
30099 var tw = this.getTotalWidth();
30100 var clen = this.cm.getColumnCount();
30101 var ws = [];
30102 for(var i = 0; i < clen; i++){
30103 ws[i] = this.getColumnWidth(i);
30106 this.innerHd.firstChild.firstChild.style.width = tw;
30108 for(var i = 0; i < clen; i++){
30109 var hd = this.getHeaderCell(i);
30110 hd.style.width = ws[i];
30113 var ns = this.getRows();
30114 for(var i = 0, len = ns.length; i < len; i++){
30115 ns[i].style.width = tw;
30116 ns[i].firstChild.style.width = tw;
30117 var row = ns[i].firstChild.rows[0];
30118 for(var j = 0; j < clen; j++){
30119 row.childNodes[j].style.width = ws[j];
30123 this.onAllColumnWidthsUpdated(ws, tw);
30124 },
30126 updateColumnWidth : function(col, width){
30127 var w = this.getColumnWidth(col);
30128 var tw = this.getTotalWidth();
30130 this.innerHd.firstChild.firstChild.style.width = tw;
30131 var hd = this.getHeaderCell(col);
30132 hd.style.width = w;
30134 var ns = this.getRows();
30135 for(var i = 0, len = ns.length; i < len; i++){
30136 ns[i].style.width = tw;
30137 ns[i].firstChild.style.width = tw;
30138 ns[i].firstChild.rows[0].childNodes[col].style.width = w;
30141 this.onColumnWidthUpdated(col, w, tw);
30142 },
30144 updateColumnHidden : function(col, hidden){
30145 var tw = this.getTotalWidth();
30147 this.innerHd.firstChild.firstChild.style.width = tw;
30149 var display = hidden ? 'none' : '';
30151 var hd = this.getHeaderCell(col);
30152 hd.style.display = display;
30154 var ns = this.getRows();
30155 for(var i = 0, len = ns.length; i < len; i++){
30156 ns[i].style.width = tw;
30157 ns[i].firstChild.style.width = tw;
30158 ns[i].firstChild.rows[0].childNodes[col].style.display = display;
30161 this.onColumnHiddenUpdated(col, hidden, tw);
30163 delete this.lastViewWidth; this.layout();
30164 },
30166 doRender : function(cs, rs, ds, startRow, colCount, stripe){
30167 var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount-1;
30168 var tstyle = 'width:'+this.getTotalWidth()+';';
30169 var buf = [], cb, c, p = {}, rp = {tstyle: tstyle}, r;
30170 for(var j = 0, len = rs.length; j < len; j++){
30171 r = rs[j]; cb = [];
30172 var rowIndex = (j+startRow);
30173 for(var i = 0; i < colCount; i++){
30174 c = cs[i];
30175 p.id = c.id;
30176 p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
30177 p.attr = p.cellAttr = "";
30178 p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
30179 p.style = c.style;
30180 if(p.value == undefined || p.value === "") p.value = "&#160;";
30181 if(r.dirty && typeof r.modified[c.name] !== 'undefined'){
30182 p.css += ' x-grid3-dirty-cell';
30184 cb[cb.length] = ct.apply(p);
30186 var alt = [];
30187 if(stripe && ((rowIndex+1) % 2 == 0)){
30188 alt[0] = "x-grid3-row-alt";
30190 if(r.dirty){
30191 alt[1] = " x-grid3-dirty-row";
30193 rp.cols = colCount;
30194 if(this.getRowClass){
30195 alt[2] = this.getRowClass(r, rowIndex, rp, ds);
30197 rp.alt = alt.join(" ");
30198 rp.cells = cb.join("");
30199 buf[buf.length] = rt.apply(rp);
30201 return buf.join("");
30202 },
30204 processRows : function(startRow, skipStripe){
30205 if(this.ds.getCount() < 1){
30206 return;
30208 skipStripe = skipStripe || !this.grid.stripeRows;
30209 startRow = startRow || 0;
30210 var rows = this.getRows();
30211 var cls = ' x-grid3-row-alt ';
30212 for(var i = startRow, len = rows.length; i < len; i++){
30213 var row = rows[i];
30214 row.rowIndex = i;
30215 if(!skipStripe){
30216 var isAlt = ((i+1) % 2 == 0);
30217 var hasAlt = (' '+row.className + ' ').indexOf(cls) != -1;
30218 if(isAlt == hasAlt){
30219 continue;
30221 if(isAlt){
30222 row.className += " x-grid3-row-alt";
30223 }else{
30224 row.className = row.className.replace("x-grid3-row-alt", "");
30228 },
30230 renderUI : function(){
30232 var header = this.renderHeaders();
30233 var body = this.templates.body.apply({rows:''});
30236 var html = this.templates.master.apply({
30237 body: body,
30238 header: header
30239 });
30241 var g = this.grid;
30243 g.getGridEl().dom.innerHTML = html;
30245 this.initElements();
30248 this.mainBody.dom.innerHTML = this.renderRows();
30249 this.processRows(0, true);
30251 if(this.deferEmptyText !== true){
30252 this.applyEmptyText();
30255 Ext.fly(this.innerHd).on("click", this.handleHdDown, this);
30256 this.mainHd.on("mouseover", this.handleHdOver, this);
30257 this.mainHd.on("mouseout", this.handleHdOut, this);
30258 this.mainHd.on("mousemove", this.handleHdMove, this);
30260 this.scroller.on('scroll', this.syncScroll, this);
30261 if(g.enableColumnResize !== false){
30262 this.splitone = new Ext.grid.GridView.SplitDragZone(g, this.mainHd.dom);
30265 if(g.enableColumnMove){
30266 this.columnDrag = new Ext.grid.GridView.ColumnDragZone(g, this.innerHd);
30267 this.columnDrop = new Ext.grid.HeaderDropZone(g, this.mainHd.dom);
30270 if(g.enableHdMenu !== false){
30271 if(g.enableColumnHide !== false){
30272 this.colMenu = new Ext.menu.Menu({id:g.id + "-hcols-menu"});
30273 this.colMenu.on("beforeshow", this.beforeColMenuShow, this);
30274 this.colMenu.on("itemclick", this.handleHdMenuClick, this);
30276 this.hmenu = new Ext.menu.Menu({id: g.id + "-hctx"});
30277 this.hmenu.add(
30278 {id:"asc", text: this.sortAscText, cls: "xg-hmenu-sort-asc"},
30279 {id:"desc", text: this.sortDescText, cls: "xg-hmenu-sort-desc"}
30280 );
30281 if(g.enableColumnHide !== false){
30282 this.hmenu.add('-',
30283 {id:"columns", text: this.columnsText, menu: this.colMenu, iconCls: 'x-cols-icon'}
30284 );
30286 this.hmenu.on("itemclick", this.handleHdMenuClick, this);
30290 if(g.enableDragDrop || g.enableDrag){
30291 this.dragZone = new Ext.grid.GridDragZone(g, {
30292 ddGroup : g.ddGroup || 'GridDD'
30293 });
30296 this.updateHeaderSortState();
30298 },
30300 layout : function(){
30301 if(!this.mainBody){
30302 return; }
30303 var g = this.grid;
30304 var c = g.getGridEl();
30305 var csize = c.getSize(true);
30306 var vw = csize.width;
30308 if(vw < 20 || csize.height < 20){ return;
30311 if(g.autoHeight){
30312 this.scroller.dom.style.overflow = 'visible';
30313 }else{
30314 this.el.setSize(csize.width, csize.height);
30316 var hdHeight = this.mainHd.getHeight();
30317 var vh = csize.height - (hdHeight);
30319 this.scroller.setSize(vw, vh);
30320 if(this.innerHd){
30321 this.innerHd.style.width = (vw)+'px';
30324 if(this.forceFit){
30325 if(this.lastViewWidth != vw){
30326 this.fitColumns(false, false);
30327 this.lastViewWidth = vw;
30329 }else {
30330 this.autoExpand();
30331 this.syncHeaderScroll();
30333 this.onLayout(vw, vh);
30334 },
30336 onLayout : function(vw, vh){
30337 },
30339 onColumnWidthUpdated : function(col, w, tw){
30340 },
30342 onAllColumnWidthsUpdated : function(ws, tw){
30343 },
30345 onColumnHiddenUpdated : function(col, hidden, tw){
30346 },
30348 updateColumnText : function(col, text){
30349 },
30351 afterMove : function(colIndex){
30352 },
30355 init: function(grid){
30356 this.grid = grid;
30358 this.initTemplates();
30359 this.initData(grid.store, grid.colModel);
30360 this.initUI(grid);
30361 },
30363 getColumnId : function(index){
30364 return this.cm.getColumnId(index);
30365 },
30367 renderHeaders : function(){
30368 var cm = this.cm, ts = this.templates;
30369 var ct = ts.hcell;
30371 var cb = [], sb = [], p = {};
30373 for(var i = 0, len = cm.getColumnCount(); i < len; i++){
30374 p.id = cm.getColumnId(i);
30375 p.value = cm.getColumnHeader(i) || "";
30376 p.style = this.getColumnStyle(i, true);
30377 p.tooltip = this.getColumnTooltip(i);
30378 if(cm.config[i].align == 'right'){
30379 p.istyle = 'padding-right:16px';
30380 } else {
30381 delete p.istyle;
30383 cb[cb.length] = ct.apply(p);
30385 return ts.header.apply({cells: cb.join(""), tstyle:'width:'+this.getTotalWidth()+';'});
30386 },
30388 getColumnTooltip : function(i){
30389 var tt = this.cm.getColumnTooltip(i);
30390 if(tt){
30391 if(Ext.QuickTips.isEnabled()){
30392 return 'ext:qtip="'+tt+'"';
30393 }else{
30394 return 'title="'+tt+'"';
30397 return "";
30398 },
30400 beforeUpdate : function(){
30401 this.grid.stopEditing(true);
30402 },
30404 updateHeaders : function(){
30405 this.innerHd.firstChild.innerHTML = this.renderHeaders();
30406 },
30409 focusRow : function(row){
30410 this.focusCell(row, 0, false);
30411 },
30414 focusCell : function(row, col, hscroll){
30415 var xy = this.ensureVisible(row, col, hscroll);
30416 this.focusEl.setXY(xy);
30417 if(Ext.isGecko){
30418 this.focusEl.focus();
30419 }else{
30420 this.focusEl.focus.defer(1, this.focusEl);
30422 },
30424 ensureVisible : function(row, col, hscroll){
30425 if(typeof row != "number"){
30426 row = row.rowIndex;
30428 if(!this.ds){
30429 return;
30431 if(row < 0 || row >= this.ds.getCount()){
30432 return;
30434 col = (col !== undefined ? col : 0);
30436 var rowEl = this.getRow(row), cellEl;
30437 if(!(hscroll === false && col === 0)){
30438 while(this.cm.isHidden(col)){
30439 col++;
30441 cellEl = this.getCell(row, col);
30443 if(!rowEl){
30444 return;
30447 var c = this.scroller.dom;
30449 var ctop = 0;
30450 var p = rowEl, stop = this.el.dom;
30451 while(p && p != stop){
30452 ctop += p.offsetTop;
30453 p = p.offsetParent;
30455 ctop -= this.mainHd.dom.offsetHeight;
30457 var cbot = ctop + rowEl.offsetHeight;
30459 var ch = c.clientHeight;
30460 var stop = parseInt(c.scrollTop, 10);
30461 var sbot = stop + ch;
30463 if(ctop < stop){
30464 c.scrollTop = ctop;
30465 }else if(cbot > sbot){
30466 c.scrollTop = cbot-ch;
30469 if(hscroll !== false){
30470 var cleft = parseInt(cellEl.offsetLeft, 10);
30471 var cright = cleft + cellEl.offsetWidth;
30473 var sleft = parseInt(c.scrollLeft, 10);
30474 var sright = sleft + c.clientWidth;
30475 if(cleft < sleft){
30476 c.scrollLeft = cleft;
30477 }else if(cright > sright){
30478 c.scrollLeft = cright-c.clientWidth;
30481 return cellEl ? Ext.fly(cellEl).getXY() : [c.scrollLeft, Ext.fly(rowEl).getY()];
30482 },
30484 insertRows : function(dm, firstRow, lastRow, isUpdate){
30485 if(!isUpdate && firstRow === 0 && lastRow == dm.getCount()-1){
30486 this.refresh();
30487 }else{
30488 if(!isUpdate){
30489 this.fireEvent("beforerowsinserted", this, firstRow, lastRow);
30491 var html = this.renderRows(firstRow, lastRow);
30492 var before = this.getRow(firstRow);
30493 if(before){
30494 Ext.DomHelper.insertHtml('beforeBegin', before, html);
30495 }else{
30496 Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html);
30498 if(!isUpdate){
30499 this.fireEvent("rowsinserted", this, firstRow, lastRow);
30500 this.processRows(firstRow);
30503 },
30505 deleteRows : function(dm, firstRow, lastRow){
30506 if(dm.getRowCount()<1){
30507 this.refresh();
30508 }else{
30509 this.fireEvent("beforerowsdeleted", this, firstRow, lastRow);
30511 this.removeRows(firstRow, lastRow);
30513 this.processRows(firstRow);
30514 this.fireEvent("rowsdeleted", this, firstRow, lastRow);
30516 },
30518 getColumnStyle : function(col, isHeader){
30519 var style = !isHeader ? (this.cm.config[col].css || '') : '';
30520 style += 'width:'+this.getColumnWidth(col)+';';
30521 if(this.cm.isHidden(col)){
30522 style += 'display:none;';
30524 var align = this.cm.config[col].align;
30525 if(align){
30526 style += 'text-align:'+align+';';
30528 return style;
30529 },
30531 getColumnWidth : function(col){
30532 var w = this.cm.getColumnWidth(col);
30533 if(typeof w == 'number'){
30534 return (Ext.isBorderBox ? w : (w-this.borderWidth > 0 ? w-this.borderWidth:0)) + 'px';
30536 return w;
30537 },
30539 getTotalWidth : function(){
30540 return this.cm.getTotalWidth()+'px';
30541 },
30543 fitColumns : function(preventRefresh, onlyExpand, omitColumn){
30544 var cm = this.cm, leftOver, dist, i;
30545 var tw = cm.getTotalWidth(false);
30546 var aw = this.grid.getGridEl().getWidth(true)-this.scrollOffset;
30548 if(aw < 20){ return;
30550 var extra = aw - tw;
30552 if(extra === 0){
30553 return false;
30556 var vc = cm.getColumnCount(true);
30557 var ac = vc-(typeof omitColumn == 'number' ? 1 : 0);
30558 if(ac === 0){
30559 ac = 1;
30560 omitColumn = undefined;
30562 var colCount = cm.getColumnCount();
30563 var cols = [];
30564 var extraCol = 0;
30565 var width = 0;
30566 var w;
30567 for (i = 0; i < colCount; i++){
30568 if(!cm.isHidden(i) && !cm.isFixed(i) && i !== omitColumn){
30569 w = cm.getColumnWidth(i);
30570 cols.push(i);
30571 extraCol = i;
30572 cols.push(w);
30573 width += w;
30576 var frac = (aw - cm.getTotalWidth())/width;
30577 while (cols.length){
30578 w = cols.pop();
30579 i = cols.pop();
30580 cm.setColumnWidth(i, Math.max(this.grid.minColumnWidth, Math.floor(w + w*frac)), true);
30583 if((tw = cm.getTotalWidth(false)) > aw){
30584 var adjustCol = ac != vc ? omitColumn : extraCol;
30585 cm.setColumnWidth(adjustCol, Math.max(1,
30586 cm.getColumnWidth(adjustCol)- (tw-aw)), true);
30589 if(preventRefresh !== true){
30590 this.updateAllColumnWidths();
30594 return true;
30595 },
30597 autoExpand : function(preventUpdate){
30598 var g = this.grid, cm = this.cm;
30599 if(!this.userResized && g.autoExpandColumn){
30600 var tw = cm.getTotalWidth(false);
30601 var aw = this.grid.getGridEl().getWidth(true)-this.scrollOffset;
30602 if(tw != aw){
30603 var ci = cm.getIndexById(g.autoExpandColumn);
30604 var currentWidth = cm.getColumnWidth(ci);
30605 var cw = Math.min(Math.max(((aw-tw)+currentWidth), g.autoExpandMin), g.autoExpandMax);
30606 if(cw != currentWidth){
30607 cm.setColumnWidth(ci, cw, true);
30608 if(preventUpdate !== true){
30609 this.updateColumnWidth(ci, cw);
30614 },
30616 getColumnData : function(){
30617 var cs = [], cm = this.cm, colCount = cm.getColumnCount();
30618 for(var i = 0; i < colCount; i++){
30619 var name = cm.getDataIndex(i);
30620 cs[i] = {
30621 name : (typeof name == 'undefined' ? this.ds.fields.get(i).name : name),
30622 renderer : cm.getRenderer(i),
30623 id : cm.getColumnId(i),
30624 style : this.getColumnStyle(i)
30625 };
30627 return cs;
30628 },
30630 renderRows : function(startRow, endRow){
30631 var g = this.grid, cm = g.colModel, ds = g.store, stripe = g.stripeRows;
30632 var colCount = cm.getColumnCount();
30634 if(ds.getCount() < 1){
30635 return "";
30638 var cs = this.getColumnData();
30640 startRow = startRow || 0;
30641 endRow = typeof endRow == "undefined"? ds.getCount()-1 : endRow;
30643 var rs = ds.getRange(startRow, endRow);
30645 return this.doRender(cs, rs, ds, startRow, colCount, stripe);
30646 },
30648 renderBody : function(){
30649 var markup = this.renderRows();
30650 return this.templates.body.apply({rows: markup});
30651 },
30653 refreshRow : function(record){
30654 var ds = this.ds, index;
30655 if(typeof record == 'number'){
30656 index = record;
30657 record = ds.getAt(index);
30658 }else{
30659 index = ds.indexOf(record);
30661 var cls = [];
30662 this.insertRows(ds, index, index, true);
30663 this.getRow(index).rowIndex = index;
30664 this.onRemove(ds, record, index+1, true);
30665 this.fireEvent("rowupdated", this, index, record);
30666 },
30669 refresh : function(headersToo){
30670 this.fireEvent("beforerefresh", this);
30671 this.grid.stopEditing(true);
30673 var result = this.renderBody();
30674 this.mainBody.update(result);
30676 if(headersToo === true){
30677 this.updateHeaders();
30678 this.updateHeaderSortState();
30680 this.processRows(0, true);
30681 this.layout();
30682 this.applyEmptyText();
30683 this.fireEvent("refresh", this);
30684 },
30686 applyEmptyText : function(){
30687 if(this.emptyText && !this.hasRows()){
30688 this.mainBody.update('<div class="x-grid-empty">' + this.emptyText + '</div>');
30690 },
30692 updateHeaderSortState : function(){
30693 var state = this.ds.getSortState();
30694 if(!state){
30695 return;
30697 if(!this.sortState || (this.sortState.field != state.field || this.sortState.direction != state.direction)){
30698 this.grid.fireEvent('sortchange', this.grid, state);
30700 this.sortState = state;
30701 var sortColumn = this.cm.findColumnIndex(state.field);
30702 if(sortColumn != -1){
30703 var sortDir = state.direction;
30704 this.updateSortIcon(sortColumn, sortDir);
30706 },
30708 destroy : function(){
30709 if(this.colMenu){
30710 this.colMenu.removeAll();
30711 Ext.menu.MenuMgr.unregister(this.colMenu);
30712 this.colMenu.getEl().remove();
30713 delete this.colMenu;
30715 if(this.hmenu){
30716 this.hmenu.removeAll();
30717 Ext.menu.MenuMgr.unregister(this.hmenu);
30718 this.hmenu.getEl().remove();
30719 delete this.hmenu;
30721 if(this.grid.enableColumnMove){
30722 var dds = Ext.dd.DDM.ids['gridHeader' + this.grid.getGridEl().id];
30723 if(dds){
30724 for(var dd in dds){
30725 if(!dds[dd].config.isTarget && dds[dd].dragElId){
30726 var elid = dds[dd].dragElId;
30727 dds[dd].unreg();
30728 Ext.get(elid).remove();
30729 } else if(dds[dd].config.isTarget){
30730 dds[dd].proxyTop.remove();
30731 dds[dd].proxyBottom.remove();
30732 dds[dd].unreg();
30734 if(Ext.dd.DDM.locationCache[dd]){
30735 delete Ext.dd.DDM.locationCache[dd];
30738 delete Ext.dd.DDM.ids['gridHeader' + this.grid.getGridEl().id];
30742 Ext.destroy(this.resizeMarker, this.resizeProxy);
30744 if(this.dragZone){
30745 this.dragZone.unreg();
30748 this.initData(null, null);
30749 Ext.EventManager.removeResizeListener(this.onWindowResize, this);
30750 },
30752 onDenyColumnHide : function(){
30754 },
30756 render : function(){
30758 var cm = this.cm;
30759 var colCount = cm.getColumnCount();
30761 if(this.autoFill){
30762 this.fitColumns(true, true);
30763 }else if(this.forceFit){
30764 this.fitColumns(true, false);
30765 }else if(this.grid.autoExpandColumn){
30766 this.autoExpand(true);
30769 this.renderUI();
30770 },
30773 initData : function(ds, cm){
30774 if(this.ds){
30775 this.ds.un("load", this.onLoad, this);
30776 this.ds.un("datachanged", this.onDataChange, this);
30777 this.ds.un("add", this.onAdd, this);
30778 this.ds.un("remove", this.onRemove, this);
30779 this.ds.un("update", this.onUpdate, this);
30780 this.ds.un("clear", this.onClear, this);
30782 if(ds){
30783 ds.on("load", this.onLoad, this);
30784 ds.on("datachanged", this.onDataChange, this);
30785 ds.on("add", this.onAdd, this);
30786 ds.on("remove", this.onRemove, this);
30787 ds.on("update", this.onUpdate, this);
30788 ds.on("clear", this.onClear, this);
30790 this.ds = ds;
30792 if(this.cm){
30793 this.cm.un("configchange", this.onColConfigChange, this);
30794 this.cm.un("widthchange", this.onColWidthChange, this);
30795 this.cm.un("headerchange", this.onHeaderChange, this);
30796 this.cm.un("hiddenchange", this.onHiddenChange, this);
30797 this.cm.un("columnmoved", this.onColumnMove, this);
30798 this.cm.un("columnlockchange", this.onColumnLock, this);
30800 if(cm){
30801 cm.on("configchange", this.onColConfigChange, this);
30802 cm.on("widthchange", this.onColWidthChange, this);
30803 cm.on("headerchange", this.onHeaderChange, this);
30804 cm.on("hiddenchange", this.onHiddenChange, this);
30805 cm.on("columnmoved", this.onColumnMove, this);
30806 cm.on("columnlockchange", this.onColumnLock, this);
30808 this.cm = cm;
30809 },
30811 onDataChange : function(){
30812 this.refresh();
30813 this.updateHeaderSortState();
30814 },
30816 onClear : function(){
30817 this.refresh();
30818 },
30820 onUpdate : function(ds, record){
30821 this.refreshRow(record);
30822 },
30824 onAdd : function(ds, records, index){
30825 this.insertRows(ds, index, index + (records.length-1));
30826 },
30828 onRemove : function(ds, record, index, isUpdate){
30829 if(isUpdate !== true){
30830 this.fireEvent("beforerowremoved", this, index, record);
30832 this.removeRow(index);
30833 if(isUpdate !== true){
30834 this.processRows(index);
30835 this.applyEmptyText();
30836 this.fireEvent("rowremoved", this, index, record);
30838 },
30840 onLoad : function(){
30841 this.scrollToTop();
30842 },
30844 onColWidthChange : function(cm, col, width){
30845 this.updateColumnWidth(col, width);
30846 },
30848 onHeaderChange : function(cm, col, text){
30849 this.updateHeaders();
30850 },
30852 onHiddenChange : function(cm, col, hidden){
30853 this.updateColumnHidden(col, hidden);
30854 },
30856 onColumnMove : function(cm, oldIndex, newIndex){
30857 this.indexMap = null;
30858 var s = this.getScrollState();
30859 this.refresh(true);
30860 this.restoreScroll(s);
30861 this.afterMove(newIndex);
30862 },
30864 onColConfigChange : function(){
30865 delete this.lastViewWidth;
30866 this.indexMap = null;
30867 this.refresh(true);
30868 },
30871 initUI : function(grid){
30872 grid.on("headerclick", this.onHeaderClick, this);
30874 if(grid.trackMouseOver){
30875 grid.on("mouseover", this.onRowOver, this);
30876 grid.on("mouseout", this.onRowOut, this);
30878 },
30880 initEvents : function(){
30882 },
30884 onHeaderClick : function(g, index){
30885 if(this.headersDisabled || !this.cm.isSortable(index)){
30886 return;
30888 g.stopEditing(true);
30889 g.store.sort(this.cm.getDataIndex(index));
30890 },
30892 onRowOver : function(e, t){
30893 var row;
30894 if((row = this.findRowIndex(t)) !== false){
30895 this.addRowClass(row, "x-grid3-row-over");
30897 },
30899 onRowOut : function(e, t){
30900 var row;
30901 if((row = this.findRowIndex(t)) !== false && row !== this.findRowIndex(e.getRelatedTarget())){
30902 this.removeRowClass(row, "x-grid3-row-over");
30904 },
30906 handleWheel : function(e){
30907 e.stopPropagation();
30908 },
30910 onRowSelect : function(row){
30911 this.addRowClass(row, "x-grid3-row-selected");
30912 },
30914 onRowDeselect : function(row){
30915 this.removeRowClass(row, "x-grid3-row-selected");
30916 },
30918 onCellSelect : function(row, col){
30919 var cell = this.getCell(row, col);
30920 if(cell){
30921 this.fly(cell).addClass("x-grid3-cell-selected");
30923 },
30925 onCellDeselect : function(row, col){
30926 var cell = this.getCell(row, col);
30927 if(cell){
30928 this.fly(cell).removeClass("x-grid3-cell-selected");
30930 },
30932 onColumnSplitterMoved : function(i, w){
30933 this.userResized = true;
30934 var cm = this.grid.colModel;
30935 cm.setColumnWidth(i, w, true);
30937 if(this.forceFit){
30938 this.fitColumns(true, false, i);
30939 this.updateAllColumnWidths();
30940 }else{
30941 this.updateColumnWidth(i, w);
30944 this.grid.fireEvent("columnresize", i, w);
30945 },
30947 handleHdMenuClick : function(item){
30948 var index = this.hdCtxIndex;
30949 var cm = this.cm, ds = this.ds;
30950 switch(item.id){
30951 case "asc":
30952 ds.sort(cm.getDataIndex(index), "ASC");
30953 break;
30954 case "desc":
30955 ds.sort(cm.getDataIndex(index), "DESC");
30956 break;
30957 default:
30958 index = cm.getIndexById(item.id.substr(4));
30959 if(index != -1){
30960 if(item.checked && cm.getColumnsBy(this.isHideableColumn, this).length <= 1){
30961 this.onDenyColumnHide();
30962 return false;
30964 cm.setHidden(index, item.checked);
30967 return true;
30968 },
30970 isHideableColumn : function(c){
30971 return !c.hidden && !c.fixed;
30972 },
30974 beforeColMenuShow : function(){
30975 var cm = this.cm, colCount = cm.getColumnCount();
30976 this.colMenu.removeAll();
30977 for(var i = 0; i < colCount; i++){
30978 if(cm.config[i].fixed !== true && cm.config[i].hideable !== false){
30979 this.colMenu.add(new Ext.menu.CheckItem({
30980 id: "col-"+cm.getColumnId(i),
30981 text: cm.getColumnHeader(i),
30982 checked: !cm.isHidden(i),
30983 hideOnClick:false,
30984 disabled: cm.config[i].hideable === false
30985 }));
30988 },
30990 handleHdDown : function(e, t){
30991 if(Ext.fly(t).hasClass('x-grid3-hd-btn')){
30992 e.stopEvent();
30993 var hd = this.findHeaderCell(t);
30994 Ext.fly(hd).addClass('x-grid3-hd-menu-open');
30995 var index = this.getCellIndex(hd);
30996 this.hdCtxIndex = index;
30997 var ms = this.hmenu.items, cm = this.cm;
30998 ms.get("asc").setDisabled(!cm.isSortable(index));
30999 ms.get("desc").setDisabled(!cm.isSortable(index));
31000 this.hmenu.on("hide", function(){
31001 Ext.fly(hd).removeClass('x-grid3-hd-menu-open');
31002 }, this, {single:true});
31003 this.hmenu.show(t, "tl-bl?");
31005 },
31007 handleHdOver : function(e, t){
31008 var hd = this.findHeaderCell(t);
31009 if(hd && !this.headersDisabled){
31010 this.activeHd = hd;
31011 this.activeHdIndex = this.getCellIndex(hd);
31012 var fly = this.fly(hd);
31013 this.activeHdRegion = fly.getRegion();
31014 if(!this.cm.isMenuDisabled(this.activeHdIndex)){
31015 fly.addClass("x-grid3-hd-over");
31016 this.activeHdBtn = fly.child('.x-grid3-hd-btn');
31017 if(this.activeHdBtn){
31018 this.activeHdBtn.dom.style.height = (hd.firstChild.offsetHeight-1)+'px';
31022 },
31024 handleHdMove : function(e, t){
31025 if(this.activeHd && !this.headersDisabled){
31026 var hw = this.splitHandleWidth || 5;
31027 var r = this.activeHdRegion;
31028 var x = e.getPageX();
31029 var ss = this.activeHd.style;
31030 if(x - r.left <= hw && this.cm.isResizable(this.activeHdIndex-1)){
31031 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)){
31032 ss.cursor = Ext.isAir ? 'move' : Ext.isSafari ? 'w-resize' : 'col-resize';
31033 }else{
31034 ss.cursor = '';
31037 },
31039 handleHdOut : function(e, t){
31040 var hd = this.findHeaderCell(t);
31041 if(hd && (!Ext.isIE || !e.within(hd, true))){
31042 this.activeHd = null;
31043 this.fly(hd).removeClass("x-grid3-hd-over");
31044 hd.style.cursor = '';
31046 },
31048 hasRows : function(){
31049 var fc = this.mainBody.dom.firstChild;
31050 return fc && fc.className != 'x-grid-empty';
31051 },
31053 bind : function(d, c){
31054 this.initData(d, c);
31056 });
31059 Ext.grid.GridView.SplitDragZone = function(grid, hd){
31060 this.grid = grid;
31061 this.view = grid.getView();
31062 this.marker = this.view.resizeMarker;
31063 this.proxy = this.view.resizeProxy;
31064 Ext.grid.GridView.SplitDragZone.superclass.constructor.call(this, hd,
31065 "gridSplitters" + this.grid.getGridEl().id, {
31066 dragElId : Ext.id(this.proxy.dom), resizeFrame:false
31067 });
31068 this.scroll = false;
31069 this.hw = this.view.splitHandleWidth || 5;
31070 };
31071 Ext.extend(Ext.grid.GridView.SplitDragZone, Ext.dd.DDProxy, {
31073 b4StartDrag : function(x, y){
31074 this.view.headersDisabled = true;
31075 var h = this.view.mainWrap.getHeight();
31076 this.marker.setHeight(h);
31077 this.marker.show();
31078 this.marker.alignTo(this.view.getHeaderCell(this.cellIndex), 'tl-tl', [-2, 0]);
31079 this.proxy.setHeight(h);
31080 var w = this.cm.getColumnWidth(this.cellIndex);
31081 var minw = Math.max(w-this.grid.minColumnWidth, 0);
31082 this.resetConstraints();
31083 this.setXConstraint(minw, 1000);
31084 this.setYConstraint(0, 0);
31085 this.minX = x - minw;
31086 this.maxX = x + 1000;
31087 this.startPos = x;
31088 Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
31089 },
31092 handleMouseDown : function(e){
31093 var t = this.view.findHeaderCell(e.getTarget());
31094 if(t){
31095 var xy = this.view.fly(t).getXY(), x = xy[0], y = xy[1];
31096 var exy = e.getXY(), ex = exy[0], ey = exy[1];
31097 var w = t.offsetWidth, adjust = false;
31098 if((ex - x) <= this.hw){
31099 adjust = -1;
31100 }else if((x+w) - ex <= this.hw){
31101 adjust = 0;
31103 if(adjust !== false){
31104 this.cm = this.grid.colModel;
31105 var ci = this.view.getCellIndex(t);
31106 if(adjust == -1){
31107 if (ci + adjust < 0) {
31108 return;
31110 while(this.cm.isHidden(ci+adjust)){
31111 --adjust;
31112 if(ci+adjust < 0){
31113 return;
31117 this.cellIndex = ci+adjust;
31118 this.split = t.dom;
31119 if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
31120 Ext.grid.GridView.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
31122 }else if(this.view.columnDrag){
31123 this.view.columnDrag.callHandleMouseDown(e);
31126 },
31128 endDrag : function(e){
31129 this.marker.hide();
31130 var v = this.view;
31131 var endX = Math.max(this.minX, e.getPageX());
31132 var diff = endX - this.startPos;
31133 v.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
31134 setTimeout(function(){
31135 v.headersDisabled = false;
31136 }, 50);
31137 },
31139 autoOffset : function(){
31140 this.setDelta(0,0);
31142 });
31145 Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
31147 hideGroupedColumn:false,
31149 showGroupName:true,
31151 startCollapsed:false,
31153 enableGrouping:true,
31155 enableGroupingMenu:true,
31157 enableNoGroups:true,
31159 emptyGroupText : '(None)',
31161 ignoreAdd: false,
31163 groupTextTpl : '{text}',
31168 gidSeed : 1000,
31171 initTemplates : function(){
31172 Ext.grid.GroupingView.superclass.initTemplates.call(this);
31173 this.state = {};
31175 var sm = this.grid.getSelectionModel();
31176 sm.on(sm.selectRow ? 'beforerowselect' : 'beforecellselect',
31177 this.onBeforeRowSelect, this);
31179 if(!this.startGroup){
31180 this.startGroup = new Ext.XTemplate(
31181 '<div id="{groupId}" class="x-grid-group {cls}">',
31182 '<div id="{groupId}-hd" class="x-grid-group-hd" style="{style}"><div>', this.groupTextTpl ,'</div></div>',
31183 '<div id="{groupId}-bd" class="x-grid-group-body">'
31184 );
31186 this.startGroup.compile();
31187 this.endGroup = '</div></div>';
31188 },
31191 findGroup : function(el){
31192 return Ext.fly(el).up('.x-grid-group', this.mainBody.dom);
31193 },
31196 getGroups : function(){
31197 return this.hasRows() ? this.mainBody.dom.childNodes : [];
31198 },
31201 onAdd : function(){
31202 if(this.enableGrouping && !this.ignoreAdd){
31203 var ss = this.getScrollState();
31204 this.refresh();
31205 this.restoreScroll(ss);
31206 }else if(!this.enableGrouping){
31207 Ext.grid.GroupingView.superclass.onAdd.apply(this, arguments);
31209 },
31212 onRemove : function(ds, record, index, isUpdate){
31213 Ext.grid.GroupingView.superclass.onRemove.apply(this, arguments);
31214 var g = document.getElementById(record._groupId);
31215 if(g && g.childNodes[1].childNodes.length < 1){
31216 Ext.removeNode(g);
31218 this.applyEmptyText();
31219 },
31222 refreshRow : function(record){
31223 if(this.ds.getCount()==1){
31224 this.refresh();
31225 }else{
31226 this.isUpdating = true;
31227 Ext.grid.GroupingView.superclass.refreshRow.apply(this, arguments);
31228 this.isUpdating = false;
31230 },
31233 beforeMenuShow : function(){
31234 var field = this.getGroupField();
31235 var g = this.hmenu.items.get('groupBy');
31236 if(g){
31237 g.setDisabled(this.cm.config[this.hdCtxIndex].groupable === false);
31239 var s = this.hmenu.items.get('showGroups');
31240 if(s){
31241 s.setDisabled(!field && this.cm.config[this.hdCtxIndex].groupable === false);
31242 s.setChecked(!!field, true);
31244 },
31247 renderUI : function(){
31248 Ext.grid.GroupingView.superclass.renderUI.call(this);
31249 this.mainBody.on('mousedown', this.interceptMouse, this);
31251 if(this.enableGroupingMenu && this.hmenu){
31252 this.hmenu.add('-',{
31253 id:'groupBy',
31254 text: this.groupByText,
31255 handler: this.onGroupByClick,
31256 scope: this,
31257 iconCls:'x-group-by-icon'
31258 });
31259 if(this.enableNoGroups){
31260 this.hmenu.add({
31261 id:'showGroups',
31262 text: this.showGroupsText,
31263 checked: true,
31264 checkHandler: this.onShowGroupsClick,
31265 scope: this
31266 });
31268 this.hmenu.on('beforeshow', this.beforeMenuShow, this);
31270 },
31273 onGroupByClick : function(){
31274 this.grid.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex));
31275 this.beforeMenuShow();
31276 },
31279 onShowGroupsClick : function(mi, checked){
31280 if(checked){
31281 this.onGroupByClick();
31282 }else{
31283 this.grid.store.clearGrouping();
31285 },
31288 toggleGroup : function(group, expanded){
31289 this.grid.stopEditing(true);
31290 group = Ext.getDom(group);
31291 var gel = Ext.fly(group);
31292 expanded = expanded !== undefined ?
31293 expanded : gel.hasClass('x-grid-group-collapsed');
31295 this.state[gel.dom.id] = expanded;
31296 gel[expanded ? 'removeClass' : 'addClass']('x-grid-group-collapsed');
31297 },
31300 toggleAllGroups : function(expanded){
31301 var groups = this.getGroups();
31302 for(var i = 0, len = groups.length; i < len; i++){
31303 this.toggleGroup(groups[i], expanded);
31305 },
31308 expandAllGroups : function(){
31309 this.toggleAllGroups(true);
31310 },
31313 collapseAllGroups : function(){
31314 this.toggleAllGroups(false);
31315 },
31318 interceptMouse : function(e){
31319 var hd = e.getTarget('.x-grid-group-hd', this.mainBody);
31320 if(hd){
31321 e.stopEvent();
31322 this.toggleGroup(hd.parentNode);
31324 },
31327 getGroup : function(v, r, groupRenderer, rowIndex, colIndex, ds){
31328 var g = groupRenderer ? groupRenderer(v, {}, r, rowIndex, colIndex, ds) : String(v);
31329 if(g === ''){
31330 g = this.cm.config[colIndex].emptyGroupText || this.emptyGroupText;
31332 return g;
31333 },
31336 getGroupField : function(){
31337 return this.grid.store.getGroupState();
31338 },
31341 renderRows : function(){
31342 var groupField = this.getGroupField();
31343 var eg = !!groupField;
31345 if(this.hideGroupedColumn) {
31346 var colIndex = this.cm.findColumnIndex(groupField);
31347 if(!eg && this.lastGroupField !== undefined) {
31348 this.mainBody.update('');
31349 this.cm.setHidden(this.cm.findColumnIndex(this.lastGroupField), false);
31350 delete this.lastGroupField;
31351 }else if (eg && this.lastGroupField === undefined) {
31352 this.lastGroupField = groupField;
31353 this.cm.setHidden(colIndex, true);
31354 }else if (eg && this.lastGroupField !== undefined && groupField !== this.lastGroupField) {
31355 this.mainBody.update('');
31356 var oldIndex = this.cm.findColumnIndex(this.lastGroupField);
31357 this.cm.setHidden(oldIndex, false);
31358 this.lastGroupField = groupField;
31359 this.cm.setHidden(colIndex, true);
31362 return Ext.grid.GroupingView.superclass.renderRows.apply(
31363 this, arguments);
31364 },
31367 doRender : function(cs, rs, ds, startRow, colCount, stripe){
31368 if(rs.length < 1){
31369 return '';
31371 var groupField = this.getGroupField();
31372 var colIndex = this.cm.findColumnIndex(groupField);
31374 this.enableGrouping = !!groupField;
31376 if(!this.enableGrouping || this.isUpdating){
31377 return Ext.grid.GroupingView.superclass.doRender.apply(
31378 this, arguments);
31380 var gstyle = 'width:'+this.getTotalWidth()+';';
31382 var gidPrefix = this.grid.getGridEl().id;
31383 var cfg = this.cm.config[colIndex];
31384 var groupRenderer = cfg.groupRenderer || cfg.renderer;
31385 var prefix = this.showGroupName ?
31386 (cfg.groupName || cfg.header)+': ' : '';
31388 var groups = [], curGroup, i, len, gid;
31389 for(i = 0, len = rs.length; i < len; i++){
31390 var rowIndex = startRow + i;
31391 var r = rs[i],
31392 gvalue = r.data[groupField],
31393 g = this.getGroup(gvalue, r, groupRenderer, rowIndex, colIndex, ds);
31394 if(!curGroup || curGroup.group != g){
31395 gid = gidPrefix + '-gp-' + groupField + '-' + Ext.util.Format.htmlEncode(g);
31398 var isCollapsed = typeof this.state[gid] !== 'undefined' ? !this.state[gid] : this.startCollapsed;
31399 var gcls = isCollapsed ? 'x-grid-group-collapsed' : '';
31400 curGroup = {
31401 group: g,
31402 gvalue: gvalue,
31403 text: prefix + g,
31404 groupId: gid,
31405 startRow: rowIndex,
31406 rs: [r],
31407 cls: gcls,
31408 style: gstyle
31409 };
31410 groups.push(curGroup);
31411 }else{
31412 curGroup.rs.push(r);
31414 r._groupId = gid;
31417 var buf = [];
31418 for(i = 0, len = groups.length; i < len; i++){
31419 var g = groups[i];
31420 this.doGroupStart(buf, g, cs, ds, colCount);
31421 buf[buf.length] = Ext.grid.GroupingView.superclass.doRender.call(
31422 this, cs, g.rs, ds, g.startRow, colCount, stripe);
31424 this.doGroupEnd(buf, g, cs, ds, colCount);
31426 return buf.join('');
31427 },
31430 getGroupId : function(value){
31431 var gidPrefix = this.grid.getGridEl().id;
31432 var groupField = this.getGroupField();
31433 var colIndex = this.cm.findColumnIndex(groupField);
31434 var cfg = this.cm.config[colIndex];
31435 var groupRenderer = cfg.groupRenderer || cfg.renderer;
31436 var gtext = this.getGroup(value, {data:{}}, groupRenderer, 0, colIndex, this.ds);
31437 return gidPrefix + '-gp-' + groupField + '-' + Ext.util.Format.htmlEncode(value);
31438 },
31441 doGroupStart : function(buf, g, cs, ds, colCount){
31442 buf[buf.length] = this.startGroup.apply(g);
31443 },
31446 doGroupEnd : function(buf, g, cs, ds, colCount){
31447 buf[buf.length] = this.endGroup;
31448 },
31451 getRows : function(){
31452 if(!this.enableGrouping){
31453 return Ext.grid.GroupingView.superclass.getRows.call(this);
31455 var r = [];
31456 var g, gs = this.getGroups();
31457 for(var i = 0, len = gs.length; i < len; i++){
31458 g = gs[i].childNodes[1].childNodes;
31459 for(var j = 0, jlen = g.length; j < jlen; j++){
31460 r[r.length] = g[j];
31463 return r;
31464 },
31467 updateGroupWidths : function(){
31468 if(!this.enableGrouping || !this.hasRows()){
31469 return;
31471 var tw = Math.max(this.cm.getTotalWidth(), this.el.dom.offsetWidth-this.scrollOffset) +'px';
31472 var gs = this.getGroups();
31473 for(var i = 0, len = gs.length; i < len; i++){
31474 gs[i].firstChild.style.width = tw;
31476 },
31479 onColumnWidthUpdated : function(col, w, tw){
31480 this.updateGroupWidths();
31481 },
31484 onAllColumnWidthsUpdated : function(ws, tw){
31485 this.updateGroupWidths();
31486 },
31489 onColumnHiddenUpdated : function(col, hidden, tw){
31490 this.updateGroupWidths();
31491 },
31494 onLayout : function(){
31495 this.updateGroupWidths();
31496 },
31499 onBeforeRowSelect : function(sm, rowIndex){
31500 if(!this.enableGrouping){
31501 return;
31503 var row = this.getRow(rowIndex);
31504 if(row && !row.offsetParent){
31505 var g = this.findGroup(row);
31506 this.toggleGroup(g, true);
31508 },
31511 groupByText: 'Group By This Field',
31513 showGroupsText: 'Show in Groups'
31514 });
31516 Ext.grid.GroupingView.GROUP_ID = 1000;
31519 Ext.grid.HeaderDragZone = function(grid, hd, hd2){
31520 this.grid = grid;
31521 this.view = grid.getView();
31522 this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
31523 Ext.grid.HeaderDragZone.superclass.constructor.call(this, hd);
31524 if(hd2){
31525 this.setHandleElId(Ext.id(hd));
31526 this.setOuterHandleElId(Ext.id(hd2));
31528 this.scroll = false;
31529 };
31530 Ext.extend(Ext.grid.HeaderDragZone, Ext.dd.DragZone, {
31531 maxDragWidth: 120,
31532 getDragData : function(e){
31533 var t = Ext.lib.Event.getTarget(e);
31534 var h = this.view.findHeaderCell(t);
31535 if(h){
31536 return {ddel: h.firstChild, header:h};
31538 return false;
31539 },
31541 onInitDrag : function(e){
31542 this.view.headersDisabled = true;
31543 var clone = this.dragData.ddel.cloneNode(true);
31544 clone.id = Ext.id();
31545 clone.style.width = Math.min(this.dragData.header.offsetWidth,this.maxDragWidth) + "px";
31546 this.proxy.update(clone);
31547 return true;
31548 },
31550 afterValidDrop : function(){
31551 var v = this.view;
31552 setTimeout(function(){
31553 v.headersDisabled = false;
31554 }, 50);
31555 },
31557 afterInvalidDrop : function(){
31558 var v = this.view;
31559 setTimeout(function(){
31560 v.headersDisabled = false;
31561 }, 50);
31563 });
31567 Ext.grid.HeaderDropZone = function(grid, hd, hd2){
31568 this.grid = grid;
31569 this.view = grid.getView();
31571 this.proxyTop = Ext.DomHelper.append(document.body, {
31572 cls:"col-move-top", html:"&#160;"
31573 }, true);
31574 this.proxyBottom = Ext.DomHelper.append(document.body, {
31575 cls:"col-move-bottom", html:"&#160;"
31576 }, true);
31577 this.proxyTop.hide = this.proxyBottom.hide = function(){
31578 this.setLeftTop(-100,-100);
31579 this.setStyle("visibility", "hidden");
31580 };
31581 this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
31584 Ext.grid.HeaderDropZone.superclass.constructor.call(this, grid.getGridEl().dom);
31585 };
31586 Ext.extend(Ext.grid.HeaderDropZone, Ext.dd.DropZone, {
31587 proxyOffsets : [-4, -9],
31588 fly: Ext.Element.fly,
31590 getTargetFromEvent : function(e){
31591 var t = Ext.lib.Event.getTarget(e);
31592 var cindex = this.view.findCellIndex(t);
31593 if(cindex !== false){
31594 return this.view.getHeaderCell(cindex);
31596 },
31598 nextVisible : function(h){
31599 var v = this.view, cm = this.grid.colModel;
31600 h = h.nextSibling;
31601 while(h){
31602 if(!cm.isHidden(v.getCellIndex(h))){
31603 return h;
31605 h = h.nextSibling;
31607 return null;
31608 },
31610 prevVisible : function(h){
31611 var v = this.view, cm = this.grid.colModel;
31612 h = h.prevSibling;
31613 while(h){
31614 if(!cm.isHidden(v.getCellIndex(h))){
31615 return h;
31617 h = h.prevSibling;
31619 return null;
31620 },
31622 positionIndicator : function(h, n, e){
31623 var x = Ext.lib.Event.getPageX(e);
31624 var r = Ext.lib.Dom.getRegion(n.firstChild);
31625 var px, pt, py = r.top + this.proxyOffsets[1];
31626 if((r.right - x) <= (r.right-r.left)/2){
31627 px = r.right+this.view.borderWidth;
31628 pt = "after";
31629 }else{
31630 px = r.left;
31631 pt = "before";
31633 var oldIndex = this.view.getCellIndex(h);
31634 var newIndex = this.view.getCellIndex(n);
31636 if(this.grid.colModel.isFixed(newIndex)){
31637 return false;
31640 var locked = this.grid.colModel.isLocked(newIndex);
31642 if(pt == "after"){
31643 newIndex++;
31645 if(oldIndex < newIndex){
31646 newIndex--;
31648 if(oldIndex == newIndex && (locked == this.grid.colModel.isLocked(oldIndex))){
31649 return false;
31651 px += this.proxyOffsets[0];
31652 this.proxyTop.setLeftTop(px, py);
31653 this.proxyTop.show();
31654 if(!this.bottomOffset){
31655 this.bottomOffset = this.view.mainHd.getHeight();
31657 this.proxyBottom.setLeftTop(px, py+this.proxyTop.dom.offsetHeight+this.bottomOffset);
31658 this.proxyBottom.show();
31659 return pt;
31660 },
31662 onNodeEnter : function(n, dd, e, data){
31663 if(data.header != n){
31664 this.positionIndicator(data.header, n, e);
31666 },
31668 onNodeOver : function(n, dd, e, data){
31669 var result = false;
31670 if(data.header != n){
31671 result = this.positionIndicator(data.header, n, e);
31673 if(!result){
31674 this.proxyTop.hide();
31675 this.proxyBottom.hide();
31677 return result ? this.dropAllowed : this.dropNotAllowed;
31678 },
31680 onNodeOut : function(n, dd, e, data){
31681 this.proxyTop.hide();
31682 this.proxyBottom.hide();
31683 },
31685 onNodeDrop : function(n, dd, e, data){
31686 var h = data.header;
31687 if(h != n){
31688 var cm = this.grid.colModel;
31689 var x = Ext.lib.Event.getPageX(e);
31690 var r = Ext.lib.Dom.getRegion(n.firstChild);
31691 var pt = (r.right - x) <= ((r.right-r.left)/2) ? "after" : "before";
31692 var oldIndex = this.view.getCellIndex(h);
31693 var newIndex = this.view.getCellIndex(n);
31694 var locked = cm.isLocked(newIndex);
31695 if(pt == "after"){
31696 newIndex++;
31698 if(oldIndex < newIndex){
31699 newIndex--;
31701 if(oldIndex == newIndex && (locked == cm.isLocked(oldIndex))){
31702 return false;
31704 cm.setLocked(oldIndex, locked, true);
31705 cm.moveColumn(oldIndex, newIndex);
31706 this.grid.fireEvent("columnmove", oldIndex, newIndex);
31707 return true;
31709 return false;
31711 });
31714 Ext.grid.GridView.ColumnDragZone = function(grid, hd){
31715 Ext.grid.GridView.ColumnDragZone.superclass.constructor.call(this, grid, hd, null);
31716 this.proxy.el.addClass('x-grid3-col-dd');
31717 };
31719 Ext.extend(Ext.grid.GridView.ColumnDragZone, Ext.grid.HeaderDragZone, {
31720 handleMouseDown : function(e){
31722 },
31724 callHandleMouseDown : function(e){
31725 Ext.grid.GridView.ColumnDragZone.superclass.handleMouseDown.call(this, e);
31727 });
31728 Ext.grid.SplitDragZone = function(grid, hd, hd2){
31729 this.grid = grid;
31730 this.view = grid.getView();
31731 this.proxy = this.view.resizeProxy;
31732 Ext.grid.SplitDragZone.superclass.constructor.call(this, hd,
31733 "gridSplitters" + this.grid.getGridEl().id, {
31734 dragElId : Ext.id(this.proxy.dom), resizeFrame:false
31735 });
31736 this.setHandleElId(Ext.id(hd));
31737 this.setOuterHandleElId(Ext.id(hd2));
31738 this.scroll = false;
31739 };
31740 Ext.extend(Ext.grid.SplitDragZone, Ext.dd.DDProxy, {
31741 fly: Ext.Element.fly,
31743 b4StartDrag : function(x, y){
31744 this.view.headersDisabled = true;
31745 this.proxy.setHeight(this.view.mainWrap.getHeight());
31746 var w = this.cm.getColumnWidth(this.cellIndex);
31747 var minw = Math.max(w-this.grid.minColumnWidth, 0);
31748 this.resetConstraints();
31749 this.setXConstraint(minw, 1000);
31750 this.setYConstraint(0, 0);
31751 this.minX = x - minw;
31752 this.maxX = x + 1000;
31753 this.startPos = x;
31754 Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
31755 },
31758 handleMouseDown : function(e){
31759 ev = Ext.EventObject.setEvent(e);
31760 var t = this.fly(ev.getTarget());
31761 if(t.hasClass("x-grid-split")){
31762 this.cellIndex = this.view.getCellIndex(t.dom);
31763 this.split = t.dom;
31764 this.cm = this.grid.colModel;
31765 if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
31766 Ext.grid.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
31769 },
31771 endDrag : function(e){
31772 this.view.headersDisabled = false;
31773 var endX = Math.max(this.minX, Ext.lib.Event.getPageX(e));
31774 var diff = endX - this.startPos;
31775 this.view.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
31776 },
31778 autoOffset : function(){
31779 this.setDelta(0,0);
31781 });
31782 Ext.grid.GridDragZone = function(grid, config){
31783 this.view = grid.getView();
31784 Ext.grid.GridDragZone.superclass.constructor.call(this, this.view.mainBody.dom, config);
31785 if(this.view.lockedBody){
31786 this.setHandleElId(Ext.id(this.view.mainBody.dom));
31787 this.setOuterHandleElId(Ext.id(this.view.lockedBody.dom));
31789 this.scroll = false;
31790 this.grid = grid;
31791 this.ddel = document.createElement('div');
31792 this.ddel.className = 'x-grid-dd-wrap';
31793 };
31795 Ext.extend(Ext.grid.GridDragZone, Ext.dd.DragZone, {
31796 ddGroup : "GridDD",
31798 getDragData : function(e){
31799 var t = Ext.lib.Event.getTarget(e);
31800 var rowIndex = this.view.findRowIndex(t);
31801 if(rowIndex !== false){
31802 var sm = this.grid.selModel;
31803 if(!sm.isSelected(rowIndex) || e.hasModifier()){
31804 sm.handleMouseDown(this.grid, rowIndex, e);
31806 return {grid: this.grid, ddel: this.ddel, rowIndex: rowIndex, selections:sm.getSelections()};
31808 return false;
31809 },
31811 onInitDrag : function(e){
31812 var data = this.dragData;
31813 this.ddel.innerHTML = this.grid.getDragDropText();
31814 this.proxy.update(this.ddel);
31815 },
31817 afterRepair : function(){
31818 this.dragging = false;
31819 },
31821 getRepairXY : function(e, data){
31822 return false;
31823 },
31825 onEndDrag : function(data, e){
31826 },
31828 onValidDrop : function(dd, e, id){
31829 this.hideProxy();
31830 },
31832 beforeInvalidDrop : function(e, id){
31835 });
31838 Ext.grid.ColumnModel = function(config){
31840 this.defaultWidth = 100;
31843 this.defaultSortable = false;
31846 if(config.columns){
31847 Ext.apply(this, config);
31848 this.setConfig(config.columns, true);
31849 }else{
31850 this.setConfig(config, true);
31852 this.addEvents(
31854 "widthchange",
31856 "headerchange",
31858 "hiddenchange",
31860 "columnmoved",
31861 "columnlockchange",
31863 "configchange"
31864 );
31865 Ext.grid.ColumnModel.superclass.constructor.call(this);
31866 };
31867 Ext.extend(Ext.grid.ColumnModel, Ext.util.Observable, {
31885 getColumnId : function(index){
31886 return this.config[index].id;
31887 },
31890 setConfig : function(config, initial){
31891 if(!initial){ delete this.totalWidth;
31892 for(var i = 0, len = this.config.length; i < len; i++){
31893 var c = this.config[i];
31894 if(c.editor){
31895 c.editor.destroy();
31899 this.config = config;
31900 this.lookup = {};
31901 for(var i = 0, len = config.length; i < len; i++){
31902 var c = config[i];
31903 if(typeof c.renderer == "string"){
31904 c.renderer = Ext.util.Format[c.renderer];
31906 if(typeof c.id == "undefined"){
31907 c.id = i;
31909 if(c.editor && c.editor.isFormField){
31910 c.editor = new Ext.grid.GridEditor(c.editor);
31912 this.lookup[c.id] = c;
31914 if(!initial){
31915 this.fireEvent('configchange', this);
31917 },
31920 getColumnById : function(id){
31921 return this.lookup[id];
31922 },
31925 getIndexById : function(id){
31926 for(var i = 0, len = this.config.length; i < len; i++){
31927 if(this.config[i].id == id){
31928 return i;
31931 return -1;
31932 },
31934 moveColumn : function(oldIndex, newIndex){
31935 var c = this.config[oldIndex];
31936 this.config.splice(oldIndex, 1);
31937 this.config.splice(newIndex, 0, c);
31938 this.dataMap = null;
31939 this.fireEvent("columnmoved", this, oldIndex, newIndex);
31940 },
31942 isLocked : function(colIndex){
31943 return this.config[colIndex].locked === true;
31944 },
31946 setLocked : function(colIndex, value, suppressEvent){
31947 if(this.isLocked(colIndex) == value){
31948 return;
31950 this.config[colIndex].locked = value;
31951 if(!suppressEvent){
31952 this.fireEvent("columnlockchange", this, colIndex, value);
31954 },
31956 getTotalLockedWidth : function(){
31957 var totalWidth = 0;
31958 for(var i = 0; i < this.config.length; i++){
31959 if(this.isLocked(i) && !this.isHidden(i)){
31960 this.totalWidth += this.getColumnWidth(i);
31963 return totalWidth;
31964 },
31966 getLockedCount : function(){
31967 for(var i = 0, len = this.config.length; i < len; i++){
31968 if(!this.isLocked(i)){
31969 return i;
31972 },
31975 getColumnCount : function(visibleOnly){
31976 if(visibleOnly === true){
31977 var c = 0;
31978 for(var i = 0, len = this.config.length; i < len; i++){
31979 if(!this.isHidden(i)){
31980 c++;
31983 return c;
31985 return this.config.length;
31986 },
31989 getColumnsBy : function(fn, scope){
31990 var r = [];
31991 for(var i = 0, len = this.config.length; i < len; i++){
31992 var c = this.config[i];
31993 if(fn.call(scope||this, c, i) === true){
31994 r[r.length] = c;
31997 return r;
31998 },
32001 isSortable : function(col){
32002 if(typeof this.config[col].sortable == "undefined"){
32003 return this.defaultSortable;
32005 return this.config[col].sortable;
32006 },
32009 isMenuDisabled : function(col){
32010 return !!this.config[col].menuDisabled;
32011 },
32014 getRenderer : function(col){
32015 if(!this.config[col].renderer){
32016 return Ext.grid.ColumnModel.defaultRenderer;
32018 return this.config[col].renderer;
32019 },
32022 setRenderer : function(col, fn){
32023 this.config[col].renderer = fn;
32024 },
32027 getColumnWidth : function(col){
32028 return this.config[col].width || this.defaultWidth;
32029 },
32032 setColumnWidth : function(col, width, suppressEvent){
32033 this.config[col].width = width;
32034 this.totalWidth = null;
32035 if(!suppressEvent){
32036 this.fireEvent("widthchange", this, col, width);
32038 },
32041 getTotalWidth : function(includeHidden){
32042 if(!this.totalWidth){
32043 this.totalWidth = 0;
32044 for(var i = 0, len = this.config.length; i < len; i++){
32045 if(includeHidden || !this.isHidden(i)){
32046 this.totalWidth += this.getColumnWidth(i);
32050 return this.totalWidth;
32051 },
32054 getColumnHeader : function(col){
32055 return this.config[col].header;
32056 },
32059 setColumnHeader : function(col, header){
32060 this.config[col].header = header;
32061 this.fireEvent("headerchange", this, col, header);
32062 },
32065 getColumnTooltip : function(col){
32066 return this.config[col].tooltip;
32067 },
32069 setColumnTooltip : function(col, tooltip){
32070 this.config[col].tooltip = tooltip;
32071 },
32074 getDataIndex : function(col){
32075 return this.config[col].dataIndex;
32076 },
32079 setDataIndex : function(col, dataIndex){
32080 this.config[col].dataIndex = dataIndex;
32081 },
32084 findColumnIndex : function(dataIndex){
32085 var c = this.config;
32086 for(var i = 0, len = c.length; i < len; i++){
32087 if(c[i].dataIndex == dataIndex){
32088 return i;
32091 return -1;
32092 },
32095 isCellEditable : function(colIndex, rowIndex){
32096 return (this.config[colIndex].editable || (typeof this.config[colIndex].editable == "undefined" && this.config[colIndex].editor)) ? true : false;
32097 },
32100 getCellEditor : function(colIndex, rowIndex){
32101 return this.config[colIndex].editor;
32102 },
32105 setEditable : function(col, editable){
32106 this.config[col].editable = editable;
32107 },
32111 isHidden : function(colIndex){
32112 return this.config[colIndex].hidden;
32113 },
32117 isFixed : function(colIndex){
32118 return this.config[colIndex].fixed;
32119 },
32122 isResizable : function(colIndex){
32123 return colIndex >= 0 && this.config[colIndex].resizable !== false && this.config[colIndex].fixed !== true;
32124 },
32126 setHidden : function(colIndex, hidden){
32127 var c = this.config[colIndex];
32128 if(c.hidden !== hidden){
32129 c.hidden = hidden;
32130 this.totalWidth = null;
32131 this.fireEvent("hiddenchange", this, colIndex, hidden);
32133 },
32136 setEditor : function(col, editor){
32137 this.config[col].editor = editor;
32139 });
32141 Ext.grid.ColumnModel.defaultRenderer = function(value){
32142 if(typeof value == "string" && value.length < 1){
32143 return "&#160;";
32145 return value;
32146 };
32148 Ext.grid.DefaultColumnModel = Ext.grid.ColumnModel;
32151 Ext.grid.AbstractSelectionModel = function(){
32152 this.locked = false;
32153 Ext.grid.AbstractSelectionModel.superclass.constructor.call(this);
32154 };
32156 Ext.extend(Ext.grid.AbstractSelectionModel, Ext.util.Observable, {
32158 init : function(grid){
32159 this.grid = grid;
32160 this.initEvents();
32161 },
32164 lock : function(){
32165 this.locked = true;
32166 },
32169 unlock : function(){
32170 this.locked = false;
32171 },
32174 isLocked : function(){
32175 return this.locked;
32177 });
32179 Ext.grid.RowSelectionModel = function(config){
32180 Ext.apply(this, config);
32181 this.selections = new Ext.util.MixedCollection(false, function(o){
32182 return o.id;
32183 });
32185 this.last = false;
32186 this.lastActive = false;
32188 this.addEvents(
32190 "selectionchange",
32192 "beforerowselect",
32194 "rowselect",
32196 "rowdeselect"
32197 );
32199 Ext.grid.RowSelectionModel.superclass.constructor.call(this);
32200 };
32202 Ext.extend(Ext.grid.RowSelectionModel, Ext.grid.AbstractSelectionModel, {
32204 singleSelect : false,
32207 initEvents : function(){
32209 if(!this.grid.enableDragDrop && !this.grid.enableDrag){
32210 this.grid.on("rowmousedown", this.handleMouseDown, this);
32211 }else{ this.grid.on("rowclick", function(grid, rowIndex, e) {
32212 if(e.button === 0 && !e.shiftKey && !e.ctrlKey) {
32213 this.selectRow(rowIndex, false);
32214 grid.view.focusRow(rowIndex);
32216 }, this);
32219 this.rowNav = new Ext.KeyNav(this.grid.getGridEl(), {
32220 "up" : function(e){
32221 if(!e.shiftKey){
32222 this.selectPrevious(e.shiftKey);
32223 }else if(this.last !== false && this.lastActive !== false){
32224 var last = this.last;
32225 this.selectRange(this.last, this.lastActive-1);
32226 this.grid.getView().focusRow(this.lastActive);
32227 if(last !== false){
32228 this.last = last;
32230 }else{
32231 this.selectFirstRow();
32233 },
32234 "down" : function(e){
32235 if(!e.shiftKey){
32236 this.selectNext(e.shiftKey);
32237 }else if(this.last !== false && this.lastActive !== false){
32238 var last = this.last;
32239 this.selectRange(this.last, this.lastActive+1);
32240 this.grid.getView().focusRow(this.lastActive);
32241 if(last !== false){
32242 this.last = last;
32244 }else{
32245 this.selectFirstRow();
32247 },
32248 scope: this
32249 });
32251 var view = this.grid.view;
32252 view.on("refresh", this.onRefresh, this);
32253 view.on("rowupdated", this.onRowUpdated, this);
32254 view.on("rowremoved", this.onRemove, this);
32255 },
32257 onRefresh : function(){
32258 var ds = this.grid.store, index;
32259 var s = this.getSelections();
32260 this.clearSelections(true);
32261 for(var i = 0, len = s.length; i < len; i++){
32262 var r = s[i];
32263 if((index = ds.indexOfId(r.id)) != -1){
32264 this.selectRow(index, true);
32267 if(s.length != this.selections.getCount()){
32268 this.fireEvent("selectionchange", this);
32270 },
32272 onRemove : function(v, index, r){
32273 if(this.selections.remove(r) !== false){
32274 this.fireEvent('selectionchange', this);
32276 },
32278 onRowUpdated : function(v, index, r){
32279 if(this.isSelected(r)){
32280 v.onRowSelect(index);
32282 },
32285 selectRecords : function(records, keepExisting){
32286 if(!keepExisting){
32287 this.clearSelections();
32289 var ds = this.grid.store;
32290 for(var i = 0, len = records.length; i < len; i++){
32291 this.selectRow(ds.indexOf(records[i]), true);
32293 },
32296 getCount : function(){
32297 return this.selections.length;
32298 },
32301 selectFirstRow : function(){
32302 this.selectRow(0);
32303 },
32306 selectLastRow : function(keepExisting){
32307 this.selectRow(this.grid.store.getCount() - 1, keepExisting);
32308 },
32311 selectNext : function(keepExisting){
32312 if(this.hasNext()){
32313 this.selectRow(this.last+1, keepExisting);
32314 this.grid.getView().focusRow(this.last);
32315 return true;
32317 return false;
32318 },
32321 selectPrevious : function(keepExisting){
32322 if(this.hasPrevious()){
32323 this.selectRow(this.last-1, keepExisting);
32324 this.grid.getView().focusRow(this.last);
32325 return true;
32327 return false;
32328 },
32331 hasNext : function(){
32332 return this.last !== false && (this.last+1) < this.grid.store.getCount();
32333 },
32336 hasPrevious : function(){
32337 return !!this.last;
32338 },
32342 getSelections : function(){
32343 return [].concat(this.selections.items);
32344 },
32347 getSelected : function(){
32348 return this.selections.itemAt(0);
32349 },
32352 each : function(fn, scope){
32353 var s = this.getSelections();
32354 for(var i = 0, len = s.length; i < len; i++){
32355 if(fn.call(scope || this, s[i], i) === false){
32356 return false;
32359 return true;
32360 },
32363 clearSelections : function(fast){
32364 if(this.locked) return;
32365 if(fast !== true){
32366 var ds = this.grid.store;
32367 var s = this.selections;
32368 s.each(function(r){
32369 this.deselectRow(ds.indexOfId(r.id));
32370 }, this);
32371 s.clear();
32372 }else{
32373 this.selections.clear();
32375 this.last = false;
32376 },
32380 selectAll : function(){
32381 if(this.locked) return;
32382 this.selections.clear();
32383 for(var i = 0, len = this.grid.store.getCount(); i < len; i++){
32384 this.selectRow(i, true);
32386 },
32389 hasSelection : function(){
32390 return this.selections.length > 0;
32391 },
32394 isSelected : function(index){
32395 var r = typeof index == "number" ? this.grid.store.getAt(index) : index;
32396 return (r && this.selections.key(r.id) ? true : false);
32397 },
32400 isIdSelected : function(id){
32401 return (this.selections.key(id) ? true : false);
32402 },
32404 handleMouseDown : function(g, rowIndex, e){
32405 if(e.button !== 0 || this.isLocked()){
32406 return;
32407 };
32408 var view = this.grid.getView();
32409 if(e.shiftKey && this.last !== false){
32410 var last = this.last;
32411 this.selectRange(last, rowIndex, e.ctrlKey);
32412 this.last = last; view.focusRow(rowIndex);
32413 }else{
32414 var isSelected = this.isSelected(rowIndex);
32415 if(e.ctrlKey && isSelected){
32416 this.deselectRow(rowIndex);
32417 }else if(!isSelected || this.getCount() > 1){
32418 this.selectRow(rowIndex, e.ctrlKey || e.shiftKey);
32419 view.focusRow(rowIndex);
32422 },
32425 selectRows : function(rows, keepExisting){
32426 if(!keepExisting){
32427 this.clearSelections();
32429 for(var i = 0, len = rows.length; i < len; i++){
32430 this.selectRow(rows[i], true);
32432 },
32435 selectRange : function(startRow, endRow, keepExisting){
32436 if(this.locked) return;
32437 if(!keepExisting){
32438 this.clearSelections();
32440 if(startRow <= endRow){
32441 for(var i = startRow; i <= endRow; i++){
32442 this.selectRow(i, true);
32444 }else{
32445 for(var i = startRow; i >= endRow; i--){
32446 this.selectRow(i, true);
32449 },
32452 deselectRange : function(startRow, endRow, preventViewNotify){
32453 if(this.locked) return;
32454 for(var i = startRow; i <= endRow; i++){
32455 this.deselectRow(i, preventViewNotify);
32457 },
32460 selectRow : function(index, keepExisting, preventViewNotify){
32461 if(this.locked || (index < 0 || index >= this.grid.store.getCount())) return;
32462 var r = this.grid.store.getAt(index);
32463 if(r && this.fireEvent("beforerowselect", this, index, keepExisting, r) !== false){
32464 if(!keepExisting || this.singleSelect){
32465 this.clearSelections();
32467 this.selections.add(r);
32468 this.last = this.lastActive = index;
32469 if(!preventViewNotify){
32470 this.grid.getView().onRowSelect(index);
32472 this.fireEvent("rowselect", this, index, r);
32473 this.fireEvent("selectionchange", this);
32475 },
32478 deselectRow : function(index, preventViewNotify){
32479 if(this.locked) return;
32480 if(this.last == index){
32481 this.last = false;
32483 if(this.lastActive == index){
32484 this.lastActive = false;
32486 var r = this.grid.store.getAt(index);
32487 if(r){
32488 this.selections.remove(r);
32489 if(!preventViewNotify){
32490 this.grid.getView().onRowDeselect(index);
32492 this.fireEvent("rowdeselect", this, index, r);
32493 this.fireEvent("selectionchange", this);
32495 },
32497 restoreLast : function(){
32498 if(this._last){
32499 this.last = this._last;
32501 },
32503 acceptsNav : function(row, col, cm){
32504 return !cm.isHidden(col) && cm.isCellEditable(col, row);
32505 },
32507 onEditorKey : function(field, e){
32508 var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor;
32509 var shift = e.shiftKey;
32510 if(k == e.TAB){
32511 e.stopEvent();
32512 ed.completeEdit();
32513 if(shift){
32514 newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
32515 }else{
32516 newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
32518 }else if(k == e.ENTER){
32519 e.stopEvent();
32520 ed.completeEdit();
32521 if(this.moveEditorOnEnter !== false){
32522 if(shift){
32523 newCell = g.walkCells(ed.row - 1, ed.col, -1, this.acceptsNav, this);
32524 }else{
32525 newCell = g.walkCells(ed.row + 1, ed.col, 1, this.acceptsNav, this);
32528 }else if(k == e.ESC){
32529 ed.cancelEdit();
32531 if(newCell){
32532 g.startEditing(newCell[0], newCell[1]);
32535 });
32537 Ext.grid.CellSelectionModel = function(config){
32538 Ext.apply(this, config);
32540 this.selection = null;
32542 this.addEvents(
32544 "beforecellselect",
32546 "cellselect",
32548 "selectionchange"
32549 );
32551 Ext.grid.CellSelectionModel.superclass.constructor.call(this);
32552 };
32554 Ext.extend(Ext.grid.CellSelectionModel, Ext.grid.AbstractSelectionModel, {
32557 initEvents : function(){
32558 this.grid.on("cellmousedown", this.handleMouseDown, this);
32559 this.grid.getGridEl().on(Ext.isIE || Ext.isSafari3 ? "keydown" : "keypress", this.handleKeyDown, this);
32560 var view = this.grid.view;
32561 view.on("refresh", this.onViewChange, this);
32562 view.on("rowupdated", this.onRowUpdated, this);
32563 view.on("beforerowremoved", this.clearSelections, this);
32564 view.on("beforerowsinserted", this.clearSelections, this);
32565 if(this.grid.isEditor){
32566 this.grid.on("beforeedit", this.beforeEdit, this);
32568 },
32570 beforeEdit : function(e){
32571 this.select(e.row, e.column, false, true, e.record);
32572 },
32574 onRowUpdated : function(v, index, r){
32575 if(this.selection && this.selection.record == r){
32576 v.onCellSelect(index, this.selection.cell[1]);
32578 },
32580 onViewChange : function(){
32581 this.clearSelections(true);
32582 },
32585 getSelectedCell : function(){
32586 return this.selection ? this.selection.cell : null;
32587 },
32590 clearSelections : function(preventNotify){
32591 var s = this.selection;
32592 if(s){
32593 if(preventNotify !== true){
32594 this.grid.view.onCellDeselect(s.cell[0], s.cell[1]);
32596 this.selection = null;
32597 this.fireEvent("selectionchange", this, null);
32599 },
32602 hasSelection : function(){
32603 return this.selection ? true : false;
32604 },
32607 handleMouseDown : function(g, row, cell, e){
32608 if(e.button !== 0 || this.isLocked()){
32609 return;
32610 };
32611 this.select(row, cell);
32612 },
32615 select : function(rowIndex, colIndex, preventViewNotify, preventFocus, r){
32616 if(this.fireEvent("beforecellselect", this, rowIndex, colIndex) !== false){
32617 this.clearSelections();
32618 r = r || this.grid.store.getAt(rowIndex);
32619 this.selection = {
32620 record : r,
32621 cell : [rowIndex, colIndex]
32622 };
32623 if(!preventViewNotify){
32624 var v = this.grid.getView();
32625 v.onCellSelect(rowIndex, colIndex);
32626 if(preventFocus !== true){
32627 v.focusCell(rowIndex, colIndex);
32630 this.fireEvent("cellselect", this, rowIndex, colIndex);
32631 this.fireEvent("selectionchange", this, this.selection);
32633 },
32635 isSelectable : function(rowIndex, colIndex, cm){
32636 return !cm.isHidden(colIndex);
32637 },
32640 handleKeyDown : function(e){
32641 if(!e.isNavKeyPress()){
32642 return;
32644 var g = this.grid, s = this.selection;
32645 if(!s){
32646 e.stopEvent();
32647 var cell = g.walkCells(0, 0, 1, this.isSelectable, this);
32648 if(cell){
32649 this.select(cell[0], cell[1]);
32651 return;
32653 var sm = this;
32654 var walk = function(row, col, step){
32655 return g.walkCells(row, col, step, sm.isSelectable, sm);
32656 };
32657 var k = e.getKey(), r = s.cell[0], c = s.cell[1];
32658 var newCell;
32660 switch(k){
32661 case e.TAB:
32662 if(e.shiftKey){
32663 newCell = walk(r, c-1, -1);
32664 }else{
32665 newCell = walk(r, c+1, 1);
32667 break;
32668 case e.DOWN:
32669 newCell = walk(r+1, c, 1);
32670 break;
32671 case e.UP:
32672 newCell = walk(r-1, c, -1);
32673 break;
32674 case e.RIGHT:
32675 newCell = walk(r, c+1, 1);
32676 break;
32677 case e.LEFT:
32678 newCell = walk(r, c-1, -1);
32679 break;
32680 case e.ENTER:
32681 if(g.isEditor && !g.editing){
32682 g.startEditing(r, c);
32683 e.stopEvent();
32684 return;
32686 break;
32687 };
32688 if(newCell){
32689 this.select(newCell[0], newCell[1]);
32690 e.stopEvent();
32692 },
32694 acceptsNav : function(row, col, cm){
32695 return !cm.isHidden(col) && cm.isCellEditable(col, row);
32696 },
32698 onEditorKey : function(field, e){
32699 var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor;
32700 if(k == e.TAB){
32701 if(e.shiftKey){
32702 newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
32703 }else{
32704 newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
32706 e.stopEvent();
32707 }else if(k == e.ENTER){
32708 ed.completeEdit();
32709 e.stopEvent();
32710 }else if(k == e.ESC){
32711 e.stopEvent();
32712 ed.cancelEdit();
32714 if(newCell){
32715 g.startEditing(newCell[0], newCell[1]);
32718 });
32720 Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, {
32722 clicksToEdit: 2,
32724 isEditor : true,
32725 detectEdit: false,
32728 autoEncode : false,
32731 trackMouseOver: false,
32732 initComponent : function(){
32733 Ext.grid.EditorGridPanel.superclass.initComponent.call(this);
32735 if(!this.selModel){
32737 this.selModel = new Ext.grid.CellSelectionModel();
32740 this.activeEditor = null;
32742 this.addEvents(
32744 "beforeedit",
32746 "afteredit",
32748 "validateedit"
32749 );
32750 },
32752 initEvents : function(){
32753 Ext.grid.EditorGridPanel.superclass.initEvents.call(this);
32755 this.on("bodyscroll", this.stopEditing, this, [true]);
32757 if(this.clicksToEdit == 1){
32758 this.on("cellclick", this.onCellDblClick, this);
32759 }else {
32760 if(this.clicksToEdit == 'auto' && this.view.mainBody){
32761 this.view.mainBody.on("mousedown", this.onAutoEditClick, this);
32763 this.on("celldblclick", this.onCellDblClick, this);
32765 this.getGridEl().addClass("xedit-grid");
32766 },
32768 onCellDblClick : function(g, row, col){
32769 this.startEditing(row, col);
32770 },
32772 onAutoEditClick : function(e, t){
32773 if(e.button !== 0){
32774 return;
32776 var row = this.view.findRowIndex(t);
32777 var col = this.view.findCellIndex(t);
32778 if(row !== false && col !== false){
32779 this.stopEditing();
32780 if(this.selModel.getSelectedCell){ var sc = this.selModel.getSelectedCell();
32781 if(sc && sc.cell[0] === row && sc.cell[1] === col){
32782 this.startEditing(row, col);
32784 }else{
32785 if(this.selModel.isSelected(row)){
32786 this.startEditing(row, col);
32790 },
32792 onEditComplete : function(ed, value, startValue){
32793 this.editing = false;
32794 this.activeEditor = null;
32795 ed.un("specialkey", this.selModel.onEditorKey, this.selModel);
32796 var r = ed.record;
32797 var field = this.colModel.getDataIndex(ed.col);
32798 value = this.postEditValue(value, startValue, r, field);
32799 if(String(value) !== String(startValue)){
32800 var e = {
32801 grid: this,
32802 record: r,
32803 field: field,
32804 originalValue: startValue,
32805 value: value,
32806 row: ed.row,
32807 column: ed.col,
32808 cancel:false
32809 };
32810 if(this.fireEvent("validateedit", e) !== false && !e.cancel){
32811 r.set(field, e.value);
32812 delete e.cancel;
32813 this.fireEvent("afteredit", e);
32816 this.view.focusCell(ed.row, ed.col);
32817 },
32820 startEditing : function(row, col){
32821 this.stopEditing();
32822 if(this.colModel.isCellEditable(col, row)){
32823 this.view.ensureVisible(row, col, true);
32824 var r = this.store.getAt(row);
32825 var field = this.colModel.getDataIndex(col);
32826 var e = {
32827 grid: this,
32828 record: r,
32829 field: field,
32830 value: r.data[field],
32831 row: row,
32832 column: col,
32833 cancel:false
32834 };
32835 if(this.fireEvent("beforeedit", e) !== false && !e.cancel){
32836 this.editing = true;
32837 var ed = this.colModel.getCellEditor(col, row);
32838 if(!ed.rendered){
32839 ed.render(this.view.getEditorParent(ed));
32841 (function(){ ed.row = row;
32842 ed.col = col;
32843 ed.record = r;
32844 ed.on("complete", this.onEditComplete, this, {single: true});
32845 ed.on("specialkey", this.selModel.onEditorKey, this.selModel);
32846 this.activeEditor = ed;
32847 var v = this.preEditValue(r, field);
32848 ed.startEdit(this.view.getCell(row, col), v);
32849 }).defer(50, this);
32852 },
32854 preEditValue : function(r, field){
32855 return this.autoEncode && typeof value == 'string' ? Ext.util.Format.htmlDecode(r.data[field]) : r.data[field];
32856 },
32858 postEditValue : function(value, originalValue, r, field){
32859 return this.autoEncode && typeof value == 'string' ? Ext.util.Format.htmlEncode(value) : value;
32860 },
32863 stopEditing : function(cancel){
32864 if(this.activeEditor){
32865 this.activeEditor[cancel === true ? 'cancelEdit' : 'completeEdit']();
32867 this.activeEditor = null;
32869 });
32870 Ext.reg('editorgrid', Ext.grid.EditorGridPanel);
32871 Ext.grid.GridEditor = function(field, config){
32872 Ext.grid.GridEditor.superclass.constructor.call(this, field, config);
32873 field.monitorTab = false;
32874 };
32876 Ext.extend(Ext.grid.GridEditor, Ext.Editor, {
32877 alignment: "tl-tl",
32878 autoSize: "width",
32879 hideEl : false,
32880 cls: "x-small-editor x-grid-editor",
32881 shim:false,
32882 shadow:false
32883 });
32885 Ext.grid.PropertyRecord = Ext.data.Record.create([
32886 {name:'name',type:'string'}, 'value'
32887 ]);
32890 Ext.grid.PropertyStore = function(grid, source){
32891 this.grid = grid;
32892 this.store = new Ext.data.Store({
32893 recordType : Ext.grid.PropertyRecord
32894 });
32895 this.store.on('update', this.onUpdate, this);
32896 if(source){
32897 this.setSource(source);
32899 Ext.grid.PropertyStore.superclass.constructor.call(this);
32900 };
32901 Ext.extend(Ext.grid.PropertyStore, Ext.util.Observable, {
32902 setSource : function(o){
32903 this.source = o;
32904 this.store.removeAll();
32905 var data = [];
32906 for(var k in o){
32907 if(this.isEditableValue(o[k])){
32908 data.push(new Ext.grid.PropertyRecord({name: k, value: o[k]}, k));
32911 this.store.loadRecords({records: data}, {}, true);
32912 },
32914 onUpdate : function(ds, record, type){
32915 if(type == Ext.data.Record.EDIT){
32916 var v = record.data['value'];
32917 var oldValue = record.modified['value'];
32918 if(this.grid.fireEvent('beforepropertychange', this.source, record.id, v, oldValue) !== false){
32919 this.source[record.id] = v;
32920 record.commit();
32921 this.grid.fireEvent('propertychange', this.source, record.id, v, oldValue);
32922 }else{
32923 record.reject();
32926 },
32928 getProperty : function(row){
32929 return this.store.getAt(row);
32930 },
32932 isEditableValue: function(val){
32933 if(Ext.isDate(val)){
32934 return true;
32935 }else if(typeof val == 'object' || typeof val == 'function'){
32936 return false;
32938 return true;
32939 },
32941 setValue : function(prop, value){
32942 this.source[prop] = value;
32943 this.store.getById(prop).set('value', value);
32944 },
32946 getSource : function(){
32947 return this.source;
32949 });
32952 Ext.grid.PropertyColumnModel = function(grid, store){
32953 this.grid = grid;
32954 var g = Ext.grid;
32955 g.PropertyColumnModel.superclass.constructor.call(this, [
32956 {header: this.nameText, width:50, sortable: true, dataIndex:'name', id: 'name', menuDisabled:true},
32957 {header: this.valueText, width:50, resizable:false, dataIndex: 'value', id: 'value', menuDisabled:true}
32958 ]);
32959 this.store = store;
32960 this.bselect = Ext.DomHelper.append(document.body, {
32961 tag: 'select', cls: 'x-grid-editor x-hide-display', children: [
32962 {tag: 'option', value: 'true', html: 'true'},
32963 {tag: 'option', value: 'false', html: 'false'}
32965 });
32966 var f = Ext.form;
32968 var bfield = new f.Field({
32969 el:this.bselect,
32970 bselect : this.bselect,
32971 autoShow: true,
32972 getValue : function(){
32973 return this.bselect.value == 'true';
32975 });
32976 this.editors = {
32977 'date' : new g.GridEditor(new f.DateField({selectOnFocus:true})),
32978 'string' : new g.GridEditor(new f.TextField({selectOnFocus:true})),
32979 'number' : new g.GridEditor(new f.NumberField({selectOnFocus:true, style:'text-align:left;'})),
32980 'boolean' : new g.GridEditor(bfield)
32981 };
32982 this.renderCellDelegate = this.renderCell.createDelegate(this);
32983 this.renderPropDelegate = this.renderProp.createDelegate(this);
32984 };
32986 Ext.extend(Ext.grid.PropertyColumnModel, Ext.grid.ColumnModel, {
32987 nameText : 'Name',
32988 valueText : 'Value',
32989 dateFormat : 'm/j/Y',
32991 renderDate : function(dateVal){
32992 return dateVal.dateFormat(this.dateFormat);
32993 },
32995 renderBool : function(bVal){
32996 return bVal ? 'true' : 'false';
32997 },
32999 isCellEditable : function(colIndex, rowIndex){
33000 return colIndex == 1;
33001 },
33003 getRenderer : function(col){
33004 return col == 1 ?
33005 this.renderCellDelegate : this.renderPropDelegate;
33006 },
33008 renderProp : function(v){
33009 return this.getPropertyName(v);
33010 },
33012 renderCell : function(val){
33013 var rv = val;
33014 if(Ext.isDate(val)){
33015 rv = this.renderDate(val);
33016 }else if(typeof val == 'boolean'){
33017 rv = this.renderBool(val);
33019 return Ext.util.Format.htmlEncode(rv);
33020 },
33022 getPropertyName : function(name){
33023 var pn = this.grid.propertyNames;
33024 return pn && pn[name] ? pn[name] : name;
33025 },
33027 getCellEditor : function(colIndex, rowIndex){
33028 var p = this.store.getProperty(rowIndex);
33029 var n = p.data['name'], val = p.data['value'];
33030 if(this.grid.customEditors[n]){
33031 return this.grid.customEditors[n];
33033 if(Ext.isDate(val)){
33034 return this.editors['date'];
33035 }else if(typeof val == 'number'){
33036 return this.editors['number'];
33037 }else if(typeof val == 'boolean'){
33038 return this.editors['boolean'];
33039 }else{
33040 return this.editors['string'];
33043 });
33046 Ext.grid.PropertyGrid = Ext.extend(Ext.grid.EditorGridPanel, {
33050 enableColumnMove:false,
33051 stripeRows:false,
33052 trackMouseOver: false,
33053 clicksToEdit:1,
33054 enableHdMenu : false,
33055 viewConfig : {
33056 forceFit:true
33057 },
33059 initComponent : function(){
33060 this.customEditors = this.customEditors || {};
33061 this.lastEditRow = null;
33062 var store = new Ext.grid.PropertyStore(this);
33063 this.propStore = store;
33064 var cm = new Ext.grid.PropertyColumnModel(this, store);
33065 store.store.sort('name', 'ASC');
33066 this.addEvents(
33068 'beforepropertychange',
33070 'propertychange'
33071 );
33072 this.cm = cm;
33073 this.ds = store.store;
33074 Ext.grid.PropertyGrid.superclass.initComponent.call(this);
33076 this.selModel.on('beforecellselect', function(sm, rowIndex, colIndex){
33077 if(colIndex === 0){
33078 this.startEditing.defer(200, this, [rowIndex, 1]);
33079 return false;
33081 }, this);
33082 },
33084 onRender : function(){
33085 Ext.grid.PropertyGrid.superclass.onRender.apply(this, arguments);
33087 this.getGridEl().addClass('x-props-grid');
33088 },
33090 afterRender: function(){
33091 Ext.grid.PropertyGrid.superclass.afterRender.apply(this, arguments);
33092 if(this.source){
33093 this.setSource(this.source);
33095 },
33098 setSource : function(source){
33099 this.propStore.setSource(source);
33100 },
33103 getSource : function(){
33104 return this.propStore.getSource();
33106 });
33107 Ext.reg("propertygrid", Ext.grid.PropertyGrid);
33110 Ext.grid.RowNumberer = function(config){
33111 Ext.apply(this, config);
33112 if(this.rowspan){
33113 this.renderer = this.renderer.createDelegate(this);
33115 };
33117 Ext.grid.RowNumberer.prototype = {
33119 header: "",
33121 width: 23,
33123 sortable: false,
33126 fixed:true,
33127 menuDisabled:true,
33128 dataIndex: '',
33129 id: 'numberer',
33130 rowspan: undefined,
33133 renderer : function(v, p, record, rowIndex){
33134 if(this.rowspan){
33135 p.cellAttr = 'rowspan="'+this.rowspan+'"';
33137 return rowIndex+1;
33139 };
33141 Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, {
33143 header: '<div class="x-grid3-hd-checker">&#160;</div>',
33145 width: 20,
33147 sortable: false,
33150 menuDisabled:true,
33151 fixed:true,
33152 dataIndex: '',
33153 id: 'checker',
33156 initEvents : function(){
33157 Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this);
33158 this.grid.on('render', function(){
33159 var view = this.grid.getView();
33160 view.mainBody.on('mousedown', this.onMouseDown, this);
33161 Ext.fly(view.innerHd).on('mousedown', this.onHdMouseDown, this);
33163 }, this);
33164 },
33167 onMouseDown : function(e, t){
33168 if(e.button === 0 && t.className == 'x-grid3-row-checker'){
33169 e.stopEvent();
33170 var row = e.getTarget('.x-grid3-row');
33171 if(row){
33172 var index = row.rowIndex;
33173 if(this.isSelected(index)){
33174 this.deselectRow(index);
33175 }else{
33176 this.selectRow(index, true);
33180 },
33183 onHdMouseDown : function(e, t){
33184 if(t.className == 'x-grid3-hd-checker'){
33185 e.stopEvent();
33186 var hd = Ext.fly(t.parentNode);
33187 var isChecked = hd.hasClass('x-grid3-hd-checker-on');
33188 if(isChecked){
33189 hd.removeClass('x-grid3-hd-checker-on');
33190 this.clearSelections();
33191 }else{
33192 hd.addClass('x-grid3-hd-checker-on');
33193 this.selectAll();
33196 },
33199 renderer : function(v, p, record){
33200 return '<div class="x-grid3-row-checker">&#160;</div>';
33202 });
33204 Ext.LoadMask = function(el, config){
33205 this.el = Ext.get(el);
33206 Ext.apply(this, config);
33207 if(this.store){
33208 this.store.on('beforeload', this.onBeforeLoad, this);
33209 this.store.on('load', this.onLoad, this);
33210 this.store.on('loadexception', this.onLoad, this);
33211 this.removeMask = Ext.value(this.removeMask, false);
33212 }else{
33213 var um = this.el.getUpdater();
33214 um.showLoadIndicator = false; um.on('beforeupdate', this.onBeforeLoad, this);
33215 um.on('update', this.onLoad, this);
33216 um.on('failure', this.onLoad, this);
33217 this.removeMask = Ext.value(this.removeMask, true);
33219 };
33221 Ext.LoadMask.prototype = {
33225 msg : 'Loading...',
33227 msgCls : 'x-mask-loading',
33230 disabled: false,
33233 disable : function(){
33234 this.disabled = true;
33235 },
33238 enable : function(){
33239 this.disabled = false;
33240 },
33242 onLoad : function(){
33243 this.el.unmask(this.removeMask);
33244 },
33246 onBeforeLoad : function(){
33247 if(!this.disabled){
33248 this.el.mask(this.msg, this.msgCls);
33250 },
33253 show: function(){
33254 this.onBeforeLoad();
33255 },
33258 hide: function(){
33259 this.onLoad();
33260 },
33262 destroy : function(){
33263 if(this.store){
33264 this.store.un('beforeload', this.onBeforeLoad, this);
33265 this.store.un('load', this.onLoad, this);
33266 this.store.un('loadexception', this.onLoad, this);
33267 }else{
33268 var um = this.el.getUpdater();
33269 um.un('beforeupdate', this.onBeforeLoad, this);
33270 um.un('update', this.onLoad, this);
33271 um.un('failure', this.onLoad, this);
33274 };
33276 Ext.ProgressBar = Ext.extend(Ext.BoxComponent, {
33278 baseCls : 'x-progress',
33281 waitTimer : null,
33284 initComponent : function(){
33285 Ext.ProgressBar.superclass.initComponent.call(this);
33286 this.addEvents(
33288 "update"
33289 );
33290 },
33293 onRender : function(ct, position){
33294 Ext.ProgressBar.superclass.onRender.call(this, ct, position);
33296 var tpl = new Ext.Template(
33297 '<div class="{cls}-wrap">',
33298 '<div class="{cls}-inner">',
33299 '<div class="{cls}-bar">',
33300 '<div class="{cls}-text">',
33301 '<div>&#160;</div>',
33302 '</div>',
33303 '</div>',
33304 '<div class="{cls}-text {cls}-text-back">',
33305 '<div>&#160;</div>',
33306 '</div>',
33307 '</div>',
33308 '</div>'
33309 );
33311 if(position){
33312 this.el = tpl.insertBefore(position, {cls: this.baseCls}, true);
33313 }else{
33314 this.el = tpl.append(ct, {cls: this.baseCls}, true);
33316 if(this.id){
33317 this.el.dom.id = this.id;
33319 var inner = this.el.dom.firstChild;
33320 this.progressBar = Ext.get(inner.firstChild);
33322 if(this.textEl){
33324 this.textEl = Ext.get(this.textEl);
33325 delete this.textTopEl;
33326 }else{
33328 this.textTopEl = Ext.get(this.progressBar.dom.firstChild);
33329 var textBackEl = Ext.get(inner.childNodes[1]);
33330 this.textTopEl.setStyle("z-index", 99).addClass('x-hidden');
33331 this.textEl = new Ext.CompositeElement([this.textTopEl.dom.firstChild, textBackEl.dom.firstChild]);
33332 this.textEl.setWidth(inner.offsetWidth);
33334 this.progressBar.setHeight(inner.offsetHeight);
33335 },
33338 afterRender : function(){
33339 Ext.ProgressBar.superclass.afterRender.call(this);
33340 if(this.value){
33341 this.updateProgress(this.value, this.text);
33342 }else{
33343 this.updateText(this.text);
33345 },
33348 updateProgress : function(value, text){
33349 this.value = value || 0;
33350 if(text){
33351 this.updateText(text);
33353 var w = Math.floor(value*this.el.dom.firstChild.offsetWidth);
33354 this.progressBar.setWidth(w);
33355 if(this.textTopEl){
33357 this.textTopEl.removeClass('x-hidden').setWidth(w);
33359 this.fireEvent('update', this, value, text);
33360 return this;
33361 },
33364 wait : function(o){
33365 if(!this.waitTimer){
33366 var scope = this;
33367 o = o || {};
33368 this.waitTimer = Ext.TaskMgr.start({
33369 run: function(i){
33370 var inc = o.increment || 10;
33371 this.updateProgress(((((i+inc)%inc)+1)*(100/inc))*.01);
33372 },
33373 interval: o.interval || 1000,
33374 duration: o.duration,
33375 onStop: function(){
33376 if(o.fn){
33377 o.fn.apply(o.scope || this);
33379 this.reset();
33380 },
33381 scope: scope
33382 });
33384 return this;
33385 },
33388 isWaiting : function(){
33389 return this.waitTimer != null;
33390 },
33393 updateText : function(text){
33394 this.text = text || '&#160;';
33395 this.textEl.update(this.text);
33396 return this;
33397 },
33400 setSize : function(w, h){
33401 Ext.ProgressBar.superclass.setSize.call(this, w, h);
33402 if(this.textTopEl){
33403 var inner = this.el.dom.firstChild;
33404 this.textEl.setSize(inner.offsetWidth, inner.offsetHeight);
33406 return this;
33407 },
33410 reset : function(hide){
33411 this.updateProgress(0);
33412 if(this.textTopEl){
33413 this.textTopEl.addClass('x-hidden');
33415 if(this.waitTimer){
33416 this.waitTimer.onStop = null;
33417 Ext.TaskMgr.stop(this.waitTimer);
33418 this.waitTimer = null;
33420 if(hide === true){
33421 this.hide();
33423 return this;
33425 });
33426 Ext.reg('progress', Ext.ProgressBar);
33428 Ext.Slider = Ext.extend(Ext.BoxComponent, {
33431 vertical: false,
33433 minValue: 0,
33435 maxValue: 100,
33437 keyIncrement: 1,
33439 increment: 0,
33441 clickRange: [5,15],
33443 clickToChange : true,
33445 animate: true,
33448 initComponent : function(){
33449 if(this.value === undefined){
33450 this.value = this.minValue;
33452 Ext.Slider.superclass.initComponent.call(this);
33453 this.keyIncrement = Math.max(this.increment, this.keyIncrement);
33454 this.addEvents(
33456 'beforechange',
33458 'change',
33460 'dragstart',
33462 'drag',
33464 'dragend'
33465 );
33467 if(this.vertical){
33468 Ext.apply(this, Ext.Slider.Vertical);
33470 },
33473 onRender : function(){
33474 this.autoEl = {
33475 cls: 'x-slider ' + (this.vertical ? 'x-slider-vert' : 'x-slider-horz'),
33476 cn:{cls:'x-slider-end',cn:{cls:'x-slider-inner',cn:[{cls:'x-slider-thumb'},{tag:'a', cls:'x-slider-focus', href:"#", tabIndex: '-1', hidefocus:'on'}]}}
33477 };
33478 Ext.Slider.superclass.onRender.apply(this, arguments);
33479 this.endEl = this.el.first();
33480 this.innerEl = this.endEl.first();
33481 this.thumb = this.innerEl.first();
33482 this.halfThumb = (this.vertical ? this.thumb.getHeight() : this.thumb.getWidth())/2;
33483 this.focusEl = this.thumb.next();
33484 this.initEvents();
33485 },
33488 initEvents : function(){
33489 this.thumb.addClassOnOver('x-slider-thumb-over');
33490 this.mon(this.el, 'mousedown', this.onMouseDown, this);
33491 this.mon(this.el, 'keydown', this.onKeyDown, this);
33493 this.tracker = new Ext.dd.DragTracker({
33494 onBeforeStart: this.onBeforeDragStart.createDelegate(this),
33495 onStart: this.onDragStart.createDelegate(this),
33496 onDrag: this.onDrag.createDelegate(this),
33497 onEnd: this.onDragEnd.createDelegate(this),
33498 tolerance: 3,
33499 autoStart: 300
33500 });
33501 this.tracker.initEl(this.thumb);
33502 this.on('beforedestroy', this.tracker.destroy, this.tracker);
33503 },
33506 onMouseDown : function(e){
33507 if(this.disabled) {return;}
33508 if(this.clickToChange && e.target != this.thumb.dom){
33509 var local = this.innerEl.translatePoints(e.getXY());
33510 this.onClickChange(local);
33512 this.focus();
33513 },
33516 onClickChange : function(local){
33517 if(local.top > this.clickRange[0] && local.top < this.clickRange[1]){
33518 this.setValue(Math.round(local.left/this.getRatio()));
33520 },
33523 onKeyDown : function(e){
33524 if(this.disabled){e.preventDefault();return;}
33525 var k = e.getKey();
33526 switch(k){
33527 case e.UP:
33528 case e.RIGHT:
33529 e.stopEvent();
33530 if(e.ctrlKey){
33531 this.setValue(this.maxValue);
33532 }else{
33533 this.setValue(this.value+this.keyIncrement);
33535 break;
33536 case e.DOWN:
33537 case e.LEFT:
33538 e.stopEvent();
33539 if(e.ctrlKey){
33540 this.setValue(this.minValue);
33541 }else{
33542 this.setValue(this.value-this.keyIncrement);
33544 break;
33545 default:
33546 e.preventDefault();
33548 },
33551 doSnap : function(value){
33552 if(!this.increment || this.increment == 1 || !value) {
33553 return value;
33555 var newValue = value, inc = this.increment;
33556 var m = value % inc;
33557 if(m > 0){
33558 if(m > (inc/2)){
33559 newValue = value + (inc-m);
33560 }else{
33561 newValue = value - m;
33564 return newValue.constrain(this.minValue, this.maxValue);
33565 },
33568 afterRender : function(){
33569 Ext.Slider.superclass.afterRender.apply(this, arguments);
33570 if(this.value !== undefined){
33571 var v = this.normalizeValue(this.value);
33572 if(v !== this.value){
33573 delete this.value;
33574 this.setValue(v, false);
33575 }else{
33576 this.moveThumb(this.translateValue(v), false);
33579 },
33582 getRatio : function(){
33583 var w = this.innerEl.getWidth();
33584 var v = this.maxValue - this.minValue;
33585 return w/v;
33586 },
33589 normalizeValue : function(v){
33590 if(typeof v != 'number'){
33591 v = parseInt(v);
33593 v = Math.round(v);
33594 v = this.doSnap(v);
33595 v = v.constrain(this.minValue, this.maxValue);
33596 return v;
33597 },
33600 setValue : function(v, animate){
33601 v = this.normalizeValue(v);
33602 if(v !== this.value && this.fireEvent('beforechange', this, v, this.value) !== false){
33603 this.value = v;
33604 this.moveThumb(this.translateValue(v), animate !== false);
33605 this.fireEvent('change', this, v);
33607 },
33610 translateValue : function(v){
33611 return (v * this.getRatio())-this.halfThumb;
33612 },
33615 moveThumb: function(v, animate){
33616 if(!animate || this.animate === false){
33617 this.thumb.setLeft(v);
33618 }else{
33619 this.thumb.shift({left: v, stopFx: true, duration:.35});
33621 },
33624 focus : function(){
33625 this.focusEl.focus(10);
33626 },
33629 onBeforeDragStart : function(e){
33630 return !this.disabled;
33631 },
33634 onDragStart: function(e){
33635 this.thumb.addClass('x-slider-thumb-drag');
33636 this.fireEvent('dragstart', this, e);
33637 },
33640 onDrag: function(e){
33641 var pos = this.innerEl.translatePoints(this.tracker.getXY());
33642 this.setValue(Math.round(pos.left/this.getRatio()), false);
33643 this.fireEvent('drag', this, e);
33644 },
33647 onDragEnd: function(e){
33648 this.thumb.removeClass('x-slider-thumb-drag');
33649 this.fireEvent('dragend', this, e);
33650 },
33653 onResize : function(w, h){
33654 this.innerEl.setWidth(w - (this.el.getPadding('l') + this.endEl.getPadding('r')));
33655 },
33658 getValue : function(){
33659 return this.value;
33661 });
33662 Ext.reg('slider', Ext.Slider);
33665 Ext.Slider.Vertical = {
33666 onResize : function(w, h){
33667 this.innerEl.setHeight(h - (this.el.getPadding('t') + this.endEl.getPadding('b')));
33668 },
33670 getRatio : function(){
33671 var h = this.innerEl.getHeight();
33672 var v = this.maxValue - this.minValue;
33673 return h/v;
33674 },
33676 moveThumb: function(v, animate){
33677 if(!animate || this.animate === false){
33678 this.thumb.setBottom(v);
33679 }else{
33680 this.thumb.shift({bottom: v, stopFx: true, duration:.35});
33682 },
33684 onDrag: function(e){
33685 var pos = this.innerEl.translatePoints(this.tracker.getXY());
33686 var bottom = this.innerEl.getHeight()-pos.top;
33687 this.setValue(Math.round(bottom/this.getRatio()), false);
33688 this.fireEvent('drag', this, e);
33689 },
33691 onClickChange : function(local){
33692 if(local.left > this.clickRange[0] && local.left < this.clickRange[1]){
33693 var bottom = this.innerEl.getHeight()-local.top;
33694 this.setValue(Math.round(bottom/this.getRatio()));
33697 };
33699 Ext.StatusBar = Ext.extend(Ext.Toolbar, {
33707 cls : 'x-statusbar',
33709 busyIconCls : 'x-status-busy',
33711 busyText : 'Loading...',
33713 autoClear : 5000,
33715 activeThreadId : 0,
33717 initComponent : function(){
33718 if(this.statusAlign=='right'){
33719 this.cls += ' x-status-right';
33721 Ext.StatusBar.superclass.initComponent.call(this);
33722 },
33724 afterRender : function(){
33725 Ext.StatusBar.superclass.afterRender.call(this);
33727 var right = this.statusAlign=='right',
33728 td = Ext.get(this.nextBlock());
33730 if(right){
33731 this.tr.appendChild(td.dom);
33732 }else{
33733 td.insertBefore(this.tr.firstChild);
33736 this.statusEl = td.createChild({
33737 cls: 'x-status-text ' + (this.iconCls || this.defaultIconCls || ''),
33738 html: this.text || this.defaultText || ''
33739 });
33740 this.statusEl.unselectable();
33742 this.spacerEl = td.insertSibling({
33743 tag: 'td',
33744 style: 'width:100%',
33745 cn: [{cls:'ytb-spacer'}]
33746 }, right ? 'before' : 'after');
33747 },
33750 setStatus : function(o){
33751 o = o || {};
33753 if(typeof o == 'string'){
33754 o = {text:o};
33756 if(o.text !== undefined){
33757 this.setText(o.text);
33759 if(o.iconCls !== undefined){
33760 this.setIcon(o.iconCls);
33763 if(o.clear){
33764 var c = o.clear,
33765 wait = this.autoClear,
33766 defaults = {useDefaults: true, anim: true};
33768 if(typeof c == 'object'){
33769 c = Ext.applyIf(c, defaults);
33770 if(c.wait){
33771 wait = c.wait;
33773 }else if(typeof c == 'number'){
33774 wait = c;
33775 c = defaults;
33776 }else if(typeof c == 'boolean'){
33777 c = defaults;
33780 c.threadId = this.activeThreadId;
33781 this.clearStatus.defer(wait, this, [c]);
33783 return this;
33784 },
33787 clearStatus : function(o){
33788 o = o || {};
33790 if(o.threadId && o.threadId !== this.activeThreadId){
33791 return this;
33794 var text = o.useDefaults ? this.defaultText : '',
33795 iconCls = o.useDefaults ? this.defaultIconCls : '';
33797 if(o.anim){
33798 this.statusEl.fadeOut({
33799 remove: false,
33800 useDisplay: true,
33801 scope: this,
33802 callback: function(){
33803 this.setStatus({
33804 text: text,
33805 iconCls: iconCls
33806 });
33807 this.statusEl.show();
33809 });
33810 }else{
33811 this.statusEl.hide();
33812 this.setStatus({
33813 text: text,
33814 iconCls: iconCls
33815 });
33816 this.statusEl.show();
33818 return this;
33819 },
33822 setText : function(text){
33823 this.activeThreadId++;
33824 this.text = text || '';
33825 if(this.rendered){
33826 this.statusEl.update(this.text);
33828 return this;
33829 },
33832 getText : function(){
33833 return this.text;
33834 },
33837 setIcon : function(cls){
33838 this.activeThreadId++;
33839 cls = cls || '';
33841 if(this.rendered){
33842 if(this.currIconCls){
33843 this.statusEl.removeClass(this.currIconCls);
33844 this.currIconCls = null;
33846 if(cls.length > 0){
33847 this.statusEl.addClass(cls);
33848 this.currIconCls = cls;
33850 }else{
33851 this.currIconCls = cls;
33853 return this;
33854 },
33857 showBusy : function(o){
33858 if(typeof o == 'string'){
33859 o = {text:o};
33861 o = Ext.applyIf(o || {}, {
33862 text: this.busyText,
33863 iconCls: this.busyIconCls
33864 });
33865 return this.setStatus(o);
33867 });
33868 Ext.reg('statusbar', Ext.StatusBar);
33870 Ext.debug = {};
33872 (function(){
33874 var cp;
33876 function createConsole(){
33878 var scriptPanel = new Ext.debug.ScriptsPanel();
33879 var logView = new Ext.debug.LogPanel();
33880 var tree = new Ext.debug.DomTree();
33882 var tabs = new Ext.TabPanel({
33883 activeTab: 0,
33884 border: false,
33885 tabPosition: 'bottom',
33886 items: [{
33887 title: 'Debug Console',
33888 layout:'border',
33889 items: [logView, scriptPanel]
33890 },{
33891 title: 'DOM Inspector',
33892 layout:'border',
33893 items: [tree]
33894 }]
33895 });
33897 cp = new Ext.Panel({
33898 id: 'x-debug-browser',
33899 title: 'Console',
33900 collapsible: true,
33901 animCollapse: false,
33902 style: 'position:absolute;left:0;bottom:0;',
33903 height:200,
33904 logView: logView,
33905 layout: 'fit',
33907 tools:[{
33908 id: 'close',
33909 handler: function(){
33910 cp.destroy();
33911 cp = null;
33912 Ext.EventManager.removeResizeListener(handleResize);
33914 }],
33916 items: tabs
33917 });
33919 cp.render(document.body);
33921 cp.resizer = new Ext.Resizable(cp.el, {
33922 minHeight:50,
33923 handles: "n",
33924 pinned: true,
33925 transparent:true,
33926 resizeElement : function(){
33927 var box = this.proxy.getBox();
33928 this.proxy.hide();
33929 cp.setHeight(box.height);
33930 return box;
33932 });
33934 function handleResize(){
33935 cp.setWidth(Ext.getBody().getViewSize().width);
33937 Ext.EventManager.onWindowResize(handleResize);
33939 handleResize();
33943 Ext.apply(Ext, {
33944 log : function(){
33945 if(!cp){
33946 createConsole();
33948 cp.logView.log.apply(cp.logView, arguments);
33949 },
33951 logf : function(format, arg1, arg2, etc){
33952 Ext.log(String.format.apply(String, arguments));
33953 },
33955 dump : function(o){
33956 if(typeof o == 'string' || typeof o == 'number' || typeof o == 'undefined' || Ext.isDate(o)){
33957 Ext.log(o);
33958 }else if(!o){
33959 Ext.log("null");
33960 }else if(typeof o != "object"){
33961 Ext.log('Unknown return type');
33962 }else if(Ext.isArray(o)){
33963 Ext.log('['+o.join(',')+']');
33964 }else{
33965 var b = ["{\n"];
33966 for(var key in o){
33967 var to = typeof o[key];
33968 if(to != "function" && to != "object"){
33969 b.push(String.format(" {0}: {1},\n", key, o[key]));
33972 var s = b.join("");
33973 if(s.length > 3){
33974 s = s.substr(0, s.length-2);
33976 Ext.log(s + "\n}");
33978 },
33980 _timers : {},
33982 time : function(name){
33983 name = name || "def";
33984 Ext._timers[name] = new Date().getTime();
33985 },
33987 timeEnd : function(name, printResults){
33988 var t = new Date().getTime();
33989 name = name || "def";
33990 var v = String.format("{0} ms", t-Ext._timers[name]);
33991 Ext._timers[name] = new Date().getTime();
33992 if(printResults !== false){
33993 Ext.log('Timer ' + (name == "def" ? v : name + ": " + v));
33995 return v;
33997 });
33999 })();
34002 Ext.debug.ScriptsPanel = Ext.extend(Ext.Panel, {
34003 id:'x-debug-scripts',
34004 region: 'east',
34005 minWidth: 200,
34006 split: true,
34007 width: 350,
34008 border: false,
34009 layout:'anchor',
34010 style:'border-width:0 0 0 1px;',
34012 initComponent : function(){
34014 this.scriptField = new Ext.form.TextArea({
34015 anchor: '100% -26',
34016 style:'border-width:0;'
34017 });
34019 this.trapBox = new Ext.form.Checkbox({
34020 id: 'console-trap',
34021 boxLabel: 'Trap Errors',
34022 checked: true
34023 });
34025 this.toolbar = new Ext.Toolbar([{
34026 text: 'Run',
34027 scope: this,
34028 handler: this.evalScript
34029 },{
34030 text: 'Clear',
34031 scope: this,
34032 handler: this.clear
34033 },
34034 '->',
34035 this.trapBox,
34036 ' ', ' '
34037 ]);
34039 this.items = [this.toolbar, this.scriptField];
34041 Ext.debug.ScriptsPanel.superclass.initComponent.call(this);
34042 },
34044 evalScript : function(){
34045 var s = this.scriptField.getValue();
34046 if(this.trapBox.getValue()){
34047 try{
34048 var rt = eval(s);
34049 Ext.dump(rt === undefined? '(no return)' : rt);
34050 }catch(e){
34051 Ext.log(e.message || e.descript);
34053 }else{
34054 var rt = eval(s);
34055 Ext.dump(rt === undefined? '(no return)' : rt);
34057 },
34059 clear : function(){
34060 this.scriptField.setValue('');
34061 this.scriptField.focus();
34064 });
34066 Ext.debug.LogPanel = Ext.extend(Ext.Panel, {
34067 autoScroll: true,
34068 region: 'center',
34069 border: false,
34070 style:'border-width:0 1px 0 0',
34072 log : function(){
34073 var markup = [ '<div style="padding:5px !important;border-bottom:1px solid #ccc;">',
34074 Ext.util.Format.htmlEncode(Array.prototype.join.call(arguments, ', ')).replace(/\n/g, '<br />').replace(/\s/g, '&#160;'),
34075 '</div>'].join('');
34077 this.body.insertHtml('beforeend', markup);
34078 this.body.scrollTo('top', 100000);
34079 },
34081 clear : function(){
34082 this.body.update('');
34083 this.body.dom.scrollTop = 0;
34085 });
34087 Ext.debug.DomTree = Ext.extend(Ext.tree.TreePanel, {
34088 enableDD:false ,
34089 lines:false,
34090 rootVisible:false,
34091 animate:false,
34092 hlColor:'ffff9c',
34093 autoScroll: true,
34094 region:'center',
34095 border:false,
34097 initComponent : function(){
34100 Ext.debug.DomTree.superclass.initComponent.call(this);
34102 var styles = false, hnode;
34103 var nonSpace = /^\s*$/;
34104 var html = Ext.util.Format.htmlEncode;
34105 var ellipsis = Ext.util.Format.ellipsis;
34106 var styleRe = /\s?([a-z\-]*)\:([^;]*)(?:[;\s\n\r]*)/gi;
34108 function findNode(n){
34109 if(!n || n.nodeType != 1 || n == document.body || n == document){
34110 return false;
34112 var pn = [n], p = n;
34113 while((p = p.parentNode) && p.nodeType == 1 && p.tagName.toUpperCase() != 'HTML'){
34114 pn.unshift(p);
34116 var cn = hnode;
34117 for(var i = 0, len = pn.length; i < len; i++){
34118 cn.expand();
34119 cn = cn.findChild('htmlNode', pn[i]);
34120 if(!cn){ return false;
34123 cn.select();
34124 var a = cn.ui.anchor;
34125 treeEl.dom.scrollTop = Math.max(0 ,a.offsetTop-10);
34126 cn.highlight();
34127 return true;
34130 function nodeTitle(n){
34131 var s = n.tagName;
34132 if(n.id){
34133 s += '#'+n.id;
34134 }else if(n.className){
34135 s += '.'+n.className;
34137 return s;
34140 function onNodeSelect(t, n, last){
34141 return;
34142 if(last && last.unframe){
34143 last.unframe();
34145 var props = {};
34146 if(n && n.htmlNode){
34147 if(frameEl.pressed){
34148 n.frame();
34150 if(inspecting){
34151 return;
34153 addStyle.enable();
34154 reload.setDisabled(n.leaf);
34155 var dom = n.htmlNode;
34156 stylePanel.setTitle(nodeTitle(dom));
34157 if(styles && !showAll.pressed){
34158 var s = dom.style ? dom.style.cssText : '';
34159 if(s){
34160 var m;
34161 while ((m = styleRe.exec(s)) != null){
34162 props[m[1].toLowerCase()] = m[2];
34165 }else if(styles){
34166 var cl = Ext.debug.cssList;
34167 var s = dom.style, fly = Ext.fly(dom);
34168 if(s){
34169 for(var i = 0, len = cl.length; i<len; i++){
34170 var st = cl[i];
34171 var v = s[st] || fly.getStyle(st);
34172 if(v != undefined && v !== null && v !== ''){
34173 props[st] = v;
34177 }else{
34178 for(var a in dom){
34179 var v = dom[a];
34180 if((isNaN(a+10)) && v != undefined && v !== null && v !== '' && !(Ext.isGecko && a[0] == a[0].toUpperCase())){
34181 props[a] = v;
34185 }else{
34186 if(inspecting){
34187 return;
34189 addStyle.disable();
34190 reload.disabled();
34192 stylesGrid.setSource(props);
34193 stylesGrid.treeNode = n;
34194 stylesGrid.view.fitColumns();
34197 this.loader = new Ext.tree.TreeLoader();
34198 this.loader.load = function(n, cb){
34199 var isBody = n.htmlNode == document.body;
34200 var cn = n.htmlNode.childNodes;
34201 for(var i = 0, c; c = cn[i]; i++){
34202 if(isBody && c.id == 'x-debug-browser'){
34203 continue;
34205 if(c.nodeType == 1){
34206 n.appendChild(new Ext.debug.HtmlNode(c));
34207 }else if(c.nodeType == 3 && !nonSpace.test(c.nodeValue)){
34208 n.appendChild(new Ext.tree.TreeNode({
34209 text:'<em>' + ellipsis(html(String(c.nodeValue)), 35) + '</em>',
34210 cls: 'x-tree-noicon'
34211 }));
34214 cb();
34215 };
34218 this.root = this.setRootNode(new Ext.tree.TreeNode('Ext'));
34220 hnode = this.root.appendChild(new Ext.debug.HtmlNode(
34221 document.getElementsByTagName('html')[0]
34222 ));
34225 });
34228 Ext.debug.HtmlNode = function(){
34229 var html = Ext.util.Format.htmlEncode;
34230 var ellipsis = Ext.util.Format.ellipsis;
34231 var nonSpace = /^\s*$/;
34233 var attrs = [
34234 {n: 'id', v: 'id'},
34235 {n: 'className', v: 'class'},
34236 {n: 'name', v: 'name'},
34237 {n: 'type', v: 'type'},
34238 {n: 'src', v: 'src'},
34239 {n: 'href', v: 'href'}
34240 ];
34242 function hasChild(n){
34243 for(var i = 0, c; c = n.childNodes[i]; i++){
34244 if(c.nodeType == 1){
34245 return true;
34248 return false;
34251 function renderNode(n, leaf){
34252 var tag = n.tagName.toLowerCase();
34253 var s = '&lt;' + tag;
34254 for(var i = 0, len = attrs.length; i < len; i++){
34255 var a = attrs[i];
34256 var v = n[a.n];
34257 if(v && !nonSpace.test(v)){
34258 s += ' ' + a.v + '=&quot;<i>' + html(v) +'</i>&quot;';
34261 var style = n.style ? n.style.cssText : '';
34262 if(style){
34263 s += ' style=&quot;<i>' + html(style.toLowerCase()) +'</i>&quot;';
34265 if(leaf && n.childNodes.length > 0){
34266 s+='&gt;<em>' + ellipsis(html(String(n.innerHTML)), 35) + '</em>&lt;/'+tag+'&gt;';
34267 }else if(leaf){
34268 s += ' /&gt;';
34269 }else{
34270 s += '&gt;';
34272 return s;
34275 var HtmlNode = function(n){
34276 var leaf = !hasChild(n);
34277 this.htmlNode = n;
34278 this.tagName = n.tagName.toLowerCase();
34279 var attr = {
34280 text : renderNode(n, leaf),
34281 leaf : leaf,
34282 cls: 'x-tree-noicon'
34283 };
34284 HtmlNode.superclass.constructor.call(this, attr);
34285 this.attributes.htmlNode = n; if(!leaf){
34286 this.on('expand', this.onExpand, this);
34287 this.on('collapse', this.onCollapse, this);
34289 };
34292 Ext.extend(HtmlNode, Ext.tree.AsyncTreeNode, {
34293 cls: 'x-tree-noicon',
34294 preventHScroll: true,
34295 refresh : function(highlight){
34296 var leaf = !hasChild(this.htmlNode);
34297 this.setText(renderNode(this.htmlNode, leaf));
34298 if(highlight){
34299 Ext.fly(this.ui.textNode).highlight();
34301 },
34303 onExpand : function(){
34304 if(!this.closeNode && this.parentNode){
34305 this.closeNode = this.parentNode.insertBefore(new Ext.tree.TreeNode({
34306 text:'&lt;/' + this.tagName + '&gt;',
34307 cls: 'x-tree-noicon'
34308 }), this.nextSibling);
34309 }else if(this.closeNode){
34310 this.closeNode.ui.show();
34312 },
34314 onCollapse : function(){
34315 if(this.closeNode){
34316 this.closeNode.ui.hide();
34318 },
34320 render : function(bulkRender){
34321 HtmlNode.superclass.render.call(this, bulkRender);
34322 },
34324 highlightNode : function(){
34325 },
34327 highlight : function(){
34328 },
34330 frame : function(){
34331 this.htmlNode.style.border = '1px solid #0000ff';
34332 },
34334 unframe : function(){
34335 this.htmlNode.style.border = '';
34337 });
34339 return HtmlNode;
34340 }();