2 * Ext JS Library 0.30
\r
3 * Copyright(c) 2006-2009, Ext JS, LLC.
\r
4 * licensing@extjs.com
\r
6 * http://extjs.com/license
\r
10 * Ext JS Library 2.0.2
\r
11 * Copyright(c) 2006-2008, Ext JS, LLC.
\r
12 * licensing@extjs.com
\r
14 * http://extjs.com/license
\r
18 Ext.DomHelper = function(){
\r
19 var tempTableEl = null;
\r
20 var emptyTags = /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i;
\r
21 var tableRe = /^table|tbody|tr|td$/i;
\r
24 var createHtml = function(o){
\r
25 if(typeof o == 'string'){
\r
29 if (Ext.isArray(o)) {
\r
30 for (var i = 0, l = o.length; i < l; i++) {
\r
31 b += createHtml(o[i]);
\r
40 if(attr == "tag" || attr == "children" || attr == "cn" || attr == "html" || typeof o[attr] == "function") continue;
\r
41 if(attr == "style"){
\r
43 if(typeof s == "function"){
\r
46 if(typeof s == "string"){
\r
47 b += ' style="' + s + '"';
\r
48 }else if(typeof s == "object"){
\r
51 if(typeof s[key] != "function"){
\r
52 b += key + ":" + s[key] + ";";
\r
59 b += ' class="' + o["cls"] + '"';
\r
60 }else if(attr == "htmlFor"){
\r
61 b += ' for="' + o["htmlFor"] + '"';
\r
63 b += " " + attr + '="' + o[attr] + '"';
\r
67 if(emptyTags.test(o.tag)){
\r
71 var cn = o.children || o.cn;
\r
73 b += createHtml(cn);
\r
77 b += "</" + o.tag + ">";
\r
84 var createDom = function(o, parentNode){
\r
87 el = document.createDocumentFragment();
88 for(var i = 0, l = o.length; i < l; i++) {
\r
89 createDom(o[i], el);
\r
91 } else if (typeof o == "string)") {
92 el = document.createTextNode(o);
\r
94 el = document.createElement(o.tag||'div');
\r
95 var useSet = !!el.setAttribute;
97 if(attr == "tag" || attr == "children" || attr == "cn" || attr == "html" || attr == "style" || typeof o[attr] == "function") continue;
\r
99 el.className = o["cls"];
\r
101 if(useSet) el.setAttribute(attr, o[attr]);
\r
102 else el[attr] = o[attr];
\r
105 Ext.DomHelper.applyStyles(el, o.style);
\r
106 var cn = o.children || o.cn;
\r
110 el.innerHTML = o.html;
\r
114 parentNode.appendChild(el);
\r
119 var ieTable = function(depth, s, h, e){
\r
120 tempTableEl.innerHTML = [s, h, e].join('');
\r
121 var i = -1, el = tempTableEl;
\r
122 while(++i < depth){
\r
123 el = el.firstChild;
\r
129 var ts = '<table>',
\r
131 tbs = ts+'<tbody>',
\r
132 tbe = '</tbody>'+te,
\r
133 trs = tbs + '<tr>',
\r
137 var insertIntoTable = function(tag, where, el, html){
\r
139 tempTableEl = document.createElement('div');
\r
144 if(where == 'afterbegin' || where == 'beforeend'){
147 if(where == 'beforebegin'){
\r
149 el = el.parentNode;
\r
151 before = el.nextSibling;
\r
152 el = el.parentNode;
\r
154 node = ieTable(4, trs, html, tre);
\r
156 else if(tag == 'tr'){
\r
157 if(where == 'beforebegin'){
\r
159 el = el.parentNode;
\r
160 node = ieTable(3, tbs, html, tbe);
\r
161 } else if(where == 'afterend'){
\r
162 before = el.nextSibling;
\r
163 el = el.parentNode;
\r
164 node = ieTable(3, tbs, html, tbe);
\r
166 if(where == 'afterbegin'){
\r
167 before = el.firstChild;
\r
169 node = ieTable(4, trs, html, tre);
\r
171 } else if(tag == 'tbody'){
\r
172 if(where == 'beforebegin'){
\r
174 el = el.parentNode;
\r
175 node = ieTable(2, ts, html, te);
\r
176 } else if(where == 'afterend'){
\r
177 before = el.nextSibling;
\r
178 el = el.parentNode;
\r
179 node = ieTable(2, ts, html, te);
\r
181 if(where == 'afterbegin'){
\r
182 before = el.firstChild;
\r
184 node = ieTable(3, tbs, html, tbe);
\r
187 if(where == 'beforebegin' || where == 'afterend'){
190 if(where == 'afterbegin'){
\r
191 before = el.firstChild;
\r
193 node = ieTable(2, ts, html, te);
\r
195 el.insertBefore(node, before);
\r
205 markup : function(o){
\r
206 return createHtml(o);
\r
210 applyStyles : function(el, styles){
\r
213 if(typeof styles == "string"){
\r
214 var re = /\s?([a-z\-]*)\:\s?([^;]*);?/gi;
\r
216 while ((matches = re.exec(styles)) != null){
\r
217 el.setStyle(matches[1], matches[2]);
\r
219 }else if (typeof styles == "object"){
\r
220 for (var style in styles){
\r
221 el.setStyle(style, styles[style]);
\r
223 }else if (typeof styles == "function"){
\r
224 Ext.DomHelper.applyStyles(el, styles.call());
\r
230 insertHtml : function(where, el, html){
\r
231 where = where.toLowerCase();
\r
232 if(el.insertAdjacentHTML){
\r
233 if(tableRe.test(el.tagName)){
\r
235 if(rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html)){
\r
240 case "beforebegin":
\r
241 el.insertAdjacentHTML('BeforeBegin', html);
\r
242 return el.previousSibling;
\r
244 el.insertAdjacentHTML('AfterBegin', html);
\r
245 return el.firstChild;
\r
247 el.insertAdjacentHTML('BeforeEnd', html);
\r
248 return el.lastChild;
\r
250 el.insertAdjacentHTML('AfterEnd', html);
\r
251 return el.nextSibling;
\r
253 throw 'Illegal insertion point -> "' + where + '"';
\r
255 var range = el.ownerDocument.createRange();
\r
258 case "beforebegin":
\r
259 range.setStartBefore(el);
\r
260 frag = range.createContextualFragment(html);
\r
261 el.parentNode.insertBefore(frag, el);
\r
262 return el.previousSibling;
\r
265 range.setStartBefore(el.firstChild);
\r
266 frag = range.createContextualFragment(html);
\r
267 el.insertBefore(frag, el.firstChild);
\r
268 return el.firstChild;
\r
270 el.innerHTML = html;
\r
271 return el.firstChild;
\r
275 range.setStartAfter(el.lastChild);
\r
276 frag = range.createContextualFragment(html);
\r
277 el.appendChild(frag);
\r
278 return el.lastChild;
\r
280 el.innerHTML = html;
\r
281 return el.lastChild;
\r
284 range.setStartAfter(el);
\r
285 frag = range.createContextualFragment(html);
\r
286 el.parentNode.insertBefore(frag, el.nextSibling);
\r
287 return el.nextSibling;
\r
289 throw 'Illegal insertion point -> "' + where + '"';
\r
293 insertBefore : function(el, o, returnElement){
\r
294 return this.doInsert(el, o, returnElement, "beforeBegin");
\r
298 insertAfter : function(el, o, returnElement){
\r
299 return this.doInsert(el, o, returnElement, "afterEnd", "nextSibling");
\r
303 insertFirst : function(el, o, returnElement){
\r
304 return this.doInsert(el, o, returnElement, "afterBegin", "firstChild");
\r
308 doInsert : function(el, o, returnElement, pos, sibling){
\r
309 el = Ext.getDom(el);
\r
312 newNode = createDom(o, null);
\r
313 (sibling === "firstChild" ? el : el.parentNode).insertBefore(newNode, sibling ? el[sibling] : el);
\r
315 var html = createHtml(o);
\r
316 newNode = this.insertHtml(pos, el, html);
\r
318 return returnElement ? Ext.get(newNode, true) : newNode;
\r
322 append : function(el, o, returnElement){
\r
323 el = Ext.getDom(el);
\r
326 newNode = createDom(o, null);
\r
327 el.appendChild(newNode);
\r
329 var html = createHtml(o);
\r
330 newNode = this.insertHtml("beforeEnd", el, html);
\r
332 return returnElement ? Ext.get(newNode, true) : newNode;
\r
336 overwrite : function(el, o, returnElement){
\r
337 el = Ext.getDom(el);
\r
338 el.innerHTML = createHtml(o);
\r
339 return returnElement ? Ext.get(el.firstChild, true) : el.firstChild;
\r
343 createTemplate : function(o){
\r
344 var html = createHtml(o);
\r
345 return new Ext.Template(html);
\r
351 Ext.Template = function(html){
\r
353 if(Ext.isArray(html)){
\r
354 html = html.join("");
\r
355 }else if(a.length > 1){
\r
357 for(var i = 0, len = a.length; i < len; i++){
\r
358 if(typeof a[i] == 'object'){
\r
359 Ext.apply(this, a[i]);
\r
361 buf[buf.length] = a[i];
\r
364 html = buf.join('');
\r
372 Ext.Template.prototype = {
\r
374 applyTemplate : function(values){
\r
376 return this.compiled(values);
\r
378 var useF = this.disableFormats !== true;
\r
379 var fm = Ext.util.Format, tpl = this;
\r
380 var fn = function(m, name, format, args){
\r
381 if(format && useF){
\r
382 if(format.substr(0, 5) == "this."){
\r
383 return tpl.call(format.substr(5), values[name], values);
\r
389 var re = /^\s*['"](.*)["']\s*$/;
\r
390 args = args.split(',');
\r
391 for(var i = 0, len = args.length; i < len; i++){
\r
392 args[i] = args[i].replace(re, "$1");
\r
394 args = [values[name]].concat(args);
\r
396 args = [values[name]];
\r
398 return fm[format].apply(fm, args);
\r
401 return values[name] !== undefined ? values[name] : "";
\r
404 return this.html.replace(this.re, fn);
\r
408 set : function(html, compile){
\r
410 this.compiled = null;
\r
418 disableFormats : false,
\r
421 re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
\r
424 compile : function(){
\r
425 var fm = Ext.util.Format;
\r
426 var useF = this.disableFormats !== true;
\r
427 var sep = Ext.isGecko ? "+" : ",";
\r
428 var fn = function(m, name, format, args){
\r
429 if(format && useF){
\r
430 args = args ? ',' + args : "";
\r
431 if(format.substr(0, 5) != "this."){
\r
432 format = "fm." + format + '(';
\r
434 format = 'this.call("'+ format.substr(5) + '", ';
\r
438 args= ''; format = "(values['" + name + "'] == undefined ? '' : ";
\r
440 return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'";
\r
445 body = "this.compiled = function(values){ return '" +
\r
446 this.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) +
\r
449 body = ["this.compiled = function(values){ return ['"];
\r
450 body.push(this.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn));
\r
451 body.push("'].join('');};");
\r
452 body = body.join('');
\r
459 call : function(fnName, value, allValues){
\r
460 return this[fnName](value, allValues);
\r
464 insertFirst: function(el, values, returnElement){
\r
465 return this.doInsert('afterBegin', el, values, returnElement);
\r
469 insertBefore: function(el, values, returnElement){
\r
470 return this.doInsert('beforeBegin', el, values, returnElement);
\r
474 insertAfter : function(el, values, returnElement){
\r
475 return this.doInsert('afterEnd', el, values, returnElement);
\r
479 append : function(el, values, returnElement){
\r
480 return this.doInsert('beforeEnd', el, values, returnElement);
\r
483 doInsert : function(where, el, values, returnEl){
\r
484 el = Ext.getDom(el);
\r
485 var newNode = Ext.DomHelper.insertHtml(where, el, this.applyTemplate(values));
\r
486 return returnEl ? Ext.get(newNode, true) : newNode;
\r
490 overwrite : function(el, values, returnElement){
\r
491 el = Ext.getDom(el);
\r
492 el.innerHTML = this.applyTemplate(values);
\r
493 return returnElement ? Ext.get(el.firstChild, true) : el.firstChild;
\r
497 Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;
\r
500 Ext.DomHelper.Template = Ext.Template;
\r
503 Ext.Template.from = function(el, config){
\r
504 el = Ext.getDom(el);
\r
505 return new Ext.Template(el.value || el.innerHTML, config || '');
\r
509 Ext.DomQuery = function(){
\r
510 var cache = {}, simpleCache = {}, valueCache = {};
\r
511 var nonSpace = /\S/;
\r
512 var trimRe = /^\s+|\s+$/g;
\r
513 var tplRe = /\{(\d+)\}/g;
\r
514 var modeRe = /^(\s?[\/>+~]\s?|\s|$)/;
\r
515 var tagTokenRe = /^(#)?([\w-\*]+)/;
\r
516 var nthRe = /(\d*)n\+?(\d*)/, nthRe2 = /\D/;
\r
518 function child(p, index){
\r
520 var n = p.firstChild;
\r
522 if(n.nodeType == 1){
\r
533 while((n = n.nextSibling) && n.nodeType != 1);
\r
538 while((n = n.previousSibling) && n.nodeType != 1);
\r
542 function children(d){
\r
543 var n = d.firstChild, ni = -1;
\r
545 var nx = n.nextSibling;
\r
546 if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){
\r
549 n.nodeIndex = ++ni;
\r
556 function byClassName(c, a, v){
\r
560 var r = [], ri = -1, cn;
\r
561 for(var i = 0, ci; ci = c[i]; i++){
\r
562 if((' '+ci.className+' ').indexOf(v) != -1){
\r
569 function attrValue(n, attr){
\r
570 if(!n.tagName && typeof n.length != "undefined"){
\r
579 if(attr == "class" || attr == "className"){
\r
580 return n.className;
\r
582 return n.getAttribute(attr) || n[attr];
\r
586 function getNodes(ns, mode, tagName){
\r
587 var result = [], ri = -1, cs;
\r
591 tagName = tagName || "*";
\r
592 if(typeof ns.getElementsByTagName != "undefined"){
\r
596 for(var i = 0, ni; ni = ns[i]; i++){
\r
597 cs = ni.getElementsByTagName(tagName);
\r
598 for(var j = 0, ci; ci = cs[j]; j++){
\r
602 }else if(mode == "/" || mode == ">"){
\r
603 var utag = tagName.toUpperCase();
\r
604 for(var i = 0, ni, cn; ni = ns[i]; i++){
\r
605 cn = ni.children || ni.childNodes;
\r
606 for(var j = 0, cj; cj = cn[j]; j++){
\r
607 if(cj.nodeName == utag || cj.nodeName == tagName || tagName == '*'){
\r
612 }else if(mode == "+"){
\r
613 var utag = tagName.toUpperCase();
\r
614 for(var i = 0, n; n = ns[i]; i++){
\r
615 while((n = n.nextSibling) && n.nodeType != 1);
\r
616 if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){
\r
620 }else if(mode == "~"){
\r
621 for(var i = 0, n; n = ns[i]; i++){
\r
622 while((n = n.nextSibling) && (n.nodeType != 1 || (tagName == '*' || n.tagName.toLowerCase()!=tagName)));
\r
631 function concat(a, b){
\r
633 return a.concat(b);
\r
635 for(var i = 0, l = b.length; i < l; i++){
\r
636 a[a.length] = b[i];
\r
641 function byTag(cs, tagName){
\r
642 if(cs.tagName || cs == document){
\r
648 var r = [], ri = -1;
\r
649 tagName = tagName.toLowerCase();
\r
650 for(var i = 0, ci; ci = cs[i]; i++){
\r
651 if(ci.nodeType == 1 && ci.tagName.toLowerCase()==tagName){
\r
658 function byId(cs, attr, id){
\r
659 if(cs.tagName || cs == document){
\r
665 var r = [], ri = -1;
\r
666 for(var i = 0,ci; ci = cs[i]; i++){
\r
667 if(ci && ci.id == id){
\r
675 function byAttribute(cs, attr, value, op, custom){
\r
676 var r = [], ri = -1, st = custom=="{";
\r
677 var f = Ext.DomQuery.operators[op];
\r
678 for(var i = 0, ci; ci = cs[i]; i++){
\r
681 a = Ext.DomQuery.getStyle(ci, attr);
\r
683 else if(attr == "class" || attr == "className"){
\r
685 }else if(attr == "for"){
\r
687 }else if(attr == "href"){
\r
688 a = ci.getAttribute("href", 2);
\r
690 a = ci.getAttribute(attr);
\r
692 if((f && f(a, value)) || (!f && a)){
\r
699 function byPseudo(cs, name, value){
\r
700 return Ext.DomQuery.pseudos[name](cs, value);
\r
706 var isIE = window.ActiveXObject ? true : false;
\r
710 eval("var batch = 30803;");
\r
714 function nodupIEXml(cs){
\r
716 cs[0].setAttribute("_nodup", d);
\r
718 for(var i = 1, len = cs.length; i < len; i++){
\r
720 if(!c.getAttribute("_nodup") != d){
\r
721 c.setAttribute("_nodup", d);
\r
725 for(var i = 0, len = cs.length; i < len; i++){
\r
726 cs[i].removeAttribute("_nodup");
\r
731 function nodup(cs){
\r
735 var len = cs.length, c, i, r = cs, cj, ri = -1;
\r
736 if(!len || typeof cs.nodeType != "undefined" || len == 1){
\r
739 if(isIE && typeof cs[0].selectSingleNode != "undefined"){
\r
740 return nodupIEXml(cs);
\r
744 for(i = 1; c = cs[i]; i++){
\r
749 for(var j = 0; j < i; j++){
\r
752 for(j = i+1; cj = cs[j]; j++){
\r
753 if(cj._nodup != d){
\r
764 function quickDiffIEXml(c1, c2){
\r
766 for(var i = 0, len = c1.length; i < len; i++){
\r
767 c1[i].setAttribute("_qdiff", d);
\r
770 for(var i = 0, len = c2.length; i < len; i++){
\r
771 if(c2[i].getAttribute("_qdiff") != d){
\r
772 r[r.length] = c2[i];
\r
775 for(var i = 0, len = c1.length; i < len; i++){
\r
776 c1[i].removeAttribute("_qdiff");
\r
781 function quickDiff(c1, c2){
\r
782 var len1 = c1.length;
\r
786 if(isIE && c1[0].selectSingleNode){
\r
787 return quickDiffIEXml(c1, c2);
\r
790 for(var i = 0; i < len1; i++){
\r
794 for(var i = 0, len = c2.length; i < len; i++){
\r
795 if(c2[i]._qdiff != d){
\r
796 r[r.length] = c2[i];
\r
802 function quickId(ns, mode, root, id){
\r
804 var d = root.ownerDocument || root;
\r
805 return d.getElementById(id);
\r
807 ns = getNodes(ns, mode, "*");
\r
808 return byId(ns, null, id);
\r
812 getStyle : function(el, name){
\r
813 return Ext.fly(el).getStyle(name);
\r
816 compile : function(path, type){
\r
817 type = type || "select";
\r
819 var fn = ["var f = function(root){\n var mode; ++batch; var n = root || document;\n"];
\r
820 var q = path, mode, lq;
\r
821 var tk = Ext.DomQuery.matchers;
\r
822 var tklen = tk.length;
\r
826 var lmode = q.match(modeRe);
\r
827 if(lmode && lmode[1]){
\r
828 fn[fn.length] = 'mode="'+lmode[1].replace(trimRe, "")+'";';
\r
829 q = q.replace(lmode[1], "");
\r
832 while(path.substr(0, 1)=="/"){
\r
833 path = path.substr(1);
\r
836 while(q && lq != q){
\r
838 var tm = q.match(tagTokenRe);
\r
839 if(type == "select"){
\r
842 fn[fn.length] = 'n = quickId(n, mode, root, "'+tm[2]+'");';
\r
844 fn[fn.length] = 'n = getNodes(n, mode, "'+tm[2]+'");';
\r
846 q = q.replace(tm[0], "");
\r
847 }else if(q.substr(0, 1) != '@'){
\r
848 fn[fn.length] = 'n = getNodes(n, mode, "*");';
\r
853 fn[fn.length] = 'n = byId(n, null, "'+tm[2]+'");';
\r
855 fn[fn.length] = 'n = byTag(n, "'+tm[2]+'");';
\r
857 q = q.replace(tm[0], "");
\r
860 while(!(mm = q.match(modeRe))){
\r
861 var matched = false;
\r
862 for(var j = 0; j < tklen; j++){
\r
864 var m = q.match(t.re);
\r
866 fn[fn.length] = t.select.replace(tplRe, function(x, i){
\r
869 q = q.replace(m[0], "");
\r
876 throw 'Error parsing selector, parsing failed at "' + q + '"';
\r
880 fn[fn.length] = 'mode="'+mm[1].replace(trimRe, "")+'";';
\r
881 q = q.replace(mm[1], "");
\r
884 fn[fn.length] = "return nodup(n);\n}";
\r
890 select : function(path, root, type){
\r
891 if(!root || root == document){
\r
894 if(typeof root == "string"){
\r
895 root = document.getElementById(root);
\r
897 var paths = path.split(",");
\r
899 for(var i = 0, len = paths.length; i < len; i++){
\r
900 var p = paths[i].replace(trimRe, "");
\r
902 cache[p] = Ext.DomQuery.compile(p);
\r
904 throw p + " is not a valid selector";
\r
907 var result = cache[p](root);
\r
908 if(result && result != document){
\r
909 results = results.concat(result);
\r
912 if(paths.length > 1){
\r
913 return nodup(results);
\r
919 selectNode : function(path, root){
\r
920 return Ext.DomQuery.select(path, root)[0];
\r
924 selectValue : function(path, root, defaultValue){
\r
925 path = path.replace(trimRe, "");
\r
926 if(!valueCache[path]){
\r
927 valueCache[path] = Ext.DomQuery.compile(path, "select");
\r
929 var n = valueCache[path](root);
\r
930 n = n[0] ? n[0] : n;
\r
931 var v = (n && n.firstChild ? n.firstChild.nodeValue : null);
\r
932 return ((v === null||v === undefined||v==='') ? defaultValue : v);
\r
936 selectNumber : function(path, root, defaultValue){
\r
937 var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0);
\r
938 return parseFloat(v);
\r
942 is : function(el, ss){
\r
943 if(typeof el == "string"){
\r
944 el = document.getElementById(el);
\r
946 var isArray = Ext.isArray(el);
\r
947 var result = Ext.DomQuery.filter(isArray ? el : [el], ss);
\r
948 return isArray ? (result.length == el.length) : (result.length > 0);
\r
952 filter : function(els, ss, nonMatches){
\r
953 ss = ss.replace(trimRe, "");
\r
954 if(!simpleCache[ss]){
\r
955 simpleCache[ss] = Ext.DomQuery.compile(ss, "simple");
\r
957 var result = simpleCache[ss](els);
\r
958 return nonMatches ? quickDiff(result, els) : result;
\r
964 select: 'n = byClassName(n, null, " {1} ");'
\r
966 re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,
\r
967 select: 'n = byPseudo(n, "{1}", "{2}");'
\r
969 re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,
\r
970 select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'
\r
973 select: 'n = byId(n, null, "{1}");'
\r
976 select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
\r
982 "=" : function(a, v){
\r
985 "!=" : function(a, v){
\r
988 "^=" : function(a, v){
\r
989 return a && a.substr(0, v.length) == v;
\r
991 "$=" : function(a, v){
\r
992 return a && a.substr(a.length-v.length) == v;
\r
994 "*=" : function(a, v){
\r
995 return a && a.indexOf(v) !== -1;
\r
997 "%=" : function(a, v){
\r
998 return (a % v) == 0;
\r
1000 "|=" : function(a, v){
\r
1001 return a && (a == v || a.substr(0, v.length+1) == v+'-');
\r
1003 "~=" : function(a, v){
\r
1004 return a && (' '+a+' ').indexOf(' '+v+' ') != -1;
\r
1010 "first-child" : function(c){
\r
1011 var r = [], ri = -1, n;
\r
1012 for(var i = 0, ci; ci = n = c[i]; i++){
\r
1013 while((n = n.previousSibling) && n.nodeType != 1);
\r
1021 "last-child" : function(c){
\r
1022 var r = [], ri = -1, n;
\r
1023 for(var i = 0, ci; ci = n = c[i]; i++){
\r
1024 while((n = n.nextSibling) && n.nodeType != 1);
\r
1032 "nth-child" : function(c, a) {
\r
1033 var r = [], ri = -1;
\r
1034 var m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a);
\r
1035 var f = (m[1] || 1) - 0, l = m[2] - 0;
\r
1036 for(var i = 0, n; n = c[i]; i++){
\r
1037 var pn = n.parentNode;
\r
1038 if (batch != pn._batch) {
\r
1040 for(var cn = pn.firstChild; cn; cn = cn.nextSibling){
\r
1041 if(cn.nodeType == 1){
\r
1042 cn.nodeIndex = ++j;
\r
1045 pn._batch = batch;
\r
1048 if (l == 0 || n.nodeIndex == l){
\r
1051 } else if ((n.nodeIndex + l) % f == 0){
\r
1059 "only-child" : function(c){
\r
1060 var r = [], ri = -1;;
\r
1061 for(var i = 0, ci; ci = c[i]; i++){
\r
1062 if(!prev(ci) && !next(ci)){
\r
1069 "empty" : function(c){
\r
1070 var r = [], ri = -1;
\r
1071 for(var i = 0, ci; ci = c[i]; i++){
\r
1072 var cns = ci.childNodes, j = 0, cn, empty = true;
\r
1073 while(cn = cns[j]){
\r
1075 if(cn.nodeType == 1 || cn.nodeType == 3){
\r
1087 "contains" : function(c, v){
\r
1088 var r = [], ri = -1;
\r
1089 for(var i = 0, ci; ci = c[i]; i++){
\r
1090 if((ci.textContent||ci.innerText||'').indexOf(v) != -1){
\r
1097 "nodeValue" : function(c, v){
\r
1098 var r = [], ri = -1;
\r
1099 for(var i = 0, ci; ci = c[i]; i++){
\r
1100 if(ci.firstChild && ci.firstChild.nodeValue == v){
\r
1107 "checked" : function(c){
\r
1108 var r = [], ri = -1;
\r
1109 for(var i = 0, ci; ci = c[i]; i++){
\r
1110 if(ci.checked == true){
\r
1117 "not" : function(c, ss){
\r
1118 return Ext.DomQuery.filter(c, ss, true);
\r
1121 "any" : function(c, selectors){
\r
1122 var ss = selectors.split('|');
\r
1123 var r = [], ri = -1, s;
\r
1124 for(var i = 0, ci; ci = c[i]; i++){
\r
1125 for(var j = 0; s = ss[j]; j++){
\r
1126 if(Ext.DomQuery.is(ci, s)){
\r
1135 "odd" : function(c){
\r
1136 return this["nth-child"](c, "odd");
\r
1139 "even" : function(c){
\r
1140 return this["nth-child"](c, "even");
\r
1143 "nth" : function(c, a){
\r
1144 return c[a-1] || [];
\r
1147 "first" : function(c){
\r
1148 return c[0] || [];
\r
1151 "last" : function(c){
\r
1152 return c[c.length-1] || [];
\r
1155 "has" : function(c, ss){
\r
1156 var s = Ext.DomQuery.select;
\r
1157 var r = [], ri = -1;
\r
1158 for(var i = 0, ci; ci = c[i]; i++){
\r
1159 if(s(ss, ci).length > 0){
\r
1166 "next" : function(c, ss){
\r
1167 var is = Ext.DomQuery.is;
\r
1168 var r = [], ri = -1;
\r
1169 for(var i = 0, ci; ci = c[i]; i++){
\r
1171 if(n && is(n, ss)){
\r
1178 "prev" : function(c, ss){
\r
1179 var is = Ext.DomQuery.is;
\r
1180 var r = [], ri = -1;
\r
1181 for(var i = 0, ci; ci = c[i]; i++){
\r
1183 if(n && is(n, ss)){
\r
1194 Ext.query = Ext.DomQuery.select;
\r
1197 Ext.util.Observable = function(){
1200 this.on(this.listeners);
1201 delete this.listeners;
1204 Ext.util.Observable.prototype = {
1206 fireEvent : function(){
1207 if(this.eventsSuspended !== true){
1208 var ce = this.events[arguments[0].toLowerCase()];
1209 if(typeof ce == "object"){
1210 return ce.fire.apply(ce, Array.prototype.slice.call(arguments, 1));
1216 filterOptRe : /^(?:scope|delay|buffer|single)$/,
1219 addListener : function(eventName, fn, scope, o){
1220 if(typeof eventName == "object"){
1223 if(this.filterOptRe.test(e)){
1226 if(typeof o[e] == "function"){
1227 this.addListener(e, o[e], o.scope, o);
1229 this.addListener(e, o[e].fn, o[e].scope, o[e]);
1234 o = (!o || typeof o == "boolean") ? {} : o;
1235 eventName = eventName.toLowerCase();
1236 var ce = this.events[eventName] || true;
1237 if(typeof ce == "boolean"){
1238 ce = new Ext.util.Event(this, eventName);
1239 this.events[eventName] = ce;
1241 ce.addListener(fn, scope, o);
1245 removeListener : function(eventName, fn, scope){
1246 var ce = this.events[eventName.toLowerCase()];
1247 if(typeof ce == "object"){
1248 ce.removeListener(fn, scope);
1253 purgeListeners : function(){
1254 for(var evt in this.events){
1255 if(typeof this.events[evt] == "object"){
1256 this.events[evt].clearListeners();
1261 relayEvents : function(o, events){
1262 var createHandler = function(ename){
1264 return this.fireEvent.apply(this, Ext.combine(ename, Array.prototype.slice.call(arguments, 0)));
1267 for(var i = 0, len = events.length; i < len; i++){
1268 var ename = events[i];
1269 if(!this.events[ename]){ this.events[ename] = true; };
1270 o.on(ename, createHandler(ename), this);
1275 addEvents : function(o){
1279 if(typeof o == 'string'){
1280 for(var i = 0, a = arguments, v; v = a[i]; i++){
1281 if(!this.events[a[i]]){
1286 Ext.applyIf(this.events, o);
1291 hasListener : function(eventName){
1292 var e = this.events[eventName];
1293 return typeof e == "object" && e.listeners.length > 0;
1297 suspendEvents : function(){
1298 this.eventsSuspended = true;
1302 resumeEvents : function(){
1303 this.eventsSuspended = false;
1306 getMethodEvent : function(method){
1307 if(!this.methodEvents){
1308 this.methodEvents = {};
1310 var e = this.methodEvents[method];
1313 this.methodEvents[method] = e;
1315 e.originalFn = this[method];
1316 e.methodName = method;
1321 var returnValue, v, cancel;
1324 var makeCall = function(fn, scope, args){
1325 if((v = fn.apply(scope || obj, args)) !== undefined){
1326 if(typeof v === 'object'){
1327 if(v.returnValue !== undefined){
1328 returnValue = v.returnValue;
1332 if(v.cancel === true){
1335 }else if(v === false){
1343 this[method] = function(){
1344 returnValue = v = undefined; cancel = false;
1345 var args = Array.prototype.slice.call(arguments, 0);
1346 for(var i = 0, len = e.before.length; i < len; i++){
1347 makeCall(e.before[i].fn, e.before[i].scope, args);
1353 if((v = e.originalFn.apply(obj, args)) !== undefined){
1357 for(var i = 0, len = e.after.length; i < len; i++){
1358 makeCall(e.after[i].fn, e.after[i].scope, args);
1369 beforeMethod : function(method, fn, scope){
1370 var e = this.getMethodEvent(method);
1371 e.before.push({fn: fn, scope: scope});
1374 afterMethod : function(method, fn, scope){
1375 var e = this.getMethodEvent(method);
1376 e.after.push({fn: fn, scope: scope});
1379 removeMethodListener : function(method, fn, scope){
1380 var e = this.getMethodEvent(method);
1381 for(var i = 0, len = e.before.length; i < len; i++){
1382 if(e.before[i].fn == fn && e.before[i].scope == scope){
1383 e.before.splice(i, 1);
1387 for(var i = 0, len = e.after.length; i < len; i++){
1388 if(e.after[i].fn == fn && e.after[i].scope == scope){
1389 e.after.splice(i, 1);
1396 Ext.util.Observable.prototype.on = Ext.util.Observable.prototype.addListener;
1398 Ext.util.Observable.prototype.un = Ext.util.Observable.prototype.removeListener;
1401 Ext.util.Observable.capture = function(o, fn, scope){
1402 o.fireEvent = o.fireEvent.createInterceptor(fn, scope);
1406 Ext.util.Observable.releaseCapture = function(o){
1407 o.fireEvent = Ext.util.Observable.prototype.fireEvent;
1412 var createBuffered = function(h, o, scope){
1413 var task = new Ext.util.DelayedTask();
1415 task.delay(o.buffer, h, scope, Array.prototype.slice.call(arguments, 0));
1419 var createSingle = function(h, e, fn, scope){
1421 e.removeListener(fn, scope);
1422 return h.apply(scope, arguments);
1426 var createDelayed = function(h, o, scope){
1428 var args = Array.prototype.slice.call(arguments, 0);
1429 setTimeout(function(){
1430 h.apply(scope, args);
1435 Ext.util.Event = function(obj, name){
1438 this.listeners = [];
1441 Ext.util.Event.prototype = {
1442 addListener : function(fn, scope, options){
1443 scope = scope || this.obj;
1444 if(!this.isListening(fn, scope)){
1445 var l = this.createListener(fn, scope, options);
1447 this.listeners.push(l);
1448 }else{ this.listeners = this.listeners.slice(0);
1449 this.listeners.push(l);
1454 createListener : function(fn, scope, o){
1456 scope = scope || this.obj;
1457 var l = {fn: fn, scope: scope, options: o};
1460 h = createDelayed(h, o, scope);
1463 h = createSingle(h, this, fn, scope);
1466 h = createBuffered(h, o, scope);
1472 findListener : function(fn, scope){
1473 scope = scope || this.obj;
1474 var ls = this.listeners;
1475 for(var i = 0, len = ls.length; i < len; i++){
1477 if(l.fn == fn && l.scope == scope){
1484 isListening : function(fn, scope){
1485 return this.findListener(fn, scope) != -1;
1488 removeListener : function(fn, scope){
1490 if((index = this.findListener(fn, scope)) != -1){
1492 this.listeners.splice(index, 1);
1494 this.listeners = this.listeners.slice(0);
1495 this.listeners.splice(index, 1);
1502 clearListeners : function(){
1503 this.listeners = [];
1507 var ls = this.listeners, scope, len = ls.length;
1510 var args = Array.prototype.slice.call(arguments, 0);
1511 for(var i = 0; i < len; i++){
1513 if(l.fireFn.apply(l.scope||this.obj||window, arguments) === false){
1514 this.firing = false;
1518 this.firing = false;
1525 Ext.EventManager = function(){
\r
1526 var docReadyEvent, docReadyProcId, docReadyState = false;
\r
1527 var resizeEvent, resizeTask, textEvent, textSize;
\r
1528 var E = Ext.lib.Event;
\r
1529 var D = Ext.lib.Dom;
\r
1532 var fireDocReady = function(){
\r
1533 if(!docReadyState){
\r
1534 docReadyState = true;
\r
1535 Ext.isReady = true;
\r
1536 if(docReadyProcId){
\r
1537 clearInterval(docReadyProcId);
\r
1539 if(Ext.isGecko || Ext.isOpera) {
\r
1540 document.removeEventListener("DOMContentLoaded", fireDocReady, false);
\r
1543 var defer = document.getElementById("ie-deferred-loader");
\r
1545 defer.onreadystatechange = null;
\r
1546 defer.parentNode.removeChild(defer);
\r
1549 if(docReadyEvent){
\r
1550 docReadyEvent.fire();
\r
1551 docReadyEvent.clearListeners();
\r
1556 var initDocReady = function(){
\r
1557 docReadyEvent = new Ext.util.Event();
\r
1558 if(Ext.isGecko || Ext.isOpera) {
\r
1559 document.addEventListener("DOMContentLoaded", fireDocReady, false);
\r
1560 }else if(Ext.isIE){
\r
1561 document.write("<s"+'cript id="ie-deferred-loader" defer="defer" src="/'+'/:"></s'+"cript>");
\r
1562 var defer = document.getElementById("ie-deferred-loader");
\r
1563 defer.onreadystatechange = function(){
\r
1564 if(this.readyState == "complete"){
\r
1568 }else if(Ext.isSafari){
\r
1569 docReadyProcId = setInterval(function(){
\r
1570 var rs = document.readyState;
\r
1571 if(rs == "complete") {
\r
1577 E.on(window, "load", fireDocReady);
\r
1580 var createBuffered = function(h, o){
\r
1581 var task = new Ext.util.DelayedTask(h);
\r
1582 return function(e){
\r
1584 e = new Ext.EventObjectImpl(e);
\r
1585 task.delay(o.buffer, h, null, [e]);
\r
1589 var createSingle = function(h, el, ename, fn){
\r
1590 return function(e){
\r
1591 Ext.EventManager.removeListener(el, ename, fn);
\r
1596 var createDelayed = function(h, o){
\r
1597 return function(e){
\r
1599 e = new Ext.EventObjectImpl(e);
\r
1600 setTimeout(function(){
\r
1602 }, o.delay || 10);
\r
1606 var listen = function(element, ename, opt, fn, scope){
\r
1607 var o = (!opt || typeof opt == "boolean") ? {} : opt;
\r
1608 fn = fn || o.fn; scope = scope || o.scope;
\r
1609 var el = Ext.getDom(element);
\r
1611 throw "Error listening for \"" + ename + '\". Element "' + element + '" doesn\'t exist.';
\r
1613 var h = function(e){
\r
1614 e = Ext.EventObject.setEvent(e);
\r
1617 t = e.getTarget(o.delegate, el);
\r
1624 if(o.stopEvent === true){
\r
1627 if(o.preventDefault === true){
\r
1628 e.preventDefault();
\r
1630 if(o.stopPropagation === true){
\r
1631 e.stopPropagation();
\r
1634 if(o.normalized === false){
\r
1635 e = e.browserEvent;
\r
1638 fn.call(scope || el, e, t, o);
\r
1641 h = createDelayed(h, o);
\r
1644 h = createSingle(h, el, ename, fn);
\r
1647 h = createBuffered(h, o);
\r
1649 fn._handlers = fn._handlers || [];
\r
1650 fn._handlers.push([Ext.id(el), ename, h]);
\r
1652 E.on(el, ename, h);
\r
1653 if(ename == "mousewheel" && el.addEventListener){
1654 el.addEventListener("DOMMouseScroll", h, false);
\r
1655 E.on(window, 'unload', function(){
\r
1656 el.removeEventListener("DOMMouseScroll", h, false);
\r
1659 if(ename == "mousedown" && el == document){
1660 Ext.EventManager.stoppedMouseDownEvent.addListener(h);
\r
1665 var stopListening = function(el, ename, fn){
\r
1666 var id = Ext.id(el), hds = fn._handlers, hd = fn;
\r
1668 for(var i = 0, len = hds.length; i < len; i++){
\r
1670 if(h[0] == id && h[1] == ename){
\r
1677 E.un(el, ename, hd);
\r
1678 el = Ext.getDom(el);
\r
1679 if(ename == "mousewheel" && el.addEventListener){
\r
1680 el.removeEventListener("DOMMouseScroll", hd, false);
\r
1682 if(ename == "mousedown" && el == document){
1683 Ext.EventManager.stoppedMouseDownEvent.removeListener(hd);
\r
1687 var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
\r
1691 addListener : function(element, eventName, fn, scope, options){
\r
1692 if(typeof eventName == "object"){
\r
1693 var o = eventName;
\r
1695 if(propRe.test(e)){
\r
1698 if(typeof o[e] == "function"){
\r
1700 listen(element, e, o, o[e], o.scope);
\r
1703 listen(element, e, o[e]);
\r
1708 return listen(element, eventName, options, fn, scope);
\r
1712 removeListener : function(element, eventName, fn){
\r
1713 return stopListening(element, eventName, fn);
\r
1717 onDocumentReady : function(fn, scope, options){
\r
1719 docReadyEvent.addListener(fn, scope, options);
\r
1720 docReadyEvent.fire();
\r
1721 docReadyEvent.clearListeners();
\r
1724 if(!docReadyEvent){
\r
1727 docReadyEvent.addListener(fn, scope, options);
\r
1731 onWindowResize : function(fn, scope, options){
\r
1733 resizeEvent = new Ext.util.Event();
\r
1734 resizeTask = new Ext.util.DelayedTask(function(){
\r
1735 resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
\r
1737 E.on(window, "resize", this.fireWindowResize, this);
\r
1739 resizeEvent.addListener(fn, scope, options);
\r
1743 fireWindowResize : function(){
\r
1745 if((Ext.isIE||Ext.isAir) && resizeTask){
\r
1746 resizeTask.delay(50);
\r
1748 resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
\r
1754 onTextResize : function(fn, scope, options){
\r
1756 textEvent = new Ext.util.Event();
\r
1757 var textEl = new Ext.Element(document.createElement('div'));
\r
1758 textEl.dom.className = 'x-text-resize';
\r
1759 textEl.dom.innerHTML = 'X';
\r
1760 textEl.appendTo(document.body);
\r
1761 textSize = textEl.dom.offsetHeight;
\r
1762 setInterval(function(){
\r
1763 if(textEl.dom.offsetHeight != textSize){
\r
1764 textEvent.fire(textSize, textSize = textEl.dom.offsetHeight);
\r
1766 }, this.textResizeInterval);
\r
1768 textEvent.addListener(fn, scope, options);
\r
1772 removeResizeListener : function(fn, scope){
\r
1774 resizeEvent.removeListener(fn, scope);
\r
1779 fireResize : function(){
\r
1781 resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
\r
1785 ieDeferSrc : false,
\r
1787 textResizeInterval : 50
\r
1790 pub.on = pub.addListener;
\r
1792 pub.un = pub.removeListener;
\r
1794 pub.stoppedMouseDownEvent = new Ext.util.Event();
\r
1798 Ext.onReady = Ext.EventManager.onDocumentReady;
\r
1800 Ext.onReady(function(){
\r
1801 var bd = Ext.getBody();
\r
1802 if(!bd){ return; }
\r
1805 Ext.isIE ? "ext-ie " + (Ext.isIE6 ? 'ext-ie6' : 'ext-ie7')
\r
1806 : Ext.isGecko ? "ext-gecko"
\r
1807 : Ext.isOpera ? "ext-opera"
\r
1808 : Ext.isSafari ? "ext-safari" : ""];
\r
1811 cls.push("ext-mac");
\r
1814 cls.push("ext-linux");
\r
1816 if(Ext.isBorderBox){
\r
1817 cls.push('ext-border-box');
\r
1820 var p = bd.dom.parentNode;
\r
1822 p.className += ' ext-strict';
\r
1825 bd.addClass(cls.join(' '));
\r
1829 Ext.EventObject = function(){
\r
1831 var E = Ext.lib.Event;
\r
1834 var safariKeys = {
\r
1847 var btnMap = Ext.isIE ? {1:0,4:1,2:2} :
\r
1848 (Ext.isSafari ? {1:0,2:1,3:2} : {0:0,1:1,2:2});
\r
1850 Ext.EventObjectImpl = function(e){
\r
1852 this.setEvent(e.browserEvent || e);
\r
1855 Ext.EventObjectImpl.prototype = {
\r
1857 browserEvent : null,
\r
1905 setEvent : function(e){
\r
1906 if(e == this || (e && e.browserEvent)){
1909 this.browserEvent = e;
\r
1912 this.button = e.button ? btnMap[e.button] : (e.which ? e.which-1 : -1);
\r
1913 if(e.type == 'click' && this.button == -1){
\r
1916 this.type = e.type;
\r
1917 this.shiftKey = e.shiftKey;
\r
1919 this.ctrlKey = e.ctrlKey || e.metaKey;
\r
1920 this.altKey = e.altKey;
\r
1922 this.keyCode = e.keyCode;
\r
1923 this.charCode = e.charCode;
\r
1925 this.target = E.getTarget(e);
\r
1927 this.xy = E.getXY(e);
\r
1930 this.shiftKey = false;
\r
1931 this.ctrlKey = false;
\r
1932 this.altKey = false;
\r
1935 this.target = null;
\r
1942 stopEvent : function(){
\r
1943 if(this.browserEvent){
\r
1944 if(this.browserEvent.type == 'mousedown'){
\r
1945 Ext.EventManager.stoppedMouseDownEvent.fire(this);
\r
1947 E.stopEvent(this.browserEvent);
\r
1952 preventDefault : function(){
\r
1953 if(this.browserEvent){
\r
1954 E.preventDefault(this.browserEvent);
\r
1959 isNavKeyPress : function(){
\r
1960 var k = this.keyCode;
\r
1961 k = Ext.isSafari ? (safariKeys[k] || k) : k;
\r
1962 return (k >= 33 && k <= 40) || k == this.RETURN || k == this.TAB || k == this.ESC;
\r
1965 isSpecialKey : function(){
\r
1966 var k = this.keyCode;
\r
1967 return (this.type == 'keypress' && this.ctrlKey) || k == 9 || k == 13 || k == 40 || k == 27 ||
\r
1968 (k == 16) || (k == 17) ||
\r
1969 (k >= 18 && k <= 20) ||
\r
1970 (k >= 33 && k <= 35) ||
\r
1971 (k >= 36 && k <= 39) ||
\r
1972 (k >= 44 && k <= 45);
\r
1975 stopPropagation : function(){
\r
1976 if(this.browserEvent){
\r
1977 if(this.browserEvent.type == 'mousedown'){
\r
1978 Ext.EventManager.stoppedMouseDownEvent.fire(this);
\r
1980 E.stopPropagation(this.browserEvent);
\r
1985 getCharCode : function(){
\r
1986 return this.charCode || this.keyCode;
\r
1990 getKey : function(){
\r
1991 var k = this.keyCode || this.charCode;
\r
1992 return Ext.isSafari ? (safariKeys[k] || k) : k;
\r
1996 getPageX : function(){
\r
1997 return this.xy[0];
\r
2001 getPageY : function(){
\r
2002 return this.xy[1];
\r
2006 getTime : function(){
\r
2007 if(this.browserEvent){
\r
2008 return E.getTime(this.browserEvent);
\r
2014 getXY : function(){
\r
2019 getTarget : function(selector, maxDepth, returnEl){
\r
2020 var t = Ext.get(this.target);
\r
2021 return selector ? t.findParent(selector, maxDepth, returnEl) : (returnEl ? t : this.target);
\r
2025 getRelatedTarget : function(){
\r
2026 if(this.browserEvent){
\r
2027 return E.getRelatedTarget(this.browserEvent);
\r
2033 getWheelDelta : function(){
\r
2034 var e = this.browserEvent;
\r
2036 if(e.wheelDelta){
\r
2037 delta = e.wheelDelta/120;
\r
2038 }else if(e.detail){
\r
2039 delta = -e.detail/3;
\r
2045 hasModifier : function(){
\r
2046 return ((this.ctrlKey || this.altKey) || this.shiftKey) ? true : false;
\r
2050 within : function(el, related){
\r
2051 var t = this[related ? "getRelatedTarget" : "getTarget"]();
\r
2052 return t && Ext.fly(el).contains(t);
\r
2055 getPoint : function(){
\r
2056 return new Ext.lib.Point(this.xy[0], this.xy[1]);
\r
2060 return new Ext.EventObjectImpl();
\r
2064 var D = Ext.lib.Dom;
2065 var E = Ext.lib.Event;
2066 var A = Ext.lib.Anim;
2069 var camelRe = /(-[a-z])/gi;
2070 var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };
2071 var view = document.defaultView;
2073 Ext.Element = function(element, forceNew){
2074 var dom = typeof element == "string" ?
2075 document.getElementById(element) : element;
2076 if(!dom){ return null;
2079 if(forceNew !== true && id && Ext.Element.cache[id]){ return Ext.Element.cache[id];
2086 this.id = id || Ext.id(dom);
2089 var El = Ext.Element;
2093 originalDisplay : "",
2099 setVisibilityMode : function(visMode){
2100 this.visibilityMode = visMode;
2104 enableDisplayMode : function(display){
2105 this.setVisibilityMode(El.DISPLAY);
2106 if(typeof display != "undefined") this.originalDisplay = display;
2111 findParent : function(simpleSelector, maxDepth, returnEl){
2112 var p = this.dom, b = document.body, depth = 0, dq = Ext.DomQuery, stopEl;
2113 maxDepth = maxDepth || 50;
2114 if(typeof maxDepth != "number"){
2115 stopEl = Ext.getDom(maxDepth);
2118 while(p && p.nodeType == 1 && depth < maxDepth && p != b && p != stopEl){
2119 if(dq.is(p, simpleSelector)){
2120 return returnEl ? Ext.get(p) : p;
2130 findParentNode : function(simpleSelector, maxDepth, returnEl){
2131 var p = Ext.fly(this.dom.parentNode, '_internal');
2132 return p ? p.findParent(simpleSelector, maxDepth, returnEl) : null;
2136 up : function(simpleSelector, maxDepth){
2137 return this.findParentNode(simpleSelector, maxDepth, true);
2143 is : function(simpleSelector){
2144 return Ext.DomQuery.is(this.dom, simpleSelector);
2148 animate : function(args, duration, onComplete, easing, animType){
2149 this.anim(args, {duration: duration, callback: onComplete, easing: easing}, animType);
2154 anim : function(args, opt, animType, defaultDur, defaultEase, cb){
2155 animType = animType || 'run';
2157 var anim = Ext.lib.Anim[animType](
2159 (opt.duration || defaultDur) || .35,
2160 (opt.easing || defaultEase) || 'easeOut',
2162 Ext.callback(cb, this);
2163 Ext.callback(opt.callback, opt.scope || this, [this, opt]);
2171 preanim : function(a, i){
2172 return !a[i] ? false : (typeof a[i] == "object" ? a[i]: {duration: a[i+1], callback: a[i+2], easing: a[i+3]});
2176 clean : function(forceReclean){
2177 if(this.isCleaned && forceReclean !== true){
2181 var d = this.dom, n = d.firstChild, ni = -1;
2183 var nx = n.nextSibling;
2184 if(n.nodeType == 3 && !ns.test(n.nodeValue)){
2191 this.isCleaned = true;
2196 scrollIntoView : function(container, hscroll){
2197 var c = Ext.getDom(container) || Ext.getBody().dom;
2200 var o = this.getOffsetsTo(c),
2201 l = o[0] + c.scrollLeft,
2202 t = o[1] + c.scrollTop,
2203 b = t+el.offsetHeight,
2204 r = l+el.offsetWidth;
2206 var ch = c.clientHeight;
2207 var ct = parseInt(c.scrollTop, 10);
2208 var cl = parseInt(c.scrollLeft, 10);
2210 var cr = cl + c.clientWidth;
2212 if(el.offsetHeight > ch || t < ct){
2217 c.scrollTop = c.scrollTop;
2218 if(hscroll !== false){
2219 if(el.offsetWidth > c.clientWidth || l < cl){
2222 c.scrollLeft = r-c.clientWidth;
2224 c.scrollLeft = c.scrollLeft;
2229 scrollChildIntoView : function(child, hscroll){
2230 Ext.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll);
2234 autoHeight : function(animate, duration, onComplete, easing){
2235 var oldHeight = this.getHeight();
2237 this.setHeight(1); setTimeout(function(){
2238 var height = parseInt(this.dom.scrollHeight, 10); if(!animate){
2239 this.setHeight(height);
2241 if(typeof onComplete == "function"){
2245 this.setHeight(oldHeight); this.setHeight(height, animate, duration, function(){
2247 if(typeof onComplete == "function") onComplete();
2248 }.createDelegate(this), easing);
2250 }.createDelegate(this), 0);
2255 contains : function(el){
2256 if(!el){return false;}
2257 return D.isAncestor(this.dom, el.dom ? el.dom : el);
2261 isVisible : function(deep) {
2262 var vis = !(this.getStyle("visibility") == "hidden" || this.getStyle("display") == "none");
2263 if(deep !== true || !vis){
2266 var p = this.dom.parentNode;
2267 while(p && p.tagName.toLowerCase() != "body"){
2268 if(!Ext.fly(p, '_isVisible').isVisible()){
2277 select : function(selector, unique){
2278 return El.select(selector, unique, this.dom);
2282 query : function(selector, unique){
2283 return Ext.DomQuery.select(selector, this.dom);
2287 child : function(selector, returnDom){
2288 var n = Ext.DomQuery.selectNode(selector, this.dom);
2289 return returnDom ? n : Ext.get(n);
2293 down : function(selector, returnDom){
2294 var n = Ext.DomQuery.selectNode(" > " + selector, this.dom);
2295 return returnDom ? n : Ext.get(n);
2299 initDD : function(group, config, overrides){
2300 var dd = new Ext.dd.DD(Ext.id(this.dom), group, config);
2301 return Ext.apply(dd, overrides);
2305 initDDProxy : function(group, config, overrides){
2306 var dd = new Ext.dd.DDProxy(Ext.id(this.dom), group, config);
2307 return Ext.apply(dd, overrides);
2311 initDDTarget : function(group, config, overrides){
2312 var dd = new Ext.dd.DDTarget(Ext.id(this.dom), group, config);
2313 return Ext.apply(dd, overrides);
2317 setVisible : function(visible, animate){
2319 if(this.visibilityMode == El.DISPLAY){
2320 this.setDisplayed(visible);
2323 this.dom.style.visibility = visible ? "visible" : "hidden";
2327 var visMode = this.visibilityMode;
2329 this.setOpacity(.01);
2330 this.setVisible(true);
2332 this.anim({opacity: { to: (visible?1:0) }},
2333 this.preanim(arguments, 1),
2334 null, .35, 'easeIn', function(){
2336 if(visMode == El.DISPLAY){
2337 dom.style.display = "none";
2339 dom.style.visibility = "hidden";
2341 Ext.get(dom).setOpacity(1);
2349 isDisplayed : function() {
2350 return this.getStyle("display") != "none";
2354 toggle : function(animate){
2355 this.setVisible(!this.isVisible(), this.preanim(arguments, 0));
2360 setDisplayed : function(value) {
2361 if(typeof value == "boolean"){
2362 value = value ? this.originalDisplay : "none";
2364 this.setStyle("display", value);
2369 focus : function() {
2385 addClass : function(className){
2386 if(Ext.isArray(className)){
2387 for(var i = 0, len = className.length; i < len; i++) {
2388 this.addClass(className[i]);
2391 if(className && !this.hasClass(className)){
2392 this.dom.className = this.dom.className + " " + className;
2399 radioClass : function(className){
2400 var siblings = this.dom.parentNode.childNodes;
2401 for(var i = 0; i < siblings.length; i++) {
2402 var s = siblings[i];
2403 if(s.nodeType == 1){
2404 Ext.get(s).removeClass(className);
2407 this.addClass(className);
2412 removeClass : function(className){
2413 if(!className || !this.dom.className){
2416 if(Ext.isArray(className)){
2417 for(var i = 0, len = className.length; i < len; i++) {
2418 this.removeClass(className[i]);
2421 if(this.hasClass(className)){
2422 var re = this.classReCache[className];
2424 re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)', "g");
2425 this.classReCache[className] = re;
2427 this.dom.className =
2428 this.dom.className.replace(re, " ");
2437 toggleClass : function(className){
2438 if(this.hasClass(className)){
2439 this.removeClass(className);
2441 this.addClass(className);
2447 hasClass : function(className){
2448 return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1;
2452 replaceClass : function(oldClassName, newClassName){
2453 this.removeClass(oldClassName);
2454 this.addClass(newClassName);
2459 getStyles : function(){
2460 var a = arguments, len = a.length, r = {};
2461 for(var i = 0; i < len; i++){
2462 r[a[i]] = this.getStyle(a[i]);
2468 getStyle : function(){
2469 return view && view.getComputedStyle ?
2471 var el = this.dom, v, cs, camel;
2472 if(prop == 'float'){
2475 if(v = el.style[prop]){
2478 if(cs = view.getComputedStyle(el, "")){
2479 if(!(camel = propCache[prop])){
2480 camel = propCache[prop] = prop.replace(camelRe, camelFn);
2487 var el = this.dom, v, cs, camel;
2488 if(prop == 'opacity'){
2489 if(typeof el.style.filter == 'string'){
2490 var m = el.style.filter.match(/alpha\(opacity=(.*)\)/i);
2492 var fv = parseFloat(m[1]);
2494 return fv ? fv / 100 : 0;
2499 }else if(prop == 'float'){
2500 prop = "styleFloat";
2502 if(!(camel = propCache[prop])){
2503 camel = propCache[prop] = prop.replace(camelRe, camelFn);
2505 if(v = el.style[camel]){
2508 if(cs = el.currentStyle){
2516 setStyle : function(prop, value){
2517 if(typeof prop == "string"){
2519 if(!(camel = propCache[prop])){
2520 camel = propCache[prop] = prop.replace(camelRe, camelFn);
2522 if(camel == 'opacity') {
2523 this.setOpacity(value);
2525 this.dom.style[camel] = value;
2528 for(var style in prop){
2529 if(typeof prop[style] != "function"){
2530 this.setStyle(style, prop[style]);
2538 applyStyles : function(style){
2539 Ext.DomHelper.applyStyles(this.dom, style);
2545 return D.getX(this.dom);
2550 return D.getY(this.dom);
2555 return D.getXY(this.dom);
2559 getOffsetsTo : function(el){
2560 var o = this.getXY();
2561 var e = Ext.fly(el, '_internal').getXY();
2562 return [o[0]-e[0],o[1]-e[1]];
2566 setX : function(x, animate){
2568 D.setX(this.dom, x);
2570 this.setXY([x, this.getY()], this.preanim(arguments, 1));
2576 setY : function(y, animate){
2578 D.setY(this.dom, y);
2580 this.setXY([this.getX(), y], this.preanim(arguments, 1));
2586 setLeft : function(left){
2587 this.setStyle("left", this.addUnits(left));
2592 setTop : function(top){
2593 this.setStyle("top", this.addUnits(top));
2598 setRight : function(right){
2599 this.setStyle("right", this.addUnits(right));
2604 setBottom : function(bottom){
2605 this.setStyle("bottom", this.addUnits(bottom));
2610 setXY : function(pos, animate){
2612 D.setXY(this.dom, pos);
2614 this.anim({points: {to: pos}}, this.preanim(arguments, 1), 'motion');
2620 setLocation : function(x, y, animate){
2621 this.setXY([x, y], this.preanim(arguments, 2));
2626 moveTo : function(x, y, animate){
2627 this.setXY([x, y], this.preanim(arguments, 2));
2632 getRegion : function(){
2633 return D.getRegion(this.dom);
2637 getHeight : function(contentHeight){
2638 var h = this.dom.offsetHeight || 0;
2639 h = contentHeight !== true ? h : h-this.getBorderWidth("tb")-this.getPadding("tb");
2640 return h < 0 ? 0 : h;
2644 getWidth : function(contentWidth){
2645 var w = this.dom.offsetWidth || 0;
2646 w = contentWidth !== true ? w : w-this.getBorderWidth("lr")-this.getPadding("lr");
2647 return w < 0 ? 0 : w;
2651 getComputedHeight : function(){
2652 var h = Math.max(this.dom.offsetHeight, this.dom.clientHeight);
2654 h = parseInt(this.getStyle('height'), 10) || 0;
2655 if(!this.isBorderBox()){
2656 h += this.getFrameWidth('tb');
2663 getComputedWidth : function(){
2664 var w = Math.max(this.dom.offsetWidth, this.dom.clientWidth);
2666 w = parseInt(this.getStyle('width'), 10) || 0;
2667 if(!this.isBorderBox()){
2668 w += this.getFrameWidth('lr');
2675 getSize : function(contentSize){
2676 return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)};
2679 getStyleSize : function(){
2680 var w, h, d = this.dom, s = d.style;
2681 if(s.width && s.width != 'auto'){
2682 w = parseInt(s.width, 10);
2683 if(Ext.isBorderBox){
2684 w -= this.getFrameWidth('lr');
2687 if(s.height && s.height != 'auto'){
2688 h = parseInt(s.height, 10);
2689 if(Ext.isBorderBox){
2690 h -= this.getFrameWidth('tb');
2693 return {width: w || this.getWidth(true), height: h || this.getHeight(true)};
2698 getViewSize : function(){
2699 var d = this.dom, doc = document, aw = 0, ah = 0;
2700 if(d == doc || d == doc.body){
2701 return {width : D.getViewWidth(), height: D.getViewHeight()};
2704 width : d.clientWidth,
2705 height: d.clientHeight
2711 getValue : function(asNumber){
2712 return asNumber ? parseInt(this.dom.value, 10) : this.dom.value;
2715 adjustWidth : function(width){
2716 if(typeof width == "number"){
2717 if(this.autoBoxAdjust && !this.isBorderBox()){
2718 width -= (this.getBorderWidth("lr") + this.getPadding("lr"));
2727 adjustHeight : function(height){
2728 if(typeof height == "number"){
2729 if(this.autoBoxAdjust && !this.isBorderBox()){
2730 height -= (this.getBorderWidth("tb") + this.getPadding("tb"));
2740 setWidth : function(width, animate){
2741 width = this.adjustWidth(width);
2743 this.dom.style.width = this.addUnits(width);
2745 this.anim({width: {to: width}}, this.preanim(arguments, 1));
2751 setHeight : function(height, animate){
2752 height = this.adjustHeight(height);
2754 this.dom.style.height = this.addUnits(height);
2756 this.anim({height: {to: height}}, this.preanim(arguments, 1));
2762 setSize : function(width, height, animate){
2763 if(typeof width == "object"){ height = width.height; width = width.width;
2765 width = this.adjustWidth(width); height = this.adjustHeight(height);
2767 this.dom.style.width = this.addUnits(width);
2768 this.dom.style.height = this.addUnits(height);
2770 this.anim({width: {to: width}, height: {to: height}}, this.preanim(arguments, 2));
2776 setBounds : function(x, y, width, height, animate){
2778 this.setSize(width, height);
2779 this.setLocation(x, y);
2781 width = this.adjustWidth(width); height = this.adjustHeight(height);
2782 this.anim({points: {to: [x, y]}, width: {to: width}, height: {to: height}},
2783 this.preanim(arguments, 4), 'motion');
2789 setRegion : function(region, animate){
2790 this.setBounds(region.left, region.top, region.right-region.left, region.bottom-region.top, this.preanim(arguments, 1));
2795 addListener : function(eventName, fn, scope, options){
2796 Ext.EventManager.on(this.dom, eventName, fn, scope || this, options);
2800 removeListener : function(eventName, fn){
2801 Ext.EventManager.removeListener(this.dom, eventName, fn);
2806 removeAllListeners : function(){
2807 E.purgeElement(this.dom);
2812 relayEvent : function(eventName, observable){
2813 this.on(eventName, function(e){
2814 observable.fireEvent(eventName, e);
2819 setOpacity : function(opacity, animate){
2821 var s = this.dom.style;
2824 s.filter = (s.filter || '').replace(/alpha\([^\)]*\)/gi,"") +
2825 (opacity == 1 ? "" : " alpha(opacity=" + opacity * 100 + ")");
2827 s.opacity = opacity;
2830 this.anim({opacity: {to: opacity}}, this.preanim(arguments, 1), null, .35, 'easeIn');
2836 getLeft : function(local){
2840 return parseInt(this.getStyle("left"), 10) || 0;
2845 getRight : function(local){
2847 return this.getX() + this.getWidth();
2849 return (this.getLeft(true) + this.getWidth()) || 0;
2854 getTop : function(local) {
2858 return parseInt(this.getStyle("top"), 10) || 0;
2863 getBottom : function(local){
2865 return this.getY() + this.getHeight();
2867 return (this.getTop(true) + this.getHeight()) || 0;
2872 position : function(pos, zIndex, x, y){
2874 if(this.getStyle('position') == 'static'){
2875 this.setStyle('position', 'relative');
2878 this.setStyle("position", pos);
2881 this.setStyle("z-index", zIndex);
2883 if(x !== undefined && y !== undefined){
2885 }else if(x !== undefined){
2887 }else if(y !== undefined){
2893 clearPositioning : function(value){
2901 "position" : "static"
2907 getPositioning : function(){
2908 var l = this.getStyle("left");
2909 var t = this.getStyle("top");
2911 "position" : this.getStyle("position"),
2913 "right" : l ? "" : this.getStyle("right"),
2915 "bottom" : t ? "" : this.getStyle("bottom"),
2916 "z-index" : this.getStyle("z-index")
2921 getBorderWidth : function(side){
2922 return this.addStyles(side, El.borders);
2926 getPadding : function(side){
2927 return this.addStyles(side, El.paddings);
2931 setPositioning : function(pc){
2932 this.applyStyles(pc);
2933 if(pc.right == "auto"){
2934 this.dom.style.right = "";
2936 if(pc.bottom == "auto"){
2937 this.dom.style.bottom = "";
2942 fixDisplay : function(){
2943 if(this.getStyle("display") == "none"){
2944 this.setStyle("visibility", "hidden");
2945 this.setStyle("display", this.originalDisplay); if(this.getStyle("display") == "none"){ this.setStyle("display", "block");
2950 setOverflow : function(v){
2951 if(v=='auto' && Ext.isMac && Ext.isGecko){ this.dom.style.overflow = 'hidden';
2952 (function(){this.dom.style.overflow = 'auto';}).defer(1, this);
2954 this.dom.style.overflow = v;
2959 setLeftTop : function(left, top){
2960 this.dom.style.left = this.addUnits(left);
2961 this.dom.style.top = this.addUnits(top);
2966 move : function(direction, distance, animate){
2967 var xy = this.getXY();
2968 direction = direction.toLowerCase();
2972 this.moveTo(xy[0]-distance, xy[1], this.preanim(arguments, 2));
2976 this.moveTo(xy[0]+distance, xy[1], this.preanim(arguments, 2));
2981 this.moveTo(xy[0], xy[1]-distance, this.preanim(arguments, 2));
2986 this.moveTo(xy[0], xy[1]+distance, this.preanim(arguments, 2));
2994 if(!this.isClipped){
2995 this.isClipped = true;
2996 this.originalClip = {
2997 "o": this.getStyle("overflow"),
2998 "x": this.getStyle("overflow-x"),
2999 "y": this.getStyle("overflow-y")
3001 this.setStyle("overflow", "hidden");
3002 this.setStyle("overflow-x", "hidden");
3003 this.setStyle("overflow-y", "hidden");
3009 unclip : function(){
3011 this.isClipped = false;
3012 var o = this.originalClip;
3013 if(o.o){this.setStyle("overflow", o.o);}
3014 if(o.x){this.setStyle("overflow-x", o.x);}
3015 if(o.y){this.setStyle("overflow-y", o.y);}
3022 getAnchorXY : function(anchor, local, s){
3024 var w, h, vp = false;
3027 if(d == document.body || d == document){
3029 w = D.getViewWidth(); h = D.getViewHeight();
3031 w = this.getWidth(); h = this.getHeight();
3034 w = s.width; h = s.height;
3036 var x = 0, y = 0, r = Math.round;
3037 switch((anchor || "tl").toLowerCase()){
3079 var sc = this.getScroll();
3080 return [x + sc.left, y + sc.top];
3082 var o = this.getXY();
3083 return [x+o[0], y+o[1]];
3087 getAlignToXY : function(el, p, o){
3090 throw "Element.alignToXY with an element that doesn't exist";
3093 var c = false; var p1 = "", p2 = "";
3100 }else if(p.indexOf("-") == -1){
3103 p = p.toLowerCase();
3104 var m = p.match(/^([a-z]+)-([a-z]+)(\?)?$/);
3106 throw "Element.alignTo with an invalid alignment " + p;
3108 p1 = m[1]; p2 = m[2]; c = !!m[3];
3110 var a1 = this.getAnchorXY(p1, true);
3111 var a2 = el.getAnchorXY(p2, false);
3113 var x = a2[0] - a1[0] + o[0];
3114 var y = a2[1] - a1[1] + o[1];
3117 var w = this.getWidth(), h = this.getHeight(), r = el.getRegion();
3118 var dw = D.getViewWidth()-5, dh = D.getViewHeight()-5;
3120 var p1y = p1.charAt(0), p1x = p1.charAt(p1.length-1);
3121 var p2y = p2.charAt(0), p2x = p2.charAt(p2.length-1);
3122 var swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t"));
3123 var swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r"));
3126 var scrollX = (doc.documentElement.scrollLeft || doc.body.scrollLeft || 0)+5;
3127 var scrollY = (doc.documentElement.scrollTop || doc.body.scrollTop || 0)+5;
3129 if((x+w) > dw + scrollX){
3130 x = swapX ? r.left-w : dw+scrollX-w;
3133 x = swapX ? r.right : scrollX;
3135 if((y+h) > dh + scrollY){
3136 y = swapY ? r.top-h : dh+scrollY-h;
3139 y = swapY ? r.bottom : scrollY;
3145 getConstrainToXY : function(){
3146 var os = {top:0, left:0, bottom:0, right: 0};
3148 return function(el, local, offsets, proposedXY){
3150 offsets = offsets ? Ext.applyIf(offsets, os) : os;
3152 var vw, vh, vx = 0, vy = 0;
3153 if(el.dom == document.body || el.dom == document){
3154 vw = Ext.lib.Dom.getViewWidth();
3155 vh = Ext.lib.Dom.getViewHeight();
3157 vw = el.dom.clientWidth;
3158 vh = el.dom.clientHeight;
3160 var vxy = el.getXY();
3166 var s = el.getScroll();
3168 vx += offsets.left + s.left;
3169 vy += offsets.top + s.top;
3171 vw -= offsets.right;
3172 vh -= offsets.bottom;
3177 var xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]);
3178 var x = xy[0], y = xy[1];
3179 var w = this.dom.offsetWidth, h = this.dom.offsetHeight;
3199 return moved ? [x, y] : false;
3203 adjustForConstraints : function(xy, parent, offsets){
3204 return this.getConstrainToXY(parent || document, false, offsets, xy) || xy;
3208 alignTo : function(element, position, offsets, animate){
3209 var xy = this.getAlignToXY(element, position, offsets);
3210 this.setXY(xy, this.preanim(arguments, 3));
3215 anchorTo : function(el, alignment, offsets, animate, monitorScroll, callback){
3216 var action = function(){
3217 this.alignTo(el, alignment, offsets, animate);
3218 Ext.callback(callback, this);
3220 Ext.EventManager.onWindowResize(action, this);
3221 var tm = typeof monitorScroll;
3222 if(tm != 'undefined'){
3223 Ext.EventManager.on(window, 'scroll', action, this,
3224 {buffer: tm == 'number' ? monitorScroll : 50});
3226 action.call(this); return this;
3229 clearOpacity : function(){
3230 if (window.ActiveXObject) {
3231 if(typeof this.dom.style.filter == 'string' && (/alpha/i).test(this.dom.style.filter)){
3232 this.dom.style.filter = "";
3235 this.dom.style.opacity = "";
3236 this.dom.style["-moz-opacity"] = "";
3237 this.dom.style["-khtml-opacity"] = "";
3243 hide : function(animate){
3244 this.setVisible(false, this.preanim(arguments, 0));
3249 show : function(animate){
3250 this.setVisible(true, this.preanim(arguments, 0));
3255 addUnits : function(size){
3256 return Ext.Element.addUnits(size, this.defaultUnit);
3260 update : function(html, loadScripts, callback){
3261 if(typeof html == "undefined"){
3264 if(loadScripts !== true){
3265 this.dom.innerHTML = html;
3266 if(typeof callback == "function"){
3274 html += '<span id="' + id + '"></span>';
3276 E.onAvailable(id, function(){
3277 var hd = document.getElementsByTagName("head")[0];
3278 var re = /(?:<script([^>]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig;
3279 var srcRe = /\ssrc=([\'\"])(.*?)\1/i;
3280 var typeRe = /\stype=([\'\"])(.*?)\1/i;
3283 while(match = re.exec(html)){
3284 var attrs = match[1];
3285 var srcMatch = attrs ? attrs.match(srcRe) : false;
3286 if(srcMatch && srcMatch[2]){
3287 var s = document.createElement("script");
3288 s.src = srcMatch[2];
3289 var typeMatch = attrs.match(typeRe);
3290 if(typeMatch && typeMatch[2]){
3291 s.type = typeMatch[2];
3294 }else if(match[2] && match[2].length > 0){
3295 if(window.execScript) {
3296 window.execScript(match[2]);
3298 window.eval(match[2]);
3302 var el = document.getElementById(id);
3303 if(el){Ext.removeNode(el);}
3304 if(typeof callback == "function"){
3308 dom.innerHTML = html.replace(/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig, "");
3314 var um = this.getUpdater();
3315 um.update.apply(um, arguments);
3320 getUpdater : function(){
3321 if(!this.updateManager){
3322 this.updateManager = new Ext.Updater(this);
3324 return this.updateManager;
3328 unselectable : function(){
3329 this.dom.unselectable = "on";
3330 this.swallowEvent("selectstart", true);
3331 this.applyStyles("-moz-user-select:none;-khtml-user-select:none;");
3332 this.addClass("x-unselectable");
3337 getCenterXY : function(){
3338 return this.getAlignToXY(document, 'c-c');
3342 center : function(centerIn){
3343 this.alignTo(centerIn || document, 'c-c');
3348 isBorderBox : function(){
3349 return noBoxAdjust[this.dom.tagName.toLowerCase()] || Ext.isBorderBox;
3353 getBox : function(contentBox, local){
3358 var left = parseInt(this.getStyle("left"), 10) || 0;
3359 var top = parseInt(this.getStyle("top"), 10) || 0;
3362 var el = this.dom, w = el.offsetWidth, h = el.offsetHeight, bx;
3364 bx = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: w, height: h};
3366 var l = this.getBorderWidth("l")+this.getPadding("l");
3367 var r = this.getBorderWidth("r")+this.getPadding("r");
3368 var t = this.getBorderWidth("t")+this.getPadding("t");
3369 var b = this.getBorderWidth("b")+this.getPadding("b");
3370 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)};
3372 bx.right = bx.x + bx.width;
3373 bx.bottom = bx.y + bx.height;
3378 getFrameWidth : function(sides, onlyContentBox){
3379 return onlyContentBox && Ext.isBorderBox ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides));
3383 setBox : function(box, adjust, animate){
3384 var w = box.width, h = box.height;
3385 if((adjust && !this.autoBoxAdjust) && !this.isBorderBox()){
3386 w -= (this.getBorderWidth("lr") + this.getPadding("lr"));
3387 h -= (this.getBorderWidth("tb") + this.getPadding("tb"));
3389 this.setBounds(box.x, box.y, w, h, this.preanim(arguments, 2));
3394 repaint : function(){
3396 this.addClass("x-repaint");
3397 setTimeout(function(){
3398 Ext.get(dom).removeClass("x-repaint");
3404 getMargins : function(side){
3407 top: parseInt(this.getStyle("margin-top"), 10) || 0,
3408 left: parseInt(this.getStyle("margin-left"), 10) || 0,
3409 bottom: parseInt(this.getStyle("margin-bottom"), 10) || 0,
3410 right: parseInt(this.getStyle("margin-right"), 10) || 0
3413 return this.addStyles(side, El.margins);
3417 addStyles : function(sides, styles){
3419 for(var i = 0, len = sides.length; i < len; i++){
3420 v = this.getStyle(styles[sides.charAt(i)]);
3422 w = parseInt(v, 10);
3423 if(w){ val += (w >= 0 ? w : -1 * w); }
3430 createProxy : function(config, renderTo, matchBox){
3431 config = typeof config == "object" ?
3432 config : {tag : "div", cls: config};
3436 proxy = Ext.DomHelper.append(renderTo, config, true);
3438 proxy = Ext.DomHelper.insertBefore(this.dom, config, true);
3441 proxy.setBox(this.getBox());
3447 mask : function(msg, msgCls){
3448 if(this.getStyle("position") == "static"){
3449 this.setStyle("position", "relative");
3452 this._maskMsg.remove();
3455 this._mask.remove();
3458 this._mask = Ext.DomHelper.append(this.dom, {cls:"ext-el-mask"}, true);
3460 this.addClass("x-masked");
3461 this._mask.setDisplayed(true);
3462 if(typeof msg == 'string'){
3463 this._maskMsg = Ext.DomHelper.append(this.dom, {cls:"ext-el-mask-msg", cn:{tag:'div'}}, true);
3464 var mm = this._maskMsg;
3465 mm.dom.className = msgCls ? "ext-el-mask-msg " + msgCls : "ext-el-mask-msg";
3466 mm.dom.firstChild.innerHTML = msg;
3467 mm.setDisplayed(true);
3470 if(Ext.isIE && !(Ext.isIE7 && Ext.isStrict) && this.getStyle('height') == 'auto'){ this._mask.setSize(this.dom.clientWidth, this.getHeight());
3476 unmask : function(){
3479 this._maskMsg.remove();
3480 delete this._maskMsg;
3482 this._mask.remove();
3485 this.removeClass("x-masked");
3489 isMasked : function(){
3490 return this._mask && this._mask.isVisible();
3494 createShim : function(){
3495 var el = document.createElement('iframe');
3496 el.frameBorder = 'no';
3497 el.className = 'ext-shim';
3498 if(Ext.isIE && Ext.isSecure){
3499 el.src = Ext.SSL_SECURE_URL;
3501 var shim = Ext.get(this.dom.parentNode.insertBefore(el, this.dom));
3502 shim.autoBoxAdjust = false;
3507 remove : function(){
3508 Ext.removeNode(this.dom);
3509 delete El.cache[this.dom.id];
3513 hover : function(overFn, outFn, scope){
3514 var preOverFn = function(e){
3515 if(!e.within(this, true)){
3516 overFn.apply(scope || this, arguments);
3519 var preOutFn = function(e){
3520 if(!e.within(this, true)){
3521 outFn.apply(scope || this, arguments);
3524 this.on("mouseover", preOverFn, this.dom);
3525 this.on("mouseout", preOutFn, this.dom);
3530 addClassOnOver : function(className, preventFlicker){
3533 Ext.fly(this, '_internal').addClass(className);
3536 Ext.fly(this, '_internal').removeClass(className);
3543 addClassOnFocus : function(className){
3544 this.on("focus", function(){
3545 Ext.fly(this, '_internal').addClass(className);
3547 this.on("blur", function(){
3548 Ext.fly(this, '_internal').removeClass(className);
3553 addClassOnClick : function(className){
3555 this.on("mousedown", function(){
3556 Ext.fly(dom, '_internal').addClass(className);
3557 var d = Ext.getDoc();
3558 var fn = function(){
3559 Ext.fly(dom, '_internal').removeClass(className);
3560 d.removeListener("mouseup", fn);
3562 d.on("mouseup", fn);
3568 swallowEvent : function(eventName, preventDefault){
3569 var fn = function(e){
3570 e.stopPropagation();
3575 if(Ext.isArray(eventName)){
3576 for(var i = 0, len = eventName.length; i < len; i++){
3577 this.on(eventName[i], fn);
3581 this.on(eventName, fn);
3586 parent : function(selector, returnDom){
3587 return this.matchNode('parentNode', 'parentNode', selector, returnDom);
3591 next : function(selector, returnDom){
3592 return this.matchNode('nextSibling', 'nextSibling', selector, returnDom);
3596 prev : function(selector, returnDom){
3597 return this.matchNode('previousSibling', 'previousSibling', selector, returnDom);
3602 first : function(selector, returnDom){
3603 return this.matchNode('nextSibling', 'firstChild', selector, returnDom);
3607 last : function(selector, returnDom){
3608 return this.matchNode('previousSibling', 'lastChild', selector, returnDom);
3611 matchNode : function(dir, start, selector, returnDom){
3612 var n = this.dom[start];
3614 if(n.nodeType == 1 && (!selector || Ext.DomQuery.is(n, selector))){
3615 return !returnDom ? Ext.get(n) : n;
3623 appendChild: function(el){
3630 createChild: function(config, insertBefore, returnDom){
3631 config = config || {tag:'div'};
3633 return Ext.DomHelper.insertBefore(insertBefore, config, returnDom !== true);
3635 return Ext.DomHelper[!this.dom.firstChild ? 'overwrite' : 'append'](this.dom, config, returnDom !== true);
3639 appendTo: function(el){
3640 el = Ext.getDom(el);
3641 el.appendChild(this.dom);
3646 insertBefore: function(el){
3647 el = Ext.getDom(el);
3648 el.parentNode.insertBefore(this.dom, el);
3653 insertAfter: function(el){
3654 el = Ext.getDom(el);
3655 el.parentNode.insertBefore(this.dom, el.nextSibling);
3660 insertFirst: function(el, returnDom){
3662 if(typeof el == 'object' && !el.nodeType && !el.dom){ return this.createChild(el, this.dom.firstChild, returnDom);
3664 el = Ext.getDom(el);
3665 this.dom.insertBefore(el, this.dom.firstChild);
3666 return !returnDom ? Ext.get(el) : el;
3671 insertSibling: function(el, where, returnDom){
3673 if(Ext.isArray(el)){
3674 for(var i = 0, len = el.length; i < len; i++){
3675 rt = this.insertSibling(el[i], where, returnDom);
3679 where = where ? where.toLowerCase() : 'before';
3681 var refNode = where == 'before' ? this.dom : this.dom.nextSibling;
3683 if(typeof el == 'object' && !el.nodeType && !el.dom){ if(where == 'after' && !this.dom.nextSibling){
3684 rt = Ext.DomHelper.append(this.dom.parentNode, el, !returnDom);
3686 rt = Ext.DomHelper[where == 'after' ? 'insertAfter' : 'insertBefore'](this.dom, el, !returnDom);
3690 rt = this.dom.parentNode.insertBefore(Ext.getDom(el), refNode);
3699 wrap: function(config, returnDom){
3701 config = {tag: "div"};
3703 var newEl = Ext.DomHelper.insertBefore(this.dom, config, !returnDom);
3704 newEl.dom ? newEl.dom.appendChild(this.dom) : newEl.appendChild(this.dom);
3709 replace: function(el){
3711 this.insertBefore(el);
3717 replaceWith: function(el){
3718 if(typeof el == 'object' && !el.nodeType && !el.dom){ el = this.insertSibling(el, 'before');
3720 el = Ext.getDom(el);
3721 this.dom.parentNode.insertBefore(el, this.dom);
3723 El.uncache(this.id);
3724 this.dom.parentNode.removeChild(this.dom);
3726 this.id = Ext.id(el);
3727 El.cache[this.id] = this;
3732 insertHtml : function(where, html, returnEl){
3733 var el = Ext.DomHelper.insertHtml(where, this.dom, html);
3734 return returnEl ? Ext.get(el) : el;
3738 set : function(o, useSet){
3740 useSet = typeof useSet == 'undefined' ? (el.setAttribute ? true : false) : useSet;
3742 if(attr == "style" || typeof o[attr] == "function") continue;
3744 el.className = o["cls"];
3745 }else if(o.hasOwnProperty(attr)){
3746 if(useSet) el.setAttribute(attr, o[attr]);
3747 else el[attr] = o[attr];
3751 Ext.DomHelper.applyStyles(el, o.style);
3757 addKeyListener : function(key, fn, scope){
3759 if(typeof key != "object" || Ext.isArray(key)){
3775 return new Ext.KeyMap(this, config);
3779 addKeyMap : function(config){
3780 return new Ext.KeyMap(this, config);
3784 isScrollable : function(){
3786 return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth;
3790 scrollTo : function(side, value, animate){
3791 var prop = side.toLowerCase() == "left" ? "scrollLeft" : "scrollTop";
3793 this.dom[prop] = value;
3795 var to = prop == "scrollLeft" ? [value, this.dom.scrollTop] : [this.dom.scrollLeft, value];
3796 this.anim({scroll: {"to": to}}, this.preanim(arguments, 2), 'scroll');
3802 scroll : function(direction, distance, animate){
3803 if(!this.isScrollable()){
3807 var l = el.scrollLeft, t = el.scrollTop;
3808 var w = el.scrollWidth, h = el.scrollHeight;
3809 var cw = el.clientWidth, ch = el.clientHeight;
3810 direction = direction.toLowerCase();
3811 var scrolled = false;
3812 var a = this.preanim(arguments, 2);
3817 var v = Math.min(l + distance, w-cw);
3818 this.scrollTo("left", v, a);
3825 var v = Math.max(l - distance, 0);
3826 this.scrollTo("left", v, a);
3834 var v = Math.max(t - distance, 0);
3835 this.scrollTo("top", v, a);
3843 var v = Math.min(t + distance, h-ch);
3844 this.scrollTo("top", v, a);
3853 translatePoints : function(x, y){
3854 if(typeof x == 'object' || Ext.isArray(x)){
3857 var p = this.getStyle('position');
3858 var o = this.getXY();
3860 var l = parseInt(this.getStyle('left'), 10);
3861 var t = parseInt(this.getStyle('top'), 10);
3864 l = (p == "relative") ? 0 : this.dom.offsetLeft;
3867 t = (p == "relative") ? 0 : this.dom.offsetTop;
3870 return {left: (x - o[0] + l), top: (y - o[1] + t)};
3874 getScroll : function(){
3875 var d = this.dom, doc = document;
3876 if(d == doc || d == doc.body){
3878 if(Ext.isIE && Ext.isStrict){
3879 l = doc.documentElement.scrollLeft || (doc.body.scrollLeft || 0);
3880 t = doc.documentElement.scrollTop || (doc.body.scrollTop || 0);
3882 l = window.pageXOffset || (doc.body.scrollLeft || 0);
3883 t = window.pageYOffset || (doc.body.scrollTop || 0);
3885 return {left: l, top: t};
3887 return {left: d.scrollLeft, top: d.scrollTop};
3892 getColor : function(attr, defaultValue, prefix){
3893 var v = this.getStyle(attr);
3894 if(!v || v == "transparent" || v == "inherit") {
3895 return defaultValue;
3897 var color = typeof prefix == "undefined" ? "#" : prefix;
3898 if(v.substr(0, 4) == "rgb("){
3899 var rvs = v.slice(4, v.length -1).split(",");
3900 for(var i = 0; i < 3; i++){
3901 var h = parseInt(rvs[i]);
3902 var s = h.toString(16);
3909 if(v.substr(0, 1) == "#"){
3911 for(var i = 1; i < 4; i++){
3912 var c = v.charAt(i);
3915 }else if(v.length == 7){
3916 color += v.substr(1);
3920 return(color.length > 5 ? color.toLowerCase() : defaultValue);
3924 boxWrap : function(cls){
3925 cls = cls || 'x-box';
3926 var el = Ext.get(this.insertHtml('beforeBegin', String.format('<div class="{0}">'+El.boxMarkup+'</div>', cls)));
3927 el.child('.'+cls+'-mc').dom.appendChild(this.dom);
3932 getAttributeNS : Ext.isIE ? function(ns, name){
3934 var type = typeof d[ns+":"+name];
3935 if(type != 'undefined' && type != 'unknown'){
3936 return d[ns+":"+name];
3939 } : function(ns, name){
3941 return d.getAttributeNS(ns, name) || d.getAttribute(ns+":"+name) || d.getAttribute(name) || d[name];
3944 getTextWidth : function(text, min, max){
3945 return (Ext.util.TextMetrics.measure(this.dom, Ext.value(text, this.dom.innerHTML, true)).width).constrain(min || 0, max || 1000000);
3949 var ep = El.prototype;
3952 ep.on = ep.addListener;
3953 ep.mon = ep.addListener;
3955 ep.getUpdateManager = ep.getUpdater;
3958 ep.un = ep.removeListener;
3961 ep.autoBoxAdjust = true;
3963 El.unitPattern = /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i;
3965 El.addUnits = function(v, defaultUnit){
3966 if(v === "" || v == "auto"){
3969 if(v === undefined){
3972 if(typeof v == "number" || !El.unitPattern.test(v)){
3973 return v + (defaultUnit || 'px');
3978 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>';
3984 El.borders = {l: "border-left-width", r: "border-right-width", t: "border-top-width", b: "border-bottom-width"};
3985 El.paddings = {l: "padding-left", r: "padding-right", t: "padding-top", b: "padding-bottom"};
3986 El.margins = {l: "margin-left", r: "margin-right", t: "margin-top", b: "margin-bottom"};
3996 El.get = function(el){
3998 if(!el){ return null; }
3999 if(typeof el == "string"){ if(!(elm = document.getElementById(el))){
4002 if(ex = El.cache[el]){
4005 ex = El.cache[el] = new El(elm);
4008 }else if(el.tagName){ if(!(id = el.id)){
4011 if(ex = El.cache[id]){
4014 ex = El.cache[id] = new El(el);
4017 }else if(el instanceof El){
4019 el.dom = document.getElementById(el.id) || el.dom; El.cache[el.id] = el; }
4021 }else if(el.isComposite){
4023 }else if(Ext.isArray(el)){
4024 return El.select(el);
4025 }else if(el == document){
4027 var f = function(){};
4028 f.prototype = El.prototype;
4030 docEl.dom = document;
4037 El.uncache = function(el){
4038 for(var i = 0, a = arguments, len = a.length; i < len; i++) {
4040 delete El.cache[a[i].id || a[i]];
4045 El.garbageCollect = function(){
4046 if(!Ext.enableGarbageCollector){
4047 clearInterval(El.collectorThread);
4050 for(var eid in El.cache){
4051 var el = El.cache[eid], d = el.dom;
4052 if(!d || !d.parentNode || (!d.offsetParent && !document.getElementById(eid))){
4053 delete El.cache[eid];
4054 if(d && Ext.enableListenerCollection){
4060 El.collectorThreadId = setInterval(El.garbageCollect, 30000);
4062 var flyFn = function(){};
4063 flyFn.prototype = El.prototype;
4064 var _cls = new flyFn();
4066 El.Flyweight = function(dom){
4070 El.Flyweight.prototype = _cls;
4071 El.Flyweight.prototype.isFlyweight = true;
4073 El._flyweights = {};
4075 El.fly = function(el, named){
4076 named = named || '_global';
4077 el = Ext.getDom(el);
4081 if(!El._flyweights[named]){
4082 El._flyweights[named] = new El.Flyweight();
4084 El._flyweights[named].dom = el;
4085 return El._flyweights[named];
4093 var noBoxAdjust = Ext.isStrict ? {
4096 input:1, select:1, textarea:1
4098 if(Ext.isIE || Ext.isGecko){
4099 noBoxAdjust['button'] = 1;
4103 Ext.EventManager.on(window, 'unload', function(){
4105 delete El._flyweights;
4109 Ext.enableFx = true;
4114 slideIn : function(anchor, o){
4115 var el = this.getFxEl();
4118 el.queueFx(o, function(){
4120 anchor = anchor || "t";
4124 var r = this.getFxRestore();
4125 var b = this.getBox();
4128 var wrap = this.fxWrap(r.pos, o, "hidden");
4130 var st = this.dom.style;
4131 st.visibility = "visible";
4132 st.position = "absolute";
4134 var after = function(){
4135 el.fxUnwrap(wrap, r.pos, o);
4137 st.height = r.height;
4140 var a, pt = {to: [b.x, b.y]}, bw = {to: b.width}, bh = {to: b.height};
4142 switch(anchor.toLowerCase()){
4144 wrap.setSize(b.width, 0);
4145 st.left = st.bottom = "0";
4149 wrap.setSize(0, b.height);
4150 st.right = st.top = "0";
4154 wrap.setSize(0, b.height);
4156 st.left = st.top = "0";
4157 a = {width: bw, points: pt};
4160 wrap.setSize(b.width, 0);
4161 wrap.setY(b.bottom);
4162 st.left = st.top = "0";
4163 a = {height: bh, points: pt};
4167 st.right = st.bottom = "0";
4168 a = {width: bw, height: bh};
4172 wrap.setY(b.y+b.height);
4173 st.right = st.top = "0";
4174 a = {width: bw, height: bh, points: pt};
4178 wrap.setXY([b.right, b.bottom]);
4179 st.left = st.top = "0";
4180 a = {width: bw, height: bh, points: pt};
4184 wrap.setX(b.x+b.width);
4185 st.left = st.bottom = "0";
4186 a = {width: bw, height: bh, points: pt};
4189 this.dom.style.visibility = "visible";
4192 arguments.callee.anim = wrap.fxanim(a,
4202 slideOut : function(anchor, o){
4203 var el = this.getFxEl();
4206 el.queueFx(o, function(){
4208 anchor = anchor || "t";
4210 var r = this.getFxRestore();
4212 var b = this.getBox();
4215 var wrap = this.fxWrap(r.pos, o, "visible");
4217 var st = this.dom.style;
4218 st.visibility = "visible";
4219 st.position = "absolute";
4223 var after = function(){
4225 el.setDisplayed(false);
4230 el.fxUnwrap(wrap, r.pos, o);
4233 st.height = r.height;
4238 var a, zero = {to: 0};
4239 switch(anchor.toLowerCase()){
4241 st.left = st.bottom = "0";
4245 st.right = st.top = "0";
4249 st.left = st.top = "0";
4250 a = {width: zero, points: {to:[b.right, b.y]}};
4253 st.left = st.top = "0";
4254 a = {height: zero, points: {to:[b.x, b.bottom]}};
4257 st.right = st.bottom = "0";
4258 a = {width: zero, height: zero};
4261 st.right = st.top = "0";
4262 a = {width: zero, height: zero, points: {to:[b.x, b.bottom]}};
4265 st.left = st.top = "0";
4266 a = {width: zero, height: zero, points: {to:[b.x+b.width, b.bottom]}};
4269 st.left = st.bottom = "0";
4270 a = {width: zero, height: zero, points: {to:[b.right, b.y]}};
4274 arguments.callee.anim = wrap.fxanim(a,
4285 var el = this.getFxEl();
4288 el.queueFx(o, function(){
4289 this.clearOpacity();
4292 var r = this.getFxRestore();
4293 var st = this.dom.style;
4295 var after = function(){
4297 el.setDisplayed(false);
4304 el.setPositioning(r.pos);
4306 st.height = r.height;
4311 var width = this.getWidth();
4312 var height = this.getHeight();
4314 arguments.callee.anim = this.fxanim({
4315 width : {to: this.adjustWidth(width * 2)},
4316 height : {to: this.adjustHeight(height * 2)},
4317 points : {by: [-(width * .5), -(height * .5)]},
4319 fontSize: {to:200, unit: "%"}
4330 switchOff : function(o){
4331 var el = this.getFxEl();
4334 el.queueFx(o, function(){
4335 this.clearOpacity();
4338 var r = this.getFxRestore();
4339 var st = this.dom.style;
4341 var after = function(){
4343 el.setDisplayed(false);
4349 el.setPositioning(r.pos);
4351 st.height = r.height;
4356 this.fxanim({opacity:{to:0.3}}, null, null, .1, null, function(){
4357 this.clearOpacity();
4361 points:{by:[0, this.getHeight() * .5]}
4362 }, o, 'motion', 0.3, 'easeIn', after);
4363 }).defer(100, this);
4370 highlight : function(color, o){
4371 var el = this.getFxEl();
4374 el.queueFx(o, function(){
4375 color = color || "ffff9c";
4376 var attr = o.attr || "backgroundColor";
4378 this.clearOpacity();
4381 var origColor = this.getColor(attr);
4382 var restoreColor = this.dom.style[attr];
4383 var endColor = (o.endColor || origColor) || "ffffff";
4385 var after = function(){
4386 el.dom.style[attr] = restoreColor;
4391 a[attr] = {from: color, to: endColor};
4392 arguments.callee.anim = this.fxanim(a,
4402 frame : function(color, count, o){
4403 var el = this.getFxEl();
4406 el.queueFx(o, function(){
4407 color = color || "#C3DAF9";
4408 if(color.length == 6){
4409 color = "#" + color;
4412 var duration = o.duration || 1;
4415 var b = this.getBox();
4416 var animFn = function(){
4417 var proxy = Ext.getBody().createChild({
4420 position:"absolute",
4421 "z-index":"35000", border:"0px solid " + color
4424 var scale = Ext.isBorderBox ? 2 : 1;
4426 top:{from:b.y, to:b.y - 20},
4427 left:{from:b.x, to:b.x - 20},
4428 borderWidth:{from:0, to:10},
4429 opacity:{from:1, to:0},
4430 height:{from:b.height, to:(b.height + (20*scale))},
4431 width:{from:b.width, to:(b.width + (20*scale))}
4432 }, duration, function(){
4447 pause : function(seconds){
4448 var el = this.getFxEl();
4451 el.queueFx(o, function(){
4452 setTimeout(function(){
4460 fadeIn : function(o){
4461 var el = this.getFxEl();
4463 el.queueFx(o, function(){
4466 this.dom.style.visibility = 'visible';
4467 var to = o.endOpacity || 1;
4468 arguments.callee.anim = this.fxanim({opacity:{to:to}},
4469 o, null, .5, "easeOut", function(){
4471 this.clearOpacity();
4480 fadeOut : function(o){
4481 var el = this.getFxEl();
4483 el.queueFx(o, function(){
4484 arguments.callee.anim = this.fxanim({opacity:{to:o.endOpacity || 0}},
4485 o, null, .5, "easeOut", function(){
4486 if(this.visibilityMode == Ext.Element.DISPLAY || o.useDisplay){
4487 this.dom.style.display = "none";
4489 this.dom.style.visibility = "hidden";
4491 this.clearOpacity();
4499 scale : function(w, h, o){
4500 this.shift(Ext.apply({}, o, {
4508 shift : function(o){
4509 var el = this.getFxEl();
4511 el.queueFx(o, function(){
4512 var a = {}, w = o.width, h = o.height, x = o.x, y = o.y, op = o.opacity;
4513 if(w !== undefined){
4514 a.width = {to: this.adjustWidth(w)};
4516 if(h !== undefined){
4517 a.height = {to: this.adjustHeight(h)};
4519 if(x !== undefined || y !== undefined){
4521 x !== undefined ? x : this.getX(),
4522 y !== undefined ? y : this.getY()
4525 if(op !== undefined){
4526 a.opacity = {to: op};
4528 if(o.xy !== undefined){
4529 a.points = {to: o.xy};
4531 arguments.callee.anim = this.fxanim(a,
4532 o, 'motion', .35, "easeOut", function(){
4540 ghost : function(anchor, o){
4541 var el = this.getFxEl();
4544 el.queueFx(o, function(){
4545 anchor = anchor || "b";
4547 var r = this.getFxRestore();
4548 var w = this.getWidth(),
4549 h = this.getHeight();
4551 var st = this.dom.style;
4553 var after = function(){
4555 el.setDisplayed(false);
4561 el.setPositioning(r.pos);
4563 st.height = r.height;
4568 var a = {opacity: {to: 0}, points: {}}, pt = a.points;
4569 switch(anchor.toLowerCase()){
4596 arguments.callee.anim = this.fxanim(a,
4606 syncFx : function(){
4607 this.fxDefaults = Ext.apply(this.fxDefaults || {}, {
4616 sequenceFx : function(){
4617 this.fxDefaults = Ext.apply(this.fxDefaults || {}, {
4626 nextFx : function(){
4627 var ef = this.fxQueue[0];
4634 hasActiveFx : function(){
4635 return this.fxQueue && this.fxQueue[0];
4639 stopFx : function(){
4640 if(this.hasActiveFx()){
4641 var cur = this.fxQueue[0];
4642 if(cur && cur.anim && cur.anim.isAnimated()){
4643 this.fxQueue = [cur]; cur.anim.stop(true);
4650 beforeFx : function(o){
4651 if(this.hasActiveFx() && !o.concurrent){
4662 hasFxBlock : function(){
4663 var q = this.fxQueue;
4664 return q && q[0] && q[0].block;
4668 queueFx : function(o, fn){
4672 if(!this.hasFxBlock()){
4673 Ext.applyIf(o, this.fxDefaults);
4675 var run = this.beforeFx(o);
4677 this.fxQueue.push(fn);
4689 fxWrap : function(pos, o, vis){
4691 if(!o.wrap || !(wrap = Ext.get(o.wrap))){
4694 wrapXY = this.getXY();
4696 var div = document.createElement("div");
4697 div.style.visibility = vis;
4698 wrap = Ext.get(this.dom.parentNode.insertBefore(div, this.dom));
4699 wrap.setPositioning(pos);
4700 if(wrap.getStyle("position") == "static"){
4701 wrap.position("relative");
4703 this.clearPositioning('auto');
4705 wrap.dom.appendChild(this.dom);
4714 fxUnwrap : function(wrap, pos, o){
4715 this.clearPositioning();
4716 this.setPositioning(pos);
4718 wrap.dom.parentNode.insertBefore(this.dom, wrap.dom);
4724 getFxRestore : function(){
4725 var st = this.dom.style;
4726 return {pos: this.getPositioning(), width: st.width, height : st.height};
4730 afterFx : function(o){
4732 this.applyStyles(o.afterStyle);
4735 this.addClass(o.afterCls);
4737 if(o.remove === true){
4740 Ext.callback(o.callback, o.scope, [this]);
4742 this.fxQueue.shift();
4748 getFxEl : function(){ return Ext.get(this.dom);
4752 fxanim : function(args, opt, animType, defaultDur, defaultEase, cb){
4753 animType = animType || 'run';
4755 var anim = Ext.lib.Anim[animType](
4757 (opt.duration || defaultDur) || .35,
4758 (opt.easing || defaultEase) || 'easeOut',
4760 Ext.callback(cb, this);
4769 Ext.Fx.resize = Ext.Fx.scale;
4771 Ext.apply(Ext.Element.prototype, Ext.Fx);
4774 Ext.CompositeElement = function(els){
\r
4775 this.elements = [];
\r
4776 this.addElements(els);
\r
4778 Ext.CompositeElement.prototype = {
\r
4779 isComposite: true,
\r
4780 addElements : function(els){
\r
4781 if(!els) return this;
\r
4782 if(typeof els == "string"){
\r
4783 els = Ext.Element.selectorFunction(els);
\r
4785 var yels = this.elements;
\r
4786 var index = yels.length-1;
\r
4787 for(var i = 0, len = els.length; i < len; i++) {
\r
4788 yels[++index] = Ext.get(els[i]);
\r
4794 fill : function(els){
\r
4795 this.elements = [];
\r
4801 filter : function(selector){
\r
4803 this.each(function(el){
\r
4804 if(el.is(selector)){
\r
4805 els[els.length] = el.dom;
\r
4812 invoke : function(fn, args){
\r
4813 var els = this.elements;
\r
4814 for(var i = 0, len = els.length; i < len; i++) {
\r
4815 Ext.Element.prototype[fn].apply(els[i], args);
\r
4820 add : function(els){
\r
4821 if(typeof els == "string"){
\r
4822 this.addElements(Ext.Element.selectorFunction(els));
\r
4823 }else if(els.length !== undefined){
\r
4824 this.addElements(els);
\r
4826 this.addElements([els]);
\r
4831 each : function(fn, scope){
\r
4832 var els = this.elements;
\r
4833 for(var i = 0, len = els.length; i < len; i++){
\r
4834 if(fn.call(scope || els[i], els[i], this, i) === false) {
\r
4842 item : function(index){
\r
4843 return this.elements[index] || null;
\r
4847 first : function(){
\r
4848 return this.item(0);
\r
4852 last : function(){
\r
4853 return this.item(this.elements.length-1);
\r
4857 getCount : function(){
\r
4858 return this.elements.length;
\r
4862 contains : function(el){
\r
4863 return this.indexOf(el) !== -1;
\r
4867 indexOf : function(el){
\r
4868 return this.elements.indexOf(Ext.get(el));
\r
4873 removeElement : function(el, removeDom){
\r
4874 if(Ext.isArray(el)){
\r
4875 for(var i = 0, len = el.length; i < len; i++){
\r
4876 this.removeElement(el[i]);
\r
4880 var index = typeof el == 'number' ? el : this.indexOf(el);
\r
4881 if(index !== -1 && this.elements[index]){
\r
4883 var d = this.elements[index];
\r
4887 Ext.removeNode(d);
\r
4890 this.elements.splice(index, 1);
\r
4896 replaceElement : function(el, replacement, domReplace){
\r
4897 var index = typeof el == 'number' ? el : this.indexOf(el);
\r
4900 this.elements[index].replaceWith(replacement);
\r
4902 this.elements.splice(index, 1, Ext.get(replacement))
\r
4909 clear : function(){
\r
4910 this.elements = [];
\r
4914 Ext.CompositeElement.createCall = function(proto, fnName){
\r
4915 if(!proto[fnName]){
\r
4916 proto[fnName] = function(){
\r
4917 return this.invoke(fnName, arguments);
\r
4921 for(var fnName in Ext.Element.prototype){
\r
4922 if(typeof Ext.Element.prototype[fnName] == "function"){
\r
4923 Ext.CompositeElement.createCall(Ext.CompositeElement.prototype, fnName);
\r
4929 Ext.CompositeElementLite = function(els){
\r
4930 Ext.CompositeElementLite.superclass.constructor.call(this, els);
\r
4931 this.el = new Ext.Element.Flyweight();
\r
4933 Ext.extend(Ext.CompositeElementLite, Ext.CompositeElement, {
\r
4934 addElements : function(els){
\r
4936 if(Ext.isArray(els)){
\r
4937 this.elements = this.elements.concat(els);
\r
4939 var yels = this.elements;
\r
4940 var index = yels.length-1;
\r
4941 for(var i = 0, len = els.length; i < len; i++) {
\r
4942 yels[++index] = els[i];
\r
4948 invoke : function(fn, args){
\r
4949 var els = this.elements;
\r
4951 for(var i = 0, len = els.length; i < len; i++) {
\r
4953 Ext.Element.prototype[fn].apply(el, args);
\r
4958 item : function(index){
\r
4959 if(!this.elements[index]){
\r
4962 this.el.dom = this.elements[index];
\r
4967 addListener : function(eventName, handler, scope, opt){
\r
4968 var els = this.elements;
\r
4969 for(var i = 0, len = els.length; i < len; i++) {
\r
4970 Ext.EventManager.on(els[i], eventName, handler, scope || els[i], opt);
\r
4976 each : function(fn, scope){
\r
4977 var els = this.elements;
\r
4979 for(var i = 0, len = els.length; i < len; i++){
\r
4981 if(fn.call(scope || el, el, this, i) === false){
\r
4988 indexOf : function(el){
\r
4989 return this.elements.indexOf(Ext.getDom(el));
\r
4992 replaceElement : function(el, replacement, domReplace){
\r
4993 var index = typeof el == 'number' ? el : this.indexOf(el);
\r
4995 replacement = Ext.getDom(replacement);
\r
4997 var d = this.elements[index];
\r
4998 d.parentNode.insertBefore(replacement, d);
\r
4999 Ext.removeNode(d);
\r
5001 this.elements.splice(index, 1, replacement);
\r
5006 Ext.CompositeElementLite.prototype.on = Ext.CompositeElementLite.prototype.addListener;
\r
5008 Ext.Element.selectorFunction = Ext.DomQuery.select;
\r
5011 Ext.Element.select = function(selector, unique, root){
\r
5013 if(typeof selector == "string"){
\r
5014 els = Ext.Element.selectorFunction(selector, root);
\r
5015 }else if(selector.length !== undefined){
\r
5018 throw "Invalid selector";
\r
5020 if(unique === true){
\r
5021 return new Ext.CompositeElement(els);
\r
5023 return new Ext.CompositeElementLite(els);
\r
5027 Ext.select = Ext.Element.select;
5029 Ext.data.Connection = function(config){
\r
5030 Ext.apply(this, config);
\r
5035 "requestcomplete",
\r
5037 "requestexception"
\r
5039 Ext.data.Connection.superclass.constructor.call(this);
\r
5042 Ext.extend(Ext.data.Connection, Ext.util.Observable, {
\r
5053 disableCaching: true,
\r
5056 request : function(o){
\r
5057 if(this.fireEvent("beforerequest", this, o) !== false){
\r
5060 if(typeof p == "function"){
\r
5061 p = p.call(o.scope||window, o);
\r
5063 if(typeof p == "object"){
\r
5064 p = Ext.urlEncode(p);
\r
5066 if(this.extraParams){
\r
5067 var extras = Ext.urlEncode(this.extraParams);
\r
5068 p = p ? (p + '&' + extras) : extras;
\r
5071 var url = o.url || this.url;
\r
5072 if(typeof url == 'function'){
\r
5073 url = url.call(o.scope||window, o);
\r
5077 var form = Ext.getDom(o.form);
\r
5078 url = url || form.action;
\r
5080 var enctype = form.getAttribute("enctype");
\r
5081 if(o.isUpload || (enctype && enctype.toLowerCase() == 'multipart/form-data')){
\r
5082 return this.doFormUpload(o, p, url);
\r
5084 var f = Ext.lib.Ajax.serializeForm(form);
\r
5085 p = p ? (p + '&' + f) : f;
\r
5088 var hs = o.headers;
\r
5089 if(this.defaultHeaders){
\r
5090 hs = Ext.apply(hs || {}, this.defaultHeaders);
\r
5097 success: this.handleResponse,
\r
5098 failure: this.handleFailure,
\r
5100 argument: {options: o},
\r
5101 timeout : o.timeout || this.timeout
\r
5104 var method = o.method||this.method||(p ? "POST" : "GET");
\r
5106 if(method == 'GET' && (this.disableCaching && o.disableCaching !== false) || o.disableCaching === true){
\r
5107 url += (url.indexOf('?') != -1 ? '&' : '?') + '_dc=' + (new Date().getTime());
\r
5110 if(typeof o.autoAbort == 'boolean'){
5114 }else if(this.autoAbort !== false){
\r
5117 if((method == 'GET' && p) || o.xmlData || o.jsonData){
\r
5118 url += (url.indexOf('?') != -1 ? '&' : '?') + p;
\r
5121 this.transId = Ext.lib.Ajax.request(method, url, cb, p, o);
\r
5122 return this.transId;
\r
5124 Ext.callback(o.callback, o.scope, [o, null, null]);
\r
5130 isLoading : function(transId){
\r
5132 return Ext.lib.Ajax.isCallInProgress(transId);
\r
5134 return this.transId ? true : false;
\r
5139 abort : function(transId){
\r
5140 if(transId || this.isLoading()){
\r
5141 Ext.lib.Ajax.abort(transId || this.transId);
\r
5146 handleResponse : function(response){
\r
5147 this.transId = false;
\r
5148 var options = response.argument.options;
\r
5149 response.argument = options ? options.argument : null;
\r
5150 this.fireEvent("requestcomplete", this, response, options);
\r
5151 Ext.callback(options.success, options.scope, [response, options]);
\r
5152 Ext.callback(options.callback, options.scope, [options, true, response]);
\r
5156 handleFailure : function(response, e){
\r
5157 this.transId = false;
\r
5158 var options = response.argument.options;
\r
5159 response.argument = options ? options.argument : null;
\r
5160 this.fireEvent("requestexception", this, response, options, e);
\r
5161 Ext.callback(options.failure, options.scope, [response, options]);
\r
5162 Ext.callback(options.callback, options.scope, [options, false, response]);
\r
5166 doFormUpload : function(o, ps, url){
\r
5167 var id = Ext.id();
\r
5168 var frame = document.createElement('iframe');
\r
5171 frame.className = 'x-hidden';
\r
5173 frame.src = Ext.SSL_SECURE_URL;
\r
5175 document.body.appendChild(frame);
\r
5178 document.frames[id].name = id;
\r
5181 var form = Ext.getDom(o.form);
\r
5183 form.method = 'POST';
\r
5184 form.enctype = form.encoding = 'multipart/form-data';
\r
5186 form.action = url;
\r
5192 ps = Ext.urlDecode(ps, false);
\r
5194 if(ps.hasOwnProperty(k)){
\r
5195 hd = document.createElement('input');
\r
5196 hd.type = 'hidden';
\r
5199 form.appendChild(hd);
\r
5207 responseText : '',
\r
5208 responseXML : null
\r
5211 r.argument = o ? o.argument : null;
\r
5216 doc = frame.contentWindow.document;
\r
5218 doc = (frame.contentDocument || window.frames[id].document);
\r
5220 if(doc && doc.body){
\r
5221 r.responseText = doc.body.innerHTML;
\r
5223 if(doc && doc.XMLDocument){
\r
5224 r.responseXML = doc.XMLDocument;
\r
5226 r.responseXML = doc;
\r
5233 Ext.EventManager.removeListener(frame, 'load', cb, this);
\r
5235 this.fireEvent("requestcomplete", this, r, o);
\r
5237 Ext.callback(o.success, o.scope, [r, o]);
\r
5238 Ext.callback(o.callback, o.scope, [o, true, r]);
\r
5240 setTimeout(function(){Ext.removeNode(frame);}, 100);
\r
5243 Ext.EventManager.on(frame, 'load', cb, this);
\r
5247 for(var i = 0, len = hiddens.length; i < len; i++){
\r
5248 Ext.removeNode(hiddens[i]);
\r
5255 Ext.Ajax = new Ext.data.Connection({
\r
5273 autoAbort : false,
\r
5276 serializeForm : function(form){
\r
5277 return Ext.lib.Ajax.serializeForm(form);
\r
5281 Ext.Updater = function(el, forceNew){
\r
5283 if(!forceNew && el.updateManager){
\r
5284 return el.updateManager;
\r
5289 this.defaultUrl = null;
\r
5299 var d = Ext.Updater.defaults;
\r
5301 this.sslBlankUrl = d.sslBlankUrl;
\r
5303 this.disableCaching = d.disableCaching;
\r
5305 this.indicatorText = d.indicatorText;
\r
5307 this.showLoadIndicator = d.showLoadIndicator;
\r
5309 this.timeout = d.timeout;
\r
5312 this.loadScripts = d.loadScripts;
\r
5315 this.transaction = null;
\r
5318 this.autoRefreshProcId = null;
\r
5320 this.refreshDelegate = this.refresh.createDelegate(this);
\r
5322 this.updateDelegate = this.update.createDelegate(this);
\r
5324 this.formUpdateDelegate = this.formUpdate.createDelegate(this);
\r
5326 if(!this.renderer){
\r
5328 this.renderer = new Ext.Updater.BasicRenderer();
\r
5330 Ext.Updater.superclass.constructor.call(this);
\r
5333 Ext.extend(Ext.Updater, Ext.util.Observable, {
\r
5335 getEl : function(){
\r
5339 update : function(url, params, callback, discardUrl){
\r
5340 if(this.fireEvent("beforeupdate", this.el, url, params) !== false){
\r
5341 var method = this.method, cfg, callerScope;
\r
5342 if(typeof url == "object"){
5345 params = params || cfg.params;
\r
5346 callback = callback || cfg.callback;
\r
5347 discardUrl = discardUrl || cfg.discardUrl;
\r
5348 callerScope = cfg.scope;
\r
5349 if(typeof cfg.method != "undefined"){method = cfg.method;};
\r
5350 if(typeof cfg.nocache != "undefined"){this.disableCaching = cfg.nocache;};
\r
5351 if(typeof cfg.text != "undefined"){this.indicatorText = '<div class="loading-indicator">'+cfg.text+"</div>";};
\r
5352 if(typeof cfg.scripts != "undefined"){this.loadScripts = cfg.scripts;};
\r
5353 if(typeof cfg.timeout != "undefined"){this.timeout = cfg.timeout;};
\r
5355 this.showLoading();
\r
5357 this.defaultUrl = url;
\r
5359 if(typeof url == "function"){
\r
5360 url = url.call(this);
\r
5363 method = method || (params ? "POST" : "GET");
\r
5364 if(method == "GET"){
\r
5365 url = this.prepareUrl(url);
\r
5368 var o = Ext.apply(cfg ||{}, {
\r
5370 params: (typeof params == "function" && callerScope) ? params.createDelegate(callerScope) : params,
\r
5371 success: this.processSuccess,
\r
5372 failure: this.processFailure,
\r
5374 callback: undefined,
\r
5375 timeout: (this.timeout*1000),
\r
5380 "callback": callback,
\r
5381 "scope": callerScope || window,
\r
5386 this.transaction = Ext.Ajax.request(o);
\r
5391 formUpdate : function(form, url, reset, callback){
\r
5392 if(this.fireEvent("beforeupdate", this.el, form, url) !== false){
\r
5393 if(typeof url == "function"){
\r
5394 url = url.call(this);
\r
5396 form = Ext.getDom(form)
\r
5397 this.transaction = Ext.Ajax.request({
\r
5400 success: this.processSuccess,
\r
5401 failure: this.processFailure,
\r
5403 timeout: (this.timeout*1000),
\r
5407 "callback": callback,
\r
5411 this.showLoading.defer(1, this);
\r
5416 refresh : function(callback){
\r
5417 if(this.defaultUrl == null){
\r
5420 this.update(this.defaultUrl, null, callback, true);
\r
5424 startAutoRefresh : function(interval, url, params, callback, refreshNow){
\r
5426 this.update(url || this.defaultUrl, params, callback, true);
\r
5428 if(this.autoRefreshProcId){
\r
5429 clearInterval(this.autoRefreshProcId);
\r
5431 this.autoRefreshProcId = setInterval(this.update.createDelegate(this, [url || this.defaultUrl, params, callback, true]), interval*1000);
\r
5435 stopAutoRefresh : function(){
\r
5436 if(this.autoRefreshProcId){
\r
5437 clearInterval(this.autoRefreshProcId);
\r
5438 delete this.autoRefreshProcId;
\r
5442 isAutoRefreshing : function(){
\r
5443 return this.autoRefreshProcId ? true : false;
\r
5446 showLoading : function(){
\r
5447 if(this.showLoadIndicator){
\r
5448 this.el.update(this.indicatorText);
\r
5453 prepareUrl : function(url){
\r
5454 if(this.disableCaching){
\r
5455 var append = "_dc=" + (new Date().getTime());
\r
5456 if(url.indexOf("?") !== -1){
\r
5457 url += "&" + append;
\r
5459 url += "?" + append;
\r
5466 processSuccess : function(response){
\r
5467 this.transaction = null;
\r
5468 if(response.argument.form && response.argument.reset){
\r
5470 response.argument.form.reset();
\r
5473 if(this.loadScripts){
\r
5474 this.renderer.render(this.el, response, this,
\r
5475 this.updateComplete.createDelegate(this, [response]));
\r
5477 this.renderer.render(this.el, response, this);
\r
5478 this.updateComplete(response);
\r
5482 updateComplete : function(response){
\r
5483 this.fireEvent("update", this.el, response);
\r
5484 if(typeof response.argument.callback == "function"){
\r
5485 response.argument.callback.call(response.argument.scope, this.el, true, response, response.argument.options);
\r
5490 processFailure : function(response){
\r
5491 this.transaction = null;
\r
5492 this.fireEvent("failure", this.el, response);
\r
5493 if(typeof response.argument.callback == "function"){
\r
5494 response.argument.callback.call(response.argument.scope, this.el, false, response, response.argument.options);
\r
5499 setRenderer : function(renderer){
\r
5500 this.renderer = renderer;
\r
5503 getRenderer : function(){
\r
5504 return this.renderer;
\r
5508 setDefaultUrl : function(defaultUrl){
\r
5509 this.defaultUrl = defaultUrl;
\r
5513 abort : function(){
\r
5514 if(this.transaction){
\r
5515 Ext.Ajax.abort(this.transaction);
\r
5520 isUpdating : function(){
\r
5521 if(this.transaction){
\r
5522 return Ext.Ajax.isLoading(this.transaction);
\r
5529 Ext.Updater.defaults = {
\r
5534 loadScripts : false,
\r
5537 sslBlankUrl : (Ext.SSL_SECURE_URL || "javascript:false"),
\r
5539 disableCaching : false,
\r
5541 showLoadIndicator : true,
\r
5543 indicatorText : '<div class="loading-indicator">Loading...</div>'
\r
5547 Ext.Updater.updateElement = function(el, url, params, options){
\r
5548 var um = Ext.get(el).getUpdater();
\r
5549 Ext.apply(um, options);
\r
5550 um.update(url, params, options ? options.callback : null);
\r
5553 Ext.Updater.update = Ext.Updater.updateElement;
\r
5555 Ext.Updater.BasicRenderer = function(){};
\r
5557 Ext.Updater.BasicRenderer.prototype = {
\r
5559 render : function(el, response, updateManager, callback){
\r
5560 el.update(response.responseText, updateManager.loadScripts, callback);
\r
5564 Ext.UpdateManager = Ext.Updater;
\r
5570 Date.parseFunctions = {count:0};
5571 Date.parseRegexes = [];
5572 Date.formatFunctions = {count:0};
5574 Date.prototype.dateFormat = function(format) {
5575 if (Date.formatFunctions[format] == null) {
5576 Date.createNewFormat(format);
5578 var func = Date.formatFunctions[format];
5579 return this[func]();
5584 Date.prototype.format = Date.prototype.dateFormat;
5586 Date.createNewFormat = function(format) {
5587 var funcName = "format" + Date.formatFunctions.count++;
5588 Date.formatFunctions[format] = funcName;
5589 var code = "Date.prototype." + funcName + " = function(){return ";
5590 var special = false;
5592 for (var i = 0; i < format.length; ++i) {
5593 ch = format.charAt(i);
5594 if (!special && ch == "\\") {
5599 code += "'" + String.escape(ch) + "' + ";
5602 code += Date.getFormatCode(ch);
5605 eval(code.substring(0, code.length - 3) + ";}");
5608 Date.getFormatCode = function(character) {
5609 switch (character) {
5611 return "String.leftPad(this.getDate(), 2, '0') + ";
5613 return "Date.getShortDayName(this.getDay()) + "; case "j":
5614 return "this.getDate() + ";
5616 return "Date.dayNames[this.getDay()] + ";
5618 return "(this.getDay() ? this.getDay() : 7) + ";
5620 return "this.getSuffix() + ";
5622 return "this.getDay() + ";
5624 return "this.getDayOfYear() + ";
5626 return "String.leftPad(this.getWeekOfYear(), 2, '0') + ";
5628 return "Date.monthNames[this.getMonth()] + ";
5630 return "String.leftPad(this.getMonth() + 1, 2, '0') + ";
5632 return "Date.getShortMonthName(this.getMonth()) + "; case "n":
5633 return "(this.getMonth() + 1) + ";
5635 return "this.getDaysInMonth() + ";
5637 return "(this.isLeapYear() ? 1 : 0) + ";
5639 return "(this.getFullYear() + (this.getWeekOfYear() == 1 && this.getMonth() > 0 ? +1 : (this.getWeekOfYear() >= 52 && this.getMonth() < 11 ? -1 : 0))) + ";
5641 return "this.getFullYear() + ";
5643 return "('' + this.getFullYear()).substring(2, 4) + ";
5645 return "(this.getHours() < 12 ? 'am' : 'pm') + ";
5647 return "(this.getHours() < 12 ? 'AM' : 'PM') + ";
5649 return "((this.getHours() % 12) ? this.getHours() % 12 : 12) + ";
5651 return "this.getHours() + ";
5653 return "String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0') + ";
5655 return "String.leftPad(this.getHours(), 2, '0') + ";
5657 return "String.leftPad(this.getMinutes(), 2, '0') + ";
5659 return "String.leftPad(this.getSeconds(), 2, '0') + ";
5661 return "String.leftPad(this.getMilliseconds(), 3, '0') + ";
5663 return "this.getGMTOffset() + ";
5665 return "this.getGMTOffset(true) + ";
5667 return "this.getTimezone() + ";
5669 return "(this.getTimezoneOffset() * -60) + ";
5671 for (var df = Date.getFormatCode, c = "Y-m-dTH:i:sP", code = "", i = 0, l = c.length; i < l; ++i) {
5672 var e = c.charAt(i);
5673 code += e == "T" ? "'T' + " : df(e); }
5676 return "Math.round(this.getTime() / 1000) + ";
5678 return "'" + String.escape(character) + "' + ";
5683 Date.parseDate = function(input, format) {
5684 if (Date.parseFunctions[format] == null) {
5685 Date.createParser(format);
5687 var func = Date.parseFunctions[format];
5688 return Date[func](input);
5691 Date.createParser = function(format) {
5692 var funcName = "parse" + Date.parseFunctions.count++;
5693 var regexNum = Date.parseRegexes.length;
5694 var currentGroup = 1;
5695 Date.parseFunctions[format] = funcName;
5697 var code = "Date." + funcName + " = function(input){\n"
5698 + "var y = -1, m = -1, d = -1, h = -1, i = -1, s = -1, ms = -1, o, z, u, v;\n"
5699 + "input = String(input);var d = new Date();\n"
5700 + "y = d.getFullYear();\n"
5701 + "m = d.getMonth();\n"
5702 + "d = d.getDate();\n"
5703 + "var results = input.match(Date.parseRegexes[" + regexNum + "]);\n"
5704 + "if (results && results.length > 0) {";
5707 var special = false;
5709 for (var i = 0; i < format.length; ++i) {
5710 ch = format.charAt(i);
5711 if (!special && ch == "\\") {
5716 regex += String.escape(ch);
5719 var obj = Date.formatCodeToRegex(ch, currentGroup);
5720 currentGroup += obj.g;
5722 if (obj.g && obj.c) {
5729 + "{v = new Date(u * 1000);}" + "else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0 && ms >= 0)\n"
5730 + "{v = new Date(y, m, d, h, i, s, ms);}\n"
5731 + "else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0)\n"
5732 + "{v = new Date(y, m, d, h, i, s);}\n"
5733 + "else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0)\n"
5734 + "{v = new Date(y, m, d, h, i);}\n"
5735 + "else if (y >= 0 && m >= 0 && d > 0 && h >= 0)\n"
5736 + "{v = new Date(y, m, d, h);}\n"
5737 + "else if (y >= 0 && m >= 0 && d > 0)\n"
5738 + "{v = new Date(y, m, d);}\n"
5739 + "else if (y >= 0 && m >= 0)\n"
5740 + "{v = new Date(y, m);}\n"
5741 + "else if (y >= 0)\n"
5742 + "{v = new Date(y);}\n"
5743 + "}return (v && (z || o))?\n" + " (z ? v.add(Date.SECOND, (v.getTimezoneOffset() * 60) + (z*1)) :\n" + " v.add(Date.HOUR, (v.getGMTOffset() / 100) + (o / -100))) : v\n" + ";}";
5745 Date.parseRegexes[regexNum] = new RegExp("^" + regex + "$", "i");
5749 Date.formatCodeToRegex = function(character, currentGroup) {
5751 switch (character) {
5754 c:"d = parseInt(results[" + currentGroup + "], 10);\n",
5755 s:"(\\d{2})"}; case "D":
5756 for (var a = [], i = 0; i < 7; a.push(Date.getShortDayName(i)), ++i); return {g:0,
5758 s:"(?:" + a.join("|") +")"};
5761 c:"d = parseInt(results[" + currentGroup + "], 10);\n",
5762 s:"(\\d{1,2})"}; case "l":
5765 s:"(?:" + Date.dayNames.join("|") + ")"};
5769 s:"[1-7]"}; case "S":
5772 s:"(?:st|nd|rd|th)"};
5776 s:"[0-6]"}; case "z":
5779 s:"(?:\\d{1,3}"}; case "W":
5782 s:"(?:\\d{2})"}; case "F":
5784 c:"m = parseInt(Date.getMonthNumber(results[" + currentGroup + "]), 10);\n", s:"(" + Date.monthNames.join("|") + ")"};
5787 c:"m = parseInt(results[" + currentGroup + "], 10) - 1;\n",
5788 s:"(\\d{2})"}; case "M":
5789 for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i); return {g:1,
5790 c:"m = parseInt(Date.getMonthNumber(results[" + currentGroup + "]), 10);\n", s:"(" + a.join("|") + ")"};
5793 c:"m = parseInt(results[" + currentGroup + "], 10) - 1;\n",
5794 s:"(\\d{1,2})"}; case "t":
5797 s:"(?:\\d{2})"}; case "L":
5804 c:"y = parseInt(results[" + currentGroup + "], 10);\n",
5805 s:"(\\d{4})"}; case "y":
5807 c:"var ty = parseInt(results[" + currentGroup + "], 10);\n"
5808 + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n",
5809 s:"(\\d{1,2})"}; case "a":
5811 c:"if (results[" + currentGroup + "] == 'am') {\n"
5812 + "if (h == 12) { h = 0; }\n"
5813 + "} else { if (h < 12) { h += 12; }}",
5817 c:"if (results[" + currentGroup + "] == 'AM') {\n"
5818 + "if (h == 12) { h = 0; }\n"
5819 + "} else { if (h < 12) { h += 12; }}",
5824 c:"h = parseInt(results[" + currentGroup + "], 10);\n",
5825 s:"(\\d{1,2})"}; case "h":
5828 c:"h = parseInt(results[" + currentGroup + "], 10);\n",
5829 s:"(\\d{2})"}; case "i":
5831 c:"i = parseInt(results[" + currentGroup + "], 10);\n",
5832 s:"(\\d{2})"}; case "s":
5834 c:"s = parseInt(results[" + currentGroup + "], 10);\n",
5835 s:"(\\d{2})"}; case "u":
5837 c:"ms = parseInt(results[" + currentGroup + "], 10);\n",
5838 s:"(\\d{3})"}; case "O":
5841 "o = results[", currentGroup, "];\n",
5842 "var sn = o.substring(0,1);\n", "var hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60);\n", "var mn = o.substring(3,5) % 60;\n", "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))?\n", " (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"
5844 s: "([+\-]\\d{4})"}; case "P":
5847 "o = results[", currentGroup, "];\n",
5848 "var sn = o.substring(0,1);\n", "var hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60);\n", "var mn = o.substring(4,6) % 60;\n", "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))?\n", " (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"
5850 s: "([+\-]\\d{2}:\\d{2})"}; case "T":
5853 s:"[A-Z]{1,4}"}; case "Z":
5855 c:"z = results[" + currentGroup + "] * 1;\n" + "z = (-43200 <= z && z <= 50400)? z : null;\n",
5856 s:"([+\-]?\\d{1,5})"}; case "c":
5857 var df = Date.formatCodeToRegex, calc = [];
5858 var arr = [df("Y", 1), df("m", 2), df("d", 3), df("h", 4), df("i", 5), df("s", 6), df("P", 7)];
5859 for (var i = 0, l = arr.length; i < l; ++i) {
5860 calc.push(arr[i].c);
5864 s:arr[0].s + "-" + arr[1].s + "-" + arr[2].s + "T" + arr[3].s + ":" + arr[4].s + ":" + arr[5].s + arr[6].s};
5867 c:"u = parseInt(results[" + currentGroup + "], 10);\n",
5868 s:"(-?\\d+)"}; default:
5871 s:Ext.escapeRe(character)};
5876 Date.prototype.getTimezone = function() {
5877 return this.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, "");
5881 Date.prototype.getGMTOffset = function(colon) {
5882 return (this.getTimezoneOffset() > 0 ? "-" : "+")
5883 + String.leftPad(Math.abs(Math.floor(this.getTimezoneOffset() / 60)), 2, "0")
5884 + (colon ? ":" : "")
5885 + String.leftPad(this.getTimezoneOffset() % 60, 2, "0");
5889 Date.prototype.getDayOfYear = function() {
5891 Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
5892 for (var i = 0; i < this.getMonth(); ++i) {
5893 num += Date.daysInMonth[i];
5895 return num + this.getDate() - 1;
5899 Date.prototype.getWeekOfYear = function() {
5900 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();
5901 return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
5905 Date.prototype.isLeapYear = function() {
5906 var year = this.getFullYear();
5907 return !!((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
5911 Date.prototype.getFirstDayOfMonth = function() {
5912 var day = (this.getDay() - (this.getDate() - 1)) % 7;
5913 return (day < 0) ? (day + 7) : day;
5917 Date.prototype.getLastDayOfMonth = function() {
5918 var day = (this.getDay() + (Date.daysInMonth[this.getMonth()] - this.getDate())) % 7;
5919 return (day < 0) ? (day + 7) : day;
5924 Date.prototype.getFirstDateOfMonth = function() {
5925 return new Date(this.getFullYear(), this.getMonth(), 1);
5929 Date.prototype.getLastDateOfMonth = function() {
5930 return new Date(this.getFullYear(), this.getMonth(), this.getDaysInMonth());
5933 Date.prototype.getDaysInMonth = function() {
5934 Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
5935 return Date.daysInMonth[this.getMonth()];
5939 Date.prototype.getSuffix = function() {
5940 switch (this.getDate()) {
5956 Date.daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31];
5974 Date.getShortMonthName = function(month) {
5975 return Date.monthNames[month].substring(0, 3);
5989 Date.getShortDayName = function(day) {
5990 return Date.dayNames[day].substring(0, 3);
5996 Date.monthNumbers = {
6011 Date.getMonthNumber = function(name) {
6012 return Date.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()];
6016 Date.prototype.clone = function() {
6017 return new Date(this.getTime());
6021 Date.prototype.clearTime = function(clone){
6023 return this.clone().clearTime();
6028 this.setMilliseconds(0);
6033 Date.brokenSetMonth = Date.prototype.setMonth;
6034 Date.prototype.setMonth = function(num){
6036 var n = Math.ceil(-num);
6037 var back_year = Math.ceil(n/12);
6038 var month = (n % 12) ? 12 - n % 12 : 0 ;
6039 this.setFullYear(this.getFullYear() - back_year);
6040 return Date.brokenSetMonth.call(this, month);
6042 return Date.brokenSetMonth.apply(this, arguments);
6063 Date.prototype.add = function(interval, value){
6064 var d = this.clone();
6065 if (!interval || value === 0) return d;
6066 switch(interval.toLowerCase()){
6068 d.setMilliseconds(this.getMilliseconds() + value);
6071 d.setSeconds(this.getSeconds() + value);
6074 d.setMinutes(this.getMinutes() + value);
6077 d.setHours(this.getHours() + value);
6080 d.setDate(this.getDate() + value);
6083 var day = this.getDate();
6085 day = Math.min(day, this.getFirstDateOfMonth().add('mo', value).getLastDateOfMonth().getDate());
6088 d.setMonth(this.getMonth() + value);
6091 d.setFullYear(this.getFullYear() + value);
6098 Date.prototype.between = function(start, end){
6099 var t = this.getTime();
6100 return start.getTime() <= t && t <= end.getTime();
6103 Ext.util.DelayedTask = function(fn, scope, args){
6104 var id = null, d, t;
6106 var call = function(){
6107 var now = new Date().getTime();
6111 fn.apply(scope, args || []);
6115 this.delay = function(delay, newFn, newScope, newArgs){
6116 if(id && delay != d){
6120 t = new Date().getTime();
6122 scope = newScope || scope;
6123 args = newArgs || args;
6125 id = setInterval(call, d);
6130 this.cancel = function(){
6138 Ext.util.TaskRunner = function(interval){
6139 interval = interval || 10;
6140 var tasks = [], removeQueue = [];
6142 var running = false;
6144 var stopThread = function(){
6150 var startThread = function(){
6153 id = setInterval(runTasks, interval);
6157 var removeTask = function(t){
6158 removeQueue.push(t);
6160 t.onStop.apply(t.scope || t);
6164 var runTasks = function(){
6165 if(removeQueue.length > 0){
6166 for(var i = 0, len = removeQueue.length; i < len; i++){
6167 tasks.remove(removeQueue[i]);
6170 if(tasks.length < 1){
6175 var now = new Date().getTime();
6176 for(var i = 0, len = tasks.length; i < len; ++i){
6178 var itime = now - t.taskRunTime;
6179 if(t.interval <= itime){
6180 var rt = t.run.apply(t.scope || t, t.args || [++t.taskRunCount]);
6181 t.taskRunTime = now;
6182 if(rt === false || t.taskRunCount === t.repeat){
6187 if(t.duration && t.duration <= (now - t.taskStartTime)){
6194 this.start = function(task){
6196 task.taskStartTime = new Date().getTime();
6197 task.taskRunTime = 0;
6198 task.taskRunCount = 0;
6204 this.stop = function(task){
6210 this.stopAll = function(){
6212 for(var i = 0, len = tasks.length; i < len; i++){
6213 if(tasks[i].onStop){
6223 Ext.TaskMgr = new Ext.util.TaskRunner();
6225 Ext.util.MixedCollection = function(allowFunctions, keyFn){
\r
6241 this.allowFunctions = allowFunctions === true;
\r
6243 this.getKey = keyFn;
\r
6245 Ext.util.MixedCollection.superclass.constructor.call(this);
\r
6248 Ext.extend(Ext.util.MixedCollection, Ext.util.Observable, {
\r
6249 allowFunctions : false,
\r
6252 add : function(key, o){
\r
6253 if(arguments.length == 1){
\r
6255 key = this.getKey(o);
\r
6257 if(typeof key == "undefined" || key === null){
\r
6259 this.items.push(o);
\r
6260 this.keys.push(null);
\r
6262 var old = this.map[key];
\r
6264 return this.replace(key, o);
\r
6267 this.items.push(o);
\r
6268 this.map[key] = o;
\r
6269 this.keys.push(key);
\r
6271 this.fireEvent("add", this.length-1, o, key);
\r
6276 getKey : function(o){
\r
6281 replace : function(key, o){
\r
6282 if(arguments.length == 1){
\r
6284 key = this.getKey(o);
\r
6286 var old = this.item(key);
\r
6287 if(typeof key == "undefined" || key === null || typeof old == "undefined"){
\r
6288 return this.add(key, o);
\r
6290 var index = this.indexOfKey(key);
\r
6291 this.items[index] = o;
\r
6292 this.map[key] = o;
\r
6293 this.fireEvent("replace", key, old, o);
\r
6298 addAll : function(objs){
\r
6299 if(arguments.length > 1 || Ext.isArray(objs)){
\r
6300 var args = arguments.length > 1 ? arguments : objs;
\r
6301 for(var i = 0, len = args.length; i < len; i++){
\r
6302 this.add(args[i]);
\r
6305 for(var key in objs){
\r
6306 if(this.allowFunctions || typeof objs[key] != "function"){
\r
6307 this.add(key, objs[key]);
\r
6314 each : function(fn, scope){
\r
6315 var items = [].concat(this.items);
6316 for(var i = 0, len = items.length; i < len; i++){
\r
6317 if(fn.call(scope || items[i], items[i], i, len) === false){
\r
6324 eachKey : function(fn, scope){
\r
6325 for(var i = 0, len = this.keys.length; i < len; i++){
\r
6326 fn.call(scope || window, this.keys[i], this.items[i], i, len);
\r
6331 find : function(fn, scope){
\r
6332 for(var i = 0, len = this.items.length; i < len; i++){
\r
6333 if(fn.call(scope || window, this.items[i], this.keys[i])){
\r
6334 return this.items[i];
\r
6341 insert : function(index, key, o){
\r
6342 if(arguments.length == 2){
\r
6344 key = this.getKey(o);
\r
6346 if(index >= this.length){
\r
6347 return this.add(key, o);
\r
6350 this.items.splice(index, 0, o);
\r
6351 if(typeof key != "undefined" && key != null){
\r
6352 this.map[key] = o;
\r
6354 this.keys.splice(index, 0, key);
\r
6355 this.fireEvent("add", index, o, key);
\r
6360 remove : function(o){
\r
6361 return this.removeAt(this.indexOf(o));
\r
6365 removeAt : function(index){
\r
6366 if(index < this.length && index >= 0){
\r
6368 var o = this.items[index];
\r
6369 this.items.splice(index, 1);
\r
6370 var key = this.keys[index];
\r
6371 if(typeof key != "undefined"){
\r
6372 delete this.map[key];
\r
6374 this.keys.splice(index, 1);
\r
6375 this.fireEvent("remove", o, key);
\r
6382 removeKey : function(key){
\r
6383 return this.removeAt(this.indexOfKey(key));
\r
6387 getCount : function(){
\r
6388 return this.length;
\r
6392 indexOf : function(o){
\r
6393 return this.items.indexOf(o);
\r
6397 indexOfKey : function(key){
\r
6398 return this.keys.indexOf(key);
\r
6402 item : function(key){
\r
6403 var item = typeof this.map[key] != "undefined" ? this.map[key] : this.items[key];
\r
6404 return typeof item != 'function' || this.allowFunctions ? item : null;
6408 itemAt : function(index){
\r
6409 return this.items[index];
\r
6413 key : function(key){
\r
6414 return this.map[key];
\r
6418 contains : function(o){
\r
6419 return this.indexOf(o) != -1;
\r
6423 containsKey : function(key){
\r
6424 return typeof this.map[key] != "undefined";
\r
6428 clear : function(){
\r
6433 this.fireEvent("clear");
\r
6437 first : function(){
\r
6438 return this.items[0];
\r
6442 last : function(){
\r
6443 return this.items[this.length-1];
\r
6447 _sort : function(property, dir, fn){
\r
6448 var dsc = String(dir).toUpperCase() == "DESC" ? -1 : 1;
\r
6449 fn = fn || function(a, b){
\r
6452 var c = [], k = this.keys, items = this.items;
\r
6453 for(var i = 0, len = items.length; i < len; i++){
\r
6454 c[c.length] = {key: k[i], value: items[i], index: i};
\r
6456 c.sort(function(a, b){
\r
6457 var v = fn(a[property], b[property]) * dsc;
\r
6459 v = (a.index < b.index ? -1 : 1);
\r
6463 for(var i = 0, len = c.length; i < len; i++){
\r
6464 items[i] = c[i].value;
\r
6467 this.fireEvent("sort", this);
\r
6471 sort : function(dir, fn){
\r
6472 this._sort("value", dir, fn);
\r
6476 keySort : function(dir, fn){
\r
6477 this._sort("key", dir, fn || function(a, b){
\r
6478 return String(a).toUpperCase()-String(b).toUpperCase();
\r
6483 getRange : function(start, end){
\r
6484 var items = this.items;
\r
6485 if(items.length < 1){
\r
6488 start = start || 0;
\r
6489 end = Math.min(typeof end == "undefined" ? this.length-1 : end, this.length-1);
\r
6492 for(var i = start; i <= end; i++) {
\r
6493 r[r.length] = items[i];
\r
6496 for(var i = start; i >= end; i--) {
\r
6497 r[r.length] = items[i];
\r
6504 filter : function(property, value, anyMatch, caseSensitive){
\r
6505 if(Ext.isEmpty(value, false)){
\r
6506 return this.clone();
\r
6508 value = this.createValueMatcher(value, anyMatch, caseSensitive);
\r
6509 return this.filterBy(function(o){
\r
6510 return o && value.test(o[property]);
\r
6515 filterBy : function(fn, scope){
\r
6516 var r = new Ext.util.MixedCollection();
\r
6517 r.getKey = this.getKey;
\r
6518 var k = this.keys, it = this.items;
\r
6519 for(var i = 0, len = it.length; i < len; i++){
\r
6520 if(fn.call(scope||this, it[i], k[i])){
\r
6521 r.add(k[i], it[i]);
\r
6528 findIndex : function(property, value, start, anyMatch, caseSensitive){
\r
6529 if(Ext.isEmpty(value, false)){
\r
6532 value = this.createValueMatcher(value, anyMatch, caseSensitive);
\r
6533 return this.findIndexBy(function(o){
\r
6534 return o && value.test(o[property]);
\r
6539 findIndexBy : function(fn, scope, start){
\r
6540 var k = this.keys, it = this.items;
\r
6541 for(var i = (start||0), len = it.length; i < len; i++){
\r
6542 if(fn.call(scope||this, it[i], k[i])){
\r
6546 if(typeof start == 'number' && start > 0){
\r
6547 for(var i = 0; i < start; i++){
\r
6548 if(fn.call(scope||this, it[i], k[i])){
\r
6557 createValueMatcher : function(value, anyMatch, caseSensitive){
\r
6559 value = String(value);
\r
6560 value = new RegExp((anyMatch === true ? '' : '^') + Ext.escapeRe(value), caseSensitive ? '' : 'i');
\r
6566 clone : function(){
\r
6567 var r = new Ext.util.MixedCollection();
\r
6568 var k = this.keys, it = this.items;
\r
6569 for(var i = 0, len = it.length; i < len; i++){
\r
6570 r.add(k[i], it[i]);
\r
6572 r.getKey = this.getKey;
\r
6577 Ext.util.MixedCollection.prototype.get = Ext.util.MixedCollection.prototype.item;
6579 Ext.util.JSON = new (function(){
\r
6580 var useHasOwn = {}.hasOwnProperty ? true : false;
\r
6585 var pad = function(n) {
\r
6586 return n < 10 ? "0" + n : n;
\r
6599 var encodeString = function(s){
\r
6600 if (/["\\\x00-\x1f]/.test(s)) {
\r
6601 return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) {
\r
6606 c = b.charCodeAt();
\r
6608 Math.floor(c / 16).toString(16) +
\r
6609 (c % 16).toString(16);
\r
6612 return '"' + s + '"';
\r
6615 var encodeArray = function(o){
\r
6616 var a = ["["], b, i, l = o.length, v;
\r
6617 for (i = 0; i < l; i += 1) {
\r
6619 switch (typeof v) {
\r
6628 a.push(v === null ? "null" : Ext.util.JSON.encode(v));
\r
6633 return a.join("");
\r
6636 var encodeDate = function(o){
\r
6637 return '"' + o.getFullYear() + "-" +
\r
6638 pad(o.getMonth() + 1) + "-" +
\r
6639 pad(o.getDate()) + "T" +
\r
6640 pad(o.getHours()) + ":" +
\r
6641 pad(o.getMinutes()) + ":" +
\r
6642 pad(o.getSeconds()) + '"';
\r
6646 this.encode = function(o){
\r
6647 if(typeof o == "undefined" || o === null){
\r
6649 }else if(Ext.isArray(o)){
\r
6650 return encodeArray(o);
\r
6651 }else if(Ext.isDate(o)){
\r
6652 return encodeDate(o);
\r
6653 }else if(typeof o == "string"){
\r
6654 return encodeString(o);
\r
6655 }else if(typeof o == "number"){
\r
6656 return isFinite(o) ? String(o) : "null";
\r
6657 }else if(typeof o == "boolean"){
\r
6660 var a = ["{"], b, i, v;
\r
6662 if(!useHasOwn || o.hasOwnProperty(i)) {
\r
6664 switch (typeof v) {
\r
6673 a.push(this.encode(i), ":",
\r
6674 v === null ? "null" : this.encode(v));
\r
6680 return a.join("");
\r
6685 this.decode = function(json){
\r
6686 return eval("(" + json + ')');
\r
6690 Ext.encode = Ext.util.JSON.encode;
\r
6692 Ext.decode = Ext.util.JSON.decode;
\r
6695 Ext.util.Format = function(){
\r
6696 var trimRe = /^\s+|\s+$/g;
\r
6699 ellipsis : function(value, len){
\r
6700 if(value && value.length > len){
\r
6701 return value.substr(0, len-3)+"...";
\r
6707 undef : function(value){
\r
6708 return value !== undefined ? value : "";
\r
6712 defaultValue : function(value, defaultValue){
\r
6713 return value !== undefined && value !== '' ? value : defaultValue;
\r
6717 htmlEncode : function(value){
\r
6718 return !value ? value : String(value).replace(/&/g, "&").replace(/>/g, ">").replace(/</g, "<").replace(/"/g, """);
\r
6722 htmlDecode : function(value){
\r
6723 return !value ? value : String(value).replace(/&/g, "&").replace(/>/g, ">").replace(/</g, "<").replace(/"/g, '"');
\r
6727 trim : function(value){
\r
6728 return String(value).replace(trimRe, "");
\r
6732 substr : function(value, start, length){
\r
6733 return String(value).substr(start, length);
\r
6737 lowercase : function(value){
\r
6738 return String(value).toLowerCase();
\r
6742 uppercase : function(value){
\r
6743 return String(value).toUpperCase();
\r
6747 capitalize : function(value){
\r
6748 return !value ? value : value.charAt(0).toUpperCase() + value.substr(1).toLowerCase();
\r
6752 call : function(value, fn){
\r
6753 if(arguments.length > 2){
\r
6754 var args = Array.prototype.slice.call(arguments, 2);
\r
6755 args.unshift(value);
\r
6756 return eval(fn).apply(window, args);
\r
6758 return eval(fn).call(window, value);
\r
6763 usMoney : function(v){
\r
6764 v = (Math.round((v-0)*100))/100;
\r
6765 v = (v == Math.floor(v)) ? v + ".00" : ((v*10 == Math.floor(v*10)) ? v + "0" : v);
\r
6767 var ps = v.split('.');
\r
6768 var whole = ps[0];
\r
6769 var sub = ps[1] ? '.'+ ps[1] : '.00';
\r
6770 var r = /(\d+)(\d{3})/;
\r
6771 while (r.test(whole)) {
\r
6772 whole = whole.replace(r, '$1' + ',' + '$2');
\r
6775 if(v.charAt(0) == '-'){
\r
6776 return '-$' + v.substr(1);
\r
6782 date : function(v, format){
\r
6786 if(!Ext.isDate(v)){
\r
6787 v = new Date(Date.parse(v));
\r
6789 return v.dateFormat(format || "m/d/Y");
\r
6793 dateRenderer : function(format){
\r
6794 return function(v){
\r
6795 return Ext.util.Format.date(v, format);
\r
6800 stripTagsRE : /<\/?[^>]+>/gi,
\r
6803 stripTags : function(v){
\r
6804 return !v ? v : String(v).replace(this.stripTagsRE, "");
\r
6807 stripScriptsRe : /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,
\r
6810 stripScripts : function(v){
\r
6811 return !v ? v : String(v).replace(this.stripScriptsRe, "");
\r
6815 fileSize : function(size){
\r
6817 return size + " bytes";
\r
6818 } else if(size < 1048576) {
\r
6819 return (Math.round(((size*10) / 1024))/10) + " KB";
\r
6821 return (Math.round(((size*10) / 1048576))/10) + " MB";
\r
6825 math : function(){
\r
6827 return function(v, a){
\r
6829 fns[a] = new Function('v', 'return v ' + a + ';');
\r
6837 Ext.XTemplate = function(){
\r
6838 Ext.XTemplate.superclass.constructor.apply(this, arguments);
\r
6839 var s = this.html;
\r
6841 s = ['<tpl>', s, '</tpl>'].join('');
\r
6843 var re = /<tpl\b[^>]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/;
\r
6845 var nameRe = /^<tpl\b[^>]*?for="(.*?)"/;
\r
6846 var ifRe = /^<tpl\b[^>]*?if="(.*?)"/;
\r
6847 var execRe = /^<tpl\b[^>]*?exec="(.*?)"/;
\r
6851 while(m = s.match(re)){
\r
6852 var m2 = m[0].match(nameRe);
\r
6853 var m3 = m[0].match(ifRe);
\r
6854 var m4 = m[0].match(execRe);
\r
6855 var exp = null, fn = null, exec = null;
\r
6856 var name = m2 && m2[1] ? m2[1] : '';
\r
6858 exp = m3 && m3[1] ? m3[1] : null;
\r
6860 fn = new Function('values', 'parent', 'xindex', 'xcount', 'with(values){ return '+(Ext.util.Format.htmlDecode(exp))+'; }');
\r
6864 exp = m4 && m4[1] ? m4[1] : null;
\r
6866 exec = new Function('values', 'parent', 'xindex', 'xcount', 'with(values){ '+(Ext.util.Format.htmlDecode(exp))+'; }');
\r
6871 case '.': name = new Function('values', 'parent', 'with(values){ return values; }'); break;
\r
6872 case '..': name = new Function('values', 'parent', 'with(values){ return parent; }'); break;
\r
6873 default: name = new Function('values', 'parent', 'with(values){ return '+name+'; }');
\r
6883 s = s.replace(m[0], '{xtpl'+ id + '}');
\r
6886 for(var i = tpls.length-1; i >= 0; --i){
\r
6887 this.compileTpl(tpls[i]);
\r
6889 this.master = tpls[tpls.length-1];
\r
6892 Ext.extend(Ext.XTemplate, Ext.Template, {
\r
6894 re : /\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\\]\s?[\d\.\+\-\*\\\(\)]+)?\}/g,
\r
6896 codeRe : /\{\[((?:\\\]|.|\n)*?)\]\}/g,
\r
6899 applySubTemplate : function(id, values, parent, xindex, xcount){
\r
6900 var t = this.tpls[id];
\r
6901 if(t.test && !t.test.call(this, values, parent, xindex, xcount)){
\r
6904 if(t.exec && t.exec.call(this, values, parent, xindex, xcount)){
\r
6907 var vs = t.target ? t.target.call(this, values, parent) : values;
\r
6908 parent = t.target ? values : parent;
\r
6909 if(t.target && Ext.isArray(vs)){
\r
6911 for(var i = 0, len = vs.length; i < len; i++){
\r
6912 buf[buf.length] = t.compiled.call(this, vs[i], parent, i+1, len);
\r
6914 return buf.join('');
\r
6916 return t.compiled.call(this, vs, parent, xindex, xcount);
\r
6920 compileTpl : function(tpl){
\r
6921 var fm = Ext.util.Format;
\r
6922 var useF = this.disableFormats !== true;
\r
6923 var sep = Ext.isGecko ? "+" : ",";
\r
6924 var fn = function(m, name, format, args, math){
\r
6925 if(name.substr(0, 4) == 'xtpl'){
\r
6926 return "'"+ sep +'this.applySubTemplate('+name.substr(4)+', values, parent, xindex, xcount)'+sep+"'";
\r
6931 }else if(name === '#'){
\r
6933 }else if(name.indexOf('.') != -1){
\r
6936 v = "values['" + name + "']";
\r
6939 v = '(' + v + math + ')';
\r
6941 if(format && useF){
\r
6942 args = args ? ',' + args : "";
\r
6943 if(format.substr(0, 5) != "this."){
\r
6944 format = "fm." + format + '(';
\r
6946 format = 'this.call("'+ format.substr(5) + '", ';
\r
6947 args = ", values";
\r
6950 args= ''; format = "("+v+" === undefined ? '' : ";
\r
6952 return "'"+ sep + format + v + args + ")"+sep+"'";
\r
6954 var codeFn = function(m, code){
\r
6955 return "'"+ sep +'('+code+')'+sep+"'";
\r
6961 body = "tpl.compiled = function(values, parent, xindex, xcount){ return '" +
\r
6962 tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn) +
\r
6965 body = ["tpl.compiled = function(values, parent, xindex, xcount){ return ['"];
\r
6966 body.push(tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn));
\r
6967 body.push("'].join('');};");
\r
6968 body = body.join('');
\r
6975 apply : function(values){
\r
6976 return this.master.compiled.call(this, values, {}, 1, 1);
\r
6980 applyTemplate : function(values){
\r
6981 return this.master.compiled.call(this, values, {}, 1, 1);
\r
6985 compile : function(){return this;}
\r
6994 Ext.XTemplate.from = function(el){
\r
6995 el = Ext.getDom(el);
\r
6996 return new Ext.XTemplate(el.value || el.innerHTML);
\r
6999 Ext.util.CSS = function(){
\r
7001 var doc = document;
\r
7003 var camelRe = /(-[a-z])/gi;
\r
7004 var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };
\r
7008 createStyleSheet : function(cssText, id){
\r
7010 var head = doc.getElementsByTagName("head")[0];
\r
7011 var rules = doc.createElement("style");
\r
7012 rules.setAttribute("type", "text/css");
\r
7014 rules.setAttribute("id", id);
\r
7017 head.appendChild(rules);
\r
7018 ss = rules.styleSheet;
\r
7019 ss.cssText = cssText;
\r
7022 rules.appendChild(doc.createTextNode(cssText));
\r
7024 rules.cssText = cssText;
\r
7026 head.appendChild(rules);
\r
7027 ss = rules.styleSheet ? rules.styleSheet : (rules.sheet || doc.styleSheets[doc.styleSheets.length-1]);
\r
7029 this.cacheStyleSheet(ss);
\r
7034 removeStyleSheet : function(id){
\r
7035 var existing = doc.getElementById(id);
\r
7037 existing.parentNode.removeChild(existing);
\r
7042 swapStyleSheet : function(id, url){
\r
7043 this.removeStyleSheet(id);
\r
7044 var ss = doc.createElement("link");
\r
7045 ss.setAttribute("rel", "stylesheet");
\r
7046 ss.setAttribute("type", "text/css");
\r
7047 ss.setAttribute("id", id);
\r
7048 ss.setAttribute("href", url);
\r
7049 doc.getElementsByTagName("head")[0].appendChild(ss);
\r
7053 refreshCache : function(){
\r
7054 return this.getRules(true);
\r
7058 cacheStyleSheet : function(ss){
\r
7063 var ssRules = ss.cssRules || ss.rules;
\r
7064 for(var j = ssRules.length-1; j >= 0; --j){
\r
7065 rules[ssRules[j].selectorText] = ssRules[j];
\r
7071 getRules : function(refreshCache){
\r
7072 if(rules == null || refreshCache){
\r
7074 var ds = doc.styleSheets;
\r
7075 for(var i =0, len = ds.length; i < len; i++){
\r
7077 this.cacheStyleSheet(ds[i]);
\r
7085 getRule : function(selector, refreshCache){
\r
7086 var rs = this.getRules(refreshCache);
\r
7087 if(!Ext.isArray(selector)){
\r
7088 return rs[selector];
\r
7090 for(var i = 0; i < selector.length; i++){
\r
7091 if(rs[selector[i]]){
\r
7092 return rs[selector[i]];
\r
7100 updateRule : function(selector, property, value){
\r
7101 if(!Ext.isArray(selector)){
\r
7102 var rule = this.getRule(selector);
\r
7104 rule.style[property.replace(camelRe, camelFn)] = value;
\r
7108 for(var i = 0; i < selector.length; i++){
\r
7109 if(this.updateRule(selector[i], property, value)){
\r
7119 Ext.util.ClickRepeater = function(el, config)
7121 this.el = Ext.get(el);
7122 this.el.unselectable();
7124 Ext.apply(this, config);
7135 this.el.on("mousedown", this.handleMouseDown, this);
7136 if(this.preventDefault || this.stopDefault){
7137 this.el.on("click", function(e){
7138 if(this.preventDefault){
7141 if(this.stopDefault){
7148 this.on("click", this.handler, this.scope || this);
7151 Ext.util.ClickRepeater.superclass.constructor.call(this);
7154 Ext.extend(Ext.util.ClickRepeater, Ext.util.Observable, {
7157 preventDefault : true,
7158 stopDefault : false,
7161 handleMouseDown : function(){
7162 clearTimeout(this.timer);
7164 if(this.pressClass){
7165 this.el.addClass(this.pressClass);
7167 this.mousedownTime = new Date();
7169 Ext.getDoc().on("mouseup", this.handleMouseUp, this);
7170 this.el.on("mouseout", this.handleMouseOut, this);
7172 this.fireEvent("mousedown", this);
7173 this.fireEvent("click", this);
7175 if (this.accelerate) {
7178 this.timer = this.click.defer(this.delay || this.interval, this);
7182 this.fireEvent("click", this);
7183 this.timer = this.click.defer(this.accelerate ?
7184 this.easeOutExpo(this.mousedownTime.getElapsed(),
7188 this.interval, this);
7191 easeOutExpo : function (t, b, c, d) {
7192 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
7195 handleMouseOut : function(){
7196 clearTimeout(this.timer);
7197 if(this.pressClass){
7198 this.el.removeClass(this.pressClass);
7200 this.el.on("mouseover", this.handleMouseReturn, this);
7203 handleMouseReturn : function(){
7204 this.el.un("mouseover", this.handleMouseReturn);
7205 if(this.pressClass){
7206 this.el.addClass(this.pressClass);
7211 handleMouseUp : function(){
7212 clearTimeout(this.timer);
7213 this.el.un("mouseover", this.handleMouseReturn);
7214 this.el.un("mouseout", this.handleMouseOut);
7215 Ext.getDoc().un("mouseup", this.handleMouseUp);
7216 this.el.removeClass(this.pressClass);
7217 this.fireEvent("mouseup", this);
7221 Ext.KeyNav = function(el, config){
7222 this.el = Ext.get(el);
7223 Ext.apply(this, config);
7225 this.disabled = true;
7230 Ext.KeyNav.prototype = {
7234 defaultEventAction: "stopEvent",
7236 forceKeyDown : false,
7238 prepareEvent : function(e){
7240 var h = this.keyToHandler[k];
7241 if(Ext.isSafari && h && k >= 37 && k <= 40){
7246 relay : function(e){
7248 var h = this.keyToHandler[k];
7250 if(this.doRelay(e, this[h], h) !== true){
7251 e[this.defaultEventAction]();
7256 doRelay : function(e, h, hname){
7257 return h.call(this.scope || this, e);
7291 if(this.forceKeyDown || Ext.isIE || Ext.isAir){
7292 this.el.on("keydown", this.relay, this);
7294 this.el.on("keydown", this.prepareEvent, this);
7295 this.el.on("keypress", this.relay, this);
7297 this.disabled = false;
7302 disable: function(){
7304 if(this.forceKeyDown || Ext.isIE || Ext.isAir){
7305 this.el.un("keydown", this.relay);
7307 this.el.un("keydown", this.prepareEvent);
7308 this.el.un("keypress", this.relay);
7310 this.disabled = true;
7315 Ext.KeyMap = function(el, config, eventName){
\r
7316 this.el = Ext.get(el);
\r
7317 this.eventName = eventName || "keydown";
\r
7318 this.bindings = [];
\r
7320 this.addBinding(config);
\r
7325 Ext.KeyMap.prototype = {
\r
7327 stopEvent : false,
\r
7330 addBinding : function(config){
\r
7331 if(Ext.isArray(config)){
\r
7332 for(var i = 0, len = config.length; i < len; i++){
\r
7333 this.addBinding(config[i]);
\r
7337 var keyCode = config.key,
\r
7338 shift = config.shift,
\r
7339 ctrl = config.ctrl,
\r
7341 fn = config.fn || config.handler,
\r
7342 scope = config.scope;
\r
7344 if(typeof keyCode == "string"){
\r
7346 var keyString = keyCode.toUpperCase();
\r
7347 for(var j = 0, len = keyString.length; j < len; j++){
\r
7348 ks.push(keyString.charCodeAt(j));
\r
7352 var keyArray = Ext.isArray(keyCode);
\r
7354 var handler = function(e){
\r
7355 if((!shift || e.shiftKey) && (!ctrl || e.ctrlKey) && (!alt || e.altKey)){
\r
7356 var k = e.getKey();
\r
7358 for(var i = 0, len = keyCode.length; i < len; i++){
\r
7359 if(keyCode[i] == k){
\r
7360 if(this.stopEvent){
\r
7363 fn.call(scope || window, k, e);
\r
7369 if(this.stopEvent){
\r
7372 fn.call(scope || window, k, e);
\r
7377 this.bindings.push(handler);
\r
7381 on : function(key, fn, scope){
\r
7382 var keyCode, shift, ctrl, alt;
\r
7383 if(typeof key == "object" && !Ext.isArray(key)){
\r
7384 keyCode = key.key;
\r
7385 shift = key.shift;
\r
7402 handleKeyDown : function(e){
\r
7404 var b = this.bindings;
\r
7405 for(var i = 0, len = b.length; i < len; i++){
\r
7406 b[i].call(this, e);
\r
7412 isEnabled : function(){
\r
7413 return this.enabled;
\r
7417 enable: function(){
\r
7418 if(!this.enabled){
\r
7419 this.el.on(this.eventName, this.handleKeyDown, this);
\r
7420 this.enabled = true;
\r
7425 disable: function(){
\r
7427 this.el.removeListener(this.eventName, this.handleKeyDown, this);
\r
7428 this.enabled = false;
\r
7433 Ext.util.TextMetrics = function(){
7437 measure : function(el, text, fixedWidth){
7439 shared = Ext.util.TextMetrics.Instance(el, fixedWidth);
7442 shared.setFixedWidth(fixedWidth || 'auto');
7443 return shared.getSize(text);
7447 createInstance : function(el, fixedWidth){
7448 return Ext.util.TextMetrics.Instance(el, fixedWidth);
7453 Ext.util.TextMetrics.Instance = function(bindTo, fixedWidth){
7454 var ml = new Ext.Element(document.createElement('div'));
7455 document.body.appendChild(ml.dom);
7456 ml.position('absolute');
7457 ml.setLeftTop(-1000, -1000);
7461 ml.setWidth(fixedWidth);
7466 getSize : function(text){
7468 var s = ml.getSize();
7474 bind : function(el){
7476 Ext.fly(el).getStyles('font-size','font-style', 'font-weight', 'font-family','line-height')
7481 setFixedWidth : function(width){
7486 getWidth : function(text){
7487 ml.dom.style.width = 'auto';
7488 return this.getSize(text).width;
7492 getHeight : function(text){
7493 return this.getSize(text).height;
7497 instance.bind(bindTo);
7502 Ext.Element.measureText = Ext.util.TextMetrics.measure;
7507 var Event=Ext.EventManager;
\r
7508 var Dom=Ext.lib.Dom;
\r
7511 Ext.dd.DragDrop = function(id, sGroup, config) {
\r
7513 this.init(id, sGroup, config);
\r
7517 Ext.dd.DragDrop.prototype = {
\r
7532 invalidHandleTypes: null,
\r
7535 invalidHandleIds: null,
\r
7538 invalidHandleClasses: null,
\r
7553 lock: function() { this.locked = true; },
\r
7556 unlock: function() { this.locked = false; },
\r
7568 __ygDragDrop: true,
\r
7571 constrainX: false,
\r
7574 constrainY: false,
\r
7589 maintainOffset: false,
\r
7598 primaryButtonOnly: true,
\r
7604 hasOuterHandles: false,
\r
7607 b4StartDrag: function(x, y) { },
\r
7610 startDrag: function(x, y) { },
\r
7613 b4Drag: function(e) { },
\r
7616 onDrag: function(e) { },
\r
7619 onDragEnter: function(e, id) { },
\r
7622 b4DragOver: function(e) { },
\r
7625 onDragOver: function(e, id) { },
\r
7628 b4DragOut: function(e) { },
\r
7631 onDragOut: function(e, id) { },
\r
7634 b4DragDrop: function(e) { },
\r
7637 onDragDrop: function(e, id) { },
\r
7640 onInvalidDrop: function(e) { },
\r
7643 b4EndDrag: function(e) { },
\r
7646 endDrag: function(e) { },
\r
7649 b4MouseDown: function(e) { },
\r
7652 onMouseDown: function(e) { },
\r
7655 onMouseUp: function(e) { },
\r
7658 onAvailable: function () {
\r
7662 defaultPadding : {left:0, right:0, top:0, bottom:0},
\r
7665 constrainTo : function(constrainTo, pad, inContent){
\r
7666 if(typeof pad == "number"){
\r
7667 pad = {left: pad, right:pad, top:pad, bottom:pad};
\r
7669 pad = pad || this.defaultPadding;
\r
7670 var b = Ext.get(this.getEl()).getBox();
\r
7671 var ce = Ext.get(constrainTo);
\r
7672 var s = ce.getScroll();
\r
7673 var c, cd = ce.dom;
\r
7674 if(cd == document.body){
\r
7675 c = { x: s.left, y: s.top, width: Ext.lib.Dom.getViewWidth(), height: Ext.lib.Dom.getViewHeight()};
\r
7677 var xy = ce.getXY();
\r
7678 c = {x : xy[0]+s.left, y: xy[1]+s.top, width: cd.clientWidth, height: cd.clientHeight};
\r
7682 var topSpace = b.y - c.y;
\r
7683 var leftSpace = b.x - c.x;
\r
7685 this.resetConstraints();
\r
7686 this.setXConstraint(leftSpace - (pad.left||0),
7687 c.width - leftSpace - b.width - (pad.right||0),
7690 this.setYConstraint(topSpace - (pad.top||0),
7691 c.height - topSpace - b.height - (pad.bottom||0),
7697 getEl: function() {
\r
7698 if (!this._domRef) {
\r
7699 this._domRef = Ext.getDom(this.id);
\r
7702 return this._domRef;
\r
7706 getDragEl: function() {
\r
7707 return Ext.getDom(this.dragElId);
\r
7711 init: function(id, sGroup, config) {
\r
7712 this.initTarget(id, sGroup, config);
\r
7713 Event.on(this.id, "mousedown", this.handleMouseDown, this);
\r
7718 initTarget: function(id, sGroup, config) {
\r
7721 this.config = config || {};
\r
7724 this.DDM = Ext.dd.DDM;
\r
7730 if (typeof id !== "string") {
\r
7738 this.addToGroup((sGroup) ? sGroup : "default");
\r
7742 this.handleElId = id;
\r
7745 this.setDragElId(id);
\r
7748 this.invalidHandleTypes = { A: "A" };
\r
7749 this.invalidHandleIds = {};
\r
7750 this.invalidHandleClasses = [];
\r
7752 this.applyConfig();
\r
7754 this.handleOnAvailable();
\r
7758 applyConfig: function() {
\r
7762 this.padding = this.config.padding || [0, 0, 0, 0];
\r
7763 this.isTarget = (this.config.isTarget !== false);
\r
7764 this.maintainOffset = (this.config.maintainOffset);
\r
7765 this.primaryButtonOnly = (this.config.primaryButtonOnly !== false);
\r
7770 handleOnAvailable: function() {
\r
7771 this.available = true;
\r
7772 this.resetConstraints();
\r
7773 this.onAvailable();
\r
7777 setPadding: function(iTop, iRight, iBot, iLeft) {
\r
7779 if (!iRight && 0 !== iRight) {
\r
7780 this.padding = [iTop, iTop, iTop, iTop];
\r
7781 } else if (!iBot && 0 !== iBot) {
\r
7782 this.padding = [iTop, iRight, iTop, iRight];
\r
7784 this.padding = [iTop, iRight, iBot, iLeft];
\r
7789 setInitPosition: function(diffX, diffY) {
\r
7790 var el = this.getEl();
\r
7792 if (!this.DDM.verifyEl(el)) {
\r
7796 var dx = diffX || 0;
\r
7797 var dy = diffY || 0;
\r
7799 var p = Dom.getXY( el );
\r
7801 this.initPageX = p[0] - dx;
\r
7802 this.initPageY = p[1] - dy;
\r
7804 this.lastPageX = p[0];
\r
7805 this.lastPageY = p[1];
\r
7808 this.setStartPosition(p);
\r
7812 setStartPosition: function(pos) {
\r
7813 var p = pos || Dom.getXY( this.getEl() );
\r
7814 this.deltaSetXY = null;
\r
7816 this.startPageX = p[0];
\r
7817 this.startPageY = p[1];
\r
7821 addToGroup: function(sGroup) {
\r
7822 this.groups[sGroup] = true;
\r
7823 this.DDM.regDragDrop(this, sGroup);
\r
7827 removeFromGroup: function(sGroup) {
\r
7828 if (this.groups[sGroup]) {
\r
7829 delete this.groups[sGroup];
\r
7832 this.DDM.removeDDFromGroup(this, sGroup);
\r
7836 setDragElId: function(id) {
\r
7837 this.dragElId = id;
\r
7841 setHandleElId: function(id) {
\r
7842 if (typeof id !== "string") {
\r
7845 this.handleElId = id;
\r
7846 this.DDM.regHandle(this.id, id);
\r
7850 setOuterHandleElId: function(id) {
\r
7851 if (typeof id !== "string") {
\r
7854 Event.on(id, "mousedown",
\r
7855 this.handleMouseDown, this);
\r
7856 this.setHandleElId(id);
\r
7858 this.hasOuterHandles = true;
\r
7862 unreg: function() {
\r
7863 Event.un(this.id, "mousedown",
\r
7864 this.handleMouseDown);
\r
7865 this._domRef = null;
\r
7866 this.DDM._remove(this);
\r
7869 destroy : function(){
\r
7874 isLocked: function() {
\r
7875 return (this.DDM.isLocked() || this.locked);
\r
7879 handleMouseDown: function(e, oDD){
\r
7880 if (this.primaryButtonOnly && e.button != 0) {
\r
7884 if (this.isLocked()) {
\r
7888 this.DDM.refreshCache(this.groups);
\r
7890 var pt = new Ext.lib.Point(Ext.lib.Event.getPageX(e), Ext.lib.Event.getPageY(e));
\r
7891 if (!this.hasOuterHandles && !this.DDM.isOverTarget(pt, this) ) {
\r
7893 if (this.clickValidator(e)) {
\r
7896 this.setStartPosition();
\r
7899 this.b4MouseDown(e);
\r
7900 this.onMouseDown(e);
\r
7902 this.DDM.handleMouseDown(e, this);
\r
7904 this.DDM.stopEvent(e);
\r
7912 clickValidator: function(e) {
\r
7913 var target = e.getTarget();
\r
7914 return ( this.isValidHandleChild(target) &&
\r
7915 (this.id == this.handleElId ||
\r
7916 this.DDM.handleWasClicked(target, this.id)) );
\r
7920 addInvalidHandleType: function(tagName) {
\r
7921 var type = tagName.toUpperCase();
\r
7922 this.invalidHandleTypes[type] = type;
\r
7926 addInvalidHandleId: function(id) {
\r
7927 if (typeof id !== "string") {
\r
7930 this.invalidHandleIds[id] = id;
\r
7934 addInvalidHandleClass: function(cssClass) {
\r
7935 this.invalidHandleClasses.push(cssClass);
\r
7939 removeInvalidHandleType: function(tagName) {
\r
7940 var type = tagName.toUpperCase();
\r
7942 delete this.invalidHandleTypes[type];
\r
7946 removeInvalidHandleId: function(id) {
\r
7947 if (typeof id !== "string") {
\r
7950 delete this.invalidHandleIds[id];
\r
7954 removeInvalidHandleClass: function(cssClass) {
\r
7955 for (var i=0, len=this.invalidHandleClasses.length; i<len; ++i) {
\r
7956 if (this.invalidHandleClasses[i] == cssClass) {
\r
7957 delete this.invalidHandleClasses[i];
\r
7963 isValidHandleChild: function(node) {
\r
7969 nodeName = node.nodeName.toUpperCase();
\r
7971 nodeName = node.nodeName;
\r
7973 valid = valid && !this.invalidHandleTypes[nodeName];
\r
7974 valid = valid && !this.invalidHandleIds[node.id];
\r
7976 for (var i=0, len=this.invalidHandleClasses.length; valid && i<len; ++i) {
\r
7977 valid = !Dom.hasClass(node, this.invalidHandleClasses[i]);
\r
7986 setXTicks: function(iStartX, iTickSize) {
\r
7988 this.xTickSize = iTickSize;
\r
7992 for (var i = this.initPageX; i >= this.minX; i = i - iTickSize) {
\r
7993 if (!tickMap[i]) {
\r
7994 this.xTicks[this.xTicks.length] = i;
\r
7995 tickMap[i] = true;
\r
7999 for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) {
\r
8000 if (!tickMap[i]) {
\r
8001 this.xTicks[this.xTicks.length] = i;
\r
8002 tickMap[i] = true;
\r
8006 this.xTicks.sort(this.DDM.numericSort) ;
\r
8010 setYTicks: function(iStartY, iTickSize) {
\r
8012 this.yTickSize = iTickSize;
\r
8016 for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) {
\r
8017 if (!tickMap[i]) {
\r
8018 this.yTicks[this.yTicks.length] = i;
\r
8019 tickMap[i] = true;
\r
8023 for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) {
\r
8024 if (!tickMap[i]) {
\r
8025 this.yTicks[this.yTicks.length] = i;
\r
8026 tickMap[i] = true;
\r
8030 this.yTicks.sort(this.DDM.numericSort) ;
\r
8034 setXConstraint: function(iLeft, iRight, iTickSize) {
\r
8035 this.leftConstraint = iLeft;
\r
8036 this.rightConstraint = iRight;
\r
8038 this.minX = this.initPageX - iLeft;
\r
8039 this.maxX = this.initPageX + iRight;
\r
8040 if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); }
\r
8042 this.constrainX = true;
\r
8046 clearConstraints: function() {
\r
8047 this.constrainX = false;
\r
8048 this.constrainY = false;
\r
8049 this.clearTicks();
\r
8053 clearTicks: function() {
\r
8054 this.xTicks = null;
\r
8055 this.yTicks = null;
\r
8056 this.xTickSize = 0;
\r
8057 this.yTickSize = 0;
\r
8061 setYConstraint: function(iUp, iDown, iTickSize) {
\r
8062 this.topConstraint = iUp;
\r
8063 this.bottomConstraint = iDown;
\r
8065 this.minY = this.initPageY - iUp;
\r
8066 this.maxY = this.initPageY + iDown;
\r
8067 if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); }
\r
8069 this.constrainY = true;
\r
8074 resetConstraints: function() {
\r
8078 if (this.initPageX || this.initPageX === 0) {
\r
8080 var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0;
\r
8081 var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0;
\r
8083 this.setInitPosition(dx, dy);
\r
8087 this.setInitPosition();
\r
8090 if (this.constrainX) {
\r
8091 this.setXConstraint( this.leftConstraint,
\r
8092 this.rightConstraint,
\r
8096 if (this.constrainY) {
\r
8097 this.setYConstraint( this.topConstraint,
\r
8098 this.bottomConstraint,
\r
8104 getTick: function(val, tickArray) {
\r
8110 } else if (tickArray[0] >= val) {
\r
8113 return tickArray[0];
\r
8115 for (var i=0, len=tickArray.length; i<len; ++i) {
\r
8117 if (tickArray[next] && tickArray[next] >= val) {
\r
8118 var diff1 = val - tickArray[i];
\r
8119 var diff2 = tickArray[next] - val;
\r
8120 return (diff2 > diff1) ? tickArray[i] : tickArray[next];
\r
8126 return tickArray[tickArray.length - 1];
\r
8131 toString: function() {
\r
8132 return ("DragDrop " + this.id);
\r
8142 if (!Ext.dd.DragDropMgr) {
\r
8145 Ext.dd.DragDropMgr = function() {
\r
8147 var Event = Ext.EventManager;
\r
8158 dragCurrent: null,
\r
8170 preventDefault: true,
\r
8173 stopPropagation: true,
\r
8176 initalized: false,
\r
8182 init: function() {
\r
8183 this.initialized = true;
\r
8196 _execOnAll: function(sMethod, args) {
\r
8197 for (var i in this.ids) {
\r
8198 for (var j in this.ids[i]) {
\r
8199 var oDD = this.ids[i][j];
\r
8200 if (! this.isTypeOfDD(oDD)) {
\r
8203 oDD[sMethod].apply(oDD, args);
\r
8209 _onLoad: function() {
\r
8214 Event.on(document, "mouseup", this.handleMouseUp, this, true);
\r
8215 Event.on(document, "mousemove", this.handleMouseMove, this, true);
\r
8216 Event.on(window, "unload", this._onUnload, this, true);
\r
8217 Event.on(window, "resize", this._onResize, this, true);
\r
8223 _onResize: function(e) {
\r
8224 this._execOnAll("resetConstraints", []);
\r
8228 lock: function() { this.locked = true; },
\r
8231 unlock: function() { this.locked = false; },
\r
8234 isLocked: function() { return this.locked; },
\r
8237 locationCache: {},
\r
8243 clickPixelThresh: 3,
\r
8246 clickTimeThresh: 350,
\r
8249 dragThreshMet: false,
\r
8252 clickTimeout: null,
\r
8261 regDragDrop: function(oDD, sGroup) {
\r
8262 if (!this.initialized) { this.init(); }
\r
8264 if (!this.ids[sGroup]) {
\r
8265 this.ids[sGroup] = {};
\r
8267 this.ids[sGroup][oDD.id] = oDD;
\r
8271 removeDDFromGroup: function(oDD, sGroup) {
\r
8272 if (!this.ids[sGroup]) {
\r
8273 this.ids[sGroup] = {};
\r
8276 var obj = this.ids[sGroup];
\r
8277 if (obj && obj[oDD.id]) {
\r
8278 delete obj[oDD.id];
\r
8283 _remove: function(oDD) {
\r
8284 for (var g in oDD.groups) {
\r
8285 if (g && this.ids[g][oDD.id]) {
\r
8286 delete this.ids[g][oDD.id];
\r
8289 delete this.handleIds[oDD.id];
\r
8293 regHandle: function(sDDId, sHandleId) {
\r
8294 if (!this.handleIds[sDDId]) {
\r
8295 this.handleIds[sDDId] = {};
\r
8297 this.handleIds[sDDId][sHandleId] = sHandleId;
\r
8301 isDragDrop: function(id) {
\r
8302 return ( this.getDDById(id) ) ? true : false;
\r
8306 getRelated: function(p_oDD, bTargetsOnly) {
\r
8308 for (var i in p_oDD.groups) {
\r
8309 for (j in this.ids[i]) {
\r
8310 var dd = this.ids[i][j];
\r
8311 if (! this.isTypeOfDD(dd)) {
\r
8314 if (!bTargetsOnly || dd.isTarget) {
\r
8315 oDDs[oDDs.length] = dd;
\r
8324 isLegalTarget: function (oDD, oTargetDD) {
\r
8325 var targets = this.getRelated(oDD, true);
\r
8326 for (var i=0, len=targets.length;i<len;++i) {
\r
8327 if (targets[i].id == oTargetDD.id) {
\r
8336 isTypeOfDD: function (oDD) {
\r
8337 return (oDD && oDD.__ygDragDrop);
\r
8341 isHandle: function(sDDId, sHandleId) {
\r
8342 return ( this.handleIds[sDDId] &&
\r
8343 this.handleIds[sDDId][sHandleId] );
\r
8347 getDDById: function(id) {
\r
8348 for (var i in this.ids) {
\r
8349 if (this.ids[i][id]) {
\r
8350 return this.ids[i][id];
\r
8357 handleMouseDown: function(e, oDD) {
\r
8358 if(Ext.QuickTips){
\r
8359 Ext.QuickTips.disable();
\r
8361 this.currentTarget = e.getTarget();
\r
8363 this.dragCurrent = oDD;
\r
8365 var el = oDD.getEl();
\r
8368 this.startX = e.getPageX();
\r
8369 this.startY = e.getPageY();
\r
8371 this.deltaX = this.startX - el.offsetLeft;
\r
8372 this.deltaY = this.startY - el.offsetTop;
\r
8374 this.dragThreshMet = false;
\r
8376 this.clickTimeout = setTimeout(
\r
8378 var DDM = Ext.dd.DDM;
\r
8379 DDM.startDrag(DDM.startX, DDM.startY);
\r
8381 this.clickTimeThresh );
\r
8385 startDrag: function(x, y) {
\r
8386 clearTimeout(this.clickTimeout);
\r
8387 if (this.dragCurrent) {
\r
8388 this.dragCurrent.b4StartDrag(x, y);
\r
8389 this.dragCurrent.startDrag(x, y);
\r
8391 this.dragThreshMet = true;
\r
8395 handleMouseUp: function(e) {
\r
8397 if(Ext.QuickTips){
\r
8398 Ext.QuickTips.enable();
\r
8400 if (! this.dragCurrent) {
\r
8404 clearTimeout(this.clickTimeout);
\r
8406 if (this.dragThreshMet) {
\r
8407 this.fireEvents(e, true);
\r
8413 this.stopEvent(e);
\r
8417 stopEvent: function(e){
\r
8418 if(this.stopPropagation) {
\r
8419 e.stopPropagation();
\r
8422 if (this.preventDefault) {
\r
8423 e.preventDefault();
\r
8428 stopDrag: function(e) {
\r
8430 if (this.dragCurrent) {
\r
8431 if (this.dragThreshMet) {
\r
8432 this.dragCurrent.b4EndDrag(e);
\r
8433 this.dragCurrent.endDrag(e);
\r
8436 this.dragCurrent.onMouseUp(e);
\r
8439 this.dragCurrent = null;
\r
8440 this.dragOvers = {};
\r
8444 handleMouseMove: function(e) {
\r
8445 if (! this.dragCurrent) {
\r
8452 if (Ext.isIE && (e.button !== 0 && e.button !== 1 && e.button !== 2)) {
\r
8453 this.stopEvent(e);
\r
8454 return this.handleMouseUp(e);
\r
8457 if (!this.dragThreshMet) {
\r
8458 var diffX = Math.abs(this.startX - e.getPageX());
\r
8459 var diffY = Math.abs(this.startY - e.getPageY());
\r
8460 if (diffX > this.clickPixelThresh ||
\r
8461 diffY > this.clickPixelThresh) {
\r
8462 this.startDrag(this.startX, this.startY);
\r
8466 if (this.dragThreshMet) {
\r
8467 this.dragCurrent.b4Drag(e);
\r
8468 this.dragCurrent.onDrag(e);
\r
8469 if(!this.dragCurrent.moveOnly){
\r
8470 this.fireEvents(e, false);
\r
8474 this.stopEvent(e);
\r
8480 fireEvents: function(e, isDrop) {
\r
8481 var dc = this.dragCurrent;
\r
8485 if (!dc || dc.isLocked()) {
\r
8489 var pt = e.getPoint();
\r
8492 var oldOvers = [];
\r
8495 var overEvts = [];
\r
8496 var dropEvts = [];
\r
8497 var enterEvts = [];
\r
8501 for (var i in this.dragOvers) {
\r
8503 var ddo = this.dragOvers[i];
\r
8505 if (! this.isTypeOfDD(ddo)) {
\r
8509 if (! this.isOverTarget(pt, ddo, this.mode)) {
\r
8510 outEvts.push( ddo );
\r
8513 oldOvers[i] = true;
\r
8514 delete this.dragOvers[i];
\r
8517 for (var sGroup in dc.groups) {
\r
8519 if ("string" != typeof sGroup) {
\r
8523 for (i in this.ids[sGroup]) {
\r
8524 var oDD = this.ids[sGroup][i];
\r
8525 if (! this.isTypeOfDD(oDD)) {
\r
8529 if (oDD.isTarget && !oDD.isLocked() && oDD != dc) {
\r
8530 if (this.isOverTarget(pt, oDD, this.mode)) {
\r
8533 dropEvts.push( oDD );
\r
8538 if (!oldOvers[oDD.id]) {
\r
8539 enterEvts.push( oDD );
\r
8542 overEvts.push( oDD );
\r
8545 this.dragOvers[oDD.id] = oDD;
\r
8553 if (outEvts.length) {
\r
8554 dc.b4DragOut(e, outEvts);
\r
8555 dc.onDragOut(e, outEvts);
\r
8558 if (enterEvts.length) {
\r
8559 dc.onDragEnter(e, enterEvts);
\r
8562 if (overEvts.length) {
\r
8563 dc.b4DragOver(e, overEvts);
\r
8564 dc.onDragOver(e, overEvts);
\r
8567 if (dropEvts.length) {
\r
8568 dc.b4DragDrop(e, dropEvts);
\r
8569 dc.onDragDrop(e, dropEvts);
\r
8575 for (i=0, len=outEvts.length; i<len; ++i) {
\r
8576 dc.b4DragOut(e, outEvts[i].id);
\r
8577 dc.onDragOut(e, outEvts[i].id);
\r
8581 for (i=0,len=enterEvts.length; i<len; ++i) {
\r
8583 dc.onDragEnter(e, enterEvts[i].id);
\r
8587 for (i=0,len=overEvts.length; i<len; ++i) {
\r
8588 dc.b4DragOver(e, overEvts[i].id);
\r
8589 dc.onDragOver(e, overEvts[i].id);
\r
8593 for (i=0, len=dropEvts.length; i<len; ++i) {
\r
8594 dc.b4DragDrop(e, dropEvts[i].id);
\r
8595 dc.onDragDrop(e, dropEvts[i].id);
\r
8601 if (isDrop && !dropEvts.length) {
\r
8602 dc.onInvalidDrop(e);
\r
8608 getBestMatch: function(dds) {
\r
8609 var winner = null;
\r
8616 var len = dds.length;
\r
8622 for (var i=0; i<len; ++i) {
\r
8627 if (dd.cursorIsOver) {
\r
8633 winner.overlap.getArea() < dd.overlap.getArea()) {
\r
8644 refreshCache: function(groups) {
\r
8645 for (var sGroup in groups) {
\r
8646 if ("string" != typeof sGroup) {
\r
8649 for (var i in this.ids[sGroup]) {
\r
8650 var oDD = this.ids[sGroup][i];
\r
8652 if (this.isTypeOfDD(oDD)) {
\r
8654 var loc = this.getLocation(oDD);
\r
8656 this.locationCache[oDD.id] = loc;
\r
8658 delete this.locationCache[oDD.id];
\r
8669 verifyEl: function(el) {
\r
8674 parent = el.offsetParent;
\r
8677 parent = el.offsetParent;
\r
8688 getLocation: function(oDD) {
\r
8689 if (! this.isTypeOfDD(oDD)) {
\r
8693 var el = oDD.getEl(), pos, x1, x2, y1, y2, t, r, b, l;
\r
8696 pos= Ext.lib.Dom.getXY(el);
\r
8704 x2 = x1 + el.offsetWidth;
\r
8706 y2 = y1 + el.offsetHeight;
\r
8708 t = y1 - oDD.padding[0];
\r
8709 r = x2 + oDD.padding[1];
\r
8710 b = y2 + oDD.padding[2];
\r
8711 l = x1 - oDD.padding[3];
\r
8713 return new Ext.lib.Region( t, r, b, l );
\r
8717 isOverTarget: function(pt, oTarget, intersect) {
\r
8719 var loc = this.locationCache[oTarget.id];
\r
8720 if (!loc || !this.useCache) {
\r
8721 loc = this.getLocation(oTarget);
\r
8722 this.locationCache[oTarget.id] = loc;
\r
8730 oTarget.cursorIsOver = loc.contains( pt );
\r
8737 var dc = this.dragCurrent;
\r
8738 if (!dc || !dc.getTargetCoord ||
\r
8739 (!intersect && !dc.constrainX && !dc.constrainY)) {
\r
8740 return oTarget.cursorIsOver;
\r
8743 oTarget.overlap = null;
\r
8749 var pos = dc.getTargetCoord(pt.x, pt.y);
\r
8751 var el = dc.getDragEl();
\r
8752 var curRegion = new Ext.lib.Region( pos.y,
\r
8753 pos.x + el.offsetWidth,
\r
8754 pos.y + el.offsetHeight,
\r
8757 var overlap = curRegion.intersect(loc);
\r
8760 oTarget.overlap = overlap;
\r
8761 return (intersect) ? true : oTarget.cursorIsOver;
\r
8768 _onUnload: function(e, me) {
\r
8769 Ext.dd.DragDropMgr.unregAll();
\r
8773 unregAll: function() {
\r
8775 if (this.dragCurrent) {
\r
8777 this.dragCurrent = null;
\r
8780 this._execOnAll("unreg", []);
\r
8782 for (var i in this.elementCache) {
\r
8783 delete this.elementCache[i];
\r
8786 this.elementCache = {};
\r
8794 getElWrapper: function(id) {
\r
8795 var oWrapper = this.elementCache[id];
\r
8796 if (!oWrapper || !oWrapper.el) {
\r
8797 oWrapper = this.elementCache[id] =
\r
8798 new this.ElementWrapper(Ext.getDom(id));
\r
8804 getElement: function(id) {
\r
8805 return Ext.getDom(id);
\r
8809 getCss: function(id) {
\r
8810 var el = Ext.getDom(id);
\r
8811 return (el) ? el.style : null;
\r
8815 ElementWrapper: function(el) {
\r
8817 this.el = el || null;
\r
8819 this.id = this.el && el.id;
\r
8821 this.css = this.el && el.style;
\r
8825 getPosX: function(el) {
\r
8826 return Ext.lib.Dom.getX(el);
\r
8830 getPosY: function(el) {
\r
8831 return Ext.lib.Dom.getY(el);
\r
8835 swapNode: function(n1, n2) {
\r
8836 if (n1.swapNode) {
\r
8839 var p = n2.parentNode;
\r
8840 var s = n2.nextSibling;
\r
8843 p.insertBefore(n1, n2);
\r
8844 } else if (n2 == n1.nextSibling) {
\r
8845 p.insertBefore(n2, n1);
\r
8847 n1.parentNode.replaceChild(n2, n1);
\r
8848 p.insertBefore(n1, s);
\r
8854 getScroll: function () {
\r
8855 var t, l, dde=document.documentElement, db=document.body;
\r
8856 if (dde && (dde.scrollTop || dde.scrollLeft)) {
\r
8857 t = dde.scrollTop;
\r
8858 l = dde.scrollLeft;
\r
8861 l = db.scrollLeft;
\r
8865 return { top: t, left: l };
\r
8869 getStyle: function(el, styleProp) {
\r
8870 return Ext.fly(el).getStyle(styleProp);
\r
8874 getScrollTop: function () { return this.getScroll().top; },
\r
8877 getScrollLeft: function () { return this.getScroll().left; },
\r
8880 moveToEl: function (moveEl, targetEl) {
\r
8881 var aCoord = Ext.lib.Dom.getXY(targetEl);
\r
8882 Ext.lib.Dom.setXY(moveEl, aCoord);
\r
8886 numericSort: function(a, b) { return (a - b); },
\r
8892 _addListeners: function() {
\r
8893 var DDM = Ext.dd.DDM;
\r
8894 if ( Ext.lib.Event && document ) {
\r
8897 if (DDM._timeoutCount > 2000) {
\r
8899 setTimeout(DDM._addListeners, 10);
\r
8900 if (document && document.body) {
\r
8901 DDM._timeoutCount += 1;
\r
8908 handleWasClicked: function(node, id) {
\r
8909 if (this.isHandle(id, node.id)) {
\r
8913 var p = node.parentNode;
\r
8916 if (this.isHandle(id, p.id)) {
\r
8932 Ext.dd.DDM = Ext.dd.DragDropMgr;
\r
8933 Ext.dd.DDM._addListeners();
\r
8938 Ext.dd.DD = function(id, sGroup, config) {
\r
8940 this.init(id, sGroup, config);
\r
8944 Ext.extend(Ext.dd.DD, Ext.dd.DragDrop, {
\r
8950 autoOffset: function(iPageX, iPageY) {
\r
8951 var x = iPageX - this.startPageX;
\r
8952 var y = iPageY - this.startPageY;
\r
8953 this.setDelta(x, y);
\r
8957 setDelta: function(iDeltaX, iDeltaY) {
\r
8958 this.deltaX = iDeltaX;
\r
8959 this.deltaY = iDeltaY;
\r
8963 setDragElPos: function(iPageX, iPageY) {
\r
8967 var el = this.getDragEl();
\r
8968 this.alignElWithMouse(el, iPageX, iPageY);
\r
8972 alignElWithMouse: function(el, iPageX, iPageY) {
\r
8973 var oCoord = this.getTargetCoord(iPageX, iPageY);
\r
8974 var fly = el.dom ? el : Ext.fly(el, '_dd');
\r
8975 if (!this.deltaSetXY) {
\r
8976 var aCoord = [oCoord.x, oCoord.y];
\r
8977 fly.setXY(aCoord);
\r
8978 var newLeft = fly.getLeft(true);
\r
8979 var newTop = fly.getTop(true);
\r
8980 this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ];
\r
8982 fly.setLeftTop(oCoord.x + this.deltaSetXY[0], oCoord.y + this.deltaSetXY[1]);
\r
8985 this.cachePosition(oCoord.x, oCoord.y);
\r
8986 this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
\r
8991 cachePosition: function(iPageX, iPageY) {
\r
8993 this.lastPageX = iPageX;
\r
8994 this.lastPageY = iPageY;
\r
8996 var aCoord = Ext.lib.Dom.getXY(this.getEl());
\r
8997 this.lastPageX = aCoord[0];
\r
8998 this.lastPageY = aCoord[1];
\r
9003 autoScroll: function(x, y, h, w) {
\r
9005 if (this.scroll) {
\r
9007 var clientH = Ext.lib.Dom.getViewHeight();
\r
9010 var clientW = Ext.lib.Dom.getViewWidth();
\r
9013 var st = this.DDM.getScrollTop();
\r
9016 var sl = this.DDM.getScrollLeft();
\r
9022 var right = w + x;
\r
9027 var toBot = (clientH + st - y - this.deltaY);
\r
9030 var toRight = (clientW + sl - x - this.deltaX);
\r
9040 var scrAmt = (document.all) ? 80 : 30;
\r
9044 if ( bot > clientH && toBot < thresh ) {
\r
9045 window.scrollTo(sl, st + scrAmt);
\r
9050 if ( y < st && st > 0 && y - st < thresh ) {
\r
9051 window.scrollTo(sl, st - scrAmt);
\r
9056 if ( right > clientW && toRight < thresh ) {
\r
9057 window.scrollTo(sl + scrAmt, st);
\r
9062 if ( x < sl && sl > 0 && x - sl < thresh ) {
\r
9063 window.scrollTo(sl - scrAmt, st);
\r
9069 getTargetCoord: function(iPageX, iPageY) {
\r
9072 var x = iPageX - this.deltaX;
\r
9073 var y = iPageY - this.deltaY;
\r
9075 if (this.constrainX) {
\r
9076 if (x < this.minX) { x = this.minX; }
\r
9077 if (x > this.maxX) { x = this.maxX; }
\r
9080 if (this.constrainY) {
\r
9081 if (y < this.minY) { y = this.minY; }
\r
9082 if (y > this.maxY) { y = this.maxY; }
\r
9085 x = this.getTick(x, this.xTicks);
\r
9086 y = this.getTick(y, this.yTicks);
\r
9089 return {x:x, y:y};
\r
9093 applyConfig: function() {
\r
9094 Ext.dd.DD.superclass.applyConfig.call(this);
\r
9095 this.scroll = (this.config.scroll !== false);
\r
9099 b4MouseDown: function(e) {
\r
9101 this.autoOffset(e.getPageX(),
\r
9106 b4Drag: function(e) {
\r
9107 this.setDragElPos(e.getPageX(),
\r
9111 toString: function() {
\r
9112 return ("DD " + this.id);
\r
9122 Ext.dd.DDProxy = function(id, sGroup, config) {
\r
9124 this.init(id, sGroup, config);
\r
9130 Ext.dd.DDProxy.dragElId = "ygddfdiv";
\r
9132 Ext.extend(Ext.dd.DDProxy, Ext.dd.DD, {
\r
9135 resizeFrame: true,
\r
9138 centerFrame: false,
\r
9141 createFrame: function() {
\r
9143 var body = document.body;
\r
9145 if (!body || !body.firstChild) {
\r
9146 setTimeout( function() { self.createFrame(); }, 50 );
\r
9150 var div = this.getDragEl();
\r
9153 div = document.createElement("div");
\r
9154 div.id = this.dragElId;
\r
9155 var s = div.style;
\r
9157 s.position = "absolute";
\r
9158 s.visibility = "hidden";
\r
9159 s.cursor = "move";
\r
9160 s.border = "2px solid #aaa";
\r
9166 body.insertBefore(div, body.firstChild);
\r
9171 initFrame: function() {
\r
9172 this.createFrame();
\r
9175 applyConfig: function() {
\r
9176 Ext.dd.DDProxy.superclass.applyConfig.call(this);
\r
9178 this.resizeFrame = (this.config.resizeFrame !== false);
\r
9179 this.centerFrame = (this.config.centerFrame);
\r
9180 this.setDragElId(this.config.dragElId || Ext.dd.DDProxy.dragElId);
\r
9184 showFrame: function(iPageX, iPageY) {
\r
9185 var el = this.getEl();
\r
9186 var dragEl = this.getDragEl();
\r
9187 var s = dragEl.style;
\r
9189 this._resizeProxy();
\r
9191 if (this.centerFrame) {
\r
9192 this.setDelta( Math.round(parseInt(s.width, 10)/2),
\r
9193 Math.round(parseInt(s.height, 10)/2) );
\r
9196 this.setDragElPos(iPageX, iPageY);
\r
9198 Ext.fly(dragEl).show();
\r
9202 _resizeProxy: function() {
\r
9203 if (this.resizeFrame) {
\r
9204 var el = this.getEl();
\r
9205 Ext.fly(this.getDragEl()).setSize(el.offsetWidth, el.offsetHeight);
\r
9210 b4MouseDown: function(e) {
\r
9211 var x = e.getPageX();
\r
9212 var y = e.getPageY();
\r
9213 this.autoOffset(x, y);
\r
9214 this.setDragElPos(x, y);
\r
9218 b4StartDrag: function(x, y) {
\r
9220 this.showFrame(x, y);
\r
9224 b4EndDrag: function(e) {
\r
9225 Ext.fly(this.getDragEl()).hide();
\r
9231 endDrag: function(e) {
\r
9233 var lel = this.getEl();
\r
9234 var del = this.getDragEl();
\r
9237 del.style.visibility = "";
\r
9239 this.beforeMove();
\r
9242 lel.style.visibility = "hidden";
\r
9243 Ext.dd.DDM.moveToEl(lel, del);
\r
9244 del.style.visibility = "hidden";
\r
9245 lel.style.visibility = "";
\r
9250 beforeMove : function(){
\r
9254 afterDrag : function(){
\r
9258 toString: function() {
\r
9259 return ("DDProxy " + this.id);
\r
9264 Ext.dd.DDTarget = function(id, sGroup, config) {
\r
9266 this.initTarget(id, sGroup, config);
\r
9271 Ext.extend(Ext.dd.DDTarget, Ext.dd.DragDrop, {
\r
9272 toString: function() {
\r
9273 return ("DDTarget " + this.id);
\r
9277 Ext.dd.DragTracker = function(config){
\r
9278 Ext.apply(this, config);
\r
9288 this.dragRegion = new Ext.lib.Region(0,0,0,0);
\r
9291 this.initEl(this.el);
\r
9295 Ext.extend(Ext.dd.DragTracker, Ext.util.Observable, {
\r
9300 initEl: function(el){
\r
9301 this.el = Ext.get(el);
\r
9302 el.on('mousedown', this.onMouseDown, this,
\r
9303 this.delegate ? {delegate: this.delegate} : undefined);
\r
9306 destroy : function(){
\r
9307 this.el.un('mousedown', this.onMouseDown, this);
\r
9310 onMouseDown: function(e, target){
\r
9311 if(this.fireEvent('mousedown', this, e) !== false && this.onBeforeStart(e) !== false){
\r
9312 this.startXY = this.lastXY = e.getXY();
\r
9313 this.dragTarget = this.delegate ? target : this.el.dom;
\r
9314 e.preventDefault();
\r
9315 var doc = Ext.getDoc();
\r
9316 doc.on('mouseup', this.onMouseUp, this);
\r
9317 doc.on('mousemove', this.onMouseMove, this);
\r
9318 doc.on('selectstart', this.stopSelect, this);
\r
9319 if(this.autoStart){
\r
9320 this.timer = this.triggerStart.defer(this.autoStart === true ? 1000 : this.autoStart, this);
\r
9325 onMouseMove: function(e, target){
\r
9326 e.preventDefault();
\r
9327 var xy = e.getXY(), s = this.startXY;
\r
9330 if(Math.abs(s[0]-xy[0]) > this.tolerance || Math.abs(s[1]-xy[1]) > this.tolerance){
\r
9331 this.triggerStart();
\r
9336 this.fireEvent('mousemove', this, e);
\r
9338 this.fireEvent('drag', this, e);
\r
9341 onMouseUp: function(e){
\r
9342 var doc = Ext.getDoc();
\r
9343 doc.un('mousemove', this.onMouseMove, this);
\r
9344 doc.un('mouseup', this.onMouseUp, this);
\r
9345 doc.un('selectstart', this.stopSelect, this);
\r
9346 e.preventDefault();
\r
9347 this.clearStart();
\r
9348 this.active = false;
\r
9349 delete this.elRegion;
\r
9350 this.fireEvent('mouseup', this, e);
\r
9352 this.fireEvent('dragend', this, e);
\r
9355 triggerStart: function(isTimer){
\r
9356 this.clearStart();
\r
9357 this.active = true;
\r
9358 this.onStart(this.startXY);
\r
9359 this.fireEvent('dragstart', this, this.startXY);
\r
9362 clearStart : function(){
\r
9364 clearTimeout(this.timer);
\r
9365 delete this.timer;
\r
9369 stopSelect : function(e){
\r
9374 onBeforeStart : function(e){
\r
9378 onStart : function(xy){
\r
9382 onDrag : function(e){
\r
9386 onEnd : function(e){
\r
9390 getDragTarget : function(){
\r
9391 return this.dragTarget;
\r
9394 getDragCt : function(){
\r
9398 getXY : function(constrain){
\r
9399 return constrain ?
\r
9400 this.constrainModes[constrain].call(this, this.lastXY) : this.lastXY;
\r
9403 getOffset : function(constrain){
\r
9404 var xy = this.getXY(constrain);
\r
9405 var s = this.startXY;
\r
9406 return [s[0]-xy[0], s[1]-xy[1]];
\r
9410 'point' : function(xy){
\r
9412 if(!this.elRegion){
\r
9413 this.elRegion = this.getDragCt().getRegion();
\r
9416 var dr = this.dragRegion;
\r
9421 dr.bottom = xy[1];
\r
9423 dr.constrainTo(this.elRegion);
\r
9425 return [dr.left, dr.top];
\r
9430 Ext.dd.ScrollManager = function(){
\r
9431 var ddm = Ext.dd.DragDropMgr;
\r
9433 var dragEl = null;
\r
9436 var onStop = function(e){
\r
9441 var triggerRefresh = function(){
\r
9442 if(ddm.dragCurrent){
\r
9443 ddm.refreshCache(ddm.dragCurrent.groups);
\r
9447 var doScroll = function(){
\r
9448 if(ddm.dragCurrent){
\r
9449 var dds = Ext.dd.ScrollManager;
\r
9450 var inc = proc.el.ddScrollConfig ?
\r
9451 proc.el.ddScrollConfig.increment : dds.increment;
\r
9453 if(proc.el.scroll(proc.dir, inc)){
\r
9457 proc.el.scroll(proc.dir, inc, true, dds.animDuration, triggerRefresh);
\r
9462 var clearProc = function(){
\r
9464 clearInterval(proc.id);
\r
9471 var startProc = function(el, dir){
\r
9475 proc.id = setInterval(doScroll, Ext.dd.ScrollManager.frequency);
\r
9478 var onFire = function(e, isDrop){
\r
9479 if(isDrop || !ddm.dragCurrent){ return; }
\r
9480 var dds = Ext.dd.ScrollManager;
\r
9481 if(!dragEl || dragEl != ddm.dragCurrent){
\r
9482 dragEl = ddm.dragCurrent;
\r
9484 dds.refreshCache();
\r
9487 var xy = Ext.lib.Event.getXY(e);
\r
9488 var pt = new Ext.lib.Point(xy[0], xy[1]);
\r
9489 for(var id in els){
\r
9490 var el = els[id], r = el._region;
\r
9491 var c = el.ddScrollConfig ? el.ddScrollConfig : dds;
\r
9492 if(r && r.contains(pt) && el.isScrollable()){
\r
9493 if(r.bottom - pt.y <= c.vthresh){
\r
9494 if(proc.el != el){
\r
9495 startProc(el, "down");
\r
9498 }else if(r.right - pt.x <= c.hthresh){
\r
9499 if(proc.el != el){
\r
9500 startProc(el, "left");
\r
9503 }else if(pt.y - r.top <= c.vthresh){
\r
9504 if(proc.el != el){
\r
9505 startProc(el, "up");
\r
9508 }else if(pt.x - r.left <= c.hthresh){
\r
9509 if(proc.el != el){
\r
9510 startProc(el, "right");
\r
9519 ddm.fireEvents = ddm.fireEvents.createSequence(onFire, ddm);
\r
9520 ddm.stopDrag = ddm.stopDrag.createSequence(onStop, ddm);
\r
9524 register : function(el){
\r
9525 if(Ext.isArray(el)){
\r
9526 for(var i = 0, len = el.length; i < len; i++) {
\r
9527 this.register(el[i]);
\r
9536 unregister : function(el){
\r
9537 if(Ext.isArray(el)){
\r
9538 for(var i = 0, len = el.length; i < len; i++) {
\r
9539 this.unregister(el[i]);
\r
9543 delete els[el.id];
\r
9565 refreshCache : function(){
\r
9566 for(var id in els){
\r
9567 if(typeof els[id] == 'object'){
9568 els[id]._region = els[id].getRegion();
\r
9575 Ext.dd.Registry = function(){
\r
9576 var elements = {};
\r
9577 var handles = {};
\r
9578 var autoIdSeed = 0;
\r
9580 var getId = function(el, autogen){
\r
9581 if(typeof el == "string"){
\r
9585 if(!id && autogen !== false){
\r
9586 id = "extdd-" + (++autoIdSeed);
\r
9594 register : function(el, data){
\r
9595 data = data || {};
\r
9596 if(typeof el == "string"){
\r
9597 el = document.getElementById(el);
\r
9600 elements[getId(el)] = data;
\r
9601 if(data.isHandle !== false){
\r
9602 handles[data.ddel.id] = data;
\r
9605 var hs = data.handles;
\r
9606 for(var i = 0, len = hs.length; i < len; i++){
\r
9607 handles[getId(hs[i])] = data;
\r
9613 unregister : function(el){
\r
9614 var id = getId(el, false);
\r
9615 var data = elements[id];
\r
9617 delete elements[id];
\r
9619 var hs = data.handles;
\r
9620 for(var i = 0, len = hs.length; i < len; i++){
\r
9621 delete handles[getId(hs[i], false)];
\r
9628 getHandle : function(id){
\r
9629 if(typeof id != "string"){
9632 return handles[id];
\r
9636 getHandleFromEvent : function(e){
\r
9637 var t = Ext.lib.Event.getTarget(e);
\r
9638 return t ? handles[t.id] : null;
\r
9642 getTarget : function(id){
\r
9643 if(typeof id != "string"){
9646 return elements[id];
\r
9650 getTargetFromEvent : function(e){
\r
9651 var t = Ext.lib.Event.getTarget(e);
\r
9652 return t ? elements[t.id] || handles[t.id] : null;
\r
9657 Ext.dd.StatusProxy = function(config){
\r
9658 Ext.apply(this, config);
\r
9659 this.id = this.id || Ext.id();
\r
9660 this.el = new Ext.Layer({
\r
9662 id: this.id, tag: "div", cls: "x-dd-drag-proxy "+this.dropNotAllowed, children: [
\r
9663 {tag: "div", cls: "x-dd-drop-icon"},
\r
9664 {tag: "div", cls: "x-dd-drag-ghost"}
\r
9667 shadow: !config || config.shadow !== false
\r
9669 this.ghost = Ext.get(this.el.dom.childNodes[1]);
\r
9670 this.dropStatus = this.dropNotAllowed;
\r
9673 Ext.dd.StatusProxy.prototype = {
\r
9675 dropAllowed : "x-dd-drop-ok",
\r
9677 dropNotAllowed : "x-dd-drop-nodrop",
\r
9680 setStatus : function(cssClass){
\r
9681 cssClass = cssClass || this.dropNotAllowed;
\r
9682 if(this.dropStatus != cssClass){
\r
9683 this.el.replaceClass(this.dropStatus, cssClass);
\r
9684 this.dropStatus = cssClass;
\r
9689 reset : function(clearGhost){
\r
9690 this.el.dom.className = "x-dd-drag-proxy " + this.dropNotAllowed;
\r
9691 this.dropStatus = this.dropNotAllowed;
\r
9693 this.ghost.update("");
\r
9698 update : function(html){
\r
9699 if(typeof html == "string"){
\r
9700 this.ghost.update(html);
\r
9702 this.ghost.update("");
\r
9703 html.style.margin = "0";
\r
9704 this.ghost.dom.appendChild(html);
\r
9709 getEl : function(){
\r
9714 getGhost : function(){
\r
9715 return this.ghost;
\r
9719 hide : function(clear){
\r
9727 stop : function(){
\r
9728 if(this.anim && this.anim.isAnimated && this.anim.isAnimated()){
\r
9734 show : function(){
\r
9739 sync : function(){
\r
9744 repair : function(xy, callback, scope){
\r
9745 this.callback = callback;
\r
9746 this.scope = scope;
\r
9747 if(xy && this.animRepair !== false){
\r
9748 this.el.addClass("x-dd-drag-repair");
\r
9749 this.el.hideUnders(true);
\r
9750 this.anim = this.el.shift({
\r
9751 duration: this.repairDuration || .5,
\r
9752 easing: 'easeOut',
\r
9755 callback: this.afterRepair,
\r
9759 this.afterRepair();
\r
9764 afterRepair : function(){
\r
9766 if(typeof this.callback == "function"){
\r
9767 this.callback.call(this.scope || this);
\r
9769 this.callback = null;
\r
9770 this.scope = null;
\r
9774 Ext.dd.DragSource = function(el, config){
\r
9775 this.el = Ext.get(el);
\r
9776 if(!this.dragData){
\r
9777 this.dragData = {};
\r
9780 Ext.apply(this, config);
\r
9783 this.proxy = new Ext.dd.StatusProxy();
\r
9785 Ext.dd.DragSource.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group,
\r
9786 {dragElId : this.proxy.id, resizeFrame: false, isTarget: false, scroll: this.scroll === true});
\r
9788 this.dragging = false;
\r
9791 Ext.extend(Ext.dd.DragSource, Ext.dd.DDProxy, {
\r
9794 dropAllowed : "x-dd-drop-ok",
\r
9796 dropNotAllowed : "x-dd-drop-nodrop",
\r
9799 getDragData : function(e){
\r
9800 return this.dragData;
\r
9804 onDragEnter : function(e, id){
\r
9805 var target = Ext.dd.DragDropMgr.getDDById(id);
\r
9806 this.cachedTarget = target;
\r
9807 if(this.beforeDragEnter(target, e, id) !== false){
\r
9808 if(target.isNotifyTarget){
\r
9809 var status = target.notifyEnter(this, e, this.dragData);
\r
9810 this.proxy.setStatus(status);
\r
9812 this.proxy.setStatus(this.dropAllowed);
\r
9815 if(this.afterDragEnter){
\r
9817 this.afterDragEnter(target, e, id);
\r
9823 beforeDragEnter : function(target, e, id){
\r
9828 alignElWithMouse: function() {
\r
9829 Ext.dd.DragSource.superclass.alignElWithMouse.apply(this, arguments);
\r
9830 this.proxy.sync();
\r
9834 onDragOver : function(e, id){
\r
9835 var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
\r
9836 if(this.beforeDragOver(target, e, id) !== false){
\r
9837 if(target.isNotifyTarget){
\r
9838 var status = target.notifyOver(this, e, this.dragData);
\r
9839 this.proxy.setStatus(status);
\r
9842 if(this.afterDragOver){
\r
9844 this.afterDragOver(target, e, id);
\r
9850 beforeDragOver : function(target, e, id){
\r
9855 onDragOut : function(e, id){
\r
9856 var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
\r
9857 if(this.beforeDragOut(target, e, id) !== false){
\r
9858 if(target.isNotifyTarget){
\r
9859 target.notifyOut(this, e, this.dragData);
\r
9861 this.proxy.reset();
\r
9862 if(this.afterDragOut){
\r
9864 this.afterDragOut(target, e, id);
\r
9867 this.cachedTarget = null;
\r
9871 beforeDragOut : function(target, e, id){
\r
9876 onDragDrop : function(e, id){
\r
9877 var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
\r
9878 if(this.beforeDragDrop(target, e, id) !== false){
\r
9879 if(target.isNotifyTarget){
\r
9880 if(target.notifyDrop(this, e, this.dragData)){
9881 this.onValidDrop(target, e, id);
\r
9883 this.onInvalidDrop(target, e, id);
\r
9886 this.onValidDrop(target, e, id);
\r
9889 if(this.afterDragDrop){
\r
9891 this.afterDragDrop(target, e, id);
\r
9894 delete this.cachedTarget;
\r
9898 beforeDragDrop : function(target, e, id){
\r
9903 onValidDrop : function(target, e, id){
\r
9905 if(this.afterValidDrop){
\r
9907 this.afterValidDrop(target, e, id);
\r
9912 getRepairXY : function(e, data){
\r
9913 return this.el.getXY();
\r
9917 onInvalidDrop : function(target, e, id){
\r
9918 this.beforeInvalidDrop(target, e, id);
\r
9919 if(this.cachedTarget){
\r
9920 if(this.cachedTarget.isNotifyTarget){
\r
9921 this.cachedTarget.notifyOut(this, e, this.dragData);
\r
9923 this.cacheTarget = null;
\r
9925 this.proxy.repair(this.getRepairXY(e, this.dragData), this.afterRepair, this);
\r
9927 if(this.afterInvalidDrop){
\r
9929 this.afterInvalidDrop(e, id);
\r
9934 afterRepair : function(){
\r
9936 this.el.highlight(this.hlColor || "c3daf9");
\r
9938 this.dragging = false;
\r
9942 beforeInvalidDrop : function(target, e, id){
\r
9947 handleMouseDown : function(e){
\r
9948 if(this.dragging) {
\r
9951 var data = this.getDragData(e);
\r
9952 if(data && this.onBeforeDrag(data, e) !== false){
\r
9953 this.dragData = data;
\r
9954 this.proxy.stop();
\r
9955 Ext.dd.DragSource.superclass.handleMouseDown.apply(this, arguments);
\r
9960 onBeforeDrag : function(data, e){
\r
9965 onStartDrag : Ext.emptyFn,
\r
9968 startDrag : function(x, y){
\r
9969 this.proxy.reset();
\r
9970 this.dragging = true;
\r
9971 this.proxy.update("");
\r
9972 this.onInitDrag(x, y);
\r
9973 this.proxy.show();
\r
9977 onInitDrag : function(x, y){
\r
9978 var clone = this.el.dom.cloneNode(true);
\r
9979 clone.id = Ext.id();
9980 this.proxy.update(clone);
\r
9981 this.onStartDrag(x, y);
\r
9986 getProxy : function(){
\r
9987 return this.proxy;
\r
9991 hideProxy : function(){
\r
9992 this.proxy.hide();
\r
9993 this.proxy.reset(true);
\r
9994 this.dragging = false;
\r
9998 triggerCacheRefresh : function(){
\r
9999 Ext.dd.DDM.refreshCache(this.groups);
\r
10003 b4EndDrag: function(e) {
\r
10007 endDrag : function(e){
\r
10008 this.onEndDrag(this.dragData, e);
\r
10012 onEndDrag : function(data, e){
\r
10016 autoOffset : function(x, y) {
\r
10017 this.setDelta(-12, -20);
\r
10021 Ext.dd.DropTarget = function(el, config){
\r
10022 this.el = Ext.get(el);
\r
10024 Ext.apply(this, config);
\r
10026 if(this.containerScroll){
\r
10027 Ext.dd.ScrollManager.register(this.el);
\r
10030 Ext.dd.DropTarget.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group,
\r
10031 {isTarget: true});
\r
10035 Ext.extend(Ext.dd.DropTarget, Ext.dd.DDTarget, {
\r
10039 dropAllowed : "x-dd-drop-ok",
\r
10041 dropNotAllowed : "x-dd-drop-nodrop",
\r
10047 isNotifyTarget : true,
\r
10050 notifyEnter : function(dd, e, data){
\r
10051 if(this.overClass){
\r
10052 this.el.addClass(this.overClass);
\r
10054 return this.dropAllowed;
\r
10058 notifyOver : function(dd, e, data){
\r
10059 return this.dropAllowed;
\r
10063 notifyOut : function(dd, e, data){
\r
10064 if(this.overClass){
\r
10065 this.el.removeClass(this.overClass);
\r
10070 notifyDrop : function(dd, e, data){
\r
10075 Ext.dd.DragZone = function(el, config){
\r
10076 Ext.dd.DragZone.superclass.constructor.call(this, el, config);
\r
10077 if(this.containerScroll){
\r
10078 Ext.dd.ScrollManager.register(this.el);
\r
10082 Ext.extend(Ext.dd.DragZone, Ext.dd.DragSource, {
\r
10087 getDragData : function(e){
\r
10088 return Ext.dd.Registry.getHandleFromEvent(e);
\r
10092 onInitDrag : function(x, y){
\r
10093 this.proxy.update(this.dragData.ddel.cloneNode(true));
\r
10094 this.onStartDrag(x, y);
\r
10099 afterRepair : function(){
\r
10100 if(Ext.enableFx){
\r
10101 Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9");
\r
10103 this.dragging = false;
\r
10107 getRepairXY : function(e){
\r
10108 return Ext.Element.fly(this.dragData.ddel).getXY();
\r
10112 Ext.dd.DropZone = function(el, config){
\r
10113 Ext.dd.DropZone.superclass.constructor.call(this, el, config);
\r
10116 Ext.extend(Ext.dd.DropZone, Ext.dd.DropTarget, {
\r
10118 getTargetFromEvent : function(e){
\r
10119 return Ext.dd.Registry.getTargetFromEvent(e);
\r
10123 onNodeEnter : function(n, dd, e, data){
\r
10128 onNodeOver : function(n, dd, e, data){
\r
10129 return this.dropAllowed;
\r
10133 onNodeOut : function(n, dd, e, data){
\r
10138 onNodeDrop : function(n, dd, e, data){
\r
10143 onContainerOver : function(dd, e, data){
\r
10144 return this.dropNotAllowed;
\r
10148 onContainerDrop : function(dd, e, data){
\r
10153 notifyEnter : function(dd, e, data){
\r
10154 return this.dropNotAllowed;
\r
10158 notifyOver : function(dd, e, data){
\r
10159 var n = this.getTargetFromEvent(e);
\r
10161 if(this.lastOverNode){
\r
10162 this.onNodeOut(this.lastOverNode, dd, e, data);
\r
10163 this.lastOverNode = null;
\r
10165 return this.onContainerOver(dd, e, data);
\r
10167 if(this.lastOverNode != n){
\r
10168 if(this.lastOverNode){
\r
10169 this.onNodeOut(this.lastOverNode, dd, e, data);
\r
10171 this.onNodeEnter(n, dd, e, data);
\r
10172 this.lastOverNode = n;
\r
10174 return this.onNodeOver(n, dd, e, data);
\r
10178 notifyOut : function(dd, e, data){
\r
10179 if(this.lastOverNode){
\r
10180 this.onNodeOut(this.lastOverNode, dd, e, data);
\r
10181 this.lastOverNode = null;
\r
10186 notifyDrop : function(dd, e, data){
\r
10187 if(this.lastOverNode){
\r
10188 this.onNodeOut(this.lastOverNode, dd, e, data);
\r
10189 this.lastOverNode = null;
\r
10191 var n = this.getTargetFromEvent(e);
\r
10193 this.onNodeDrop(n, dd, e, data) :
\r
10194 this.onContainerDrop(dd, e, data);
\r
10198 triggerCacheRefresh : function(){
\r
10199 Ext.dd.DDM.refreshCache(this.groups);
\r
10204 Ext.data.SortTypes = {
\r
10206 none : function(s){
\r
10211 stripTagsRE : /<\/?[^>]+>/gi,
\r
10214 asText : function(s){
\r
10215 return String(s).replace(this.stripTagsRE, "");
\r
10219 asUCText : function(s){
\r
10220 return String(s).toUpperCase().replace(this.stripTagsRE, "");
\r
10224 asUCString : function(s) {
\r
10225 return String(s).toUpperCase();
\r
10229 asDate : function(s) {
\r
10233 if(Ext.isDate(s)){
\r
10234 return s.getTime();
\r
10236 return Date.parse(String(s));
\r
10240 asFloat : function(s) {
\r
10241 var val = parseFloat(String(s).replace(/,/g, ""));
\r
10242 if(isNaN(val)) val = 0;
\r
10247 asInt : function(s) {
\r
10248 var val = parseInt(String(s).replace(/,/g, ""));
\r
10249 if(isNaN(val)) val = 0;
\r
10254 Ext.data.Record = function(data, id){
\r
10255 this.id = (id || id === 0) ? id : ++Ext.data.Record.AUTO_ID;
\r
10256 this.data = data;
\r
10260 Ext.data.Record.create = function(o){
\r
10261 var f = Ext.extend(Ext.data.Record, {});
\r
10262 var p = f.prototype;
\r
10263 p.fields = new Ext.util.MixedCollection(false, function(field){
\r
10264 return field.name;
\r
10266 for(var i = 0, len = o.length; i < len; i++){
\r
10267 p.fields.add(new Ext.data.Field(o[i]));
\r
10269 f.getField = function(name){
\r
10270 return p.fields.get(name);
\r
10275 Ext.data.Record.AUTO_ID = 1000;
\r
10276 Ext.data.Record.EDIT = 'edit';
\r
10277 Ext.data.Record.REJECT = 'reject';
\r
10278 Ext.data.Record.COMMIT = 'commit';
\r
10280 Ext.data.Record.prototype = {
\r
10291 join : function(store){
\r
10292 this.store = store;
\r
10296 set : function(name, value){
\r
10297 if(String(this.data[name]) == String(value)){
\r
10300 this.dirty = true;
\r
10301 if(!this.modified){
\r
10302 this.modified = {};
\r
10304 if(typeof this.modified[name] == 'undefined'){
\r
10305 this.modified[name] = this.data[name];
\r
10307 this.data[name] = value;
\r
10308 if(!this.editing && this.store){
\r
10309 this.store.afterEdit(this);
\r
10314 get : function(name){
\r
10315 return this.data[name];
\r
10319 beginEdit : function(){
\r
10320 this.editing = true;
\r
10321 this.modified = {};
\r
10325 cancelEdit : function(){
\r
10326 this.editing = false;
\r
10327 delete this.modified;
\r
10331 endEdit : function(){
\r
10332 this.editing = false;
\r
10333 if(this.dirty && this.store){
\r
10334 this.store.afterEdit(this);
\r
10339 reject : function(silent){
\r
10340 var m = this.modified;
\r
10342 if(typeof m[n] != "function"){
\r
10343 this.data[n] = m[n];
\r
10346 this.dirty = false;
\r
10347 delete this.modified;
\r
10348 this.editing = false;
\r
10349 if(this.store && silent !== true){
\r
10350 this.store.afterReject(this);
\r
10355 commit : function(silent){
\r
10356 this.dirty = false;
\r
10357 delete this.modified;
\r
10358 this.editing = false;
\r
10359 if(this.store && silent !== true){
\r
10360 this.store.afterCommit(this);
\r
10365 getChanges : function(){
\r
10366 var m = this.modified, cs = {};
\r
10368 if(m.hasOwnProperty(n)){
\r
10369 cs[n] = this.data[n];
\r
10376 hasError : function(){
\r
10377 return this.error != null;
\r
10381 clearError : function(){
\r
10382 this.error = null;
\r
10386 copy : function(newId) {
\r
10387 return new this.constructor(Ext.apply({}, this.data), newId || this.id);
\r
10391 isModified : function(fieldName){
\r
10392 return this.modified && this.modified.hasOwnProperty(fieldName);
\r
10396 Ext.StoreMgr = Ext.apply(new Ext.util.MixedCollection(), {
\r
10397 register : function(){
\r
10398 for(var i = 0, s; s = arguments[i]; i++){
\r
10403 unregister : function(){
\r
10404 for(var i = 0, s; s = arguments[i]; i++){
\r
10405 this.remove(this.lookup(s));
\r
10410 lookup : function(id){
\r
10411 return typeof id == "object" ? id : this.get(id);
\r
10415 getKey : function(o){
\r
10416 return o.storeId || o.id;
\r
10420 Ext.data.Store = function(config){
\r
10421 this.data = new Ext.util.MixedCollection(false);
\r
10422 this.data.getKey = function(o){
\r
10426 this.baseParams = {};
\r
10428 this.paramNames = {
\r
10429 "start" : "start",
\r
10430 "limit" : "limit",
\r
10435 if(config && config.data){
\r
10436 this.inlineData = config.data;
\r
10437 delete config.data;
\r
10440 Ext.apply(this, config);
\r
10442 if(this.url && !this.proxy){
\r
10443 this.proxy = new Ext.data.HttpProxy({url: this.url});
\r
10447 if(!this.recordType){
\r
10448 this.recordType = this.reader.recordType;
\r
10450 if(this.reader.onMetaChange){
\r
10451 this.reader.onMetaChange = this.onMetaChange.createDelegate(this);
\r
10455 if(this.recordType){
\r
10456 this.fields = this.recordType.prototype.fields;
\r
10458 this.modified = [];
\r
10482 this.relayEvents(this.proxy, ["loadexception"]);
\r
10485 this.sortToggle = {};
\r
10486 if(this.sortInfo){
\r
10487 this.setDefaultSort(this.sortInfo.field, this.sortInfo.direction);
\r
10490 Ext.data.Store.superclass.constructor.call(this);
\r
10492 if(this.storeId || this.id){
\r
10493 Ext.StoreMgr.register(this);
\r
10495 if(this.inlineData){
\r
10496 this.loadData(this.inlineData);
\r
10497 delete this.inlineData;
\r
10498 }else if(this.autoLoad){
\r
10499 this.load.defer(10, this, [
\r
10500 typeof this.autoLoad == 'object' ?
\r
10501 this.autoLoad : undefined]);
\r
10504 Ext.extend(Ext.data.Store, Ext.util.Observable, {
\r
10514 remoteSort : false,
\r
10517 pruneModifiedRecords : false,
\r
10520 lastOptions : null,
\r
10522 destroy : function(){
\r
10524 Ext.StoreMgr.unregister(this);
\r
10526 this.data = null;
\r
10527 this.purgeListeners();
\r
10531 add : function(records){
\r
10532 records = [].concat(records);
\r
10533 if(records.length < 1){
\r
10536 for(var i = 0, len = records.length; i < len; i++){
\r
10537 records[i].join(this);
\r
10539 var index = this.data.length;
\r
10540 this.data.addAll(records);
\r
10541 if(this.snapshot){
\r
10542 this.snapshot.addAll(records);
\r
10544 this.fireEvent("add", this, records, index);
\r
10548 addSorted : function(record){
\r
10549 var index = this.findInsertIndex(record);
\r
10550 this.insert(index, record);
\r
10554 remove : function(record){
\r
10555 var index = this.data.indexOf(record);
\r
10556 this.data.removeAt(index);
\r
10557 if(this.pruneModifiedRecords){
\r
10558 this.modified.remove(record);
\r
10560 if(this.snapshot){
\r
10561 this.snapshot.remove(record);
\r
10563 this.fireEvent("remove", this, record, index);
\r
10567 removeAll : function(){
\r
10568 this.data.clear();
\r
10569 if(this.snapshot){
\r
10570 this.snapshot.clear();
\r
10572 if(this.pruneModifiedRecords){
\r
10573 this.modified = [];
\r
10575 this.fireEvent("clear", this);
\r
10579 insert : function(index, records){
\r
10580 records = [].concat(records);
\r
10581 for(var i = 0, len = records.length; i < len; i++){
\r
10582 this.data.insert(index, records[i]);
\r
10583 records[i].join(this);
\r
10585 this.fireEvent("add", this, records, index);
\r
10589 indexOf : function(record){
\r
10590 return this.data.indexOf(record);
\r
10594 indexOfId : function(id){
\r
10595 return this.data.indexOfKey(id);
\r
10599 getById : function(id){
\r
10600 return this.data.key(id);
\r
10604 getAt : function(index){
\r
10605 return this.data.itemAt(index);
\r
10609 getRange : function(start, end){
\r
10610 return this.data.getRange(start, end);
\r
10614 storeOptions : function(o){
\r
10615 o = Ext.apply({}, o);
\r
10616 delete o.callback;
\r
10618 this.lastOptions = o;
\r
10622 load : function(options){
\r
10623 options = options || {};
\r
10624 if(this.fireEvent("beforeload", this, options) !== false){
\r
10625 this.storeOptions(options);
\r
10626 var p = Ext.apply(options.params || {}, this.baseParams);
\r
10627 if(this.sortInfo && this.remoteSort){
\r
10628 var pn = this.paramNames;
\r
10629 p[pn["sort"]] = this.sortInfo.field;
\r
10630 p[pn["dir"]] = this.sortInfo.direction;
\r
10632 this.proxy.load(p, this.reader, this.loadRecords, this, options);
\r
10640 reload : function(options){
\r
10641 this.load(Ext.applyIf(options||{}, this.lastOptions));
\r
10646 loadRecords : function(o, options, success){
\r
10647 if(!o || success === false){
\r
10648 if(success !== false){
\r
10649 this.fireEvent("load", this, [], options);
\r
10651 if(options.callback){
\r
10652 options.callback.call(options.scope || this, [], options, false);
\r
10656 var r = o.records, t = o.totalRecords || r.length;
\r
10657 if(!options || options.add !== true){
\r
10658 if(this.pruneModifiedRecords){
\r
10659 this.modified = [];
\r
10661 for(var i = 0, len = r.length; i < len; i++){
\r
10664 if(this.snapshot){
\r
10665 this.data = this.snapshot;
\r
10666 delete this.snapshot;
\r
10668 this.data.clear();
\r
10669 this.data.addAll(r);
\r
10670 this.totalLength = t;
\r
10671 this.applySort();
\r
10672 this.fireEvent("datachanged", this);
\r
10674 this.totalLength = Math.max(t, this.data.length+r.length);
\r
10677 this.fireEvent("load", this, r, options);
\r
10678 if(options.callback){
\r
10679 options.callback.call(options.scope || this, r, options, true);
\r
10684 loadData : function(o, append){
\r
10685 var r = this.reader.readRecords(o);
\r
10686 this.loadRecords(r, {add: append}, true);
\r
10690 getCount : function(){
\r
10691 return this.data.length || 0;
\r
10695 getTotalCount : function(){
\r
10696 return this.totalLength || 0;
\r
10700 getSortState : function(){
\r
10701 return this.sortInfo;
\r
10705 applySort : function(){
\r
10706 if(this.sortInfo && !this.remoteSort){
\r
10707 var s = this.sortInfo, f = s.field;
\r
10708 this.sortData(f, s.direction);
\r
10713 sortData : function(f, direction){
\r
10714 direction = direction || 'ASC';
\r
10715 var st = this.fields.get(f).sortType;
\r
10716 var fn = function(r1, r2){
\r
10717 var v1 = st(r1.data[f]), v2 = st(r2.data[f]);
\r
10718 return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
\r
10720 this.data.sort(direction, fn);
\r
10721 if(this.snapshot && this.snapshot != this.data){
\r
10722 this.snapshot.sort(direction, fn);
\r
10727 setDefaultSort : function(field, dir){
\r
10728 dir = dir ? dir.toUpperCase() : "ASC";
\r
10729 this.sortInfo = {field: field, direction: dir};
\r
10730 this.sortToggle[field] = dir;
\r
10734 sort : function(fieldName, dir){
\r
10735 var f = this.fields.get(fieldName);
\r
10740 if(this.sortInfo && this.sortInfo.field == f.name){
10741 dir = (this.sortToggle[f.name] || "ASC").toggle("ASC", "DESC");
\r
10746 var st = (this.sortToggle) ? this.sortToggle[f.name] : null;
\r
10747 var si = (this.sortInfo) ? this.sortInfo : null;
\r
10749 this.sortToggle[f.name] = dir;
\r
10750 this.sortInfo = {field: f.name, direction: dir};
\r
10751 if(!this.remoteSort){
\r
10752 this.applySort();
\r
10753 this.fireEvent("datachanged", this);
\r
10755 if (!this.load(this.lastOptions)) {
\r
10757 this.sortToggle[f.name] = st;
\r
10760 this.sortInfo = si;
\r
10767 each : function(fn, scope){
\r
10768 this.data.each(fn, scope);
\r
10772 getModifiedRecords : function(){
\r
10773 return this.modified;
\r
10777 createFilterFn : function(property, value, anyMatch, caseSensitive){
\r
10778 if(Ext.isEmpty(value, false)){
\r
10781 value = this.data.createValueMatcher(value, anyMatch, caseSensitive);
\r
10782 return function(r){
\r
10783 return value.test(r.data[property]);
\r
10788 sum : function(property, start, end){
\r
10789 var rs = this.data.items, v = 0;
\r
10790 start = start || 0;
\r
10791 end = (end || end === 0) ? end : rs.length-1;
\r
10793 for(var i = start; i <= end; i++){
\r
10794 v += (rs[i].data[property] || 0);
\r
10800 filter : function(property, value, anyMatch, caseSensitive){
\r
10801 var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
\r
10802 return fn ? this.filterBy(fn) : this.clearFilter();
\r
10806 filterBy : function(fn, scope){
\r
10807 this.snapshot = this.snapshot || this.data;
\r
10808 this.data = this.queryBy(fn, scope||this);
\r
10809 this.fireEvent("datachanged", this);
\r
10813 query : function(property, value, anyMatch, caseSensitive){
\r
10814 var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
\r
10815 return fn ? this.queryBy(fn) : this.data.clone();
\r
10819 queryBy : function(fn, scope){
\r
10820 var data = this.snapshot || this.data;
\r
10821 return data.filterBy(fn, scope||this);
\r
10825 find : function(property, value, start, anyMatch, caseSensitive){
\r
10826 var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
\r
10827 return fn ? this.data.findIndexBy(fn, null, start) : -1;
\r
10831 findBy : function(fn, scope, start){
\r
10832 return this.data.findIndexBy(fn, scope, start);
\r
10836 collect : function(dataIndex, allowNull, bypassFilter){
\r
10837 var d = (bypassFilter === true && this.snapshot) ?
\r
10838 this.snapshot.items : this.data.items;
\r
10839 var v, sv, r = [], l = {};
\r
10840 for(var i = 0, len = d.length; i < len; i++){
\r
10841 v = d[i].data[dataIndex];
\r
10843 if((allowNull || !Ext.isEmpty(v)) && !l[sv]){
\r
10852 clearFilter : function(suppressEvent){
\r
10853 if(this.isFiltered()){
\r
10854 this.data = this.snapshot;
\r
10855 delete this.snapshot;
\r
10856 if(suppressEvent !== true){
\r
10857 this.fireEvent("datachanged", this);
\r
10863 isFiltered : function(){
\r
10864 return this.snapshot && this.snapshot != this.data;
\r
10868 afterEdit : function(record){
\r
10869 if(this.modified.indexOf(record) == -1){
\r
10870 this.modified.push(record);
\r
10872 this.fireEvent("update", this, record, Ext.data.Record.EDIT);
\r
10876 afterReject : function(record){
\r
10877 this.modified.remove(record);
\r
10878 this.fireEvent("update", this, record, Ext.data.Record.REJECT);
\r
10882 afterCommit : function(record){
\r
10883 this.modified.remove(record);
\r
10884 this.fireEvent("update", this, record, Ext.data.Record.COMMIT);
\r
10888 commitChanges : function(){
\r
10889 var m = this.modified.slice(0);
\r
10890 this.modified = [];
\r
10891 for(var i = 0, len = m.length; i < len; i++){
\r
10897 rejectChanges : function(){
\r
10898 var m = this.modified.slice(0);
\r
10899 this.modified = [];
\r
10900 for(var i = 0, len = m.length; i < len; i++){
\r
10906 onMetaChange : function(meta, rtype, o){
\r
10907 this.recordType = rtype;
\r
10908 this.fields = rtype.prototype.fields;
\r
10909 delete this.snapshot;
\r
10910 this.sortInfo = meta.sortInfo;
\r
10911 this.modified = [];
\r
10912 this.fireEvent('metachange', this, this.reader.meta);
\r
10916 findInsertIndex : function(record){
\r
10917 this.suspendEvents();
\r
10918 var data = this.data.clone();
\r
10919 this.data.add(record);
\r
10920 this.applySort();
\r
10921 var index = this.data.indexOf(record);
\r
10922 this.data = data;
\r
10923 this.resumeEvents();
\r
10928 Ext.data.SimpleStore = function(config){
10929 Ext.data.SimpleStore.superclass.constructor.call(this, Ext.apply(config, {
10930 reader: new Ext.data.ArrayReader({
10933 Ext.data.Record.create(config.fields)
10937 Ext.extend(Ext.data.SimpleStore, Ext.data.Store, {
10938 loadData : function(data, append){
10939 if(this.expandData === true){
10941 for(var i = 0, len = data.length; i < len; i++){
10942 r[r.length] = [data[i]];
10946 Ext.data.SimpleStore.superclass.loadData.call(this, data, append);
10950 Ext.data.JsonStore = function(c){
\r
10951 Ext.data.JsonStore.superclass.constructor.call(this, Ext.apply(c, {
\r
10952 proxy: !c.data ? new Ext.data.HttpProxy({url: c.url}) : undefined,
\r
10953 reader: new Ext.data.JsonReader(c, c.fields)
\r
10956 Ext.extend(Ext.data.JsonStore, Ext.data.Store);
10960 Ext.data.Field = function(config){
\r
10961 if(typeof config == "string"){
\r
10962 config = {name: config};
\r
10964 Ext.apply(this, config);
\r
10967 this.type = "auto";
\r
10970 var st = Ext.data.SortTypes;
\r
10972 if(typeof this.sortType == "string"){
\r
10973 this.sortType = st[this.sortType];
\r
10977 if(!this.sortType){
\r
10978 switch(this.type){
\r
10980 this.sortType = st.asUCString;
\r
10983 this.sortType = st.asDate;
\r
10986 this.sortType = st.none;
\r
10991 var stripRe = /[\$,%]/g;
\r
10995 if(!this.convert){
\r
10996 var cv, dateFormat = this.dateFormat;
\r
10997 switch(this.type){
\r
11001 cv = function(v){ return v; };
\r
11004 cv = function(v){ return (v === undefined || v === null) ? '' : String(v); };
\r
11007 cv = function(v){
\r
11008 return v !== undefined && v !== null && v !== '' ?
\r
11009 parseInt(String(v).replace(stripRe, ""), 10) : '';
\r
11013 cv = function(v){
\r
11014 return v !== undefined && v !== null && v !== '' ?
\r
11015 parseFloat(String(v).replace(stripRe, ""), 10) : '';
\r
11020 cv = function(v){ return v === true || v === "true" || v == 1; };
\r
11023 cv = function(v){
\r
11027 if(Ext.isDate(v)){
\r
11031 if(dateFormat == "timestamp"){
\r
11032 return new Date(v*1000);
\r
11034 if(dateFormat == "time"){
\r
11035 return new Date(parseInt(v, 10));
\r
11037 return Date.parseDate(v, dateFormat);
\r
11039 var parsed = Date.parse(v);
\r
11040 return parsed ? new Date(parsed) : null;
\r
11045 this.convert = cv;
\r
11049 Ext.data.Field.prototype = {
\r
11050 dateFormat: null,
\r
11051 defaultValue: "",
\r
11057 Ext.data.DataReader = function(meta, recordType){
\r
11059 this.meta = meta;
\r
11060 this.recordType = Ext.isArray(recordType) ?
\r
11061 Ext.data.Record.create(recordType) : recordType;
\r
11064 Ext.data.DataReader.prototype = {
\r
11068 Ext.data.DataProxy = function(){
\r
11077 Ext.data.DataProxy.superclass.constructor.call(this);
\r
11080 Ext.extend(Ext.data.DataProxy, Ext.util.Observable);
11082 Ext.data.MemoryProxy = function(data){
\r
11083 Ext.data.MemoryProxy.superclass.constructor.call(this);
\r
11084 this.data = data;
\r
11087 Ext.extend(Ext.data.MemoryProxy, Ext.data.DataProxy, {
\r
11089 load : function(params, reader, callback, scope, arg){
\r
11090 params = params || {};
\r
11093 result = reader.readRecords(this.data);
\r
11095 this.fireEvent("loadexception", this, arg, null, e);
\r
11096 callback.call(scope, null, arg, false);
\r
11099 callback.call(scope, result, arg, true);
\r
11103 update : function(params, records){
\r
11108 Ext.data.HttpProxy = function(conn){
\r
11109 Ext.data.HttpProxy.superclass.constructor.call(this);
\r
11111 this.conn = conn;
\r
11112 this.useAjax = !conn || !conn.events;
\r
11115 Ext.extend(Ext.data.HttpProxy, Ext.data.DataProxy, {
\r
11117 getConnection : function(){
\r
11118 return this.useAjax ? Ext.Ajax : this.conn;
\r
11122 load : function(params, reader, callback, scope, arg){
\r
11123 if(this.fireEvent("beforeload", this, params) !== false){
\r
11125 params : params || {},
\r
11127 callback : callback,
\r
11132 callback : this.loadResponse,
\r
11135 if(this.useAjax){
\r
11136 Ext.applyIf(o, this.conn);
\r
11137 if(this.activeRequest){
\r
11138 Ext.Ajax.abort(this.activeRequest);
\r
11140 this.activeRequest = Ext.Ajax.request(o);
\r
11142 this.conn.request(o);
\r
11145 callback.call(scope||this, null, arg, false);
\r
11150 loadResponse : function(o, success, response){
\r
11151 delete this.activeRequest;
\r
11153 this.fireEvent("loadexception", this, o, response);
\r
11154 o.request.callback.call(o.request.scope, null, o.request.arg, false);
\r
11159 result = o.reader.read(response);
\r
11161 this.fireEvent("loadexception", this, o, response, e);
\r
11162 o.request.callback.call(o.request.scope, null, o.request.arg, false);
\r
11165 this.fireEvent("load", this, o, o.request.arg);
\r
11166 o.request.callback.call(o.request.scope, result, o.request.arg, true);
\r
11170 update : function(dataSet){
\r
11175 updateResponse : function(dataSet){
\r
11180 Ext.data.ScriptTagProxy = function(config){
\r
11181 Ext.data.ScriptTagProxy.superclass.constructor.call(this);
\r
11182 Ext.apply(this, config);
\r
11183 this.head = document.getElementsByTagName("head")[0];
\r
11186 Ext.data.ScriptTagProxy.TRANS_ID = 1000;
\r
11188 Ext.extend(Ext.data.ScriptTagProxy, Ext.data.DataProxy, {
\r
11193 callbackParam : "callback",
\r
11198 load : function(params, reader, callback, scope, arg){
\r
11199 if(this.fireEvent("beforeload", this, params) !== false){
\r
11201 var p = Ext.urlEncode(Ext.apply(params, this.extraParams));
\r
11203 var url = this.url;
\r
11204 url += (url.indexOf("?") != -1 ? "&" : "?") + p;
\r
11205 if(this.nocache){
\r
11206 url += "&_dc=" + (new Date().getTime());
\r
11208 var transId = ++Ext.data.ScriptTagProxy.TRANS_ID;
\r
11211 cb : "stcCallback"+transId,
\r
11212 scriptId : "stcScript"+transId,
\r
11216 callback : callback,
\r
11222 window[trans.cb] = function(o){
\r
11223 conn.handleResponse(o, trans);
\r
11226 url += String.format("&{0}={1}", this.callbackParam, trans.cb);
\r
11228 if(this.autoAbort !== false){
\r
11232 trans.timeoutId = this.handleFailure.defer(this.timeout, this, [trans]);
\r
11234 var script = document.createElement("script");
\r
11235 script.setAttribute("src", url);
\r
11236 script.setAttribute("type", "text/javascript");
\r
11237 script.setAttribute("id", trans.scriptId);
\r
11238 this.head.appendChild(script);
\r
11240 this.trans = trans;
\r
11242 callback.call(scope||this, null, arg, false);
\r
11247 isLoading : function(){
\r
11248 return this.trans ? true : false;
\r
11252 abort : function(){
\r
11253 if(this.isLoading()){
\r
11254 this.destroyTrans(this.trans);
\r
11259 destroyTrans : function(trans, isLoaded){
\r
11260 this.head.removeChild(document.getElementById(trans.scriptId));
\r
11261 clearTimeout(trans.timeoutId);
\r
11263 window[trans.cb] = undefined;
\r
11265 delete window[trans.cb];
\r
11269 window[trans.cb] = function(){
\r
11270 window[trans.cb] = undefined;
\r
11272 delete window[trans.cb];
\r
11279 handleResponse : function(o, trans){
\r
11280 this.trans = false;
\r
11281 this.destroyTrans(trans, true);
\r
11284 result = trans.reader.readRecords(o);
\r
11286 this.fireEvent("loadexception", this, o, trans.arg, e);
\r
11287 trans.callback.call(trans.scope||window, null, trans.arg, false);
\r
11290 this.fireEvent("load", this, o, trans.arg);
\r
11291 trans.callback.call(trans.scope||window, result, trans.arg, true);
\r
11295 handleFailure : function(trans){
\r
11296 this.trans = false;
\r
11297 this.destroyTrans(trans, false);
\r
11298 this.fireEvent("loadexception", this, null, trans.arg);
\r
11299 trans.callback.call(trans.scope||window, null, trans.arg, false);
\r
11303 Ext.data.JsonReader = function(meta, recordType){
\r
11304 meta = meta || {};
\r
11305 Ext.data.JsonReader.superclass.constructor.call(this, meta, recordType || meta.fields);
\r
11307 Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
\r
11310 read : function(response){
\r
11311 var json = response.responseText;
\r
11312 var o = eval("("+json+")");
\r
11314 throw {message: "JsonReader.read: Json object not found"};
\r
11318 this.meta = o.metaData;
\r
11319 this.recordType = Ext.data.Record.create(o.metaData.fields);
\r
11320 this.onMetaChange(this.meta, this.recordType, o);
\r
11322 return this.readRecords(o);
\r
11326 onMetaChange : function(meta, recordType, o){
\r
11331 simpleAccess: function(obj, subsc) {
\r
11332 return obj[subsc];
\r
11336 getJsonAccessor: function(){
\r
11337 var re = /[\[\.]/;
\r
11338 return function(expr) {
\r
11340 return(re.test(expr))
\r
11341 ? new Function("obj", "return obj." + expr)
\r
11343 return obj[expr];
\r
11346 return Ext.emptyFn;
\r
11351 readRecords : function(o){
\r
11353 this.jsonData = o;
\r
11354 var s = this.meta, Record = this.recordType,
\r
11355 f = Record.prototype.fields, fi = f.items, fl = f.length;
\r
11359 if(s.totalProperty) {
\r
11360 this.getTotal = this.getJsonAccessor(s.totalProperty);
\r
11362 if(s.successProperty) {
\r
11363 this.getSuccess = this.getJsonAccessor(s.successProperty);
\r
11365 this.getRoot = s.root ? this.getJsonAccessor(s.root) : function(p){return p;};
\r
11367 var g = this.getJsonAccessor(s.id);
\r
11368 this.getId = function(rec) {
\r
11370 return (r === undefined || r === "") ? null : r;
\r
11373 this.getId = function(){return null;};
\r
11376 for(var i = 0; i < fl; i++){
\r
11378 var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
\r
11379 this.ef[i] = this.getJsonAccessor(map);
\r
11383 var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;
\r
11384 if(s.totalProperty){
\r
11385 var v = parseInt(this.getTotal(o), 10);
\r
11387 totalRecords = v;
\r
11390 if(s.successProperty){
\r
11391 var v = this.getSuccess(o);
\r
11392 if(v === false || v === 'false'){
\r
11396 var records = [];
\r
11397 for(var i = 0; i < c; i++){
\r
11400 var id = this.getId(n);
\r
11401 for(var j = 0; j < fl; j++){
\r
11403 var v = this.ef[j](n);
\r
11404 values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, n);
\r
11406 var record = new Record(values, id);
\r
11408 records[i] = record;
\r
11411 success : success,
\r
11412 records : records,
\r
11413 totalRecords : totalRecords
\r
11418 Ext.data.XmlReader = function(meta, recordType){
\r
11419 meta = meta || {};
\r
11420 Ext.data.XmlReader.superclass.constructor.call(this, meta, recordType || meta.fields);
\r
11422 Ext.extend(Ext.data.XmlReader, Ext.data.DataReader, {
\r
11424 read : function(response){
\r
11425 var doc = response.responseXML;
\r
11427 throw {message: "XmlReader.read: XML Document not available"};
\r
11429 return this.readRecords(doc);
\r
11433 readRecords : function(doc){
\r
11435 this.xmlData = doc;
\r
11436 var root = doc.documentElement || doc;
\r
11437 var q = Ext.DomQuery;
\r
11438 var recordType = this.recordType, fields = recordType.prototype.fields;
\r
11439 var sid = this.meta.id;
\r
11440 var totalRecords = 0, success = true;
\r
11441 if(this.meta.totalRecords){
\r
11442 totalRecords = q.selectNumber(this.meta.totalRecords, root, 0);
\r
11445 if(this.meta.success){
\r
11446 var sv = q.selectValue(this.meta.success, root, true);
\r
11447 success = sv !== false && sv !== 'false';
\r
11449 var records = [];
\r
11450 var ns = q.select(this.meta.record, root);
\r
11451 for(var i = 0, len = ns.length; i < len; i++) {
\r
11454 var id = sid ? q.selectValue(sid, n) : undefined;
\r
11455 for(var j = 0, jlen = fields.length; j < jlen; j++){
\r
11456 var f = fields.items[j];
\r
11457 var v = q.selectValue(f.mapping || f.name, n, f.defaultValue);
\r
11458 v = f.convert(v, n);
\r
11459 values[f.name] = v;
\r
11461 var record = new recordType(values, id);
\r
11463 records[records.length] = record;
\r
11467 success : success,
\r
11468 records : records,
\r
11469 totalRecords : totalRecords || records.length
\r
11474 Ext.data.ArrayReader = Ext.extend(Ext.data.JsonReader, {
\r
11476 readRecords : function(o){
\r
11477 var sid = this.meta ? this.meta.id : null;
\r
11478 var recordType = this.recordType, fields = recordType.prototype.fields;
\r
11479 var records = [];
\r
11481 for(var i = 0; i < root.length; i++){
\r
11484 var id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);
\r
11485 for(var j = 0, jlen = fields.length; j < jlen; j++){
\r
11486 var f = fields.items[j];
\r
11487 var k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;
\r
11488 var v = n[k] !== undefined ? n[k] : f.defaultValue;
\r
11489 v = f.convert(v, n);
\r
11490 values[f.name] = v;
\r
11492 var record = new recordType(values, id);
\r
11494 records[records.length] = record;
\r
11497 records : records,
\r
11498 totalRecords : records.length
\r
11503 Ext.data.Tree = function(root){
\r
11504 this.nodeHash = {};
\r
11506 this.root = null;
\r
11508 this.setRootNode(root);
\r
11529 Ext.data.Tree.superclass.constructor.call(this);
\r
11532 Ext.extend(Ext.data.Tree, Ext.util.Observable, {
\r
11534 pathSeparator: "/",
\r
11537 proxyNodeEvent : function(){
\r
11538 return this.fireEvent.apply(this, arguments);
\r
11542 getRootNode : function(){
\r
11543 return this.root;
\r
11547 setRootNode : function(node){
\r
11548 this.root = node;
\r
11549 node.ownerTree = this;
\r
11550 node.isRoot = true;
\r
11551 this.registerNode(node);
\r
11556 getNodeById : function(id){
\r
11557 return this.nodeHash[id];
\r
11561 registerNode : function(node){
\r
11562 this.nodeHash[node.id] = node;
\r
11566 unregisterNode : function(node){
\r
11567 delete this.nodeHash[node.id];
\r
11570 toString : function(){
\r
11571 return "[Tree"+(this.id?" "+this.id:"")+"]";
\r
11576 Ext.data.Node = function(attributes){
\r
11578 this.attributes = attributes || {};
\r
11579 this.leaf = this.attributes.leaf;
\r
11581 this.id = this.attributes.id;
\r
11583 this.id = Ext.id(null, "ynode-");
\r
11584 this.attributes.id = this.id;
\r
11587 this.childNodes = [];
\r
11588 if(!this.childNodes.indexOf){
11589 this.childNodes.indexOf = function(o){
\r
11590 for(var i = 0, len = this.length; i < len; i++){
\r
11591 if(this[i] == o) return i;
\r
11597 this.parentNode = null;
\r
11599 this.firstChild = null;
\r
11601 this.lastChild = null;
\r
11603 this.previousSibling = null;
\r
11605 this.nextSibling = null;
\r
11617 "beforeappend" : true,
\r
11619 "beforeremove" : true,
\r
11621 "beforemove" : true,
\r
11623 "beforeinsert" : true
\r
11625 this.listeners = this.attributes.listeners;
\r
11626 Ext.data.Node.superclass.constructor.call(this);
\r
11629 Ext.extend(Ext.data.Node, Ext.util.Observable, {
\r
11631 fireEvent : function(evtName){
\r
11633 if(Ext.data.Node.superclass.fireEvent.apply(this, arguments) === false){
\r
11637 var ot = this.getOwnerTree();
\r
11639 if(ot.proxyNodeEvent.apply(ot, arguments) === false){
\r
11647 isLeaf : function(){
\r
11648 return this.leaf === true;
\r
11652 setFirstChild : function(node){
\r
11653 this.firstChild = node;
\r
11657 setLastChild : function(node){
\r
11658 this.lastChild = node;
\r
11663 isLast : function(){
\r
11664 return (!this.parentNode ? true : this.parentNode.lastChild == this);
\r
11668 isFirst : function(){
\r
11669 return (!this.parentNode ? true : this.parentNode.firstChild == this);
\r
11672 hasChildNodes : function(){
\r
11673 return !this.isLeaf() && this.childNodes.length > 0;
\r
11677 appendChild : function(node){
\r
11678 var multi = false;
\r
11679 if(Ext.isArray(node)){
\r
11681 }else if(arguments.length > 1){
\r
11682 multi = arguments;
\r
11686 for(var i = 0, len = multi.length; i < len; i++) {
\r
11687 this.appendChild(multi[i]);
\r
11690 if(this.fireEvent("beforeappend", this.ownerTree, this, node) === false){
\r
11693 var index = this.childNodes.length;
\r
11694 var oldParent = node.parentNode;
\r
11697 if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index) === false){
\r
11700 oldParent.removeChild(node);
\r
11702 index = this.childNodes.length;
\r
11704 this.setFirstChild(node);
\r
11706 this.childNodes.push(node);
\r
11707 node.parentNode = this;
\r
11708 var ps = this.childNodes[index-1];
\r
11710 node.previousSibling = ps;
\r
11711 ps.nextSibling = node;
\r
11713 node.previousSibling = null;
\r
11715 node.nextSibling = null;
\r
11716 this.setLastChild(node);
\r
11717 node.setOwnerTree(this.getOwnerTree());
\r
11718 this.fireEvent("append", this.ownerTree, this, node, index);
\r
11720 node.fireEvent("move", this.ownerTree, node, oldParent, this, index);
\r
11727 removeChild : function(node){
\r
11728 var index = this.childNodes.indexOf(node);
\r
11732 if(this.fireEvent("beforeremove", this.ownerTree, this, node) === false){
\r
11737 this.childNodes.splice(index, 1);
\r
11740 if(node.previousSibling){
\r
11741 node.previousSibling.nextSibling = node.nextSibling;
\r
11743 if(node.nextSibling){
\r
11744 node.nextSibling.previousSibling = node.previousSibling;
\r
11748 if(this.firstChild == node){
\r
11749 this.setFirstChild(node.nextSibling);
\r
11751 if(this.lastChild == node){
\r
11752 this.setLastChild(node.previousSibling);
\r
11755 node.setOwnerTree(null);
\r
11757 node.parentNode = null;
\r
11758 node.previousSibling = null;
\r
11759 node.nextSibling = null;
\r
11760 this.fireEvent("remove", this.ownerTree, this, node);
\r
11765 insertBefore : function(node, refNode){
\r
11767 return this.appendChild(node);
\r
11770 if(node == refNode){
\r
11774 if(this.fireEvent("beforeinsert", this.ownerTree, this, node, refNode) === false){
\r
11777 var index = this.childNodes.indexOf(refNode);
\r
11778 var oldParent = node.parentNode;
\r
11779 var refIndex = index;
\r
11782 if(oldParent == this && this.childNodes.indexOf(node) < index){
\r
11788 if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index, refNode) === false){
\r
11791 oldParent.removeChild(node);
\r
11793 if(refIndex == 0){
\r
11794 this.setFirstChild(node);
\r
11796 this.childNodes.splice(refIndex, 0, node);
\r
11797 node.parentNode = this;
\r
11798 var ps = this.childNodes[refIndex-1];
\r
11800 node.previousSibling = ps;
\r
11801 ps.nextSibling = node;
\r
11803 node.previousSibling = null;
\r
11805 node.nextSibling = refNode;
\r
11806 refNode.previousSibling = node;
\r
11807 node.setOwnerTree(this.getOwnerTree());
\r
11808 this.fireEvent("insert", this.ownerTree, this, node, refNode);
\r
11810 node.fireEvent("move", this.ownerTree, node, oldParent, this, refIndex, refNode);
\r
11816 remove : function(){
\r
11817 this.parentNode.removeChild(this);
\r
11822 item : function(index){
\r
11823 return this.childNodes[index];
\r
11827 replaceChild : function(newChild, oldChild){
\r
11828 this.insertBefore(newChild, oldChild);
\r
11829 this.removeChild(oldChild);
\r
11834 indexOf : function(child){
\r
11835 return this.childNodes.indexOf(child);
\r
11839 getOwnerTree : function(){
\r
11841 if(!this.ownerTree){
\r
11845 this.ownerTree = p.ownerTree;
\r
11848 p = p.parentNode;
\r
11851 return this.ownerTree;
\r
11855 getDepth : function(){
\r
11858 while(p.parentNode){
\r
11860 p = p.parentNode;
\r
11866 setOwnerTree : function(tree){
\r
11868 if(tree != this.ownerTree){
\r
11869 if(this.ownerTree){
\r
11870 this.ownerTree.unregisterNode(this);
\r
11872 this.ownerTree = tree;
\r
11873 var cs = this.childNodes;
\r
11874 for(var i = 0, len = cs.length; i < len; i++) {
\r
11875 cs[i].setOwnerTree(tree);
\r
11878 tree.registerNode(this);
\r
11884 getPath : function(attr){
\r
11885 attr = attr || "id";
\r
11886 var p = this.parentNode;
\r
11887 var b = [this.attributes[attr]];
\r
11889 b.unshift(p.attributes[attr]);
\r
11890 p = p.parentNode;
\r
11892 var sep = this.getOwnerTree().pathSeparator;
\r
11893 return sep + b.join(sep);
\r
11897 bubble : function(fn, scope, args){
\r
11900 if(fn.apply(scope || p, args || [p]) === false){
\r
11903 p = p.parentNode;
\r
11908 cascade : function(fn, scope, args){
\r
11909 if(fn.apply(scope || this, args || [this]) !== false){
\r
11910 var cs = this.childNodes;
\r
11911 for(var i = 0, len = cs.length; i < len; i++) {
\r
11912 cs[i].cascade(fn, scope, args);
\r
11918 eachChild : function(fn, scope, args){
\r
11919 var cs = this.childNodes;
\r
11920 for(var i = 0, len = cs.length; i < len; i++) {
\r
11921 if(fn.apply(scope || this, args || [cs[i]]) === false){
\r
11928 findChild : function(attribute, value){
\r
11929 var cs = this.childNodes;
\r
11930 for(var i = 0, len = cs.length; i < len; i++) {
\r
11931 if(cs[i].attributes[attribute] == value){
\r
11939 findChildBy : function(fn, scope){
\r
11940 var cs = this.childNodes;
\r
11941 for(var i = 0, len = cs.length; i < len; i++) {
\r
11942 if(fn.call(scope||cs[i], cs[i]) === true){
\r
11950 sort : function(fn, scope){
\r
11951 var cs = this.childNodes;
\r
11952 var len = cs.length;
\r
11954 var sortFn = scope ? function(){fn.apply(scope, arguments);} : fn;
\r
11956 for(var i = 0; i < len; i++){
\r
11958 n.previousSibling = cs[i-1];
\r
11959 n.nextSibling = cs[i+1];
\r
11961 this.setFirstChild(n);
\r
11964 this.setLastChild(n);
\r
11971 contains : function(node){
\r
11972 return node.isAncestor(this);
\r
11976 isAncestor : function(node){
\r
11977 var p = this.parentNode;
\r
11982 p = p.parentNode;
\r
11987 toString : function(){
\r
11988 return "[Node"+(this.id?" "+this.id:"")+"]";
\r
11992 Ext.data.GroupingStore = Ext.extend(Ext.data.Store, {
\r
11995 remoteGroup : false,
\r
11997 groupOnSort:false,
\r
12000 clearGrouping : function(){
\r
12001 this.groupField = false;
\r
12002 if(this.remoteGroup){
\r
12003 if(this.baseParams){
\r
12004 delete this.baseParams.groupBy;
\r
12008 this.applySort();
\r
12009 this.fireEvent('datachanged', this);
\r
12014 groupBy : function(field, forceRegroup){
\r
12015 if(this.groupField == field && !forceRegroup){
\r
12018 this.groupField = field;
\r
12019 if(this.remoteGroup){
\r
12020 if(!this.baseParams){
\r
12021 this.baseParams = {};
\r
12023 this.baseParams['groupBy'] = field;
\r
12025 if(this.groupOnSort){
\r
12026 this.sort(field);
\r
12029 if(this.remoteGroup){
\r
12032 var si = this.sortInfo || {};
\r
12033 if(si.field != field){
\r
12034 this.applySort();
\r
12036 this.sortData(field);
\r
12038 this.fireEvent('datachanged', this);
\r
12043 applySort : function(){
\r
12044 Ext.data.GroupingStore.superclass.applySort.call(this);
\r
12045 if(!this.groupOnSort && !this.remoteGroup){
\r
12046 var gs = this.getGroupState();
\r
12047 if(gs && gs != this.sortInfo.field){
\r
12048 this.sortData(this.groupField);
\r
12054 applyGrouping : function(alwaysFireChange){
\r
12055 if(this.groupField !== false){
\r
12056 this.groupBy(this.groupField, true);
\r
12059 if(alwaysFireChange === true){
\r
12060 this.fireEvent('datachanged', this);
\r
12067 getGroupState : function(){
\r
12068 return this.groupOnSort && this.groupField !== false ?
\r
12069 (this.sortInfo ? this.sortInfo.field : undefined) : this.groupField;
\r
12073 Ext.ComponentMgr = function(){
\r
12074 var all = new Ext.util.MixedCollection();
\r
12079 register : function(c){
\r
12084 unregister : function(c){
\r
12089 get : function(id){
\r
12090 return all.get(id);
\r
12094 onAvailable : function(id, fn, scope){
\r
12095 all.on("add", function(index, o){
\r
12097 fn.call(scope || o, o);
\r
12098 all.un("add", fn, scope);
\r
12107 registerType : function(xtype, cls){
\r
12108 types[xtype] = cls;
\r
12109 cls.xtype = xtype;
\r
12113 create : function(config, defaultType){
\r
12114 return new types[config.xtype || defaultType](config);
\r
12121 Ext.reg = Ext.ComponentMgr.registerType;
12123 Ext.Component = function(config){
12124 config = config || {};
12125 if(config.initialConfig){
12126 if(config.isAction){ this.baseAction = config;
12128 config = config.initialConfig; }else if(config.tagName || config.dom || typeof config == "string"){ config = {applyTo: config, id: config.id || config};
12132 this.initialConfig = config;
12134 Ext.apply(this, config);
12157 'beforestaterestore',
12166 Ext.ComponentMgr.register(this);
12167 Ext.Component.superclass.constructor.call(this);
12169 if(this.baseAction){
12170 this.baseAction.addComponent(this);
12173 this.initComponent();
12176 if(Ext.isArray(this.plugins)){
12177 for(var i = 0, len = this.plugins.length; i < len; i++){
12178 this.plugins[i].init(this);
12181 this.plugins.init(this);
12185 if(this.stateful !== false){
12186 this.initState(config);
12190 this.applyToMarkup(this.applyTo);
12191 delete this.applyTo;
12192 }else if(this.renderTo){
12193 this.render(this.renderTo);
12194 delete this.renderTo;
12198 Ext.Component.AUTO_ID = 1000;
12200 Ext.extend(Ext.Component, Ext.util.Observable, {
12216 disabledClass : "x-item-disabled",
12218 allowDomMove : true,
12222 hideMode: 'display',
12234 ctype : "Ext.Component",
12238 getActionEl : function(){
12239 return this[this.actionMode];
12243 initComponent : Ext.emptyFn,
12246 render : function(container, position){
12247 if(!this.rendered && this.fireEvent("beforerender", this) !== false){
12248 if(!container && this.el){
12249 this.el = Ext.get(this.el);
12250 container = this.el.dom.parentNode;
12251 this.allowDomMove = false;
12253 this.container = Ext.get(container);
12255 this.container.addClass(this.ctCls);
12257 this.rendered = true;
12258 if(position !== undefined){
12259 if(typeof position == 'number'){
12260 position = this.container.dom.childNodes[position];
12262 position = Ext.getDom(position);
12265 this.onRender(this.container, position || null);
12267 this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]);
12270 this.el.addClass(this.cls);
12274 this.el.applyStyles(this.style);
12277 this.fireEvent("render", this);
12278 this.afterRender(this.container);
12286 this.initStateEvents();
12291 initState : function(config){
12292 if(Ext.state.Manager){
12293 var state = Ext.state.Manager.get(this.stateId || this.id);
12295 if(this.fireEvent('beforestaterestore', this, state) !== false){
12296 this.applyState(state);
12297 this.fireEvent('staterestore', this, state);
12303 initStateEvents : function(){
12304 if(this.stateEvents){
12305 for(var i = 0, e; e = this.stateEvents[i]; i++){
12306 this.on(e, this.saveState, this, {delay:100});
12311 applyState : function(state, config){
12313 Ext.apply(this, state);
12317 getState : function(){
12321 saveState : function(){
12322 if(Ext.state.Manager){
12323 var state = this.getState();
12324 if(this.fireEvent('beforestatesave', this, state) !== false){
12325 Ext.state.Manager.set(this.stateId || this.id, state);
12326 this.fireEvent('statesave', this, state);
12332 applyToMarkup : function(el){
12333 this.allowDomMove = false;
12334 this.el = Ext.get(el);
12335 this.render(this.el.dom.parentNode);
12339 addClass : function(cls){
12341 this.el.addClass(cls);
12343 this.cls = this.cls ? this.cls + ' ' + cls : cls;
12348 removeClass : function(cls){
12350 this.el.removeClass(cls);
12351 }else if(this.cls){
12352 this.cls = this.cls.split(' ').remove(cls).join(' ');
12356 onRender : function(ct, position){
12358 if(typeof this.autoEl == 'string'){
12359 this.el = document.createElement(this.autoEl);
12361 var div = document.createElement('div');
12362 Ext.DomHelper.overwrite(div, this.autoEl);
12363 this.el = div.firstChild;
12366 this.el.id = this.getId();
12370 this.el = Ext.get(this.el);
12371 if(this.allowDomMove !== false){
12372 ct.dom.insertBefore(this.el.dom, position);
12377 getAutoCreate : function(){
12378 var cfg = typeof this.autoCreate == "object" ?
12379 this.autoCreate : Ext.apply({}, this.defaultAutoCreate);
12380 if(this.id && !cfg.id){
12386 afterRender : Ext.emptyFn,
12389 destroy : function(){
12390 if(this.fireEvent("beforedestroy", this) !== false){
12391 this.beforeDestroy();
12393 this.el.removeAllListeners();
12395 if(this.actionMode == "container"){
12396 this.container.remove();
12400 Ext.ComponentMgr.unregister(this);
12401 this.fireEvent("destroy", this);
12402 this.purgeListeners();
12406 beforeDestroy : Ext.emptyFn,
12408 onDestroy : Ext.emptyFn,
12411 getEl : function(){
12416 getId : function(){
12417 return this.id || (this.id = "ext-comp-" + (++Ext.Component.AUTO_ID));
12421 getItemId : function(){
12422 return this.itemId || this.getId();
12426 focus : function(selectText, delay){
12428 this.focus.defer(typeof delay == 'number' ? delay : 10, this, [selectText, false]);
12433 if(selectText === true){
12434 this.el.dom.select();
12448 disable : function(){
12452 this.disabled = true;
12453 this.fireEvent("disable", this);
12457 onDisable : function(){
12458 this.getActionEl().addClass(this.disabledClass);
12459 this.el.dom.disabled = true;
12463 enable : function(){
12467 this.disabled = false;
12468 this.fireEvent("enable", this);
12472 onEnable : function(){
12473 this.getActionEl().removeClass(this.disabledClass);
12474 this.el.dom.disabled = false;
12478 setDisabled : function(disabled){
12479 this[disabled ? "disable" : "enable"]();
12484 if(this.fireEvent("beforeshow", this) !== false){
12485 this.hidden = false;
12486 if(this.autoRender){
12487 this.render(typeof this.autoRender == 'boolean' ? Ext.getBody() : this.autoRender);
12492 this.fireEvent("show", this);
12497 onShow : function(){
12498 if(this.hideParent){
12499 this.container.removeClass('x-hide-' + this.hideMode);
12501 this.getActionEl().removeClass('x-hide-' + this.hideMode);
12508 if(this.fireEvent("beforehide", this) !== false){
12509 this.hidden = true;
12513 this.fireEvent("hide", this);
12518 onHide : function(){
12519 if(this.hideParent){
12520 this.container.addClass('x-hide-' + this.hideMode);
12522 this.getActionEl().addClass('x-hide-' + this.hideMode);
12527 setVisible: function(visible){
12537 isVisible : function(){
12538 return this.rendered && this.getActionEl().isVisible();
12542 cloneConfig : function(overrides){
12543 overrides = overrides || {};
12544 var id = overrides.id || Ext.id();
12545 var cfg = Ext.applyIf(overrides, this.initialConfig);
12546 cfg.id = id; return new this.constructor(cfg);
12550 getXType : function(){
12551 return this.constructor.xtype;
12555 isXType : function(xtype, shallow){
12557 ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 :
12558 this.constructor.xtype == xtype;
12562 getXTypes : function(){
12563 var tc = this.constructor;
12565 var c = [], sc = this;
12566 while(sc && sc.constructor.xtype){
12567 c.unshift(sc.constructor.xtype);
12568 sc = sc.constructor.superclass;
12571 tc.xtypes = c.join('/');
12577 findParentBy: function(fn) {
12578 for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt);
12583 findParentByType: function(xtype) {
12584 return typeof xtype == 'function' ?
12585 this.findParentBy(function(p){
12586 return p.constructor === xtype;
12588 this.findParentBy(function(p){
12589 return p.constructor.xtype === xtype;
12594 Ext.reg('component', Ext.Component);
12597 Ext.Action = function(config){
\r
12598 this.initialConfig = config;
\r
12602 Ext.Action.prototype = {
\r
12614 setText : function(text){
\r
12615 this.initialConfig.text = text;
\r
12616 this.callEach('setText', [text]);
\r
12620 getText : function(){
\r
12621 return this.initialConfig.text;
\r
12625 setIconClass : function(cls){
\r
12626 this.initialConfig.iconCls = cls;
\r
12627 this.callEach('setIconClass', [cls]);
\r
12631 getIconClass : function(){
\r
12632 return this.initialConfig.iconCls;
\r
12636 setDisabled : function(v){
\r
12637 this.initialConfig.disabled = v;
\r
12638 this.callEach('setDisabled', [v]);
\r
12642 enable : function(){
\r
12643 this.setDisabled(false);
\r
12647 disable : function(){
\r
12648 this.setDisabled(true);
\r
12652 isDisabled : function(){
\r
12653 return this.initialConfig.disabled;
\r
12657 setHidden : function(v){
\r
12658 this.initialConfig.hidden = v;
\r
12659 this.callEach('setVisible', [!v]);
\r
12663 show : function(){
\r
12664 this.setHidden(false);
\r
12668 hide : function(){
\r
12669 this.setHidden(true);
\r
12673 isHidden : function(){
\r
12674 return this.initialConfig.hidden;
\r
12678 setHandler : function(fn, scope){
\r
12679 this.initialConfig.handler = fn;
\r
12680 this.initialConfig.scope = scope;
\r
12681 this.callEach('setHandler', [fn, scope]);
\r
12685 each : function(fn, scope){
\r
12686 Ext.each(this.items, fn, scope);
\r
12690 callEach : function(fnName, args){
\r
12691 var cs = this.items;
\r
12692 for(var i = 0, len = cs.length; i < len; i++){
\r
12693 cs[i][fnName].apply(cs[i], args);
\r
12698 addComponent : function(comp){
\r
12699 this.items.push(comp);
\r
12700 comp.on('destroy', this.removeComponent, this);
\r
12704 removeComponent : function(comp){
\r
12705 this.items.remove(comp);
\r
12708 execute : function(){
\r
12709 this.initialConfig.handler.apply(this.initialConfig.scope || window, arguments);
\r
12714 Ext.Layer = function(config, existingEl){
\r
12715 config = config || {};
\r
12716 var dh = Ext.DomHelper;
\r
12717 var cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body;
\r
12719 this.dom = Ext.getDom(existingEl);
\r
12722 var o = config.dh || {tag: "div", cls: "x-layer"};
\r
12723 this.dom = dh.append(pel, o);
\r
12726 this.addClass(config.cls);
\r
12728 this.constrain = config.constrain !== false;
\r
12729 this.visibilityMode = Ext.Element.VISIBILITY;
\r
12731 this.id = this.dom.id = config.id;
\r
12733 this.id = Ext.id(this.dom);
\r
12735 this.zindex = config.zindex || this.getZIndex();
\r
12736 this.position("absolute", this.zindex);
\r
12737 if(config.shadow){
\r
12738 this.shadowOffset = config.shadowOffset || 4;
\r
12739 this.shadow = new Ext.Shadow({
\r
12740 offset : this.shadowOffset,
\r
12741 mode : config.shadow
\r
12744 this.shadowOffset = 0;
\r
12746 this.useShim = config.shim !== false && Ext.useShims;
\r
12747 this.useDisplay = config.useDisplay;
\r
12751 var supr = Ext.Element.prototype;
\r
12756 Ext.extend(Ext.Layer, Ext.Element, {
\r
12758 getZIndex : function(){
\r
12759 return this.zindex || parseInt(this.getStyle("z-index"), 10) || 11000;
\r
12762 getShim : function(){
\r
12763 if(!this.useShim){
\r
12767 return this.shim;
\r
12769 var shim = shims.shift();
\r
12771 shim = this.createShim();
\r
12772 shim.enableDisplayMode('block');
\r
12773 shim.dom.style.display = 'none';
\r
12774 shim.dom.style.visibility = 'visible';
\r
12776 var pn = this.dom.parentNode;
\r
12777 if(shim.dom.parentNode != pn){
\r
12778 pn.insertBefore(shim.dom, this.dom);
\r
12780 shim.setStyle('z-index', this.getZIndex()-2);
\r
12781 this.shim = shim;
\r
12785 hideShim : function(){
\r
12787 this.shim.setDisplayed(false);
\r
12788 shims.push(this.shim);
\r
12789 delete this.shim;
\r
12793 disableShadow : function(){
\r
12795 this.shadowDisabled = true;
\r
12796 this.shadow.hide();
\r
12797 this.lastShadowOffset = this.shadowOffset;
\r
12798 this.shadowOffset = 0;
\r
12802 enableShadow : function(show){
\r
12804 this.shadowDisabled = false;
\r
12805 this.shadowOffset = this.lastShadowOffset;
\r
12806 delete this.lastShadowOffset;
\r
12816 sync : function(doShow){
\r
12817 var sw = this.shadow;
\r
12818 if(!this.updating && this.isVisible() && (sw || this.useShim)){
\r
12819 var sh = this.getShim();
\r
12821 var w = this.getWidth(),
\r
12822 h = this.getHeight();
\r
12824 var l = this.getLeft(true),
\r
12825 t = this.getTop(true);
\r
12827 if(sw && !this.shadowDisabled){
\r
12828 if(doShow && !sw.isVisible()){
\r
12831 sw.realign(l, t, w, h);
\r
12838 var a = sw.adjusts, s = sh.dom.style;
\r
12839 s.left = (Math.min(l, l+a.l))+"px";
\r
12840 s.top = (Math.min(t, t+a.t))+"px";
\r
12841 s.width = (w+a.w)+"px";
\r
12842 s.height = (h+a.h)+"px";
\r
12848 sh.setSize(w, h);
\r
12849 sh.setLeftTop(l, t);
\r
12856 destroy : function(){
\r
12859 this.shadow.hide();
\r
12861 this.removeAllListeners();
\r
12862 Ext.removeNode(this.dom);
\r
12863 Ext.Element.uncache(this.id);
\r
12866 remove : function(){
\r
12871 beginUpdate : function(){
\r
12872 this.updating = true;
\r
12876 endUpdate : function(){
\r
12877 this.updating = false;
\r
12882 hideUnders : function(negOffset){
\r
12884 this.shadow.hide();
\r
12890 constrainXY : function(){
\r
12891 if(this.constrain){
\r
12892 var vw = Ext.lib.Dom.getViewWidth(),
\r
12893 vh = Ext.lib.Dom.getViewHeight();
\r
12894 var s = Ext.getDoc().getScroll();
\r
12896 var xy = this.getXY();
\r
12897 var x = xy[0], y = xy[1];
\r
12898 var w = this.dom.offsetWidth+this.shadowOffset, h = this.dom.offsetHeight+this.shadowOffset;
\r
12900 var moved = false;
\r
12902 if((x + w) > vw+s.left){
\r
12903 x = vw - w - this.shadowOffset;
\r
12906 if((y + h) > vh+s.top){
\r
12907 y = vh - h - this.shadowOffset;
\r
12921 var ay = this.avoidY;
\r
12922 if(y <= ay && (y+h) >= ay){
\r
12927 this.storeXY(xy);
\r
12928 supr.setXY.call(this, xy);
\r
12934 isVisible : function(){
\r
12935 return this.visible;
\r
12939 showAction : function(){
\r
12940 this.visible = true;
12941 if(this.useDisplay === true){
\r
12942 this.setDisplayed("");
\r
12943 }else if(this.lastXY){
\r
12944 supr.setXY.call(this, this.lastXY);
\r
12945 }else if(this.lastLT){
\r
12946 supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]);
\r
12951 hideAction : function(){
\r
12952 this.visible = false;
\r
12953 if(this.useDisplay === true){
\r
12954 this.setDisplayed(false);
\r
12956 this.setLeftTop(-10000,-10000);
\r
12961 setVisible : function(v, a, d, c, e){
\r
12963 this.showAction();
\r
12966 var cb = function(){
\r
12971 }.createDelegate(this);
\r
12972 supr.setVisible.call(this, true, true, d, cb, e);
\r
12975 this.hideUnders(true);
\r
12980 this.hideAction();
\r
12984 }.createDelegate(this);
\r
12986 supr.setVisible.call(this, v, a, d, cb, e);
\r
12990 this.hideAction();
\r
12995 storeXY : function(xy){
\r
12996 delete this.lastLT;
\r
12997 this.lastXY = xy;
\r
13000 storeLeftTop : function(left, top){
\r
13001 delete this.lastXY;
\r
13002 this.lastLT = [left, top];
\r
13006 beforeFx : function(){
\r
13007 this.beforeAction();
\r
13008 return Ext.Layer.superclass.beforeFx.apply(this, arguments);
\r
13012 afterFx : function(){
\r
13013 Ext.Layer.superclass.afterFx.apply(this, arguments);
\r
13014 this.sync(this.isVisible());
\r
13018 beforeAction : function(){
\r
13019 if(!this.updating && this.shadow){
\r
13020 this.shadow.hide();
\r
13025 setLeft : function(left){
\r
13026 this.storeLeftTop(left, this.getTop(true));
\r
13027 supr.setLeft.apply(this, arguments);
\r
13031 setTop : function(top){
\r
13032 this.storeLeftTop(this.getLeft(true), top);
\r
13033 supr.setTop.apply(this, arguments);
\r
13037 setLeftTop : function(left, top){
\r
13038 this.storeLeftTop(left, top);
\r
13039 supr.setLeftTop.apply(this, arguments);
\r
13043 setXY : function(xy, a, d, c, e){
\r
13044 this.fixDisplay();
\r
13045 this.beforeAction();
\r
13046 this.storeXY(xy);
\r
13047 var cb = this.createCB(c);
\r
13048 supr.setXY.call(this, xy, a, d, cb, e);
\r
13055 createCB : function(c){
\r
13057 return function(){
\r
13058 el.constrainXY();
\r
13067 setX : function(x, a, d, c, e){
\r
13068 this.setXY([x, this.getY()], a, d, c, e);
\r
13072 setY : function(y, a, d, c, e){
\r
13073 this.setXY([this.getX(), y], a, d, c, e);
\r
13077 setSize : function(w, h, a, d, c, e){
\r
13078 this.beforeAction();
\r
13079 var cb = this.createCB(c);
\r
13080 supr.setSize.call(this, w, h, a, d, cb, e);
\r
13087 setWidth : function(w, a, d, c, e){
\r
13088 this.beforeAction();
\r
13089 var cb = this.createCB(c);
\r
13090 supr.setWidth.call(this, w, a, d, cb, e);
\r
13097 setHeight : function(h, a, d, c, e){
\r
13098 this.beforeAction();
\r
13099 var cb = this.createCB(c);
\r
13100 supr.setHeight.call(this, h, a, d, cb, e);
\r
13107 setBounds : function(x, y, w, h, a, d, c, e){
\r
13108 this.beforeAction();
\r
13109 var cb = this.createCB(c);
\r
13111 this.storeXY([x, y]);
\r
13112 supr.setXY.call(this, [x, y]);
\r
13113 supr.setSize.call(this, w, h, a, d, cb, e);
\r
13116 supr.setBounds.call(this, x, y, w, h, a, d, cb, e);
\r
13122 setZIndex : function(zindex){
\r
13123 this.zindex = zindex;
\r
13124 this.setStyle("z-index", zindex + 2);
\r
13126 this.shadow.setZIndex(zindex + 1);
\r
13129 this.shim.setStyle("z-index", zindex);
\r
13135 Ext.Shadow = function(config){
13136 Ext.apply(this, config);
13137 if(typeof this.mode != "string"){
13138 this.mode = this.defaultMode;
13140 var o = this.offset, a = {h: 0};
13141 var rad = Math.floor(this.offset/2);
13142 switch(this.mode.toLowerCase()){ case "drop":
13147 a.l -= this.offset + rad;
13148 a.t -= this.offset + rad;
13159 a.l -= (this.offset - rad);
13160 a.t -= this.offset + rad;
13162 a.w -= (this.offset - rad)*2;
13173 a.l -= (this.offset - rad);
13174 a.t -= (this.offset - rad);
13176 a.w -= (this.offset + rad + 1);
13177 a.h -= (this.offset + rad);
13186 Ext.Shadow.prototype = {
13191 defaultMode: "drop",
13194 show : function(target){
13195 target = Ext.get(target);
13197 this.el = Ext.Shadow.Pool.pull();
13198 if(this.el.dom.nextSibling != target.dom){
13199 this.el.insertBefore(target);
13202 this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10)-1);
13204 this.el.dom.style.filter="progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius="+(this.offset)+")";
13207 target.getLeft(true),
13208 target.getTop(true),
13212 this.el.dom.style.display = "block";
13216 isVisible : function(){
13217 return this.el ? true : false;
13221 realign : function(l, t, w, h){
13225 var a = this.adjusts, d = this.el.dom, s = d.style;
13227 s.left = (l+a.l)+"px";
13228 s.top = (t+a.t)+"px";
13229 var sw = (w+a.w), sh = (h+a.h), sws = sw +"px", shs = sh + "px";
13230 if(s.width != sws || s.height != shs){
13234 var cn = d.childNodes;
13235 var sww = Math.max(0, (sw-12))+"px";
13236 cn[0].childNodes[1].style.width = sww;
13237 cn[1].childNodes[1].style.width = sww;
13238 cn[2].childNodes[1].style.width = sww;
13239 cn[1].style.height = Math.max(0, (sh-12))+"px";
13247 this.el.dom.style.display = "none";
13248 Ext.Shadow.Pool.push(this.el);
13254 setZIndex : function(z){
13257 this.el.setStyle("z-index", z);
13262 Ext.Shadow.Pool = function(){
13264 var markup = Ext.isIE ?
13265 '<div class="x-ie-shadow"></div>' :
13266 '<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>';
13269 var sh = p.shift();
13271 sh = Ext.get(Ext.DomHelper.insertHtml("beforeBegin", document.body.firstChild, markup));
13272 sh.autoBoxAdjust = false;
13277 push : function(sh){
13283 Ext.BoxComponent = Ext.extend(Ext.Component, {
13294 initComponent : function(){
13295 Ext.BoxComponent.superclass.initComponent.call(this);
13305 deferHeight: false,
13308 setSize : function(w, h){
13309 if(typeof w == 'object'){
13313 if(!this.boxReady){
13319 if(this.lastSize && this.lastSize.width == w && this.lastSize.height == h){
13322 this.lastSize = {width: w, height: h};
13323 var adj = this.adjustSize(w, h);
13324 var aw = adj.width, ah = adj.height;
13325 if(aw !== undefined || ah !== undefined){ var rz = this.getResizeEl();
13326 if(!this.deferHeight && aw !== undefined && ah !== undefined){
13327 rz.setSize(aw, ah);
13328 }else if(!this.deferHeight && ah !== undefined){
13330 }else if(aw !== undefined){
13333 this.onResize(aw, ah, w, h);
13334 this.fireEvent('resize', this, aw, ah, w, h);
13340 setWidth : function(width){
13341 return this.setSize(width);
13345 setHeight : function(height){
13346 return this.setSize(undefined, height);
13350 getSize : function(){
13351 return this.el.getSize();
13355 getPosition : function(local){
13356 if(local === true){
13357 return [this.el.getLeft(true), this.el.getTop(true)];
13359 return this.xy || this.el.getXY();
13363 getBox : function(local){
13364 var s = this.el.getSize();
13365 if(local === true){
13366 s.x = this.el.getLeft(true);
13367 s.y = this.el.getTop(true);
13369 var xy = this.xy || this.el.getXY();
13377 updateBox : function(box){
13378 this.setSize(box.width, box.height);
13379 this.setPagePosition(box.x, box.y);
13383 getResizeEl : function(){
13384 return this.resizeEl || this.el;
13387 getPositionEl : function(){
13388 return this.positionEl || this.el;
13392 setPosition : function(x, y){
13393 if(x && typeof x[1] == 'number'){
13399 if(!this.boxReady){
13402 var adj = this.adjustPosition(x, y);
13403 var ax = adj.x, ay = adj.y;
13405 var el = this.getPositionEl();
13406 if(ax !== undefined || ay !== undefined){
13407 if(ax !== undefined && ay !== undefined){
13408 el.setLeftTop(ax, ay);
13409 }else if(ax !== undefined){
13411 }else if(ay !== undefined){
13414 this.onPosition(ax, ay);
13415 this.fireEvent('move', this, ax, ay);
13421 setPagePosition : function(x, y){
13422 if(x && typeof x[1] == 'number'){
13428 if(!this.boxReady){
13431 if(x === undefined || y === undefined){ return;
13433 var p = this.el.translatePoints(x, y);
13434 this.setPosition(p.left, p.top);
13438 onRender : function(ct, position){
13439 Ext.BoxComponent.superclass.onRender.call(this, ct, position);
13441 this.resizeEl = Ext.get(this.resizeEl);
13443 if(this.positionEl){
13444 this.positionEl = Ext.get(this.positionEl);
13448 afterRender : function(){
13449 Ext.BoxComponent.superclass.afterRender.call(this);
13450 this.boxReady = true;
13451 this.setSize(this.width, this.height);
13452 if(this.x || this.y){
13453 this.setPosition(this.x, this.y);
13454 }else if(this.pageX || this.pageY){
13455 this.setPagePosition(this.pageX, this.pageY);
13460 syncSize : function(){
13461 delete this.lastSize;
13462 this.setSize(this.autoWidth ? undefined : this.el.getWidth(), this.autoHeight ? undefined : this.el.getHeight());
13467 onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
13472 onPosition : function(x, y){
13476 adjustSize : function(w, h){
13477 if(this.autoWidth){
13480 if(this.autoHeight){
13483 return {width : w, height: h};
13486 adjustPosition : function(x, y){
13487 return {x : x, y: y};
13490 Ext.reg('box', Ext.BoxComponent);
13492 Ext.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){
\r
13495 this.el = Ext.get(dragElement, true);
\r
13496 this.el.dom.unselectable = "on";
\r
13498 this.resizingEl = Ext.get(resizingElement, true);
\r
13501 this.orientation = orientation || Ext.SplitBar.HORIZONTAL;
\r
13504 this.minSize = 0;
\r
13507 this.maxSize = 2000;
\r
13510 this.animate = false;
\r
13513 this.useShim = false;
\r
13516 this.shim = null;
\r
13518 if(!existingProxy){
\r
13520 this.proxy = Ext.SplitBar.createProxy(this.orientation);
\r
13522 this.proxy = Ext.get(existingProxy).dom;
\r
13525 this.dd = new Ext.dd.DDProxy(this.el.dom.id, "XSplitBars", {dragElId : this.proxy.id});
\r
13528 this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this);
\r
13531 this.dd.endDrag = this.onEndProxyDrag.createDelegate(this);
\r
13534 this.dragSpecs = {};
\r
13537 this.adapter = new Ext.SplitBar.BasicLayoutAdapter();
\r
13538 this.adapter.init(this);
\r
13540 if(this.orientation == Ext.SplitBar.HORIZONTAL){
\r
13542 this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? Ext.SplitBar.LEFT : Ext.SplitBar.RIGHT);
\r
13543 this.el.addClass("x-splitbar-h");
\r
13546 this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? Ext.SplitBar.TOP : Ext.SplitBar.BOTTOM);
\r
13547 this.el.addClass("x-splitbar-v");
\r
13561 Ext.SplitBar.superclass.constructor.call(this);
\r
13564 Ext.extend(Ext.SplitBar, Ext.util.Observable, {
\r
13565 onStartProxyDrag : function(x, y){
\r
13566 this.fireEvent("beforeresize", this);
\r
13567 this.overlay = Ext.DomHelper.append(document.body, {cls: "x-drag-overlay", html: " "}, true);
\r
13568 this.overlay.unselectable();
\r
13569 this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
\r
13570 this.overlay.show();
\r
13571 Ext.get(this.proxy).setDisplayed("block");
\r
13572 var size = this.adapter.getElementSize(this);
\r
13573 this.activeMinSize = this.getMinimumSize();;
\r
13574 this.activeMaxSize = this.getMaximumSize();;
\r
13575 var c1 = size - this.activeMinSize;
\r
13576 var c2 = Math.max(this.activeMaxSize - size, 0);
\r
13577 if(this.orientation == Ext.SplitBar.HORIZONTAL){
\r
13578 this.dd.resetConstraints();
\r
13579 this.dd.setXConstraint(
\r
13580 this.placement == Ext.SplitBar.LEFT ? c1 : c2,
\r
13581 this.placement == Ext.SplitBar.LEFT ? c2 : c1
\r
13583 this.dd.setYConstraint(0, 0);
\r
13585 this.dd.resetConstraints();
\r
13586 this.dd.setXConstraint(0, 0);
\r
13587 this.dd.setYConstraint(
\r
13588 this.placement == Ext.SplitBar.TOP ? c1 : c2,
\r
13589 this.placement == Ext.SplitBar.TOP ? c2 : c1
\r
13592 this.dragSpecs.startSize = size;
\r
13593 this.dragSpecs.startPoint = [x, y];
\r
13594 Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd, x, y);
\r
13598 onEndProxyDrag : function(e){
\r
13599 Ext.get(this.proxy).setDisplayed(false);
\r
13600 var endPoint = Ext.lib.Event.getXY(e);
\r
13601 if(this.overlay){
\r
13602 this.overlay.remove();
\r
13603 delete this.overlay;
\r
13606 if(this.orientation == Ext.SplitBar.HORIZONTAL){
\r
13607 newSize = this.dragSpecs.startSize +
\r
13608 (this.placement == Ext.SplitBar.LEFT ?
\r
13609 endPoint[0] - this.dragSpecs.startPoint[0] :
\r
13610 this.dragSpecs.startPoint[0] - endPoint[0]
\r
13613 newSize = this.dragSpecs.startSize +
\r
13614 (this.placement == Ext.SplitBar.TOP ?
\r
13615 endPoint[1] - this.dragSpecs.startPoint[1] :
\r
13616 this.dragSpecs.startPoint[1] - endPoint[1]
\r
13619 newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize);
\r
13620 if(newSize != this.dragSpecs.startSize){
\r
13621 if(this.fireEvent('beforeapply', this, newSize) !== false){
\r
13622 this.adapter.setElementSize(this, newSize);
\r
13623 this.fireEvent("moved", this, newSize);
\r
13624 this.fireEvent("resize", this, newSize);
\r
13630 getAdapter : function(){
\r
13631 return this.adapter;
\r
13635 setAdapter : function(adapter){
\r
13636 this.adapter = adapter;
\r
13637 this.adapter.init(this);
\r
13641 getMinimumSize : function(){
\r
13642 return this.minSize;
\r
13646 setMinimumSize : function(minSize){
\r
13647 this.minSize = minSize;
\r
13651 getMaximumSize : function(){
\r
13652 return this.maxSize;
\r
13656 setMaximumSize : function(maxSize){
\r
13657 this.maxSize = maxSize;
\r
13661 setCurrentSize : function(size){
\r
13662 var oldAnimate = this.animate;
\r
13663 this.animate = false;
\r
13664 this.adapter.setElementSize(this, size);
\r
13665 this.animate = oldAnimate;
\r
13669 destroy : function(removeEl){
\r
13671 this.shim.remove();
\r
13674 Ext.removeNode(this.proxy);
\r
13676 this.el.remove();
\r
13682 Ext.SplitBar.createProxy = function(dir){
\r
13683 var proxy = new Ext.Element(document.createElement("div"));
\r
13684 proxy.unselectable();
\r
13685 var cls = 'x-splitbar-proxy';
\r
13686 proxy.addClass(cls + ' ' + (dir == Ext.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v'));
\r
13687 document.body.appendChild(proxy.dom);
\r
13688 return proxy.dom;
\r
13692 Ext.SplitBar.BasicLayoutAdapter = function(){
\r
13695 Ext.SplitBar.BasicLayoutAdapter.prototype = {
\r
13697 init : function(s){
\r
13701 getElementSize : function(s){
\r
13702 if(s.orientation == Ext.SplitBar.HORIZONTAL){
\r
13703 return s.resizingEl.getWidth();
\r
13705 return s.resizingEl.getHeight();
\r
13710 setElementSize : function(s, newSize, onComplete){
\r
13711 if(s.orientation == Ext.SplitBar.HORIZONTAL){
\r
13713 s.resizingEl.setWidth(newSize);
\r
13715 onComplete(s, newSize);
\r
13718 s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut');
\r
13723 s.resizingEl.setHeight(newSize);
\r
13725 onComplete(s, newSize);
\r
13728 s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut');
\r
13735 Ext.SplitBar.AbsoluteLayoutAdapter = function(container){
\r
13736 this.basic = new Ext.SplitBar.BasicLayoutAdapter();
\r
13737 this.container = Ext.get(container);
\r
13740 Ext.SplitBar.AbsoluteLayoutAdapter.prototype = {
\r
13741 init : function(s){
\r
13742 this.basic.init(s);
\r
13745 getElementSize : function(s){
\r
13746 return this.basic.getElementSize(s);
\r
13749 setElementSize : function(s, newSize, onComplete){
\r
13750 this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s]));
\r
13753 moveSplitter : function(s){
\r
13754 var yes = Ext.SplitBar;
\r
13755 switch(s.placement){
\r
13757 s.el.setX(s.resizingEl.getRight());
\r
13760 s.el.setStyle("right", (this.container.getWidth() - s.resizingEl.getLeft()) + "px");
\r
13763 s.el.setY(s.resizingEl.getBottom());
\r
13766 s.el.setY(s.resizingEl.getTop() - s.el.getHeight());
\r
13773 Ext.SplitBar.VERTICAL = 1;
\r
13776 Ext.SplitBar.HORIZONTAL = 2;
\r
13779 Ext.SplitBar.LEFT = 1;
\r
13782 Ext.SplitBar.RIGHT = 2;
\r
13785 Ext.SplitBar.TOP = 3;
\r
13788 Ext.SplitBar.BOTTOM = 4;
\r
13791 Ext.Container = Ext.extend(Ext.BoxComponent, {
13804 defaultType: 'panel',
13806 initComponent : function(){
13807 Ext.Container.superclass.initComponent.call(this);
13823 var items = this.items;
13826 if(Ext.isArray(items)){
13827 this.add.apply(this, items);
13834 initItems : function(){
13836 this.items = new Ext.util.MixedCollection(false, this.getComponentId);
13837 this.getLayout(); }
13840 setLayout : function(layout){
13841 if(this.layout && this.layout != layout){
13842 this.layout.setContainer(null);
13845 this.layout = layout;
13846 layout.setContainer(this);
13849 render : function(){
13850 Ext.Container.superclass.render.apply(this, arguments);
13852 if(typeof this.layout == 'string'){
13853 this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);
13855 this.setLayout(this.layout);
13857 if(this.activeItem !== undefined){
13858 var item = this.activeItem;
13859 delete this.activeItem;
13860 this.layout.setActiveItem(item);
13867 if(this.monitorResize === true){
13868 Ext.EventManager.onWindowResize(this.doLayout, this, [false]);
13872 getLayoutTarget : function(){
13876 getComponentId : function(comp){
13877 return comp.itemId || comp.id;
13881 add : function(comp){
13885 var a = arguments, len = a.length;
13887 for(var i = 0; i < len; i++) {
13892 var c = this.lookupComponent(this.applyDefaults(comp));
13893 var pos = this.items.length;
13894 if(this.fireEvent('beforeadd', this, c, pos) !== false && this.onBeforeAdd(c) !== false){
13897 this.fireEvent('add', this, c, pos);
13903 insert : function(index, comp){
13907 var a = arguments, len = a.length;
13909 for(var i = len-1; i >= 1; --i) {
13910 this.insert(index, a[i]);
13914 var c = this.lookupComponent(this.applyDefaults(comp));
13916 if(c.ownerCt == this && this.items.indexOf(c) < index){
13920 if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){
13921 this.items.insert(index, c);
13923 this.fireEvent('add', this, c, index);
13928 applyDefaults : function(c){
13930 if(typeof c == 'string'){
13931 c = Ext.ComponentMgr.get(c);
13932 Ext.apply(c, this.defaults);
13933 }else if(!c.events){
13934 Ext.applyIf(c, this.defaults);
13936 Ext.apply(c, this.defaults);
13942 onBeforeAdd : function(item){
13944 item.ownerCt.remove(item, false);
13946 if(this.hideBorders === true){
13947 item.border = (item.border === true);
13952 remove : function(comp, autoDestroy){
13953 var c = this.getComponent(comp);
13954 if(c && this.fireEvent('beforeremove', this, c) !== false){
13955 this.items.remove(c);
13957 if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){
13960 if(this.layout && this.layout.activeItem == c){
13961 delete this.layout.activeItem;
13963 this.fireEvent('remove', this, c);
13969 getComponent : function(comp){
13970 if(typeof comp == 'object'){
13973 return this.items.get(comp);
13976 lookupComponent : function(comp){
13977 if(typeof comp == 'string'){
13978 return Ext.ComponentMgr.get(comp);
13979 }else if(!comp.events){
13980 return this.createComponent(comp);
13985 createComponent : function(config){
13986 return Ext.ComponentMgr.create(config, this.defaultType);
13990 doLayout : function(shallow){
13991 if(this.rendered && this.layout){
13992 this.layout.layout();
13994 if(shallow !== false && this.items){
13995 var cs = this.items.items;
13996 for(var i = 0, len = cs.length; i < len; i++) {
14006 getLayout : function(){
14008 var layout = new Ext.layout.ContainerLayout(this.layoutConfig);
14009 this.setLayout(layout);
14011 return this.layout;
14014 onDestroy : function(){
14016 var cs = this.items.items;
14017 for(var i = 0, len = cs.length; i < len; i++) {
14018 Ext.destroy(cs[i]);
14021 if(this.monitorResize){
14022 Ext.EventManager.removeResizeListener(this.doLayout, this);
14024 Ext.Container.superclass.onDestroy.call(this);
14028 bubble : function(fn, scope, args){
14031 if(fn.apply(scope || p, args || [p]) === false){
14039 cascade : function(fn, scope, args){
14040 if(fn.apply(scope || this, args || [this]) !== false){
14042 var cs = this.items.items;
14043 for(var i = 0, len = cs.length; i < len; i++){
14045 cs[i].cascade(fn, scope, args);
14047 fn.apply(scope || this, args || [cs[i]]);
14055 findById : function(id){
14057 this.cascade(function(c){
14058 if(ct != c && c.id === id){
14067 findByType : function(xtype){
14068 return typeof xtype == 'function' ?
14069 this.findBy(function(c){
14070 return c.constructor === xtype;
14072 this.findBy(function(c){
14073 return c.constructor.xtype === xtype;
14078 find : function(prop, value){
14079 return this.findBy(function(c){
14080 return c[prop] === value;
14085 findBy : function(fn, scope){
14086 var m = [], ct = this;
14087 this.cascade(function(c){
14088 if(ct != c && fn.call(scope || c, c, ct) === true){
14096 Ext.Container.LAYOUTS = {};
14097 Ext.reg('container', Ext.Container);
14099 Ext.layout.ContainerLayout = function(config){
14100 Ext.apply(this, config);
14103 Ext.layout.ContainerLayout.prototype = {
14109 monitorResize:false,
14112 layout : function(){
14113 var target = this.container.getLayoutTarget();
14114 this.onLayout(this.container, target);
14115 this.container.fireEvent('afterlayout', this.container, this);
14118 onLayout : function(ct, target){
14119 this.renderAll(ct, target);
14122 isValidParent : function(c, target){
14123 var el = c.getPositionEl ? c.getPositionEl() : c.getEl();
14124 return el.dom.parentNode == target.dom;
14127 renderAll : function(ct, target){
14128 var items = ct.items.items;
14129 for(var i = 0, len = items.length; i < len; i++) {
14131 if(c && (!c.rendered || !this.isValidParent(c, target))){
14132 this.renderItem(c, i, target);
14137 renderItem : function(c, position, target){
14138 if(c && !c.rendered){
14139 c.render(target, position);
14141 var t = c.getPositionEl ? c.getPositionEl() : c;
14142 t.addClass(this.extraCls);
14144 if (this.renderHidden && c != this.activeItem) {
14147 }else if(c && !this.isValidParent(c, target)){
14149 c.addClass(this.extraCls);
14151 if(typeof position == 'number'){
14152 position = target.dom.childNodes[position];
14154 target.dom.insertBefore(c.getEl().dom, position || null);
14155 if (this.renderHidden && c != this.activeItem) {
14161 onResize: function(){
14162 if(this.container.collapsed){
14165 var b = this.container.bufferResize;
14167 if(!this.resizeTask){
14168 this.resizeTask = new Ext.util.DelayedTask(this.layout, this);
14169 this.resizeBuffer = typeof b == 'number' ? b : 100;
14171 this.resizeTask.delay(this.resizeBuffer);
14177 setContainer : function(ct){
14178 if(this.monitorResize && ct != this.container){
14179 if(this.container){
14180 this.container.un('resize', this.onResize, this);
14183 ct.on('resize', this.onResize, this);
14186 this.container = ct;
14189 parseMargins : function(v){
14190 var ms = v.split(' ');
14191 var len = ms.length;
14202 top:parseInt(ms[0], 10) || 0,
14203 right:parseInt(ms[1], 10) || 0,
14204 bottom:parseInt(ms[2], 10) || 0,
14205 left:parseInt(ms[3], 10) || 0
14209 Ext.Container.LAYOUTS['auto'] = Ext.layout.ContainerLayout;
14211 Ext.layout.FitLayout = Ext.extend(Ext.layout.ContainerLayout, {
\r
14213 monitorResize:true,
\r
14216 onLayout : function(ct, target){
\r
14217 Ext.layout.FitLayout.superclass.onLayout.call(this, ct, target);
\r
14218 if(!this.container.collapsed){
\r
14219 this.setItemSize(this.activeItem || ct.items.itemAt(0), target.getStyleSize());
\r
14224 setItemSize : function(item, size){
\r
14225 if(item && size.height > 0){
14226 item.setSize(size);
\r
14230 Ext.Container.LAYOUTS['fit'] = Ext.layout.FitLayout;
14232 Ext.layout.CardLayout = Ext.extend(Ext.layout.FitLayout, {
\r
14234 deferredRender : false,
\r
14237 renderHidden : true,
\r
14240 setActiveItem : function(item){
\r
14241 item = this.container.getComponent(item);
\r
14242 if(this.activeItem != item){
\r
14243 if(this.activeItem){
\r
14244 this.activeItem.hide();
\r
14246 this.activeItem = item;
\r
14253 renderAll : function(ct, target){
\r
14254 if(this.deferredRender){
\r
14255 this.renderItem(this.activeItem, undefined, target);
\r
14257 Ext.layout.CardLayout.superclass.renderAll.call(this, ct, target);
\r
14261 Ext.Container.LAYOUTS['card'] = Ext.layout.CardLayout;
14263 Ext.layout.AnchorLayout = Ext.extend(Ext.layout.ContainerLayout, {
\r
14265 monitorResize:true,
\r
14268 getAnchorViewSize : function(ct, target){
\r
14269 return target.dom == document.body ?
\r
14270 target.getViewSize() : target.getStyleSize();
\r
14274 onLayout : function(ct, target){
\r
14275 Ext.layout.AnchorLayout.superclass.onLayout.call(this, ct, target);
\r
14277 var size = this.getAnchorViewSize(ct, target);
\r
14279 var w = size.width, h = size.height;
\r
14281 if(w < 20 || h < 20){
\r
14287 if(ct.anchorSize){
\r
14288 if(typeof ct.anchorSize == 'number'){
\r
14289 aw = ct.anchorSize;
\r
14291 aw = ct.anchorSize.width;
\r
14292 ah = ct.anchorSize.height;
\r
14295 aw = ct.initialConfig.width;
\r
14296 ah = ct.initialConfig.height;
\r
14299 var cs = ct.items.items, len = cs.length, i, c, a, cw, ch;
\r
14300 for(i = 0; i < len; i++){
\r
14303 a = c.anchorSpec;
\r
14305 var vs = c.anchor.split(' ');
\r
14306 c.anchorSpec = a = {
\r
14307 right: this.parseAnchor(vs[0], c.initialConfig.width, aw),
\r
14308 bottom: this.parseAnchor(vs[1], c.initialConfig.height, ah)
\r
14311 cw = a.right ? this.adjustWidthAnchor(a.right(w), c) : undefined;
\r
14312 ch = a.bottom ? this.adjustHeightAnchor(a.bottom(h), c) : undefined;
\r
14315 c.setSize(cw || undefined, ch || undefined);
\r
14322 parseAnchor : function(a, start, cstart){
\r
14323 if(a && a != 'none'){
\r
14325 if(/^(r|right|b|bottom)$/i.test(a)){
14326 var diff = cstart - start;
\r
14327 return function(v){
\r
14333 }else if(a.indexOf('%') != -1){
\r
14334 var ratio = parseFloat(a.replace('%', ''))*.01;
14335 return function(v){
\r
14338 return Math.floor(v*ratio);
\r
14342 a = parseInt(a, 10);
\r
14344 return function(v){
\r
14357 adjustWidthAnchor : function(value, comp){
\r
14362 adjustHeightAnchor : function(value, comp){
\r
14368 Ext.Container.LAYOUTS['anchor'] = Ext.layout.AnchorLayout;
14370 Ext.layout.ColumnLayout = Ext.extend(Ext.layout.ContainerLayout, {
\r
14372 monitorResize:true,
\r
14374 extraCls: 'x-column',
\r
14376 scrollOffset : 0,
\r
14379 isValidParent : function(c, target){
\r
14380 return c.getEl().dom.parentNode == this.innerCt.dom;
\r
14384 onLayout : function(ct, target){
\r
14385 var cs = ct.items.items, len = cs.length, c, i;
\r
14387 if(!this.innerCt){
\r
14388 target.addClass('x-column-layout-ct');
\r
14392 this.innerCt = target.createChild({cls:'x-column-inner'});
\r
14393 this.innerCt.createChild({cls:'x-clear'});
\r
14395 this.renderAll(ct, this.innerCt);
\r
14397 var size = target.getViewSize();
\r
14399 if(size.width < 1 && size.height < 1){
14403 var w = size.width - target.getPadding('lr') - this.scrollOffset,
\r
14404 h = size.height - target.getPadding('tb'),
\r
14407 this.innerCt.setWidth(w);
\r
14412 for(i = 0; i < len; i++){
\r
14414 if(!c.columnWidth){
\r
14415 pw -= (c.getSize().width + c.getEl().getMargins('lr'));
\r
14419 pw = pw < 0 ? 0 : pw;
\r
14421 for(i = 0; i < len; i++){
\r
14423 if(c.columnWidth){
\r
14424 c.setSize(Math.floor(c.columnWidth*pw) - c.getEl().getMargins('lr'));
\r
14432 Ext.Container.LAYOUTS['column'] = Ext.layout.ColumnLayout;
14434 Ext.layout.BorderLayout = Ext.extend(Ext.layout.ContainerLayout, {
14435 monitorResize:true,
14438 onLayout : function(ct, target){
14440 if(!this.rendered){
14442 target.addClass('x-border-layout-ct');
14443 var items = ct.items.items;
14445 for(var i = 0, len = items.length; i < len; i++) {
14447 var pos = c.region;
14451 c.collapsed = false;
14453 c.cls = c.cls ? c.cls +' x-border-panel' : 'x-border-panel';
14454 c.render(target, i);
14456 this[pos] = pos != 'center' && c.split ?
14457 new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) :
14458 new Ext.layout.BorderLayout.Region(this, c.initialConfig, pos);
14459 this[pos].render(target, c);
14461 this.rendered = true;
14464 var size = target.getViewSize();
14465 if(size.width < 20 || size.height < 20){ if(collapsed){
14466 this.restoreCollapsed = collapsed;
14469 }else if(this.restoreCollapsed){
14470 collapsed = this.restoreCollapsed;
14471 delete this.restoreCollapsed;
14474 var w = size.width, h = size.height;
14475 var centerW = w, centerH = h, centerY = 0, centerX = 0;
14477 var n = this.north, s = this.south, west = this.west, e = this.east, c = this.center;
14479 throw 'No center region defined in BorderLayout ' + ct.id;
14482 if(n && n.isVisible()){
14483 var b = n.getSize();
14484 var m = n.getMargins();
14485 b.width = w - (m.left+m.right);
14488 centerY = b.height + b.y + m.bottom;
14489 centerH -= centerY;
14492 if(s && s.isVisible()){
14493 var b = s.getSize();
14494 var m = s.getMargins();
14495 b.width = w - (m.left+m.right);
14497 var totalHeight = (b.height + m.top + m.bottom);
14498 b.y = h - totalHeight + m.top;
14499 centerH -= totalHeight;
14502 if(west && west.isVisible()){
14503 var b = west.getSize();
14504 var m = west.getMargins();
14505 b.height = centerH - (m.top+m.bottom);
14507 b.y = centerY + m.top;
14508 var totalWidth = (b.width + m.left + m.right);
14509 centerX += totalWidth;
14510 centerW -= totalWidth;
14511 west.applyLayout(b);
14513 if(e && e.isVisible()){
14514 var b = e.getSize();
14515 var m = e.getMargins();
14516 b.height = centerH - (m.top+m.bottom);
14517 var totalWidth = (b.width + m.left + m.right);
14518 b.x = w - totalWidth + m.left;
14519 b.y = centerY + m.top;
14520 centerW -= totalWidth;
14524 var m = c.getMargins();
14526 x: centerX + m.left,
14527 y: centerY + m.top,
14528 width: centerW - (m.left+m.right),
14529 height: centerH - (m.top+m.bottom)
14531 c.applyLayout(centerBox);
14534 for(var i = 0, len = collapsed.length; i < len; i++){
14535 collapsed[i].collapse(false);
14539 if(Ext.isIE && Ext.isStrict){ target.repaint();
14547 Ext.layout.BorderLayout.Region = function(layout, config, pos){
14548 Ext.apply(this, config);
14549 this.layout = layout;
14550 this.position = pos;
14552 if(typeof this.margins == 'string'){
14553 this.margins = this.layout.parseMargins(this.margins);
14555 this.margins = Ext.applyIf(this.margins || {}, this.defaultMargins);
14556 if(this.collapsible){
14557 if(typeof this.cmargins == 'string'){
14558 this.cmargins = this.layout.parseMargins(this.cmargins);
14560 if(this.collapseMode == 'mini' && !this.cmargins){
14561 this.cmargins = {left:0,top:0,right:0,bottom:0};
14563 this.cmargins = Ext.applyIf(this.cmargins || {},
14564 pos == 'north' || pos == 'south' ? this.defaultNSCMargins : this.defaultEWCMargins);
14569 Ext.layout.BorderLayout.Region.prototype = {
14576 collapsible : false,
14586 defaultMargins : {left:0,top:0,right:0,bottom:0},
14587 defaultNSCMargins : {left:5,top:5,right:5,bottom:5},
14588 defaultEWCMargins : {left:5,top:0,right:5,bottom:0},
14591 isCollapsed : false,
14597 render : function(ct, p){
14599 p.el.enableDisplayMode();
14600 this.targetEl = ct;
14603 var gs = p.getState, ps = this.position;
14604 p.getState = function(){
14605 return Ext.apply(gs.call(p) || {}, this.state);
14606 }.createDelegate(this);
14608 if(ps != 'center'){
14609 p.allowQueuedExpand = false;
14611 beforecollapse: this.beforeCollapse,
14612 collapse: this.onCollapse,
14613 beforeexpand: this.beforeExpand,
14614 expand: this.onExpand,
14619 if(this.collapsible){
14620 p.collapseEl = 'el';
14621 p.slideAnchor = this.getSlideAnchor();
14623 if(p.tools && p.tools.toggle){
14624 p.tools.toggle.addClass('x-tool-collapse-'+ps);
14625 p.tools.toggle.addClassOnOver('x-tool-collapse-'+ps+'-over');
14630 getCollapsedEl : function(){
14631 if(!this.collapsedEl){
14632 if(!this.toolTemplate){
14633 var tt = new Ext.Template(
14634 '<div class="x-tool x-tool-{id}"> </div>'
14636 tt.disableFormats = true;
14638 Ext.layout.BorderLayout.Region.prototype.toolTemplate = tt;
14640 this.collapsedEl = this.targetEl.createChild({
14641 cls: "x-layout-collapsed x-layout-collapsed-"+this.position,
14642 id: this.panel.id + '-xcollapsed'
14644 this.collapsedEl.enableDisplayMode('block');
14646 if(this.collapseMode == 'mini'){
14647 this.collapsedEl.addClass('x-layout-cmini-'+this.position);
14648 this.miniCollapsedEl = this.collapsedEl.createChild({
14649 cls: "x-layout-mini x-layout-mini-"+this.position, html: " "
14651 this.miniCollapsedEl.addClassOnOver('x-layout-mini-over');
14652 this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
14653 this.collapsedEl.on('click', this.onExpandClick, this, {stopEvent:true});
14655 var t = this.toolTemplate.append(
14656 this.collapsedEl.dom,
14657 {id:'expand-'+this.position}, true);
14658 t.addClassOnOver('x-tool-expand-'+this.position+'-over');
14659 t.on('click', this.onExpandClick, this, {stopEvent:true});
14661 if(this.floatable !== false){
14662 this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
14663 this.collapsedEl.on("click", this.collapseClick, this);
14667 return this.collapsedEl;
14670 onExpandClick : function(e){
14672 this.afterSlideIn();
14673 this.panel.expand(false);
14675 this.panel.expand();
14679 onCollapseClick : function(e){
14680 this.panel.collapse();
14683 beforeCollapse : function(p, animate){
14684 this.lastAnim = animate;
14686 this.splitEl.hide();
14688 this.getCollapsedEl().show();
14689 this.panel.el.setStyle('z-index', 100);
14690 this.isCollapsed = true;
14691 this.layout.layout();
14694 onCollapse : function(animate){
14695 this.panel.el.setStyle('z-index', 1);
14696 if(this.lastAnim === false || this.panel.animCollapse === false){
14697 this.getCollapsedEl().dom.style.visibility = 'visible';
14699 this.getCollapsedEl().slideIn(this.panel.slideAnchor, {duration:.2});
14701 this.state.collapsed = true;
14702 this.panel.saveState();
14705 beforeExpand : function(animate){
14706 var c = this.getCollapsedEl();
14708 if(this.position == 'east' || this.position == 'west'){
14709 this.panel.setSize(undefined, c.getHeight());
14711 this.panel.setSize(c.getWidth(), undefined);
14714 c.dom.style.visibility = 'hidden';
14715 this.panel.el.setStyle('z-index', 100);
14718 onExpand : function(){
14719 this.isCollapsed = false;
14721 this.splitEl.show();
14723 this.layout.layout();
14724 this.panel.el.setStyle('z-index', 1);
14725 this.state.collapsed = false;
14726 this.panel.saveState();
14729 collapseClick : function(e){
14731 e.stopPropagation();
14734 e.stopPropagation();
14739 onHide : function(){
14740 if(this.isCollapsed){
14741 this.getCollapsedEl().hide();
14742 }else if(this.splitEl){
14743 this.splitEl.hide();
14747 onShow : function(){
14748 if(this.isCollapsed){
14749 this.getCollapsedEl().show();
14750 }else if(this.splitEl){
14751 this.splitEl.show();
14756 isVisible : function(){
14757 return !this.panel.hidden;
14761 getMargins : function(){
14762 return this.isCollapsed && this.cmargins ? this.cmargins : this.margins;
14766 getSize : function(){
14767 return this.isCollapsed ? this.getCollapsedEl().getSize() : this.panel.getSize();
14771 setPanel : function(panel){
14772 this.panel = panel;
14776 getMinWidth: function(){
14777 return this.minWidth;
14781 getMinHeight: function(){
14782 return this.minHeight;
14785 applyLayoutCollapsed : function(box){
14786 var ce = this.getCollapsedEl();
14787 ce.setLeftTop(box.x, box.y);
14788 ce.setSize(box.width, box.height);
14791 applyLayout : function(box){
14792 if(this.isCollapsed){
14793 this.applyLayoutCollapsed(box);
14795 this.panel.setPosition(box.x, box.y);
14796 this.panel.setSize(box.width, box.height);
14800 beforeSlide: function(){
14801 this.panel.beforeEffect();
14804 afterSlide : function(){
14805 this.panel.afterEffect();
14808 initAutoHide : function(){
14809 if(this.autoHide !== false){
14810 if(!this.autoHideHd){
14811 var st = new Ext.util.DelayedTask(this.slideIn, this);
14812 this.autoHideHd = {
14813 "mouseout": function(e){
14814 if(!e.within(this.el, true)){
14818 "mouseover" : function(e){
14824 this.el.on(this.autoHideHd);
14828 clearAutoHide : function(){
14829 if(this.autoHide !== false){
14830 this.el.un("mouseout", this.autoHideHd.mouseout);
14831 this.el.un("mouseover", this.autoHideHd.mouseover);
14835 clearMonitor : function(){
14836 Ext.getDoc().un("click", this.slideInIf, this);
14839 slideOut : function(){
14840 if(this.isSlid || this.el.hasActiveFx()){
14843 this.isSlid = true;
14844 var ts = this.panel.tools;
14845 if(ts && ts.toggle){
14849 if(this.position == 'east' || this.position == 'west'){
14850 this.panel.setSize(undefined, this.collapsedEl.getHeight());
14852 this.panel.setSize(this.collapsedEl.getWidth(), undefined);
14854 this.restoreLT = [this.el.dom.style.left, this.el.dom.style.top];
14855 this.el.alignTo(this.collapsedEl, this.getCollapseAnchor());
14856 this.el.setStyle("z-index", 102);
14857 if(this.animFloat !== false){
14858 this.beforeSlide();
14859 this.el.slideIn(this.getSlideAnchor(), {
14860 callback: function(){
14862 this.initAutoHide();
14863 Ext.getDoc().on("click", this.slideInIf, this);
14869 this.initAutoHide();
14870 Ext.getDoc().on("click", this.slideInIf, this);
14874 afterSlideIn : function(){
14875 this.clearAutoHide();
14876 this.isSlid = false;
14877 this.clearMonitor();
14878 this.el.setStyle("z-index", "");
14879 this.el.dom.style.left = this.restoreLT[0];
14880 this.el.dom.style.top = this.restoreLT[1];
14882 var ts = this.panel.tools;
14883 if(ts && ts.toggle){
14888 slideIn : function(cb){
14889 if(!this.isSlid || this.el.hasActiveFx()){
14893 this.isSlid = false;
14894 if(this.animFloat !== false){
14895 this.beforeSlide();
14896 this.el.slideOut(this.getSlideAnchor(), {
14897 callback: function(){
14900 this.afterSlideIn();
14908 this.afterSlideIn();
14912 slideInIf : function(e){
14913 if(!e.within(this.el)){
14939 getAnchor : function(){
14940 return this.anchors[this.position];
14943 getCollapseAnchor : function(){
14944 return this.canchors[this.position];
14947 getSlideAnchor : function(){
14948 return this.sanchors[this.position];
14951 getAlignAdj : function(){
14952 var cm = this.cmargins;
14953 switch(this.position){
14969 getExpandAdj : function(){
14970 var c = this.collapsedEl, cm = this.cmargins;
14971 switch(this.position){
14973 return [-(cm.right+c.getWidth()+cm.left), 0];
14976 return [cm.right+c.getWidth()+cm.left, 0];
14979 return [0, -(cm.top+cm.bottom+c.getHeight())];
14982 return [0, cm.top+cm.bottom+c.getHeight()];
14989 Ext.layout.BorderLayout.SplitRegion = function(layout, config, pos){
14990 Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this, layout, config, pos);
14991 this.applyLayout = this.applyFns[pos];
14994 Ext.extend(Ext.layout.BorderLayout.SplitRegion, Ext.layout.BorderLayout.Region, {
14996 splitTip : "Drag to resize.",
14998 collapsibleSplitTip : "Drag to resize. Double click to hide.",
15000 useSplitTips : false,
15004 orientation: Ext.SplitBar.VERTICAL,
15005 placement: Ext.SplitBar.TOP,
15006 maxFn : 'getVMaxSize',
15007 minProp: 'minHeight',
15008 maxProp: 'maxHeight'
15011 orientation: Ext.SplitBar.VERTICAL,
15012 placement: Ext.SplitBar.BOTTOM,
15013 maxFn : 'getVMaxSize',
15014 minProp: 'minHeight',
15015 maxProp: 'maxHeight'
15018 orientation: Ext.SplitBar.HORIZONTAL,
15019 placement: Ext.SplitBar.RIGHT,
15020 maxFn : 'getHMaxSize',
15021 minProp: 'minWidth',
15022 maxProp: 'maxWidth'
15025 orientation: Ext.SplitBar.HORIZONTAL,
15026 placement: Ext.SplitBar.LEFT,
15027 maxFn : 'getHMaxSize',
15028 minProp: 'minWidth',
15029 maxProp: 'maxWidth'
15034 west : function(box){
15035 if(this.isCollapsed){
15036 return this.applyLayoutCollapsed(box);
15038 var sd = this.splitEl.dom, s = sd.style;
15039 this.panel.setPosition(box.x, box.y);
15040 var sw = sd.offsetWidth;
15041 s.left = (box.x+box.width-sw)+'px';
15042 s.top = (box.y)+'px';
15043 s.height = Math.max(0, box.height)+'px';
15044 this.panel.setSize(box.width-sw, box.height);
15046 east : function(box){
15047 if(this.isCollapsed){
15048 return this.applyLayoutCollapsed(box);
15050 var sd = this.splitEl.dom, s = sd.style;
15051 var sw = sd.offsetWidth;
15052 this.panel.setPosition(box.x+sw, box.y);
15053 s.left = (box.x)+'px';
15054 s.top = (box.y)+'px';
15055 s.height = Math.max(0, box.height)+'px';
15056 this.panel.setSize(box.width-sw, box.height);
15058 north : function(box){
15059 if(this.isCollapsed){
15060 return this.applyLayoutCollapsed(box);
15062 var sd = this.splitEl.dom, s = sd.style;
15063 var sh = sd.offsetHeight;
15064 this.panel.setPosition(box.x, box.y);
15065 s.left = (box.x)+'px';
15066 s.top = (box.y+box.height-sh)+'px';
15067 s.width = Math.max(0, box.width)+'px';
15068 this.panel.setSize(box.width, box.height-sh);
15070 south : function(box){
15071 if(this.isCollapsed){
15072 return this.applyLayoutCollapsed(box);
15074 var sd = this.splitEl.dom, s = sd.style;
15075 var sh = sd.offsetHeight;
15076 this.panel.setPosition(box.x, box.y+sh);
15077 s.left = (box.x)+'px';
15078 s.top = (box.y)+'px';
15079 s.width = Math.max(0, box.width)+'px';
15080 this.panel.setSize(box.width, box.height-sh);
15084 render : function(ct, p){
15085 Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p);
15087 var ps = this.position;
15089 this.splitEl = ct.createChild({
15090 cls: "x-layout-split x-layout-split-"+ps, html: " ",
15091 id: this.panel.id + '-xsplit'
15094 if(this.collapseMode == 'mini'){
15095 this.miniSplitEl = this.splitEl.createChild({
15096 cls: "x-layout-mini x-layout-mini-"+ps, html: " "
15098 this.miniSplitEl.addClassOnOver('x-layout-mini-over');
15099 this.miniSplitEl.on('click', this.onCollapseClick, this, {stopEvent:true});
15102 var s = this.splitSettings[ps];
15104 this.split = new Ext.SplitBar(this.splitEl.dom, p.el, s.orientation);
15105 this.split.placement = s.placement;
15106 this.split.getMaximumSize = this[s.maxFn].createDelegate(this);
15107 this.split.minSize = this.minSize || this[s.minProp];
15108 this.split.on("beforeapply", this.onSplitMove, this);
15109 this.split.useShim = this.useShim === true;
15110 this.maxSize = this.maxSize || this[s.maxProp];
15113 this.splitEl.hide();
15116 if(this.useSplitTips){
15117 this.splitEl.dom.title = this.collapsible ? this.collapsibleSplitTip : this.splitTip;
15119 if(this.collapsible){
15120 this.splitEl.on("dblclick", this.onCollapseClick, this);
15124 getSize : function(){
15125 if(this.isCollapsed){
15126 return this.collapsedEl.getSize();
15128 var s = this.panel.getSize();
15129 if(this.position == 'north' || this.position == 'south'){
15130 s.height += this.splitEl.dom.offsetHeight;
15132 s.width += this.splitEl.dom.offsetWidth;
15137 getHMaxSize : function(){
15138 var cmax = this.maxSize || 10000;
15139 var center = this.layout.center;
15140 return Math.min(cmax, (this.el.getWidth()+center.el.getWidth())-center.getMinWidth());
15143 getVMaxSize : function(){
15144 var cmax = this.maxSize || 10000;
15145 var center = this.layout.center;
15146 return Math.min(cmax, (this.el.getHeight()+center.el.getHeight())-center.getMinHeight());
15149 onSplitMove : function(split, newSize){
15150 var s = this.panel.getSize();
15151 this.lastSplitSize = newSize;
15152 if(this.position == 'north' || this.position == 'south'){
15153 this.panel.setSize(s.width, newSize);
15154 this.state.height = newSize;
15156 this.panel.setSize(newSize, s.height);
15157 this.state.width = newSize;
15159 this.layout.layout();
15160 this.panel.saveState();
15165 getSplitBar : function(){
15170 Ext.Container.LAYOUTS['border'] = Ext.layout.BorderLayout;
15172 Ext.layout.FormLayout = Ext.extend(Ext.layout.AnchorLayout, {
15176 labelSeparator : ':',
15178 getAnchorViewSize : function(ct, target){
15179 return ct.body.getStyleSize();
15182 setContainer : function(ct){
15183 Ext.layout.FormLayout.superclass.setContainer.call(this, ct);
15186 ct.addClass('x-form-label-'+ct.labelAlign);
15190 this.labelStyle = "display:none";
15191 this.elementStyle = "padding-left:0;";
15192 this.labelAdjust = 0;
15194 this.labelSeparator = ct.labelSeparator || this.labelSeparator;
15195 ct.labelWidth = ct.labelWidth || 100;
15196 if(typeof ct.labelWidth == 'number'){
15197 var pad = (typeof ct.labelPad == 'number' ? ct.labelPad : 5);
15198 this.labelAdjust = ct.labelWidth+pad;
15199 this.labelStyle = "width:"+ct.labelWidth+"px;";
15200 this.elementStyle = "padding-left:"+(ct.labelWidth+pad)+'px';
15202 if(ct.labelAlign == 'top'){
15203 this.labelStyle = "width:auto;";
15204 this.labelAdjust = 0;
15205 this.elementStyle = "padding-left:0;";
15209 if(!this.fieldTpl){
15210 var t = new Ext.Template(
15211 '<div class="x-form-item {5}" tabIndex="-1">',
15212 '<label for="{0}" style="{2}" class="x-form-item-label">{1}{4}</label>',
15213 '<div class="x-form-element" id="x-form-el-{0}" style="{3}">',
15214 '</div><div class="{6}"></div>',
15217 t.disableFormats = true;
15219 Ext.layout.FormLayout.prototype.fieldTpl = t;
15223 renderItem : function(c, position, target){
15224 if(c && !c.rendered && c.isFormField && c.inputType != 'hidden'){
15226 c.id, c.fieldLabel,
15227 c.labelStyle||this.labelStyle||'',
15228 this.elementStyle||'',
15229 typeof c.labelSeparator == 'undefined' ? this.labelSeparator : c.labelSeparator,
15230 (c.itemCls||this.container.itemCls||'') + (c.hideLabel ? ' x-hide-label' : ''),
15231 c.clearCls || 'x-form-clear-left'
15233 if(typeof position == 'number'){
15234 position = target.dom.childNodes[position] || null;
15237 this.fieldTpl.insertBefore(position, args);
15239 this.fieldTpl.append(target, args);
15241 c.render('x-form-el-'+c.id);
15243 Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
15247 adjustWidthAnchor : function(value, comp){
15248 return value - (comp.isFormField ? (comp.hideLabel ? 0 : this.labelAdjust) : 0);
15251 isValidParent : function(c, target){
15258 Ext.Container.LAYOUTS['form'] = Ext.layout.FormLayout;
15260 Ext.layout.Accordion = Ext.extend(Ext.layout.FitLayout, {
\r
15264 autoWidth : true,
\r
15266 titleCollapse : true,
\r
15268 hideCollapseTool : false,
\r
15270 collapseFirst : false,
\r
15274 sequence : false,
\r
15276 activeOnTop : false,
\r
15278 renderItem : function(c){
\r
15279 if(this.animate === false){
\r
15280 c.animCollapse = false;
\r
15282 c.collapsible = true;
\r
15283 if(this.autoWidth){
\r
15284 c.autoWidth = true;
\r
15286 if(this.titleCollapse){
\r
15287 c.titleCollapse = true;
\r
15289 if(this.hideCollapseTool){
\r
15290 c.hideCollapseTool = true;
\r
15292 if(this.collapseFirst !== undefined){
\r
15293 c.collapseFirst = this.collapseFirst;
\r
15295 if(!this.activeItem && !c.collapsed){
\r
15296 this.activeItem = c;
\r
15297 }else if(this.activeItem){
\r
15298 c.collapsed = true;
\r
15300 Ext.layout.Accordion.superclass.renderItem.apply(this, arguments);
\r
15301 c.header.addClass('x-accordion-hd');
\r
15302 c.on('beforeexpand', this.beforeExpand, this);
\r
15306 beforeExpand : function(p, anim){
\r
15307 var ai = this.activeItem;
\r
15309 if(this.sequence){
\r
15310 delete this.activeItem;
\r
15311 ai.collapse({callback:function(){
\r
15312 p.expand(anim || true);
\r
15313 }, scope: this});
\r
15316 ai.collapse(this.animate);
\r
15319 this.activeItem = p;
\r
15320 if(this.activeOnTop){
\r
15321 p.el.dom.parentNode.insertBefore(p.el.dom, p.el.dom.parentNode.firstChild);
\r
15327 setItemSize : function(item, size){
\r
15328 if(this.fill && item){
\r
15329 var items = this.container.items.items;
\r
15331 for(var i = 0, len = items.length; i < len; i++){
\r
15332 var p = items[i];
\r
15334 hh += (p.getSize().height - p.bwrap.getHeight());
\r
15337 size.height -= hh;
\r
15338 item.setSize(size);
\r
15342 Ext.Container.LAYOUTS['accordion'] = Ext.layout.Accordion;
15344 Ext.layout.TableLayout = Ext.extend(Ext.layout.ContainerLayout, {
\r
15348 monitorResize:false,
\r
15351 setContainer : function(ct){
\r
15352 Ext.layout.TableLayout.superclass.setContainer.call(this, ct);
\r
15354 this.currentRow = 0;
\r
15355 this.currentColumn = 0;
\r
15360 onLayout : function(ct, target){
\r
15361 var cs = ct.items.items, len = cs.length, c, i;
\r
15364 target.addClass('x-table-layout-ct');
\r
15366 this.table = target.createChild(
\r
15367 {tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, null, true);
\r
15369 this.renderAll(ct, target);
\r
15374 getRow : function(index){
\r
15375 var row = this.table.tBodies[0].childNodes[index];
\r
15377 row = document.createElement('tr');
\r
15378 this.table.tBodies[0].appendChild(row);
\r
15384 getNextCell : function(c){
\r
15385 var cell = this.getNextNonSpan(this.currentColumn, this.currentRow);
\r
15386 var curCol = this.currentColumn = cell[0], curRow = this.currentRow = cell[1];
\r
15387 for(var rowIndex = curRow; rowIndex < curRow + (c.rowspan || 1); rowIndex++){
\r
15388 if(!this.cells[rowIndex]){
\r
15389 this.cells[rowIndex] = [];
\r
15391 for(var colIndex = curCol; colIndex < curCol + (c.colspan || 1); colIndex++){
\r
15392 this.cells[rowIndex][colIndex] = true;
\r
15395 var td = document.createElement('td');
\r
15397 td.id = c.cellId;
\r
15399 var cls = 'x-table-layout-cell';
\r
15401 cls += ' ' + c.cellCls;
\r
15403 td.className = cls;
\r
15405 td.colSpan = c.colspan;
\r
15408 td.rowSpan = c.rowspan;
\r
15410 this.getRow(curRow).appendChild(td);
\r
15415 getNextNonSpan: function(colIndex, rowIndex){
\r
15416 var cols = this.columns;
\r
15417 while((cols && colIndex >= cols) || (this.cells[rowIndex] && this.cells[rowIndex][colIndex])) {
\r
15418 if(cols && colIndex >= cols){
\r
15425 return [colIndex, rowIndex];
\r
15429 renderItem : function(c, position, target){
\r
15430 if(c && !c.rendered){
\r
15431 c.render(this.getNextCell(c));
\r
15436 isValidParent : function(c, target){
\r
15443 Ext.Container.LAYOUTS['table'] = Ext.layout.TableLayout;
15445 Ext.layout.AbsoluteLayout = Ext.extend(Ext.layout.AnchorLayout, {
\r
15446 extraCls: 'x-abs-layout-item',
\r
15449 setContainer : function(ct){
\r
15450 Ext.layout.AbsoluteLayout.superclass.setContainer.call(this, ct);
\r
15451 if(ct.isXType('form')){
\r
15452 this.isForm = true;
\r
15456 onLayout : function(ct, target){
\r
15457 if(this.isForm){ ct.body.position(); } else { target.position(); }
\r
15458 Ext.layout.AbsoluteLayout.superclass.onLayout.call(this, ct, target);
\r
15462 getAnchorViewSize : function(ct, target){
\r
15463 return this.isForm ? ct.body.getStyleSize() : Ext.layout.AbsoluteLayout.superclass.getAnchorViewSize.call(this, ct, target);
\r
15467 isValidParent : function(c, target){
\r
15468 return this.isForm ? true : Ext.layout.AbsoluteLayout.superclass.isValidParent.call(this, c, target);
\r
15472 adjustWidthAnchor : function(value, comp){
\r
15473 return value ? value - comp.getPosition(true)[0] : value;
\r
15477 adjustHeightAnchor : function(value, comp){
\r
15478 return value ? value - comp.getPosition(true)[1] : value;
\r
15482 Ext.Container.LAYOUTS['absolute'] = Ext.layout.AbsoluteLayout;
15484 Ext.Viewport = Ext.extend(Ext.Container, {
\r
15497 initComponent : function() {
\r
15498 Ext.Viewport.superclass.initComponent.call(this);
\r
15499 document.getElementsByTagName('html')[0].className += ' x-viewport';
\r
15500 this.el = Ext.getBody();
\r
15501 this.el.setHeight = Ext.emptyFn;
\r
15502 this.el.setWidth = Ext.emptyFn;
\r
15503 this.el.setSize = Ext.emptyFn;
\r
15504 this.el.dom.scroll = 'no';
\r
15505 this.allowDomMove = false;
\r
15506 this.autoWidth = true;
\r
15507 this.autoHeight = true;
\r
15508 Ext.EventManager.onWindowResize(this.fireResize, this);
\r
15509 this.renderTo = this.el;
\r
15512 fireResize : function(w, h){
\r
15513 this.fireEvent('resize', this, w, h, w, h);
\r
15516 Ext.reg('viewport', Ext.Viewport);
15518 Ext.Panel = Ext.extend(Ext.Container, {
15552 baseCls : 'x-panel',
15554 collapsedCls : 'x-panel-collapsed',
15556 maskDisabled: true,
15558 animCollapse: Ext.enableFx,
15560 headerAsText: true,
15562 buttonAlign: 'right',
15566 collapseFirst: true,
15572 toolTarget : 'header',
15573 collapseEl : 'bwrap',
15580 collapseDefaults: {
15584 initComponent : function(){
15585 Ext.Panel.superclass.initComponent.call(this);
15611 this.elements += ',tbar';
15612 if(typeof this.tbar == 'object'){
15613 this.topToolbar = this.tbar;
15618 this.elements += ',bbar';
15619 if(typeof this.bbar == 'object'){
15620 this.bottomToolbar = this.bbar;
15625 if(this.header === true){
15626 this.elements += ',header';
15627 delete this.header;
15628 }else if(this.title && this.header !== false){
15629 this.elements += ',header';
15632 if(this.footer === true){
15633 this.elements += ',footer';
15634 delete this.footer;
15638 var btns = this.buttons;
15641 for(var i = 0, len = btns.length; i < len; i++) {
15642 if(btns[i].render){ this.buttons.push(btns[i]);
15644 this.addButton(btns[i]);
15649 this.on('render', this.doAutoLoad, this, {delay:10});
15653 createElement : function(name, pnode){
15655 pnode.appendChild(this[name].dom);
15659 if(name === 'bwrap' || this.elements.indexOf(name) != -1){
15660 if(this[name+'Cfg']){
15661 this[name] = Ext.fly(pnode).createChild(this[name+'Cfg']);
15663 var el = document.createElement('div');
15664 el.className = this[name+'Cls'];
15665 this[name] = Ext.get(pnode.appendChild(el));
15670 onRender : function(ct, position){
15671 Ext.Panel.superclass.onRender.call(this, ct, position);
15673 this.createClasses();
15675 if(this.el){ this.el.addClass(this.baseCls);
15676 this.header = this.el.down('.'+this.headerCls);
15677 this.bwrap = this.el.down('.'+this.bwrapCls);
15678 var cp = this.bwrap ? this.bwrap : this.el;
15679 this.tbar = cp.down('.'+this.tbarCls);
15680 this.body = cp.down('.'+this.bodyCls);
15681 this.bbar = cp.down('.'+this.bbarCls);
15682 this.footer = cp.down('.'+this.footerCls);
15683 this.fromMarkup = true;
15685 this.el = ct.createChild({
15690 var el = this.el, d = el.dom;
15693 this.el.addClass(this.cls);
15697 this.elements += ',footer';
15702 el.insertHtml('afterBegin', String.format(Ext.Element.boxMarkup, this.baseCls));
15704 this.createElement('header', d.firstChild.firstChild.firstChild);
15705 this.createElement('bwrap', d);
15707 var bw = this.bwrap.dom;
15708 var ml = d.childNodes[1], bl = d.childNodes[2];
15709 bw.appendChild(ml);
15710 bw.appendChild(bl);
15712 var mc = bw.firstChild.firstChild.firstChild;
15713 this.createElement('tbar', mc);
15714 this.createElement('body', mc);
15715 this.createElement('bbar', mc);
15716 this.createElement('footer', bw.lastChild.firstChild.firstChild);
15719 this.bwrap.dom.lastChild.className += ' x-panel-nofooter';
15722 this.createElement('header', d);
15723 this.createElement('bwrap', d);
15725 var bw = this.bwrap.dom;
15726 this.createElement('tbar', bw);
15727 this.createElement('body', bw);
15728 this.createElement('bbar', bw);
15729 this.createElement('footer', bw);
15732 this.body.addClass(this.bodyCls + '-noheader');
15734 this.tbar.addClass(this.tbarCls + '-noheader');
15739 if(this.border === false){
15740 this.el.addClass(this.baseCls + '-noborder');
15741 this.body.addClass(this.bodyCls + '-noborder');
15743 this.header.addClass(this.headerCls + '-noborder');
15746 this.footer.addClass(this.footerCls + '-noborder');
15749 this.tbar.addClass(this.tbarCls + '-noborder');
15752 this.bbar.addClass(this.bbarCls + '-noborder');
15756 if(this.bodyBorder === false){
15757 this.body.addClass(this.bodyCls + '-noborder');
15760 if(this.bodyStyle){
15761 this.body.applyStyles(this.bodyStyle);
15764 this.bwrap.enableDisplayMode('block');
15767 this.header.unselectable();
15769 if(this.headerAsText){
15770 this.header.dom.innerHTML =
15771 '<span class="' + this.headerTextCls + '">'+this.header.dom.innerHTML+'</span>';
15774 this.setIconClass(this.iconCls);
15780 this.makeFloating(this.floating);
15783 if(this.collapsible){
15784 this.tools = this.tools ? this.tools.slice(0) : [];
15785 if(!this.hideCollapseTool){
15786 this.tools[this.collapseFirst?'unshift':'push']({
15788 handler : this.toggleCollapse,
15792 if(this.titleCollapse && this.header){
15793 this.header.on('click', this.toggleCollapse, this);
15794 this.header.setStyle('cursor', 'pointer');
15798 var ts = this.tools;
15800 this.addTool.apply(this, ts);
15805 if(this.buttons && this.buttons.length > 0){
15806 var tb = this.footer.createChild({cls:'x-panel-btns-ct', cn: {
15807 cls:"x-panel-btns x-panel-btns-"+this.buttonAlign,
15808 html:'<table cellspacing="0"><tbody><tr></tr></tbody></table><div class="x-clear"></div>'
15810 var tr = tb.getElementsByTagName('tr')[0];
15811 for(var i = 0, len = this.buttons.length; i < len; i++) {
15812 var b = this.buttons[i];
15813 var td = document.createElement('td');
15814 td.className = 'x-panel-btn-td';
15815 b.render(tr.appendChild(td));
15819 if(this.tbar && this.topToolbar){
15820 if(Ext.isArray(this.topToolbar)){
15821 this.topToolbar = new Ext.Toolbar(this.topToolbar);
15823 this.topToolbar.render(this.tbar);
15825 if(this.bbar && this.bottomToolbar){
15826 if(Ext.isArray(this.bottomToolbar)){
15827 this.bottomToolbar = new Ext.Toolbar(this.bottomToolbar);
15829 this.bottomToolbar.render(this.bbar);
15834 setIconClass : function(cls){
15835 var old = this.iconCls;
15836 this.iconCls = cls;
15837 if(this.rendered && this.header){
15839 this.header.addClass('x-panel-icon');
15840 this.header.replaceClass(old, this.iconCls);
15842 var hd = this.header.dom;
15843 var img = hd.firstChild && String(hd.firstChild.tagName).toLowerCase() == 'img' ? hd.firstChild : null;
15845 Ext.fly(img).replaceClass(old, this.iconCls);
15847 Ext.DomHelper.insertBefore(hd.firstChild, {
15848 tag:'img', src: Ext.BLANK_IMAGE_URL, cls:'x-panel-inline-icon '+this.iconCls
15855 makeFloating : function(cfg){
15856 this.floating = true;
15857 this.el = new Ext.Layer(
15858 typeof cfg == 'object' ? cfg : {
15859 shadow: this.shadow !== undefined ? this.shadow : 'sides',
15860 shadowOffset: this.shadowOffset,
15862 shim: this.shim === false ? false : undefined
15868 getTopToolbar : function(){
15869 return this.topToolbar;
15873 getBottomToolbar : function(){
15874 return this.bottomToolbar;
15878 addButton : function(config, handler, scope){
15882 minWidth: this.minButtonWidth,
15885 if(typeof config == "string"){
15888 Ext.apply(bc, config);
15890 var btn = new Ext.Button(bc);
15891 btn.ownerCt = this;
15895 this.buttons.push(btn);
15899 addTool : function(){
15900 if(!this[this.toolTarget]) { return;
15902 if(!this.toolTemplate){
15903 var tt = new Ext.Template(
15904 '<div class="x-tool x-tool-{id}"> </div>'
15906 tt.disableFormats = true;
15908 Ext.Panel.prototype.toolTemplate = tt;
15910 for(var i = 0, a = arguments, len = a.length; i < len; i++) {
15911 var tc = a[i], overCls = 'x-tool-'+tc.id+'-over';
15912 var t = this.toolTemplate.insertFirst(this[this.toolTarget], tc, true);
15913 this.tools[tc.id] = t;
15914 t.enableDisplayMode('block');
15915 t.on('click', this.createToolHandler(t, tc, overCls, this));
15923 if(typeof tc.qtip == 'object'){
15924 Ext.QuickTips.register(Ext.apply({
15928 t.dom.qtip = tc.qtip;
15931 t.addClassOnOver(overCls);
15935 onShow : function(){
15937 return this.el.show();
15939 Ext.Panel.superclass.onShow.call(this);
15942 onHide : function(){
15944 return this.el.hide();
15946 Ext.Panel.superclass.onHide.call(this);
15949 createToolHandler : function(t, tc, overCls, panel){
15950 return function(e){
15951 t.removeClass(overCls);
15954 tc.handler.call(tc.scope || t, e, t, panel);
15959 afterRender : function(){
15960 if(this.fromMarkup && this.height === undefined && !this.autoHeight){
15961 this.height = this.el.getHeight();
15963 if(this.floating && !this.hidden && !this.initHidden){
15967 this.setTitle(this.title);
15969 this.setAutoScroll();
15971 this.body.update(typeof this.html == 'object' ?
15972 Ext.DomHelper.markup(this.html) :
15976 if(this.contentEl){
15977 var ce = Ext.getDom(this.contentEl);
15978 Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']);
15979 this.body.dom.appendChild(ce);
15981 if(this.collapsed){
15982 this.collapsed = false;
15983 this.collapse(false);
15985 Ext.Panel.superclass.afterRender.call(this); this.initEvents();
15988 setAutoScroll : function(){
15989 if(this.rendered && this.autoScroll){
15990 this.body.setOverflow('auto');
15994 getKeyMap : function(){
15996 this.keyMap = new Ext.KeyMap(this.el, this.keys);
15998 return this.keyMap;
16001 initEvents : function(){
16005 if(this.draggable){
16006 this.initDraggable();
16010 initDraggable : function(){
16011 this.dd = new Ext.Panel.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);
16014 beforeEffect : function(){
16016 this.el.beforeAction();
16018 this.el.addClass('x-panel-animated');
16021 afterEffect : function(){
16023 this.el.removeClass('x-panel-animated');
16026 createEffect : function(a, cb, scope){
16034 }else if(!a.callback){
16036 }else { o.callback = function(){
16038 Ext.callback(a.callback, a.scope);
16041 return Ext.applyIf(o, a);
16045 collapse : function(animate){
16046 if(this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforecollapse', this, animate) === false){
16049 var doAnim = animate === true || (animate !== false && this.animCollapse);
16050 this.beforeEffect();
16051 this.onCollapse(doAnim, animate);
16055 onCollapse : function(doAnim, animArg){
16057 this[this.collapseEl].slideOut(this.slideAnchor,
16058 Ext.apply(this.createEffect(animArg||true, this.afterCollapse, this),
16059 this.collapseDefaults));
16061 this[this.collapseEl].hide();
16062 this.afterCollapse();
16066 afterCollapse : function(){
16067 this.collapsed = true;
16068 this.el.addClass(this.collapsedCls);
16069 this.afterEffect();
16070 this.fireEvent('collapse', this);
16074 expand : function(animate){
16075 if(!this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforeexpand', this, animate) === false){
16078 var doAnim = animate === true || (animate !== false && this.animCollapse);
16079 this.el.removeClass(this.collapsedCls);
16080 this.beforeEffect();
16081 this.onExpand(doAnim, animate);
16085 onExpand : function(doAnim, animArg){
16087 this[this.collapseEl].slideIn(this.slideAnchor,
16088 Ext.apply(this.createEffect(animArg||true, this.afterExpand, this),
16089 this.expandDefaults));
16091 this[this.collapseEl].show();
16092 this.afterExpand();
16096 afterExpand : function(){
16097 this.collapsed = false;
16098 this.afterEffect();
16099 this.fireEvent('expand', this);
16103 toggleCollapse : function(animate){
16104 this[this.collapsed ? 'expand' : 'collapse'](animate);
16108 onDisable : function(){
16109 if(this.rendered && this.maskDisabled){
16112 Ext.Panel.superclass.onDisable.call(this);
16115 onEnable : function(){
16116 if(this.rendered && this.maskDisabled){
16119 Ext.Panel.superclass.onEnable.call(this);
16122 onResize : function(w, h){
16123 if(w !== undefined || h !== undefined){
16124 if(!this.collapsed){
16125 if(typeof w == 'number'){
16126 this.body.setWidth(
16127 this.adjustBodyWidth(w - this.getFrameWidth()));
16128 }else if(w == 'auto'){
16129 this.body.setWidth(w);
16132 if(typeof h == 'number'){
16133 this.body.setHeight(
16134 this.adjustBodyHeight(h - this.getFrameHeight()));
16135 }else if(h == 'auto'){
16136 this.body.setHeight(h);
16139 this.queuedBodySize = {width: w, height: h};
16140 if(!this.queuedExpand && this.allowQueuedExpand !== false){
16141 this.queuedExpand = true;
16142 this.on('expand', function(){
16143 delete this.queuedExpand;
16144 this.onResize(this.queuedBodySize.width, this.queuedBodySize.height);
16146 }, this, {single:true});
16149 this.fireEvent('bodyresize', this, w, h);
16154 adjustBodyHeight : function(h){
16158 adjustBodyWidth : function(w){
16162 onPosition : function(){
16166 onDestroy : function(){
16168 for(var k in this.tools){
16169 Ext.destroy(this.tools[k]);
16173 for(var b in this.buttons){
16174 Ext.destroy(this.buttons[b]);
16181 Ext.Panel.superclass.onDestroy.call(this);
16185 getFrameWidth : function(){
16186 var w = this.el.getFrameWidth('lr');
16189 var l = this.bwrap.dom.firstChild;
16190 w += (Ext.fly(l).getFrameWidth('l') + Ext.fly(l.firstChild).getFrameWidth('r'));
16191 var mc = this.bwrap.dom.firstChild.firstChild.firstChild;
16192 w += Ext.fly(mc).getFrameWidth('lr');
16198 getFrameHeight : function(){
16199 var h = this.el.getFrameWidth('tb');
16200 h += (this.tbar ? this.tbar.getHeight() : 0) +
16201 (this.bbar ? this.bbar.getHeight() : 0);
16204 var hd = this.el.dom.firstChild;
16205 var ft = this.bwrap.dom.lastChild;
16206 h += (hd.offsetHeight + ft.offsetHeight);
16207 var mc = this.bwrap.dom.firstChild.firstChild.firstChild;
16208 h += Ext.fly(mc).getFrameWidth('tb');
16210 h += (this.header ? this.header.getHeight() : 0) +
16211 (this.footer ? this.footer.getHeight() : 0);
16217 getInnerWidth : function(){
16218 return this.getSize().width - this.getFrameWidth();
16222 getInnerHeight : function(){
16223 return this.getSize().height - this.getFrameHeight();
16226 syncShadow : function(){
16228 this.el.sync(true);
16232 getLayoutTarget : function(){
16237 setTitle : function(title, iconCls){
16238 this.title = title;
16239 if(this.header && this.headerAsText){
16240 this.header.child('span').update(title);
16243 this.setIconClass(iconCls);
16245 this.fireEvent('titlechange', this, title);
16250 getUpdater : function(){
16251 return this.body.getUpdater();
16256 var um = this.body.getUpdater();
16257 um.update.apply(um, arguments);
16261 beforeDestroy : function(){
16262 Ext.Element.uncache(
16271 createClasses : function(){
16272 this.headerCls = this.baseCls + '-header';
16273 this.headerTextCls = this.baseCls + '-header-text';
16274 this.bwrapCls = this.baseCls + '-bwrap';
16275 this.tbarCls = this.baseCls + '-tbar';
16276 this.bodyCls = this.baseCls + '-body';
16277 this.bbarCls = this.baseCls + '-bbar';
16278 this.footerCls = this.baseCls + '-footer';
16281 createGhost : function(cls, useShim, appendTo){
16282 var el = document.createElement('div');
16283 el.className = 'x-panel-ghost ' + (cls ? cls : '');
16285 el.appendChild(this.el.dom.firstChild.cloneNode(true));
16287 Ext.fly(el.appendChild(document.createElement('ul'))).setHeight(this.bwrap.getHeight());
16288 el.style.width = this.el.dom.offsetWidth + 'px';;
16290 this.container.dom.appendChild(el);
16292 Ext.getDom(appendTo).appendChild(el);
16294 if(useShim !== false && this.el.useShim !== false){
16295 var layer = new Ext.Layer({shadow:false, useDisplay:true, constrain:false}, el);
16299 return new Ext.Element(el);
16303 doAutoLoad : function(){
16305 typeof this.autoLoad == 'object' ?
16306 this.autoLoad : {url: this.autoLoad});
16311 Ext.reg('panel', Ext.Panel);
16314 Ext.Window = Ext.extend(Ext.Panel, {
16322 baseCls : 'x-window',
16332 constrainHeader:false,
16336 minimizable : false,
16338 maximizable : false,
16344 expandOnShow: true,
16346 closeAction: 'close',
16352 monitorResize : true,
16355 elements: 'header,body',
16361 initComponent : function(){
16362 Ext.Window.superclass.initComponent.call(this);
16377 getState : function(){
16378 return Ext.apply(Ext.Window.superclass.getState.call(this) || {}, this.getBox());
16381 onRender : function(ct, position){
16382 Ext.Window.superclass.onRender.call(this, ct, position);
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: " "});
16391 this.focusEl.swallowEvent('click', true);
16393 this.proxy = this.el.createProxy("x-window-proxy");
16394 this.proxy.enableDisplayMode('block');
16397 this.mask = this.container.createChild({cls:"ext-el-mask"}, this.el.dom);
16398 this.mask.enableDisplayMode("block");
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",
16415 resizeElement : this.resizerAction
16417 this.resizer.window = this;
16418 this.resizer.on("beforeresize", this.beforeResize, this);
16421 if(this.draggable){
16422 this.header.addClass("x-window-draggable");
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;
16435 var km = this.getKeyMap();
16436 km.on(27, this.onEsc, this);
16441 initDraggable : function(){
16442 this.dd = new Ext.Window.DD(this);
16445 onEsc : function(){
16446 this[this.closeAction]();
16449 beforeDestroy : function(){
16456 Ext.Window.superclass.beforeDestroy.call(this);
16459 onDestroy : function(){
16461 this.manager.unregister(this);
16463 Ext.Window.superclass.onDestroy.call(this);
16466 initTools : function(){
16467 if(this.minimizable){
16470 handler: this.minimize.createDelegate(this, [])
16473 if(this.maximizable){
16476 handler: this.maximize.createDelegate(this, [])
16480 handler: this.restore.createDelegate(this, []),
16483 this.header.on('dblclick', this.toggleMaximize, this);
16488 handler: this[this.closeAction].createDelegate(this, [])
16493 resizerAction : function(){
16494 var box = this.proxy.getBox();
16496 this.window.handleResize(box);
16500 beforeResize : function(){
16501 this.resizer.minHeight = Math.max(this.minHeight, this.getFrameHeight() + 40); this.resizer.minWidth = Math.max(this.minWidth, this.getFrameWidth() + 40);
16502 this.resizeBox = this.el.getBox();
16505 updateHandles : function(){
16506 if(Ext.isIE && this.resizer){
16507 this.resizer.syncHandleHeight();
16512 handleResize : function(box){
16513 var rz = this.resizeBox;
16514 if(rz.x != box.x || rz.y != box.y){
16515 this.updateBox(box);
16520 this.updateHandles();
16522 this.fireEvent("resize", this, box.width, box.height);
16526 focus : function(){
16527 var f = this.focusEl, db = this.defaultButton, t = typeof db;
16528 if(t != 'undefined'){
16530 f = this.buttons[db];
16531 }else if(t == 'string'){
16532 f = Ext.getCmp(db);
16537 f.focus.defer(10, f);
16541 setAnimateTarget : function(el){
16543 this.animateTarget = el;
16546 beforeShow : function(){
16547 delete this.el.lastXY;
16548 delete this.el.lastLT;
16549 if(this.x === undefined || this.y === undefined){
16550 var xy = this.el.getAlignToXY(this.container, 'c-c');
16551 var pos = this.el.translatePoints(xy[0], xy[1]);
16552 this.x = this.x === undefined? pos.left : this.x;
16553 this.y = this.y === undefined? pos.top : this.y;
16555 this.el.setLeftTop(this.x, this.y);
16557 if(this.expandOnShow){
16558 this.expand(false);
16562 Ext.getBody().addClass("x-body-masked");
16563 this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
16569 show : function(animateTarget, cb, scope){
16570 if(!this.rendered){
16571 this.render(Ext.getBody());
16573 if(this.hidden === false){
16577 if(this.fireEvent("beforeshow", this) === false){
16581 this.on('show', cb, scope, {single:true});
16583 this.hidden = false;
16584 if(animateTarget !== undefined){
16585 this.setAnimateTarget(animateTarget);
16588 if(this.animateTarget){
16595 afterShow : function(){
16597 this.el.setStyle('display', 'block');
16599 if(this.maximized){
16600 this.fitContainer();
16602 if(Ext.isMac && Ext.isGecko){ this.cascade(this.setAutoScroll);
16605 if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
16606 Ext.EventManager.onWindowResize(this.onWindowResize, this);
16608 this.doConstrain();
16613 this.keyMap.enable();
16616 this.updateHandles();
16617 this.fireEvent("show", this);
16620 animShow : function(){
16622 this.proxy.setBox(this.animateTarget.getBox());
16623 this.proxy.setOpacity(0);
16624 var b = this.getBox(false);
16625 b.callback = this.afterShow;
16628 b.easing = 'easeNone';
16631 this.el.setStyle('display', 'none');
16632 this.proxy.shift(b);
16636 hide : function(animateTarget, cb, scope){
16637 if(this.hidden || this.fireEvent("beforehide", this) === false){
16641 this.on('hide', cb, scope, {single:true});
16643 this.hidden = true;
16644 if(animateTarget !== undefined){
16645 this.setAnimateTarget(animateTarget);
16647 if(this.animateTarget){
16655 afterHide : function(){
16657 if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
16658 Ext.EventManager.removeResizeListener(this.onWindowResize, this);
16662 Ext.getBody().removeClass("x-body-masked");
16665 this.keyMap.disable();
16667 this.fireEvent("hide", this);
16670 animHide : function(){
16671 this.proxy.setOpacity(.5);
16673 var tb = this.getBox(false);
16674 this.proxy.setBox(tb);
16676 var b = this.animateTarget.getBox();
16677 b.callback = this.afterHide;
16680 b.easing = 'easeNone';
16683 this.proxy.shift(b);
16686 onWindowResize : function(){
16687 if(this.maximized){
16688 this.fitContainer();
16691 this.mask.setSize('100%', '100%');
16692 var force = this.mask.dom.offsetHeight;
16693 this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
16695 this.doConstrain();
16698 doConstrain : function(){
16699 if(this.constrain || this.constrainHeader){
16701 if(this.constrain){
16703 right:this.el.shadowOffset,
16704 left:this.el.shadowOffset,
16705 bottom:this.el.shadowOffset
16708 var s = this.getSize();
16710 right:-(s.width - 100),
16711 bottom:-(s.height - 25)
16715 var xy = this.el.getConstrainToXY(this.container, true, offsets);
16717 this.setPosition(xy[0], xy[1]);
16722 ghost : function(cls){
16723 var ghost = this.createGhost(cls);
16724 var box = this.getBox(true);
16725 ghost.setLeftTop(box.x, box.y);
16726 ghost.setWidth(box.width);
16728 this.activeGhost = ghost;
16732 unghost : function(show, matchPosition){
16733 if(show !== false){
16736 if(Ext.isMac && Ext.isGecko){ this.cascade(this.setAutoScroll);
16739 if(matchPosition !== false){
16740 this.setPosition(this.activeGhost.getLeft(true), this.activeGhost.getTop(true));
16742 this.activeGhost.hide();
16743 this.activeGhost.remove();
16744 delete this.activeGhost;
16748 minimize : function(){
16749 this.fireEvent('minimize', this);
16753 close : function(){
16754 if(this.fireEvent("beforeclose", this) !== false){
16755 this.hide(null, function(){
16756 this.fireEvent('close', this);
16763 maximize : function(){
16764 if(!this.maximized){
16765 this.expand(false);
16766 this.restoreSize = this.getSize();
16767 this.restorePos = this.getPosition(true);
16768 this.tools.maximize.hide();
16769 this.tools.restore.show();
16770 this.maximized = true;
16771 this.el.disableShadow();
16776 if(this.collapsible){
16777 this.tools.toggle.hide();
16779 this.el.addClass('x-window-maximized');
16780 this.container.addClass('x-window-maximized-ct');
16782 this.setPosition(0, 0);
16783 this.fitContainer();
16784 this.fireEvent('maximize', this);
16789 restore : function(){
16790 if(this.maximized){
16791 this.el.removeClass('x-window-maximized');
16792 this.tools.restore.hide();
16793 this.tools.maximize.show();
16794 this.setPosition(this.restorePos[0], this.restorePos[1]);
16795 this.setSize(this.restoreSize.width, this.restoreSize.height);
16796 delete this.restorePos;
16797 delete this.restoreSize;
16798 this.maximized = false;
16799 this.el.enableShadow(true);
16804 if(this.collapsible){
16805 this.tools.toggle.show();
16807 this.container.removeClass('x-window-maximized-ct');
16809 this.doConstrain();
16810 this.fireEvent('restore', this);
16815 toggleMaximize : function(){
16816 this[this.maximized ? 'restore' : 'maximize']();
16819 fitContainer : function(){
16820 var vs = this.container.getViewSize();
16821 this.setSize(vs.width, vs.height);
16824 setZIndex : function(index){
16826 this.mask.setStyle("z-index", index);
16828 this.el.setZIndex(++index);
16832 this.resizer.proxy.setStyle("z-index", ++index);
16835 this.lastZIndex = index;
16839 alignTo : function(element, position, offsets){
16840 var xy = this.el.getAlignToXY(element, position, offsets);
16841 this.setPagePosition(xy[0], xy[1]);
16846 anchorTo : function(el, alignment, offsets, monitorScroll, _pname){
16847 var action = function(){
16848 this.alignTo(el, alignment, offsets);
16850 Ext.EventManager.onWindowResize(action, this);
16851 var tm = typeof monitorScroll;
16852 if(tm != 'undefined'){
16853 Ext.EventManager.on(window, 'scroll', action, this,
16854 {buffer: tm == 'number' ? monitorScroll : 50});
16857 this[_pname] = action;
16862 toFront : function(){
16863 if(this.manager.bringToFront(this)){
16870 setActive : function(active){
16872 if(!this.maximized){
16873 this.el.enableShadow(true);
16875 this.fireEvent('activate', this);
16877 this.el.disableShadow();
16878 this.fireEvent('deactivate', this);
16883 toBack : function(){
16884 this.manager.sendToBack(this);
16889 center : function(){
16890 var xy = this.el.getAlignToXY(this.container, 'c-c');
16891 this.setPagePosition(xy[0], xy[1]);
16895 Ext.reg('window', Ext.Window);
16897 Ext.Window.DD = function(win){
16899 Ext.Window.DD.superclass.constructor.call(this, win.el.id, 'WindowDD-'+win.id);
16900 this.setHandleElId(win.header.id);
16901 this.scroll = false;
16904 Ext.extend(Ext.Window.DD, Ext.dd.DD, {
16906 headerOffsets:[100, 25],
16907 startDrag : function(){
16909 this.proxy = w.ghost();
16910 if(w.constrain !== false){
16911 var so = w.el.shadowOffset;
16912 this.constrainTo(w.container, {right: so, left: so, bottom: so});
16913 }else if(w.constrainHeader !== false){
16914 var s = this.proxy.getSize();
16915 this.constrainTo(w.container, {right: -(s.width-this.headerOffsets[0]), bottom: -(s.height-this.headerOffsets[1])});
16918 b4Drag : Ext.emptyFn,
16920 onDrag : function(e){
16921 this.alignElWithMouse(this.proxy, e.getPageX(), e.getPageY());
16924 endDrag : function(e){
16925 this.win.unghost();
16926 this.win.saveState();
16930 Ext.WindowGroup = function(){
16932 var accessList = [];
16935 var sortWindows = function(d1, d2){
16936 return (!d1._lastAccess || d1._lastAccess < d2._lastAccess) ? -1 : 1;
16939 var orderWindows = function(){
16940 var a = accessList, len = a.length;
16942 a.sort(sortWindows);
16943 var seed = a[0].manager.zseed;
16944 for(var i = 0; i < len; i++){
16946 if(win && !win.hidden){
16947 win.setZIndex(seed + (i*10));
16954 var setActiveWin = function(win){
16957 front.setActive(false);
16961 win.setActive(true);
16966 var activateLast = function(){
16967 for(var i = accessList.length-1; i >=0; --i) {
16968 if(!accessList[i].hidden){
16969 setActiveWin(accessList[i]);
16973 setActiveWin(null);
16980 register : function(win){
16981 list[win.id] = win;
16982 accessList.push(win);
16983 win.on('hide', activateLast);
16986 unregister : function(win){
16987 delete list[win.id];
16988 win.un('hide', activateLast);
16989 accessList.remove(win);
16993 get : function(id){
16994 return typeof id == "object" ? id : list[id];
16998 bringToFront : function(win){
16999 win = this.get(win);
17001 win._lastAccess = new Date().getTime();
17009 sendToBack : function(win){
17010 win = this.get(win);
17011 win._lastAccess = -(new Date().getTime());
17017 hideAll : function(){
17018 for(var id in list){
17019 if(list[id] && typeof list[id] != "function" && list[id].isVisible()){
17026 getActive : function(){
17031 getBy : function(fn, scope){
17033 for(var i = accessList.length-1; i >=0; --i) {
17034 var win = accessList[i];
17035 if(fn.call(scope||win, win) !== false){
17043 each : function(fn, scope){
17044 for(var id in list){
17045 if(list[id] && typeof list[id] != "function"){
17046 if(fn.call(scope || list[id], list[id]) === false){
17057 Ext.WindowMgr = new Ext.WindowGroup();
17059 Ext.dd.PanelProxy = function(panel, config){
\r
17060 this.panel = panel;
\r
17061 this.id = this.panel.id +'-ddproxy';
\r
17062 Ext.apply(this, config);
\r
17065 Ext.dd.PanelProxy.prototype = {
\r
17067 insertProxy : true,
\r
17070 setStatus : Ext.emptyFn,
\r
17071 reset : Ext.emptyFn,
\r
17072 update : Ext.emptyFn,
\r
17073 stop : Ext.emptyFn,
\r
17074 sync: Ext.emptyFn,
\r
17077 getEl : function(){
\r
17078 return this.ghost;
\r
17082 getGhost : function(){
\r
17083 return this.ghost;
\r
17087 getProxy : function(){
\r
17088 return this.proxy;
\r
17092 hide : function(){
\r
17095 this.proxy.remove();
\r
17096 delete this.proxy;
\r
17098 this.panel.el.dom.style.display = '';
\r
17099 this.ghost.remove();
\r
17100 delete this.ghost;
\r
17105 show : function(){
\r
17107 this.ghost = this.panel.createGhost(undefined, undefined, Ext.getBody());
\r
17108 this.ghost.setXY(this.panel.el.getXY())
\r
17109 if(this.insertProxy){
\r
17110 this.proxy = this.panel.el.insertSibling({cls:'x-panel-dd-spacer'});
\r
17111 this.proxy.setSize(this.panel.getSize());
\r
17113 this.panel.el.dom.style.display = 'none';
\r
17118 repair : function(xy, callback, scope){
\r
17120 if(typeof callback == "function"){
\r
17121 callback.call(scope || this);
\r
17126 moveProxy : function(parentNode, before){
\r
17128 parentNode.insertBefore(this.proxy.dom, before);
\r
17134 Ext.Panel.DD = function(panel, cfg){
\r
17135 this.panel = panel;
\r
17136 this.dragData = {panel: panel};
\r
17137 this.proxy = new Ext.dd.PanelProxy(panel, cfg);
\r
17138 Ext.Panel.DD.superclass.constructor.call(this, panel.el, cfg);
\r
17139 this.setHandleElId(panel.header.id);
\r
17140 panel.header.setStyle('cursor', 'move');
\r
17141 this.scroll = false;
\r
17144 Ext.extend(Ext.Panel.DD, Ext.dd.DragSource, {
\r
17145 showFrame: Ext.emptyFn,
\r
17146 startDrag: Ext.emptyFn,
\r
17147 b4StartDrag: function(x, y) {
\r
17148 this.proxy.show();
\r
17150 b4MouseDown: function(e) {
\r
17151 var x = e.getPageX();
\r
17152 var y = e.getPageY();
\r
17153 this.autoOffset(x, y);
\r
17155 onInitDrag : function(x, y){
\r
17156 this.onStartDrag(x, y);
\r
17159 createFrame : Ext.emptyFn,
\r
17160 getDragEl : function(e){
\r
17161 return this.proxy.ghost.dom;
\r
17163 endDrag : function(e){
\r
17164 this.proxy.hide();
\r
17165 this.panel.saveState();
\r
17168 autoOffset : function(x, y) {
\r
17169 x -= this.startPageX;
\r
17170 y -= this.startPageY;
\r
17171 this.setDelta(x, y);
\r
17175 Ext.state.Provider = function(){
\r
17177 this.addEvents("statechange");
\r
17179 Ext.state.Provider.superclass.constructor.call(this);
\r
17181 Ext.extend(Ext.state.Provider, Ext.util.Observable, {
\r
17183 get : function(name, defaultValue){
\r
17184 return typeof this.state[name] == "undefined" ?
\r
17185 defaultValue : this.state[name];
\r
17189 clear : function(name){
\r
17190 delete this.state[name];
\r
17191 this.fireEvent("statechange", this, name, null);
\r
17195 set : function(name, value){
\r
17196 this.state[name] = value;
\r
17198 this.fireEvent("statechange", this, name, value);
\r
17202 decodeValue : function(cookie){
\r
17203 var re = /^(a|n|d|b|s|o)\:(.*)$/;
\r
17204 var matches = re.exec(unescape(cookie));
\r
17205 if(!matches || !matches[1]) return;
17206 var type = matches[1];
\r
17207 var v = matches[2];
\r
17210 return parseFloat(v);
\r
17212 return new Date(Date.parse(v));
\r
17214 return (v == "1");
\r
17217 var values = v.split("^");
\r
17218 for(var i = 0, len = values.length; i < len; i++){
\r
17219 all.push(this.decodeValue(values[i]));
\r
17224 var values = v.split("^");
\r
17225 for(var i = 0, len = values.length; i < len; i++){
\r
17226 var kv = values[i].split("=");
\r
17227 all[kv[0]] = this.decodeValue(kv[1]);
\r
17236 encodeValue : function(v){
\r
17238 if(typeof v == "number"){
\r
17240 }else if(typeof v == "boolean"){
\r
17241 enc = "b:" + (v ? "1" : "0");
\r
17242 }else if(Ext.isDate(v)){
\r
17243 enc = "d:" + v.toGMTString();
\r
17244 }else if(Ext.isArray(v)){
\r
17246 for(var i = 0, len = v.length; i < len; i++){
\r
17247 flat += this.encodeValue(v[i]);
\r
17248 if(i != len-1) flat += "^";
\r
17250 enc = "a:" + flat;
\r
17251 }else if(typeof v == "object"){
\r
17253 for(var key in v){
\r
17254 if(typeof v[key] != "function" && v[key] !== undefined){
\r
17255 flat += key + "=" + this.encodeValue(v[key]) + "^";
\r
17258 enc = "o:" + flat.substring(0, flat.length-1);
\r
17262 return escape(enc);
\r
17267 Ext.state.Manager = function(){
\r
17268 var provider = new Ext.state.Provider();
\r
17272 setProvider : function(stateProvider){
\r
17273 provider = stateProvider;
\r
17277 get : function(key, defaultValue){
\r
17278 return provider.get(key, defaultValue);
\r
17282 set : function(key, value){
\r
17283 provider.set(key, value);
\r
17287 clear : function(key){
\r
17288 provider.clear(key);
\r
17292 getProvider : function(){
\r
17299 Ext.state.CookieProvider = function(config){
\r
17300 Ext.state.CookieProvider.superclass.constructor.call(this);
\r
17302 this.expires = new Date(new Date().getTime()+(1000*60*60*24*7));
17303 this.domain = null;
\r
17304 this.secure = false;
\r
17305 Ext.apply(this, config);
\r
17306 this.state = this.readCookies();
\r
17309 Ext.extend(Ext.state.CookieProvider, Ext.state.Provider, {
\r
17311 set : function(name, value){
\r
17312 if(typeof value == "undefined" || value === null){
\r
17313 this.clear(name);
\r
17316 this.setCookie(name, value);
\r
17317 Ext.state.CookieProvider.superclass.set.call(this, name, value);
\r
17321 clear : function(name){
\r
17322 this.clearCookie(name);
\r
17323 Ext.state.CookieProvider.superclass.clear.call(this, name);
\r
17327 readCookies : function(){
\r
17328 var cookies = {};
\r
17329 var c = document.cookie + ";";
\r
17330 var re = /\s?(.*?)=(.*?);/g;
\r
17332 while((matches = re.exec(c)) != null){
\r
17333 var name = matches[1];
\r
17334 var value = matches[2];
\r
17335 if(name && name.substring(0,3) == "ys-"){
\r
17336 cookies[name.substr(3)] = this.decodeValue(value);
\r
17343 setCookie : function(name, value){
\r
17344 document.cookie = "ys-"+ name + "=" + this.encodeValue(value) +
\r
17345 ((this.expires == null) ? "" : ("; expires=" + this.expires.toGMTString())) +
\r
17346 ((this.path == null) ? "" : ("; path=" + this.path)) +
\r
17347 ((this.domain == null) ? "" : ("; domain=" + this.domain)) +
\r
17348 ((this.secure == true) ? "; secure" : "");
\r
17352 clearCookie : function(name){
\r
17353 document.cookie = "ys-" + name + "=null; expires=Thu, 01-Jan-70 00:00:01 GMT" +
\r
17354 ((this.path == null) ? "" : ("; path=" + this.path)) +
\r
17355 ((this.domain == null) ? "" : ("; domain=" + this.domain)) +
\r
17356 ((this.secure == true) ? "; secure" : "");
\r
17360 Ext.DataView = Ext.extend(Ext.BoxComponent, {
\r
17370 selectedClass : "x-view-selected",
\r
17378 initComponent : function(){
\r
17379 Ext.DataView.superclass.initComponent.call(this);
\r
17380 if(typeof this.tpl == "string"){
\r
17381 this.tpl = new Ext.XTemplate(this.tpl);
\r
17390 "containerclick",
\r
17396 "selectionchange",
\r
17402 this.all = new Ext.CompositeElementLite();
\r
17403 this.selected = new Ext.CompositeElementLite();
\r
17407 onRender : function(){
\r
17409 this.el = document.createElement('div');
\r
17411 Ext.DataView.superclass.onRender.apply(this, arguments);
\r
17415 afterRender : function(){
\r
17416 Ext.DataView.superclass.afterRender.call(this);
\r
17419 "click": this.onClick,
\r
17420 "dblclick": this.onDblClick,
\r
17421 "contextmenu": this.onContextMenu,
\r
17425 if(this.overClass){
\r
17427 "mouseover": this.onMouseOver,
\r
17428 "mouseout": this.onMouseOut,
\r
17434 this.setStore(this.store, true);
\r
17439 refresh : function(){
\r
17440 this.clearSelections(false, true);
\r
17441 this.el.update("");
\r
17443 var records = this.store.getRange();
\r
17444 if(records.length < 1){
\r
17445 this.el.update(this.emptyText);
\r
17446 this.all.clear();
\r
17449 this.tpl.overwrite(this.el, this.collectData(records, 0));
\r
17450 this.all.fill(Ext.query(this.itemSelector, this.el.dom));
\r
17451 this.updateIndexes(0);
\r
17455 prepareData : function(data){
\r
17460 collectData : function(records, startIndex){
\r
17462 for(var i = 0, len = records.length; i < len; i++){
\r
17463 r[r.length] = this.prepareData(records[i].data, startIndex+i, records[i]);
\r
17469 bufferRender : function(records){
\r
17470 var div = document.createElement('div');
\r
17471 this.tpl.overwrite(div, this.collectData(records));
\r
17472 return Ext.query(this.itemSelector, div);
\r
17476 onUpdate : function(ds, record){
\r
17477 var index = this.store.indexOf(record);
\r
17478 var sel = this.isSelected(index);
\r
17479 var original = this.all.elements[index];
\r
17480 var node = this.bufferRender([record], index)[0];
\r
17482 this.all.replaceElement(index, node, true);
\r
17484 this.selected.replaceElement(original, node);
\r
17485 this.all.item(index).addClass(this.selectedClass);
\r
17487 this.updateIndexes(index, index);
\r
17491 onAdd : function(ds, records, index){
\r
17492 if(this.all.getCount() == 0){
\r
17496 var nodes = this.bufferRender(records, index), n;
\r
17497 if(index < this.all.getCount()){
\r
17498 n = this.all.item(index).insertSibling(nodes, 'before', true);
\r
17499 this.all.elements.splice(index, 0, n);
\r
17501 n = this.all.last().insertSibling(nodes, 'after', true);
\r
17502 this.all.elements.push(n);
\r
17504 this.updateIndexes(index);
\r
17508 onRemove : function(ds, record, index){
\r
17509 this.deselect(index);
\r
17510 this.all.removeElement(index, true);
\r
17511 this.updateIndexes(index);
\r
17515 refreshNode : function(index){
\r
17516 this.onUpdate(this.store, this.store.getAt(index));
\r
17520 updateIndexes : function(startIndex, endIndex){
\r
17521 var ns = this.all.elements;
\r
17522 startIndex = startIndex || 0;
\r
17523 endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length - 1));
\r
17524 for(var i = startIndex; i <= endIndex; i++){
\r
17525 ns[i].viewIndex = i;
\r
17530 setStore : function(store, initial){
\r
17531 if(!initial && this.store){
\r
17532 this.store.un("beforeload", this.onBeforeLoad, this);
\r
17533 this.store.un("datachanged", this.refresh, this);
\r
17534 this.store.un("add", this.onAdd, this);
\r
17535 this.store.un("remove", this.onRemove, this);
\r
17536 this.store.un("update", this.onUpdate, this);
\r
17537 this.store.un("clear", this.refresh, this);
\r
17540 store = Ext.StoreMgr.lookup(store);
\r
17541 store.on("beforeload", this.onBeforeLoad, this);
\r
17542 store.on("datachanged", this.refresh, this);
\r
17543 store.on("add", this.onAdd, this);
\r
17544 store.on("remove", this.onRemove, this);
\r
17545 store.on("update", this.onUpdate, this);
\r
17546 store.on("clear", this.refresh, this);
\r
17548 this.store = store;
\r
17555 findItemFromChild : function(node){
\r
17556 return Ext.fly(node).findParent(this.itemSelector, this.el);
\r
17560 onClick : function(e){
\r
17561 var item = e.getTarget(this.itemSelector, this.el);
\r
17563 var index = this.indexOf(item);
\r
17564 if(this.onItemClick(item, index, e) !== false){
\r
17565 this.fireEvent("click", this, index, item, e);
\r
17568 if(this.fireEvent("containerclick", this, e) !== false){
\r
17569 this.clearSelections();
\r
17575 onContextMenu : function(e){
\r
17576 var item = e.getTarget(this.itemSelector, this.el);
\r
17578 this.fireEvent("contextmenu", this, this.indexOf(item), item, e);
\r
17583 onDblClick : function(e){
\r
17584 var item = e.getTarget(this.itemSelector, this.el);
\r
17586 this.fireEvent("dblclick", this, this.indexOf(item), item, e);
\r
17591 onMouseOver : function(e){
\r
17592 var item = e.getTarget(this.itemSelector, this.el);
\r
17593 if(item && item !== this.lastItem){
\r
17594 this.lastItem = item;
\r
17595 Ext.fly(item).addClass(this.overClass);
\r
17600 onMouseOut : function(e){
\r
17601 if(this.lastItem){
\r
17602 if(!e.within(this.lastItem, true)){
\r
17603 Ext.fly(this.lastItem).removeClass(this.overClass);
\r
17604 delete this.lastItem;
\r
17610 onItemClick : function(item, index, e){
\r
17611 if(this.fireEvent("beforeclick", this, index, item, e) === false){
\r
17614 if(this.multiSelect){
\r
17615 this.doMultiSelection(item, index, e);
\r
17616 e.preventDefault();
\r
17617 }else if(this.singleSelect){
\r
17618 this.doSingleSelection(item, index, e);
\r
17619 e.preventDefault();
\r
17625 doSingleSelection : function(item, index, e){
\r
17626 if(e.ctrlKey && this.isSelected(index)){
\r
17627 this.deselect(index);
\r
17629 this.select(index, false);
\r
17634 doMultiSelection : function(item, index, e){
\r
17635 if(e.shiftKey && this.last !== false){
\r
17636 var last = this.last;
\r
17637 this.selectRange(last, index, e.ctrlKey);
\r
17640 if((e.ctrlKey||this.simpleSelect) && this.isSelected(index)){
\r
17641 this.deselect(index);
\r
17643 this.select(index, e.ctrlKey || e.shiftKey || this.simpleSelect);
\r
17649 getSelectionCount : function(){
\r
17650 return this.selected.getCount()
\r
17654 getSelectedNodes : function(){
\r
17655 return this.selected.elements;
\r
17659 getSelectedIndexes : function(){
\r
17660 var indexes = [], s = this.selected.elements;
\r
17661 for(var i = 0, len = s.length; i < len; i++){
\r
17662 indexes.push(s[i].viewIndex);
\r
17668 getSelectedRecords : function(){
\r
17669 var r = [], s = this.selected.elements;
\r
17670 for(var i = 0, len = s.length; i < len; i++){
\r
17671 r[r.length] = this.store.getAt(s[i].viewIndex);
\r
17677 getRecords : function(nodes){
\r
17678 var r = [], s = nodes;
\r
17679 for(var i = 0, len = s.length; i < len; i++){
\r
17680 r[r.length] = this.store.getAt(s[i].viewIndex);
\r
17686 getRecord : function(node){
\r
17687 return this.store.getAt(node.viewIndex);
\r
17691 clearSelections : function(suppressEvent, skipUpdate){
\r
17692 if(this.multiSelect || this.singleSelect){
\r
17694 this.selected.removeClass(this.selectedClass);
\r
17696 this.selected.clear();
\r
17697 this.last = false;
\r
17698 if(!suppressEvent){
\r
17699 this.fireEvent("selectionchange", this, this.selected.elements);
\r
17705 isSelected : function(node){
\r
17706 return this.selected.contains(this.getNode(node));
\r
17710 deselect : function(node){
\r
17711 if(this.isSelected(node)){
\r
17712 var node = this.getNode(node);
\r
17713 this.selected.removeElement(node);
\r
17714 if(this.last == node.viewIndex){
\r
17715 this.last = false;
\r
17717 Ext.fly(node).removeClass(this.selectedClass);
\r
17718 this.fireEvent("selectionchange", this, this.selected.elements);
\r
17723 select : function(nodeInfo, keepExisting, suppressEvent){
\r
17724 if(Ext.isArray(nodeInfo)){
\r
17725 if(!keepExisting){
\r
17726 this.clearSelections(true);
\r
17728 for(var i = 0, len = nodeInfo.length; i < len; i++){
\r
17729 this.select(nodeInfo[i], true, true);
\r
17732 var node = this.getNode(nodeInfo);
\r
17733 if(!keepExisting){
\r
17734 this.clearSelections(true);
\r
17736 if(node && !this.isSelected(node)){
\r
17737 if(this.fireEvent("beforeselect", this, node, this.selected.elements) !== false){
\r
17738 Ext.fly(node).addClass(this.selectedClass);
\r
17739 this.selected.add(node);
\r
17740 this.last = node.viewIndex;
\r
17741 if(!suppressEvent){
\r
17742 this.fireEvent("selectionchange", this, this.selected.elements);
\r
17750 selectRange : function(start, end, keepExisting){
\r
17751 if(!keepExisting){
\r
17752 this.clearSelections(true);
\r
17754 this.select(this.getNodes(start, end), true);
\r
17758 getNode : function(nodeInfo){
\r
17759 if(typeof nodeInfo == "string"){
\r
17760 return document.getElementById(nodeInfo);
\r
17761 }else if(typeof nodeInfo == "number"){
\r
17762 return this.all.elements[nodeInfo];
\r
17768 getNodes : function(start, end){
\r
17769 var ns = this.all.elements;
\r
17770 start = start || 0;
\r
17771 end = typeof end == "undefined" ? ns.length - 1 : end;
\r
17772 var nodes = [], i;
\r
17773 if(start <= end){
\r
17774 for(i = start; i <= end; i++){
\r
17775 nodes.push(ns[i]);
\r
17778 for(i = start; i >= end; i--){
\r
17779 nodes.push(ns[i]);
\r
17786 indexOf : function(node){
\r
17787 node = this.getNode(node);
\r
17788 if(typeof node.viewIndex == "number"){
\r
17789 return node.viewIndex;
\r
17791 return this.all.indexOf(node);
\r
17795 onBeforeLoad : function(){
\r
17796 if(this.loadingText){
\r
17797 this.clearSelections(false, true);
\r
17798 this.el.update('<div class="loading-indicator">'+this.loadingText+'</div>');
\r
17799 this.all.clear();
\r
17804 Ext.reg('dataview', Ext.DataView);
17806 Ext.ColorPalette = function(config){
17807 Ext.ColorPalette.superclass.constructor.call(this, config);
17814 this.on("select", this.handler, this.scope, true);
17817 Ext.extend(Ext.ColorPalette, Ext.Component, {
17819 itemCls : "x-color-palette",
17822 clickEvent:'click',
17823 ctype: "Ext.ColorPalette",
17826 allowReselect : false,
17830 "000000", "993300", "333300", "003300", "003366", "000080", "333399", "333333",
17831 "800000", "FF6600", "808000", "008000", "008080", "0000FF", "666699", "808080",
17832 "FF0000", "FF9900", "99CC00", "339966", "33CCCC", "3366FF", "800080", "969696",
17833 "FF00FF", "FFCC00", "FFFF00", "00FF00", "00FFFF", "00CCFF", "993366", "C0C0C0",
17834 "FF99CC", "FFCC99", "FFFF99", "CCFFCC", "CCFFFF", "99CCFF", "CC99FF", "FFFFFF"
17837 onRender : function(container, position){
17838 var t = this.tpl || new Ext.XTemplate(
17839 '<tpl for="."><a href="#" class="color-{.}" hidefocus="on"><em><span style="background:#{.}" unselectable="on"> </span></em></a></tpl>'
17841 var el = document.createElement("div");
17842 el.className = this.itemCls;
17843 t.overwrite(el, this.colors);
17844 container.dom.insertBefore(el, position);
17845 this.el = Ext.get(el);
17846 this.el.on(this.clickEvent, this.handleClick, this, {delegate: "a"});
17847 if(this.clickEvent != 'click'){
17848 this.el.on('click', Ext.emptyFn, this, {delegate: "a", preventDefault:true});
17852 afterRender : function(){
17853 Ext.ColorPalette.superclass.afterRender.call(this);
17855 var s = this.value;
17861 handleClick : function(e, t){
17862 e.preventDefault();
17863 if(!this.disabled){
17864 var c = t.className.match(/(?:^|\s)color-(.{6})(?:\s|$)/)[1];
17865 this.select(c.toUpperCase());
17870 select : function(color){
17871 color = color.replace("#", "");
17872 if(color != this.value || this.allowReselect){
17875 el.child("a.color-"+this.value).removeClass("x-color-palette-sel");
17877 el.child("a.color-"+color).addClass("x-color-palette-sel");
17878 this.value = color;
17879 this.fireEvent("select", this, color);
17885 Ext.reg('colorpalette', Ext.ColorPalette);
17887 Ext.DatePicker = Ext.extend(Ext.Component, {
\r
17889 todayText : "Today",
\r
17891 okText : " OK ",
17893 cancelText : "Cancel",
\r
17895 todayTip : "{0} (Spacebar)",
\r
17901 minText : "This date is before the minimum date",
\r
17903 maxText : "This date is after the maximum date",
\r
17905 format : "m/d/y",
\r
17907 disabledDays : null,
\r
17909 disabledDaysText : "",
\r
17911 disabledDatesRE : null,
\r
17913 disabledDatesText : "",
\r
17915 constrainToViewport : true,
\r
17917 monthNames : Date.monthNames,
\r
17919 dayNames : Date.dayNames,
\r
17921 nextText: 'Next Month (Control+Right)',
\r
17923 prevText: 'Previous Month (Control+Left)',
\r
17925 monthYearText: 'Choose a month (Control+Up/Down to move years)',
\r
17929 initComponent : function(){
\r
17930 Ext.DatePicker.superclass.initComponent.call(this);
\r
17932 this.value = this.value ?
\r
17933 this.value.clearTime() : new Date().clearTime();
\r
17940 if(this.handler){
\r
17941 this.on("select", this.handler, this.scope || this);
\r
17944 this.initDisabledDays();
\r
17948 initDisabledDays : function(){
\r
17949 if(!this.disabledDatesRE && this.disabledDates){
\r
17950 var dd = this.disabledDates;
\r
17952 for(var i = 0; i < dd.length; i++){
\r
17954 if(i != dd.length-1) re += "|";
\r
17956 this.disabledDatesRE = new RegExp(re + ")");
\r
17961 setValue : function(value){
\r
17962 var old = this.value;
\r
17963 this.value = value.clearTime(true);
\r
17965 this.update(this.value);
\r
17970 getValue : function(){
\r
17971 return this.value;
\r
17975 focus : function(){
\r
17977 this.update(this.activeDate);
\r
17982 onRender : function(container, position){
\r
17984 '<table cellspacing="0">',
\r
17985 '<tr><td class="x-date-left"><a href="#" title="', this.prevText ,'"> </a></td><td class="x-date-middle" align="center"></td><td class="x-date-right"><a href="#" title="', this.nextText ,'"> </a></td></tr>',
\r
17986 '<tr><td colspan="3"><table class="x-date-inner" cellspacing="0"><thead><tr>'];
\r
17987 var dn = this.dayNames;
\r
17988 for(var i = 0; i < 7; i++){
\r
17989 var d = this.startDay+i;
\r
17993 m.push("<th><span>", dn[d].substr(0,1), "</span></th>");
\r
17995 m[m.length] = "</tr></thead><tbody><tr>";
\r
17996 for(var i = 0; i < 42; i++) {
\r
17997 if(i % 7 == 0 && i != 0){
\r
17998 m[m.length] = "</tr><tr>";
\r
18000 m[m.length] = '<td><a href="#" hidefocus="on" class="x-date-date" tabIndex="1"><em><span></span></em></a></td>';
\r
18002 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>';
\r
18004 var el = document.createElement("div");
\r
18005 el.className = "x-date-picker";
\r
18006 el.innerHTML = m.join("");
\r
18008 container.dom.insertBefore(el, position);
\r
18010 this.el = Ext.get(el);
\r
18011 this.eventEl = Ext.get(el.firstChild);
\r
18013 new Ext.util.ClickRepeater(this.el.child("td.x-date-left a"), {
\r
18014 handler: this.showPrevMonth,
\r
18016 preventDefault:true,
\r
18020 new Ext.util.ClickRepeater(this.el.child("td.x-date-right a"), {
\r
18021 handler: this.showNextMonth,
\r
18023 preventDefault:true,
\r
18027 this.eventEl.on("mousewheel", this.handleMouseWheel, this);
\r
18029 this.monthPicker = this.el.down('div.x-date-mp');
\r
18030 this.monthPicker.enableDisplayMode('block');
\r
18032 var kn = new Ext.KeyNav(this.eventEl, {
\r
18033 "left" : function(e){
\r
18035 this.showPrevMonth() :
\r
18036 this.update(this.activeDate.add("d", -1));
\r
18039 "right" : function(e){
\r
18041 this.showNextMonth() :
\r
18042 this.update(this.activeDate.add("d", 1));
\r
18045 "up" : function(e){
\r
18047 this.showNextYear() :
\r
18048 this.update(this.activeDate.add("d", -7));
\r
18051 "down" : function(e){
\r
18053 this.showPrevYear() :
\r
18054 this.update(this.activeDate.add("d", 7));
\r
18057 "pageUp" : function(e){
\r
18058 this.showNextMonth();
\r
18061 "pageDown" : function(e){
\r
18062 this.showPrevMonth();
\r
18065 "enter" : function(e){
\r
18066 e.stopPropagation();
\r
18073 this.eventEl.on("click", this.handleDateClick, this, {delegate: "a.x-date-date"});
\r
18075 this.eventEl.addKeyListener(Ext.EventObject.SPACE, this.selectToday, this);
\r
18077 this.el.unselectable();
\r
18079 this.cells = this.el.select("table.x-date-inner tbody td");
\r
18080 this.textNodes = this.el.query("table.x-date-inner tbody span");
\r
18082 this.mbtn = new Ext.Button({
\r
18084 tooltip: this.monthYearText,
\r
18085 renderTo: this.el.child("td.x-date-middle", true)
\r
18088 this.mbtn.on('click', this.showMonthPicker, this);
\r
18089 this.mbtn.el.child(this.mbtn.menuClassTarget).addClass("x-btn-with-menu");
\r
18092 var today = (new Date()).dateFormat(this.format);
\r
18093 this.todayBtn = new Ext.Button({
\r
18094 renderTo: this.el.child("td.x-date-bottom", true),
\r
18095 text: String.format(this.todayText, today),
\r
18096 tooltip: String.format(this.todayTip, today),
\r
18097 handler: this.selectToday,
\r
18102 this.el.repaint();
\r
18104 this.update(this.value);
\r
18107 createMonthPicker : function(){
\r
18108 if(!this.monthPicker.dom.firstChild){
\r
18109 var buf = ['<table border="0" cellspacing="0">'];
\r
18110 for(var i = 0; i < 6; i++){
\r
18112 '<tr><td class="x-date-mp-month"><a href="#">', this.monthNames[i].substr(0, 3), '</a></td>',
\r
18113 '<td class="x-date-mp-month x-date-mp-sep"><a href="#">', this.monthNames[i+6].substr(0, 3), '</a></td>',
\r
18115 '<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>' :
\r
18116 '<td class="x-date-mp-year"><a href="#"></a></td><td class="x-date-mp-year"><a href="#"></a></td></tr>'
\r
18120 '<tr class="x-date-mp-btns"><td colspan="4"><button type="button" class="x-date-mp-ok">',
\r
18122 '</button><button type="button" class="x-date-mp-cancel">',
\r
18124 '</button></td></tr>',
\r
18127 this.monthPicker.update(buf.join(''));
\r
18128 this.monthPicker.on('click', this.onMonthClick, this);
\r
18129 this.monthPicker.on('dblclick', this.onMonthDblClick, this);
\r
18131 this.mpMonths = this.monthPicker.select('td.x-date-mp-month');
\r
18132 this.mpYears = this.monthPicker.select('td.x-date-mp-year');
\r
18134 this.mpMonths.each(function(m, a, i){
\r
18137 m.dom.xmonth = 5 + Math.round(i * .5);
\r
18139 m.dom.xmonth = Math.round((i-1) * .5);
\r
18145 showMonthPicker : function(){
\r
18146 this.createMonthPicker();
\r
18147 var size = this.el.getSize();
\r
18148 this.monthPicker.setSize(size);
\r
18149 this.monthPicker.child('table').setSize(size);
\r
18151 this.mpSelMonth = (this.activeDate || this.value).getMonth();
\r
18152 this.updateMPMonth(this.mpSelMonth);
\r
18153 this.mpSelYear = (this.activeDate || this.value).getFullYear();
\r
18154 this.updateMPYear(this.mpSelYear);
\r
18156 this.monthPicker.slideIn('t', {duration:.2});
\r
18159 updateMPYear : function(y){
\r
18161 var ys = this.mpYears.elements;
\r
18162 for(var i = 1; i <= 10; i++){
\r
18163 var td = ys[i-1], y2;
\r
18165 y2 = y + Math.round(i * .5);
\r
18166 td.firstChild.innerHTML = y2;
\r
18169 y2 = y - (5-Math.round(i * .5));
\r
18170 td.firstChild.innerHTML = y2;
\r
18173 this.mpYears.item(i-1)[y2 == this.mpSelYear ? 'addClass' : 'removeClass']('x-date-mp-sel');
\r
18177 updateMPMonth : function(sm){
\r
18178 this.mpMonths.each(function(m, a, i){
\r
18179 m[m.dom.xmonth == sm ? 'addClass' : 'removeClass']('x-date-mp-sel');
\r
18183 selectMPMonth: function(m){
\r
18187 onMonthClick : function(e, t){
\r
18189 var el = new Ext.Element(t), pn;
\r
18190 if(el.is('button.x-date-mp-cancel')){
\r
18191 this.hideMonthPicker();
\r
18193 else if(el.is('button.x-date-mp-ok')){
\r
18194 this.update(new Date(this.mpSelYear, this.mpSelMonth, (this.activeDate || this.value).getDate()));
\r
18195 this.hideMonthPicker();
\r
18197 else if(pn = el.up('td.x-date-mp-month', 2)){
\r
18198 this.mpMonths.removeClass('x-date-mp-sel');
\r
18199 pn.addClass('x-date-mp-sel');
\r
18200 this.mpSelMonth = pn.dom.xmonth;
\r
18202 else if(pn = el.up('td.x-date-mp-year', 2)){
\r
18203 this.mpYears.removeClass('x-date-mp-sel');
\r
18204 pn.addClass('x-date-mp-sel');
\r
18205 this.mpSelYear = pn.dom.xyear;
\r
18207 else if(el.is('a.x-date-mp-prev')){
\r
18208 this.updateMPYear(this.mpyear-10);
\r
18210 else if(el.is('a.x-date-mp-next')){
\r
18211 this.updateMPYear(this.mpyear+10);
\r
18215 onMonthDblClick : function(e, t){
\r
18217 var el = new Ext.Element(t), pn;
\r
18218 if(pn = el.up('td.x-date-mp-month', 2)){
\r
18219 this.update(new Date(this.mpSelYear, pn.dom.xmonth, (this.activeDate || this.value).getDate()));
\r
18220 this.hideMonthPicker();
\r
18222 else if(pn = el.up('td.x-date-mp-year', 2)){
\r
18223 this.update(new Date(pn.dom.xyear, this.mpSelMonth, (this.activeDate || this.value).getDate()));
\r
18224 this.hideMonthPicker();
\r
18228 hideMonthPicker : function(disableAnim){
\r
18229 if(this.monthPicker){
\r
18230 if(disableAnim === true){
\r
18231 this.monthPicker.hide();
\r
18233 this.monthPicker.slideOut('t', {duration:.2});
\r
18239 showPrevMonth : function(e){
\r
18240 this.update(this.activeDate.add("mo", -1));
\r
18244 showNextMonth : function(e){
\r
18245 this.update(this.activeDate.add("mo", 1));
\r
18249 showPrevYear : function(){
\r
18250 this.update(this.activeDate.add("y", -1));
\r
18254 showNextYear : function(){
\r
18255 this.update(this.activeDate.add("y", 1));
\r
18259 handleMouseWheel : function(e){
\r
18260 var delta = e.getWheelDelta();
\r
18262 this.showPrevMonth();
\r
18264 } else if(delta < 0){
\r
18265 this.showNextMonth();
\r
18271 handleDateClick : function(e, t){
\r
18273 if(t.dateValue && !Ext.fly(t.parentNode).hasClass("x-date-disabled")){
\r
18274 this.setValue(new Date(t.dateValue));
\r
18275 this.fireEvent("select", this, this.value);
\r
18280 selectToday : function(){
\r
18281 this.setValue(new Date().clearTime());
\r
18282 this.fireEvent("select", this, this.value);
\r
18286 update : function(date){
\r
18287 var vd = this.activeDate;
\r
18288 this.activeDate = date;
\r
18289 if(vd && this.el){
\r
18290 var t = date.getTime();
\r
18291 if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){
\r
18292 this.cells.removeClass("x-date-selected");
\r
18293 this.cells.each(function(c){
\r
18294 if(c.dom.firstChild.dateValue == t){
\r
18295 c.addClass("x-date-selected");
\r
18296 setTimeout(function(){
\r
18297 try{c.dom.firstChild.focus();}catch(e){}
\r
18305 var days = date.getDaysInMonth();
\r
18306 var firstOfMonth = date.getFirstDateOfMonth();
\r
18307 var startingPos = firstOfMonth.getDay()-this.startDay;
\r
18309 if(startingPos <= this.startDay){
\r
18310 startingPos += 7;
\r
18313 var pm = date.add("mo", -1);
\r
18314 var prevStart = pm.getDaysInMonth()-startingPos;
\r
18316 var cells = this.cells.elements;
\r
18317 var textEls = this.textNodes;
\r
18318 days += startingPos;
\r
18321 var day = 86400000;
\r
18322 var d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart)).clearTime();
\r
18323 var today = new Date().clearTime().getTime();
\r
18324 var sel = date.clearTime().getTime();
\r
18325 var min = this.minDate ? this.minDate.clearTime() : Number.NEGATIVE_INFINITY;
\r
18326 var max = this.maxDate ? this.maxDate.clearTime() : Number.POSITIVE_INFINITY;
\r
18327 var ddMatch = this.disabledDatesRE;
\r
18328 var ddText = this.disabledDatesText;
\r
18329 var ddays = this.disabledDays ? this.disabledDays.join("") : false;
\r
18330 var ddaysText = this.disabledDaysText;
\r
18331 var format = this.format;
\r
18333 var setCellClass = function(cal, cell){
\r
18335 var t = d.getTime();
\r
18336 cell.firstChild.dateValue = t;
\r
18338 cell.className += " x-date-today";
\r
18339 cell.title = cal.todayText;
\r
18342 cell.className += " x-date-selected";
\r
18343 setTimeout(function(){
\r
18344 try{cell.firstChild.focus();}catch(e){}
\r
18349 cell.className = " x-date-disabled";
\r
18350 cell.title = cal.minText;
\r
18354 cell.className = " x-date-disabled";
\r
18355 cell.title = cal.maxText;
\r
18359 if(ddays.indexOf(d.getDay()) != -1){
\r
18360 cell.title = ddaysText;
\r
18361 cell.className = " x-date-disabled";
\r
18364 if(ddMatch && format){
\r
18365 var fvalue = d.dateFormat(format);
\r
18366 if(ddMatch.test(fvalue)){
\r
18367 cell.title = ddText.replace("%0", fvalue);
\r
18368 cell.className = " x-date-disabled";
\r
18374 for(; i < startingPos; i++) {
\r
18375 textEls[i].innerHTML = (++prevStart);
\r
18376 d.setDate(d.getDate()+1);
\r
18377 cells[i].className = "x-date-prevday";
\r
18378 setCellClass(this, cells[i]);
\r
18380 for(; i < days; i++){
\r
18381 intDay = i - startingPos + 1;
\r
18382 textEls[i].innerHTML = (intDay);
\r
18383 d.setDate(d.getDate()+1);
\r
18384 cells[i].className = "x-date-active";
\r
18385 setCellClass(this, cells[i]);
\r
18387 var extraDays = 0;
\r
18388 for(; i < 42; i++) {
\r
18389 textEls[i].innerHTML = (++extraDays);
\r
18390 d.setDate(d.getDate()+1);
\r
18391 cells[i].className = "x-date-nextday";
\r
18392 setCellClass(this, cells[i]);
\r
18395 this.mbtn.setText(this.monthNames[date.getMonth()] + " " + date.getFullYear());
\r
18397 if(!this.internalRender){
\r
18398 var main = this.el.dom.firstChild;
\r
18399 var w = main.offsetWidth;
\r
18400 this.el.setWidth(w + this.el.getBorderWidth("lr"));
\r
18401 Ext.fly(main).setWidth(w);
\r
18402 this.internalRender = true;
\r
18406 if(Ext.isOpera && !this.secondPass){
\r
18407 main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + "px";
\r
18408 this.secondPass = true;
\r
18409 this.update.defer(10, this, [date]);
\r
18415 beforeDestroy : function() {
\r
18416 this.mbtn.destroy();
\r
18417 this.todayBtn.destroy();
\r
18422 Ext.reg('datepicker', Ext.DatePicker);
18424 Ext.TabPanel = Ext.extend(Ext.Panel, {
18427 monitorResize : true,
18429 deferredRender : true,
18437 enableTabScroll: false,
18439 scrollIncrement : 0,
18441 scrollRepeatInterval : 400,
18443 scrollDuration : .35,
18447 tabPosition: 'top',
18449 baseCls: 'x-tab-panel',
18453 autoTabSelector:'div.x-tab',
18461 wheelIncrement : 20,
18464 idDelimiter : '__',
18466 itemCls : 'x-tab-item',
18469 headerAsText: false,
18473 initComponent : function(){
18474 this.frame = false;
18475 Ext.TabPanel.superclass.initComponent.call(this);
18484 this.setLayout(new Ext.layout.CardLayout({
18485 deferredRender: this.deferredRender
18487 if(this.tabPosition == 'top'){
18488 this.elements += ',header';
18489 this.stripTarget = 'header';
18491 this.elements += ',footer';
18492 this.stripTarget = 'footer';
18495 this.stack = Ext.TabPanel.AccessStack();
18500 render : function(){
18501 Ext.TabPanel.superclass.render.apply(this, arguments);
18502 if(this.activeTab !== undefined){
18503 var item = this.activeTab;
18504 delete this.activeTab;
18505 this.setActiveTab(item);
18509 onRender : function(ct, position){
18510 Ext.TabPanel.superclass.onRender.call(this, ct, position);
18513 var pos = this.tabPosition == 'top' ? 'header' : 'footer';
18514 this[pos].addClass('x-tab-panel-'+pos+'-plain');
18517 var st = this[this.stripTarget];
18519 this.stripWrap = st.createChild({cls:'x-tab-strip-wrap', cn:{
18520 tag:'ul', cls:'x-tab-strip x-tab-strip-'+this.tabPosition}});
18521 this.stripSpacer = st.createChild({cls:'x-tab-strip-spacer'});
18522 this.strip = new Ext.Element(this.stripWrap.dom.firstChild);
18524 this.edge = this.strip.createChild({tag:'li', cls:'x-tab-edge'});
18525 this.strip.createChild({cls:'x-clear'});
18527 this.body.addClass('x-tab-panel-body-'+this.tabPosition);
18530 var tt = new Ext.Template(
18531 '<li class="{cls}" id="{id}"><a class="x-tab-strip-close" onclick="return false;"></a>',
18532 '<a class="x-tab-right" href="#" onclick="return false;"><em class="x-tab-left">',
18533 '<span class="x-tab-strip-inner"><span class="x-tab-strip-text {iconCls}">{text}</span></span>',
18536 tt.disableFormats = true;
18538 Ext.TabPanel.prototype.itemTpl = tt;
18541 this.items.each(this.initTab, this);
18544 afterRender : function(){
18545 Ext.TabPanel.superclass.afterRender.call(this);
18547 this.readTabs(false);
18551 initEvents : function(){
18552 Ext.TabPanel.superclass.initEvents.call(this);
18553 this.on('add', this.onAdd, this);
18554 this.on('remove', this.onRemove, this);
18556 this.strip.on('mousedown', this.onStripMouseDown, this);
18557 this.strip.on('click', this.onStripClick, this);
18558 this.strip.on('contextmenu', this.onStripContextMenu, this);
18559 if(this.enableTabScroll){
18560 this.strip.on('mousewheel', this.onWheel, this);
18564 findTargets : function(e){
18566 var itemEl = e.getTarget('li', this.strip);
18568 item = this.getComponent(itemEl.id.split(this.idDelimiter)[1]);
18578 close : e.getTarget('.x-tab-strip-close', this.strip),
18584 onStripMouseDown : function(e){
18585 e.preventDefault();
18589 var t = this.findTargets(e);
18591 this.remove(t.item);
18594 if(t.item && t.item != this.activeTab){
18595 this.setActiveTab(t.item);
18599 onStripClick : function(e){
18600 var t = this.findTargets(e);
18601 if(!t.close && t.item && t.item != this.activeTab){
18602 this.setActiveTab(t.item);
18606 onStripContextMenu : function(e){
18607 e.preventDefault();
18608 var t = this.findTargets(e);
18610 this.fireEvent('contextmenu', this, t.item, e);
18615 readTabs : function(removeExisting){
18616 if(removeExisting === true){
18617 this.items.each(function(item){
18621 var tabs = this.el.query(this.autoTabSelector);
18622 for(var i = 0, len = tabs.length; i < len; i++){
18624 var title = tab.getAttribute('title');
18625 tab.removeAttribute('title');
18633 initTab : function(item, index){
18634 var before = this.strip.dom.childNodes[index];
18635 var cls = item.closable ? 'x-tab-strip-closable' : '';
18637 cls += ' x-item-disabled';
18640 cls += ' x-tab-with-icon';
18643 cls += ' ' + item.tabCls;
18647 id: this.id + this.idDelimiter + item.getItemId(),
18650 iconCls: item.iconCls || ''
18653 this.itemTpl.insertBefore(before, p) :
18654 this.itemTpl.append(this.strip, p);
18656 Ext.fly(el).addClassOnOver('x-tab-strip-over');
18659 Ext.fly(el).child('span.x-tab-strip-text', true).qtip = item.tabTip;
18661 item.on('disable', this.onItemDisabled, this);
18662 item.on('enable', this.onItemEnabled, this);
18663 item.on('titlechange', this.onItemTitleChanged, this);
18664 item.on('beforeshow', this.onBeforeShowItem, this);
18667 onAdd : function(tp, item, index){
18668 this.initTab(item, index);
18669 if(this.items.getCount() == 1){
18672 this.delegateUpdates();
18675 onBeforeAdd : function(item){
18676 var existing = item.events ? (this.items.containsKey(item.getItemId()) ? item : null) : this.items.get(item);
18678 this.setActiveTab(item);
18681 Ext.TabPanel.superclass.onBeforeAdd.apply(this, arguments);
18682 var es = item.elements;
18683 item.elements = es ? es.replace(',header', '') : es;
18684 item.border = (item.border === true);
18687 onRemove : function(tp, item){
18688 Ext.removeNode(this.getTabEl(item));
18689 this.stack.remove(item);
18690 if(item == this.activeTab){
18691 var next = this.stack.next();
18693 this.setActiveTab(next);
18695 this.setActiveTab(0);
18698 this.delegateUpdates();
18701 onBeforeShowItem : function(item){
18702 if(item != this.activeTab){
18703 this.setActiveTab(item);
18708 onItemDisabled : function(item){
18709 var el = this.getTabEl(item);
18711 Ext.fly(el).addClass('x-item-disabled');
18713 this.stack.remove(item);
18716 onItemEnabled : function(item){
18717 var el = this.getTabEl(item);
18719 Ext.fly(el).removeClass('x-item-disabled');
18723 onItemTitleChanged : function(item){
18724 var el = this.getTabEl(item);
18726 Ext.fly(el).child('span.x-tab-strip-text', true).innerHTML = item.title;
18731 getTabEl : function(item){
18732 var itemId = (typeof item === 'number')?this.items.items[item].getItemId() : item.getItemId();
18733 return document.getElementById(this.id+this.idDelimiter+itemId);
18736 onResize : function(){
18737 Ext.TabPanel.superclass.onResize.apply(this, arguments);
18738 this.delegateUpdates();
18742 beginUpdate : function(){
18743 this.suspendUpdates = true;
18747 endUpdate : function(){
18748 this.suspendUpdates = false;
18749 this.delegateUpdates();
18753 hideTabStripItem : function(item){
18754 item = this.getComponent(item);
18755 var el = this.getTabEl(item);
18757 el.style.display = 'none';
18758 this.delegateUpdates();
18763 unhideTabStripItem : function(item){
18764 item = this.getComponent(item);
18765 var el = this.getTabEl(item);
18767 el.style.display = '';
18768 this.delegateUpdates();
18772 delegateUpdates : function(){
18773 if(this.suspendUpdates){
18776 if(this.resizeTabs && this.rendered){
18777 this.autoSizeTabs();
18779 if(this.enableTabScroll && this.rendered){
18780 this.autoScrollTabs();
18784 autoSizeTabs : function(){
18785 var count = this.items.length;
18786 var ce = this.tabPosition != 'bottom' ? 'header' : 'footer';
18787 var ow = this[ce].dom.offsetWidth;
18788 var aw = this[ce].dom.clientWidth;
18790 if(!this.resizeTabs || count < 1 || !aw){ return;
18793 var each = Math.max(Math.min(Math.floor((aw-4) / count) - this.tabMargin, this.tabWidth), this.minTabWidth); this.lastTabWidth = each;
18794 var lis = this.stripWrap.dom.getElementsByTagName('li');
18795 for(var i = 0, len = lis.length-1; i < len; i++) { var li = lis[i];
18796 var inner = li.childNodes[1].firstChild.firstChild;
18797 var tw = li.offsetWidth;
18798 var iw = inner.offsetWidth;
18799 inner.style.width = (each - (tw-iw)) + 'px';
18803 adjustBodyWidth : function(w){
18805 this.header.setWidth(w);
18808 this.footer.setWidth(w);
18814 setActiveTab : function(item){
18815 item = this.getComponent(item);
18816 if(!item || this.fireEvent('beforetabchange', this, item, this.activeTab) === false){
18819 if(!this.rendered){
18820 this.activeTab = item;
18823 if(this.activeTab != item){
18824 if(this.activeTab){
18825 var oldEl = this.getTabEl(this.activeTab);
18827 Ext.fly(oldEl).removeClass('x-tab-strip-active');
18829 this.activeTab.fireEvent('deactivate', this.activeTab);
18831 var el = this.getTabEl(item);
18832 Ext.fly(el).addClass('x-tab-strip-active');
18833 this.activeTab = item;
18834 this.stack.add(item);
18836 this.layout.setActiveItem(item);
18837 if(this.layoutOnTabChange && item.doLayout){
18840 if(this.scrolling){
18841 this.scrollToTab(item, this.animScroll);
18844 item.fireEvent('activate', item);
18845 this.fireEvent('tabchange', this, item);
18850 getActiveTab : function(){
18851 return this.activeTab || null;
18855 getItem : function(item){
18856 return this.getComponent(item);
18859 autoScrollTabs : function(){
18860 var count = this.items.length;
18861 var ow = this.header.dom.offsetWidth;
18862 var tw = this.header.dom.clientWidth;
18864 var wrap = this.stripWrap;
18866 var cw = wd.offsetWidth;
18867 var pos = this.getScrollPos();
18868 var l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos;
18870 if(!this.enableTabScroll || count < 1 || cw < 20){ return;
18875 if(this.scrolling){
18876 this.scrolling = false;
18877 this.header.removeClass('x-tab-scrolling');
18878 this.scrollLeft.hide();
18879 this.scrollRight.hide();
18881 wd.style.marginLeft = '';
18882 wd.style.marginRight = '';
18886 if(!this.scrolling){
18887 this.header.addClass('x-tab-scrolling');
18889 wd.style.marginLeft = '18px';
18890 wd.style.marginRight = '18px';
18893 tw -= wrap.getMargins('lr');
18894 wrap.setWidth(tw > 20 ? tw : 20);
18895 if(!this.scrolling){
18896 if(!this.scrollLeft){
18897 this.createScrollers();
18899 this.scrollLeft.show();
18900 this.scrollRight.show();
18903 this.scrolling = true;
18904 if(pos > (l-tw)){ wd.scrollLeft = l-tw;
18905 }else{ this.scrollToTab(this.activeTab, false);
18907 this.updateScrollButtons();
18911 createScrollers : function(){
18912 var h = this.stripWrap.dom.offsetHeight;
18914 var sl = this.header.insertFirst({
18915 cls:'x-tab-scroller-left'
18918 sl.addClassOnOver('x-tab-scroller-left-over');
18919 this.leftRepeater = new Ext.util.ClickRepeater(sl, {
18920 interval : this.scrollRepeatInterval,
18921 handler: this.onScrollLeft,
18924 this.scrollLeft = sl;
18926 var sr = this.header.insertFirst({
18927 cls:'x-tab-scroller-right'
18930 sr.addClassOnOver('x-tab-scroller-right-over');
18931 this.rightRepeater = new Ext.util.ClickRepeater(sr, {
18932 interval : this.scrollRepeatInterval,
18933 handler: this.onScrollRight,
18936 this.scrollRight = sr;
18939 getScrollWidth : function(){
18940 return this.edge.getOffsetsTo(this.stripWrap)[0] + this.getScrollPos();
18943 getScrollPos : function(){
18944 return parseInt(this.stripWrap.dom.scrollLeft, 10) || 0;
18947 getScrollArea : function(){
18948 return parseInt(this.stripWrap.dom.clientWidth, 10) || 0;
18951 getScrollAnim : function(){
18952 return {duration:this.scrollDuration, callback: this.updateScrollButtons, scope: this};
18955 getScrollIncrement : function(){
18956 return this.scrollIncrement || (this.resizeTabs ? this.lastTabWidth+2 : 100);
18961 scrollToTab : function(item, animate){
18962 if(!item){ return; }
18963 var el = this.getTabEl(item);
18964 var pos = this.getScrollPos(), area = this.getScrollArea();
18965 var left = Ext.fly(el).getOffsetsTo(this.stripWrap)[0] + pos;
18966 var right = left + el.offsetWidth;
18968 this.scrollTo(left, animate);
18969 }else if(right > (pos + area)){
18970 this.scrollTo(right - area, animate);
18974 scrollTo : function(pos, animate){
18975 this.stripWrap.scrollTo('left', pos, animate ? this.getScrollAnim() : false);
18977 this.updateScrollButtons();
18981 onWheel : function(e){
18982 var d = e.getWheelDelta()*this.wheelIncrement*-1;
18985 var pos = this.getScrollPos();
18986 var newpos = pos + d;
18987 var sw = this.getScrollWidth()-this.getScrollArea();
18989 var s = Math.max(0, Math.min(sw, newpos));
18991 this.scrollTo(s, false);
18995 onScrollRight : function(){
18996 var sw = this.getScrollWidth()-this.getScrollArea();
18997 var pos = this.getScrollPos();
18998 var s = Math.min(sw, pos + this.getScrollIncrement());
19000 this.scrollTo(s, this.animScroll);
19004 onScrollLeft : function(){
19005 var pos = this.getScrollPos();
19006 var s = Math.max(0, pos - this.getScrollIncrement());
19008 this.scrollTo(s, this.animScroll);
19012 updateScrollButtons : function(){
19013 var pos = this.getScrollPos();
19014 this.scrollLeft[pos == 0 ? 'addClass' : 'removeClass']('x-tab-scroller-left-disabled');
19015 this.scrollRight[pos >= (this.getScrollWidth()-this.getScrollArea()) ? 'addClass' : 'removeClass']('x-tab-scroller-right-disabled');
19029 Ext.reg('tabpanel', Ext.TabPanel);
19032 Ext.TabPanel.prototype.activate = Ext.TabPanel.prototype.setActiveTab;
19034 Ext.TabPanel.AccessStack = function(){
19037 add : function(item){
19039 if(items.length > 10){
19044 remove : function(item){
19046 for(var i = 0, len = items.length; i < len; i++) {
19047 if(items[i] != item){
19055 return items.pop();
19063 Ext.Button = Ext.extend(Ext.Component, {
19075 enableToggle: false,
19078 menuAlign : "tl-bl?",
19084 menuClassTarget: 'tr',
19087 clickEvent : 'click',
19090 handleMouseEvents : true,
19093 tooltipType : 'qtip',
19095 buttonSelector : "button:first",
19100 initComponent : function(){
19101 Ext.Button.superclass.initComponent.call(this);
19122 this.menu = Ext.menu.MenuMgr.get(this.menu);
19124 if(typeof this.toggleGroup === 'string'){
19125 this.enableToggle = true;
19129 onRender : function(ct, position){
19130 if(!this.template){
19131 if(!Ext.Button.buttonTemplate){
19132 Ext.Button.buttonTemplate = new Ext.Template(
19133 '<table border="0" cellpadding="0" cellspacing="0" class="x-btn-wrap"><tbody><tr>',
19134 '<td class="x-btn-left"><i> </i></td><td class="x-btn-center"><em unselectable="on"><button class="x-btn-text" type="{1}">{0}</button></em></td><td class="x-btn-right"><i> </i></td>',
19135 "</tr></tbody></table>");
19137 this.template = Ext.Button.buttonTemplate;
19139 var btn, targs = [this.text || ' ', this.type];
19142 btn = this.template.insertBefore(position, targs, true);
19144 btn = this.template.append(ct, targs, true);
19146 var btnEl = btn.child(this.buttonSelector);
19147 btnEl.on('focus', this.onFocus, this);
19148 btnEl.on('blur', this.onBlur, this);
19150 this.initButtonEl(btn, btnEl);
19153 this.el.child(this.menuClassTarget).addClass("x-btn-with-menu");
19155 Ext.ButtonToggleMgr.register(this);
19158 initButtonEl : function(btn, btnEl){
19161 btn.addClass("x-btn");
19164 btnEl.setStyle('background-image', 'url(' +this.icon +')');
19167 btnEl.addClass(this.iconCls);
19169 btn.addClass(this.text ? 'x-btn-text-icon' : 'x-btn-icon');
19172 if(this.tabIndex !== undefined){
19173 btnEl.dom.tabIndex = this.tabIndex;
19176 if(typeof this.tooltip == 'object'){
19177 Ext.QuickTips.register(Ext.apply({
19181 btnEl.dom[this.tooltipType] = this.tooltip;
19186 this.el.addClass("x-btn-pressed");
19189 if(this.handleMouseEvents){
19190 btn.on("mouseover", this.onMouseOver, this);
19191 btn.on("mousedown", this.onMouseDown, this);
19195 this.menu.on("show", this.onMenuShow, this);
19196 this.menu.on("hide", this.onMenuHide, this);
19200 this.el.dom.id = this.el.id = this.id;
19204 var repeater = new Ext.util.ClickRepeater(btn,
19205 typeof this.repeat == "object" ? this.repeat : {}
19207 repeater.on("click", this.onClick, this);
19210 btn.on(this.clickEvent, this.onClick, this);
19213 afterRender : function(){
19214 Ext.Button.superclass.afterRender.call(this);
19216 this.autoWidth.defer(1, this);
19223 setIconClass : function(cls){
19225 this.el.child(this.buttonSelector).replaceClass(this.iconCls, cls);
19227 this.iconCls = cls;
19230 beforeDestroy: function(){
19232 var btn = this.el.child(this.buttonSelector);
19234 btn.removeAllListeners();
19238 Ext.destroy(this.menu);
19242 onDestroy : function(){
19244 Ext.ButtonToggleMgr.unregister(this);
19248 autoWidth : function(){
19250 this.el.setWidth("auto");
19251 if(Ext.isIE7 && Ext.isStrict){
19252 var ib = this.el.child(this.buttonSelector);
19253 if(ib && ib.getWidth() > 20){
19255 ib.setWidth(Ext.util.TextMetrics.measure(ib, this.text).width+ib.getFrameWidth('lr'));
19259 if(this.el.getWidth() < this.minWidth){
19260 this.el.setWidth(this.minWidth);
19267 setHandler : function(handler, scope){
19268 this.handler = handler;
19269 this.scope = scope;
19273 setText : function(text){
19276 this.el.child("td.x-btn-center " + this.buttonSelector).update(text);
19282 getText : function(){
19287 toggle : function(state){
19288 state = state === undefined ? !this.pressed : state;
19289 if(state != this.pressed){
19291 this.el.addClass("x-btn-pressed");
19292 this.pressed = true;
19293 this.fireEvent("toggle", this, true);
19295 this.el.removeClass("x-btn-pressed");
19296 this.pressed = false;
19297 this.fireEvent("toggle", this, false);
19299 if(this.toggleHandler){
19300 this.toggleHandler.call(this.scope || this, this, state);
19306 focus : function(){
19307 this.el.child(this.buttonSelector).focus();
19310 onDisable : function(){
19312 if(!Ext.isIE6 || !this.text){
19313 this.el.addClass(this.disabledClass);
19315 this.el.dom.disabled = true;
19317 this.disabled = true;
19320 onEnable : function(){
19322 if(!Ext.isIE6 || !this.text){
19323 this.el.removeClass(this.disabledClass);
19325 this.el.dom.disabled = false;
19327 this.disabled = false;
19331 showMenu : function(){
19333 this.menu.show(this.el, this.menuAlign);
19339 hideMenu : function(){
19347 hasVisibleMenu : function(){
19348 return this.menu && this.menu.isVisible();
19351 onClick : function(e){
19353 e.preventDefault();
19358 if(!this.disabled){
19359 if(this.enableToggle && (this.allowDepress !== false || !this.pressed)){
19362 if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
19365 this.fireEvent("click", this, e);
19367 this.handler.call(this.scope || this, this, e);
19372 isMenuTriggerOver : function(e, internal){
19373 return this.menu && !internal;
19376 isMenuTriggerOut : function(e, internal){
19377 return this.menu && !internal;
19380 onMouseOver : function(e){
19381 if(!this.disabled){
19382 var internal = e.within(this.el, true);
19384 this.el.addClass("x-btn-over");
19385 Ext.getDoc().on('mouseover', this.monitorMouseOver, this);
19386 this.fireEvent('mouseover', this, e);
19388 if(this.isMenuTriggerOver(e, internal)){
19389 this.fireEvent('menutriggerover', this, this.menu, e);
19394 monitorMouseOver : function(e){
19395 if(e.target != this.el.dom && !e.within(this.el)){
19396 Ext.getDoc().un('mouseover', this.monitorMouseOver, this);
19397 this.onMouseOut(e);
19401 onMouseOut : function(e){
19402 var internal = e.within(this.el) && e.target != this.el.dom;
19403 this.el.removeClass("x-btn-over");
19404 this.fireEvent('mouseout', this, e);
19405 if(this.isMenuTriggerOut(e, internal)){
19406 this.fireEvent('menutriggerout', this, this.menu, e);
19409 onFocus : function(e){
19410 if(!this.disabled){
19411 this.el.addClass("x-btn-focus");
19414 onBlur : function(e){
19415 this.el.removeClass("x-btn-focus");
19418 getClickEl : function(e, isUp){
19422 onMouseDown : function(e){
19423 if(!this.disabled && e.button == 0){
19424 this.getClickEl(e).addClass("x-btn-click");
19425 Ext.getDoc().on('mouseup', this.onMouseUp, this);
19428 onMouseUp : function(e){
19430 this.getClickEl(e, true).removeClass("x-btn-click");
19431 Ext.getDoc().un('mouseup', this.onMouseUp, this);
19434 onMenuShow : function(e){
19435 this.ignoreNextClick = 0;
19436 this.el.addClass("x-btn-menu-active");
19437 this.fireEvent('menushow', this, this.menu);
19439 onMenuHide : function(e){
19440 this.el.removeClass("x-btn-menu-active");
19441 this.ignoreNextClick = this.restoreClick.defer(250, this);
19442 this.fireEvent('menuhide', this, this.menu);
19445 restoreClick : function(){
19446 this.ignoreNextClick = 0;
19453 Ext.reg('button', Ext.Button);
19455 Ext.ButtonToggleMgr = function(){
19458 function toggleGroup(btn, state){
19460 var g = groups[btn.toggleGroup];
19461 for(var i = 0, l = g.length; i < l; i++){
19463 g[i].toggle(false);
19470 register : function(btn){
19471 if(!btn.toggleGroup){
19474 var g = groups[btn.toggleGroup];
19476 g = groups[btn.toggleGroup] = [];
19479 btn.on("toggle", toggleGroup);
19482 unregister : function(btn){
19483 if(!btn.toggleGroup){
19486 var g = groups[btn.toggleGroup];
19489 btn.un("toggle", toggleGroup);
19495 Ext.SplitButton = Ext.extend(Ext.Button, {
\r
19497 arrowSelector : 'button:last',
\r
19500 initComponent : function(){
\r
19501 Ext.SplitButton.superclass.initComponent.call(this);
\r
19503 this.addEvents("arrowclick");
\r
19507 onRender : function(ct, position){
\r
19509 var tpl = new Ext.Template(
\r
19510 '<table cellspacing="0" class="x-btn-menu-wrap x-btn"><tr><td>',
\r
19511 '<table cellspacing="0" class="x-btn-wrap x-btn-menu-text-wrap"><tbody>',
\r
19512 '<tr><td class="x-btn-left"><i> </i></td><td class="x-btn-center"><button class="x-btn-text" type="{1}">{0}</button></td></tr>',
\r
19513 "</tbody></table></td><td>",
\r
19514 '<table cellspacing="0" class="x-btn-wrap x-btn-menu-arrow-wrap"><tbody>',
\r
19515 '<tr><td class="x-btn-center"><button class="x-btn-menu-arrow-el" type="button"> </button></td><td class="x-btn-right"><i> </i></td></tr>',
\r
19516 "</tbody></table></td></tr></table>"
\r
19518 var btn, targs = [this.text || ' ', this.type];
\r
19520 btn = tpl.insertBefore(position, targs, true);
\r
19522 btn = tpl.append(ct, targs, true);
\r
19524 var btnEl = btn.child(this.buttonSelector);
\r
19526 this.initButtonEl(btn, btnEl);
\r
19527 this.arrowBtnTable = btn.child("table:last");
\r
19528 if(this.arrowTooltip){
\r
19529 btn.child(this.arrowSelector).dom[this.tooltipType] = this.arrowTooltip;
\r
19534 autoWidth : function(){
\r
19536 var tbl = this.el.child("table:first");
\r
19537 var tbl2 = this.el.child("table:last");
\r
19538 this.el.setWidth("auto");
\r
19539 tbl.setWidth("auto");
\r
19540 if(Ext.isIE7 && Ext.isStrict){
\r
19541 var ib = this.el.child(this.buttonSelector);
\r
19542 if(ib && ib.getWidth() > 20){
\r
19544 ib.setWidth(Ext.util.TextMetrics.measure(ib, this.text).width+ib.getFrameWidth('lr'));
\r
19547 if(this.minWidth){
\r
19548 if((tbl.getWidth()+tbl2.getWidth()) < this.minWidth){
\r
19549 tbl.setWidth(this.minWidth-tbl2.getWidth());
\r
19552 this.el.setWidth(tbl.getWidth()+tbl2.getWidth());
\r
19557 setArrowHandler : function(handler, scope){
\r
19558 this.arrowHandler = handler;
\r
19559 this.scope = scope;
\r
19563 onClick : function(e){
\r
19564 e.preventDefault();
\r
19565 if(!this.disabled){
\r
19566 if(e.getTarget(".x-btn-menu-arrow-wrap")){
\r
19567 if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
\r
19570 this.fireEvent("arrowclick", this, e);
\r
19571 if(this.arrowHandler){
\r
19572 this.arrowHandler.call(this.scope || this, this, e);
\r
19575 if(this.enableToggle){
\r
19578 this.fireEvent("click", this, e);
\r
19579 if(this.handler){
\r
19580 this.handler.call(this.scope || this, this, e);
\r
19587 getClickEl : function(e, isUp){
\r
19589 return (this.lastClickEl = e.getTarget("table", 10, true));
\r
19591 return this.lastClickEl;
\r
19595 onDisable : function(){
\r
19598 this.el.addClass("x-item-disabled");
\r
19600 this.el.child(this.buttonSelector).dom.disabled = true;
\r
19601 this.el.child(this.arrowSelector).dom.disabled = true;
\r
19603 this.disabled = true;
\r
19607 onEnable : function(){
\r
19610 this.el.removeClass("x-item-disabled");
\r
19612 this.el.child(this.buttonSelector).dom.disabled = false;
\r
19613 this.el.child(this.arrowSelector).dom.disabled = false;
\r
19615 this.disabled = false;
\r
19619 isMenuTriggerOver : function(e){
\r
19620 return this.menu && e.within(this.arrowBtnTable) && !e.within(this.arrowBtnTable, true);
\r
19624 isMenuTriggerOut : function(e, internal){
\r
19625 return this.menu && !e.within(this.arrowBtnTable);
\r
19629 onDestroy : function(){
\r
19630 Ext.destroy(this.arrowBtnTable);
\r
19631 Ext.SplitButton.superclass.onDestroy.call(this);
\r
19636 Ext.MenuButton = Ext.SplitButton;
\r
19639 Ext.reg('splitbutton', Ext.SplitButton);
19641 Ext.CycleButton = Ext.extend(Ext.SplitButton, {
\r
19648 getItemText : function(item){
\r
19649 if(item && this.showText === true){
\r
19651 if(this.prependText){
\r
19652 text += this.prependText;
\r
19654 text += item.text;
\r
19657 return undefined;
\r
19661 setActiveItem : function(item, suppressEvent){
\r
19662 if(typeof item != 'object'){
\r
19663 item = this.menu.items.get(item);
\r
19666 if(!this.rendered){
\r
19667 this.text = this.getItemText(item);
\r
19668 this.iconCls = item.iconCls;
\r
19670 var t = this.getItemText(item);
\r
19674 this.setIconClass(item.iconCls);
\r
19676 this.activeItem = item;
\r
19677 if(!item.checked){
\r
19678 item.setChecked(true, true);
\r
19680 if(this.forceIcon){
\r
19681 this.setIconClass(this.forceIcon);
\r
19683 if(!suppressEvent){
\r
19684 this.fireEvent('change', this, item);
\r
19690 getActiveItem : function(){
\r
19691 return this.activeItem;
\r
19695 initComponent : function(){
\r
19701 if(this.changeHandler){
\r
19702 this.on('change', this.changeHandler, this.scope||this);
\r
19703 delete this.changeHandler;
\r
19706 this.itemCount = this.items.length;
\r
19708 this.menu = {cls:'x-cycle-menu', items:[]};
\r
19710 for(var i = 0, len = this.itemCount; i < len; i++){
\r
19711 var item = this.items[i];
\r
19712 item.group = item.group || this.id;
\r
19713 item.itemIndex = i;
\r
19714 item.checkHandler = this.checkHandler;
\r
19715 item.scope = this;
\r
19716 item.checked = item.checked || false;
\r
19717 this.menu.items.push(item);
\r
19718 if(item.checked){
\r
19722 this.setActiveItem(checked, true);
\r
19723 Ext.CycleButton.superclass.initComponent.call(this);
\r
19725 this.on('click', this.toggleSelected, this);
\r
19729 checkHandler : function(item, pressed){
\r
19731 this.setActiveItem(item);
\r
19736 toggleSelected : function(){
\r
19737 this.menu.render();
\r
19739 var nextIdx, checkItem;
\r
19740 for (var i = 1; i < this.itemCount; i++) {
\r
19741 nextIdx = (this.activeItem.itemIndex + i) % this.itemCount;
\r
19743 checkItem = this.menu.items.itemAt(nextIdx);
\r
19745 if (!checkItem.disabled) {
\r
19746 checkItem.setChecked(true);
\r
19752 Ext.reg('cycle', Ext.CycleButton);
19754 Ext.Toolbar = function(config){
\r
19755 if(Ext.isArray(config)){
\r
19756 config = {buttons:config};
\r
19758 Ext.Toolbar.superclass.constructor.call(this, config);
\r
19763 var T = Ext.Toolbar;
\r
19765 Ext.extend(T, Ext.BoxComponent, {
\r
19767 trackMenus : true,
\r
19770 initComponent : function(){
\r
19771 T.superclass.initComponent.call(this);
\r
19774 this.buttons = this.items;
\r
19777 this.items = new Ext.util.MixedCollection(false, function(o){
\r
19778 return o.itemId || o.id || Ext.id();
\r
19784 cls:'x-toolbar x-small-editor',
\r
19785 html:'<table cellspacing="0"><tr></tr></table>'
\r
19789 onRender : function(ct, position){
\r
19790 this.el = ct.createChild(Ext.apply({ id: this.id },this.autoCreate), position);
\r
19791 this.tr = this.el.child("tr", true);
\r
19795 afterRender : function(){
\r
19796 T.superclass.afterRender.call(this);
\r
19797 if(this.buttons){
\r
19798 this.add.apply(this, this.buttons);
\r
19799 delete this.buttons;
\r
19804 add : function(){
\r
19805 var a = arguments, l = a.length;
\r
19806 for(var i = 0; i < l; i++){
\r
19808 if(el.isFormField){
19809 this.addField(el);
\r
19810 }else if(el.render){
19811 this.addItem(el);
\r
19812 }else if(typeof el == "string"){
19813 if(el == "separator" || el == "-"){
\r
19814 this.addSeparator();
\r
19815 }else if(el == " "){
\r
19816 this.addSpacer();
\r
19817 }else if(el == "->"){
\r
19820 this.addText(el);
\r
19822 }else if(el.tagName){
19823 this.addElement(el);
\r
19824 }else if(typeof el == "object"){
19826 this.addField(Ext.ComponentMgr.create(el, 'button'));
\r
19828 this.addButton(el);
\r
19835 addSeparator : function(){
\r
19836 return this.addItem(new T.Separator());
\r
19840 addSpacer : function(){
\r
19841 return this.addItem(new T.Spacer());
\r
19845 addFill : function(){
\r
19846 return this.addItem(new T.Fill());
\r
19850 addElement : function(el){
\r
19851 return this.addItem(new T.Item(el));
\r
19855 addItem : function(item){
\r
19856 var td = this.nextBlock();
\r
19857 this.initMenuTracking(item);
\r
19859 this.items.add(item);
\r
19864 addButton : function(config){
\r
19865 if(Ext.isArray(config)){
\r
19866 var buttons = [];
\r
19867 for(var i = 0, len = config.length; i < len; i++) {
\r
19868 buttons.push(this.addButton(config[i]));
\r
19873 if(!(config instanceof T.Button)){
\r
19874 b = config.split ?
\r
19875 new T.SplitButton(config) :
\r
19876 new T.Button(config);
\r
19878 var td = this.nextBlock();
\r
19879 this.initMenuTracking(b);
\r
19881 this.items.add(b);
\r
19886 initMenuTracking : function(item){
\r
19887 if(this.trackMenus && item.menu){
\r
19889 'menutriggerover' : this.onButtonTriggerOver,
\r
19890 'menushow' : this.onButtonMenuShow,
\r
19891 'menuhide' : this.onButtonMenuHide,
\r
19898 addText : function(text){
\r
19899 return this.addItem(new T.TextItem(text));
\r
19903 insertButton : function(index, item){
\r
19904 if(Ext.isArray(item)){
\r
19905 var buttons = [];
\r
19906 for(var i = 0, len = item.length; i < len; i++) {
\r
19907 buttons.push(this.insertButton(index + i, item[i]));
\r
19911 if (!(item instanceof T.Button)){
\r
19912 item = new T.Button(item);
\r
19914 var td = document.createElement("td");
\r
19915 this.tr.insertBefore(td, this.tr.childNodes[index]);
\r
19916 this.initMenuTracking(item);
\r
19918 this.items.insert(index, item);
\r
19923 addDom : function(config, returnEl){
\r
19924 var td = this.nextBlock();
\r
19925 Ext.DomHelper.overwrite(td, config);
\r
19926 var ti = new T.Item(td.firstChild);
\r
19928 this.items.add(ti);
\r
19933 addField : function(field){
\r
19934 var td = this.nextBlock();
\r
19935 field.render(td);
\r
19936 var ti = new T.Item(td.firstChild);
\r
19938 this.items.add(ti);
\r
19943 nextBlock : function(){
\r
19944 var td = document.createElement("td");
\r
19945 this.tr.appendChild(td);
\r
19950 onDestroy : function(){
\r
19951 Ext.Toolbar.superclass.onDestroy.call(this);
\r
19952 if(this.rendered){
\r
19954 Ext.destroy.apply(Ext, this.items.items);
\r
19956 Ext.Element.uncache(this.tr);
\r
19961 onDisable : function(){
\r
19962 this.items.each(function(item){
\r
19963 if(item.disable){
\r
19970 onEnable : function(){
\r
19971 this.items.each(function(item){
\r
19979 onButtonTriggerOver : function(btn){
\r
19980 if(this.activeMenuBtn && this.activeMenuBtn != btn){
\r
19981 this.activeMenuBtn.hideMenu();
\r
19983 this.activeMenuBtn = btn;
\r
19988 onButtonMenuShow : function(btn){
\r
19989 this.activeMenuBtn = btn;
\r
19993 onButtonMenuHide : function(btn){
\r
19994 delete this.activeMenuBtn;
\r
19999 Ext.reg('toolbar', Ext.Toolbar);
\r
20002 T.Item = function(el){
\r
20003 this.el = Ext.getDom(el);
\r
20004 this.id = Ext.id(this.el);
\r
20005 this.hidden = false;
\r
20008 T.Item.prototype = {
\r
20011 getEl : function(){
\r
20016 render : function(td){
\r
20018 td.appendChild(this.el);
\r
20022 destroy : function(){
\r
20023 if(this.td && this.td.parentNode){
\r
20024 this.td.parentNode.removeChild(this.td);
\r
20029 show: function(){
\r
20030 this.hidden = false;
\r
20031 this.td.style.display = "";
\r
20035 hide: function(){
\r
20036 this.hidden = true;
\r
20037 this.td.style.display = "none";
\r
20041 setVisible: function(visible){
\r
20050 focus : function(){
\r
20051 Ext.fly(this.el).focus();
\r
20055 disable : function(){
\r
20056 Ext.fly(this.td).addClass("x-item-disabled");
\r
20057 this.disabled = true;
\r
20058 this.el.disabled = true;
\r
20062 enable : function(){
\r
20063 Ext.fly(this.td).removeClass("x-item-disabled");
\r
20064 this.disabled = false;
\r
20065 this.el.disabled = false;
\r
20068 Ext.reg('tbitem', T.Item);
\r
20072 T.Separator = function(){
\r
20073 var s = document.createElement("span");
\r
20074 s.className = "ytb-sep";
\r
20075 T.Separator.superclass.constructor.call(this, s);
\r
20077 Ext.extend(T.Separator, T.Item, {
\r
20078 enable:Ext.emptyFn,
\r
20079 disable:Ext.emptyFn,
\r
20080 focus:Ext.emptyFn
\r
20082 Ext.reg('tbseparator', T.Separator);
\r
20085 T.Spacer = function(){
\r
20086 var s = document.createElement("div");
\r
20087 s.className = "ytb-spacer";
\r
20088 T.Spacer.superclass.constructor.call(this, s);
\r
20090 Ext.extend(T.Spacer, T.Item, {
\r
20091 enable:Ext.emptyFn,
\r
20092 disable:Ext.emptyFn,
\r
20093 focus:Ext.emptyFn
\r
20096 Ext.reg('tbspacer', T.Spacer);
\r
20099 T.Fill = Ext.extend(T.Spacer, {
\r
20101 render : function(td){
\r
20102 td.style.width = '100%';
\r
20103 T.Fill.superclass.render.call(this, td);
\r
20106 Ext.reg('tbfill', T.Fill);
\r
20109 T.TextItem = function(t){
\r
20110 var s = document.createElement("span");
\r
20111 s.className = "ytb-text";
\r
20112 s.innerHTML = t.text ? t.text : t;
\r
20113 T.TextItem.superclass.constructor.call(this, s);
\r
20115 Ext.extend(T.TextItem, T.Item, {
\r
20116 enable:Ext.emptyFn,
\r
20117 disable:Ext.emptyFn,
\r
20118 focus:Ext.emptyFn
\r
20120 Ext.reg('tbtext', T.TextItem);
\r
20124 T.Button = Ext.extend(Ext.Button, {
\r
20125 hideParent : true,
\r
20127 onDestroy : function(){
\r
20128 T.Button.superclass.onDestroy.call(this);
\r
20129 if(this.container){
\r
20130 this.container.remove();
\r
20134 Ext.reg('tbbutton', T.Button);
\r
20137 T.SplitButton = Ext.extend(Ext.SplitButton, {
\r
20138 hideParent : true,
\r
20140 onDestroy : function(){
\r
20141 T.SplitButton.superclass.onDestroy.call(this);
\r
20142 if(this.container){
\r
20143 this.container.remove();
\r
20148 Ext.reg('tbsplit', T.SplitButton);
\r
20150 T.MenuButton = T.SplitButton;
\r
20155 Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {
20161 displayMsg : 'Displaying {0} - {1} of {2}',
20163 emptyMsg : 'No data to display',
20165 beforePageText : "Page",
20167 afterPageText : "of {0}",
20169 firstText : "First Page",
20171 prevText : "Previous Page",
20173 nextText : "Next Page",
20175 lastText : "Last Page",
20177 refreshText : "Refresh",
20180 paramNames : {start: 'start', limit: 'limit'},
20182 initComponent : function(){
20183 Ext.PagingToolbar.superclass.initComponent.call(this);
20185 this.bind(this.store);
20188 onRender : function(ct, position){
20189 Ext.PagingToolbar.superclass.onRender.call(this, ct, position);
20190 this.first = this.addButton({
20191 tooltip: this.firstText,
20192 iconCls: "x-tbar-page-first",
20194 handler: this.onClick.createDelegate(this, ["first"])
20196 this.prev = this.addButton({
20197 tooltip: this.prevText,
20198 iconCls: "x-tbar-page-prev",
20200 handler: this.onClick.createDelegate(this, ["prev"])
20202 this.addSeparator();
20203 this.add(this.beforePageText);
20204 this.field = Ext.get(this.addDom({
20209 cls: "x-tbar-page-number"
20211 this.field.on("keydown", this.onPagingKeydown, this);
20212 this.field.on("focus", function(){this.dom.select();});
20213 this.afterTextEl = this.addText(String.format(this.afterPageText, 1));
20214 this.field.setHeight(18);
20215 this.addSeparator();
20216 this.next = this.addButton({
20217 tooltip: this.nextText,
20218 iconCls: "x-tbar-page-next",
20220 handler: this.onClick.createDelegate(this, ["next"])
20222 this.last = this.addButton({
20223 tooltip: this.lastText,
20224 iconCls: "x-tbar-page-last",
20226 handler: this.onClick.createDelegate(this, ["last"])
20228 this.addSeparator();
20229 this.loading = this.addButton({
20230 tooltip: this.refreshText,
20231 iconCls: "x-tbar-loading",
20232 handler: this.onClick.createDelegate(this, ["refresh"])
20235 if(this.displayInfo){
20236 this.displayEl = Ext.fly(this.el.dom).createChild({cls:'x-paging-info'});
20239 this.onLoad.apply(this, this.dsLoaded);
20243 updateInfo : function(){
20244 if(this.displayEl){
20245 var count = this.store.getCount();
20246 var msg = count == 0 ?
20250 this.cursor+1, this.cursor+count, this.store.getTotalCount()
20252 this.displayEl.update(msg);
20256 onLoad : function(store, r, o){
20257 if(!this.rendered){
20258 this.dsLoaded = [store, r, o];
20261 this.cursor = o.params ? o.params[this.paramNames.start] : 0;
20262 var d = this.getPageData(), ap = d.activePage, ps = d.pages;
20264 this.afterTextEl.el.innerHTML = String.format(this.afterPageText, d.pages);
20265 this.field.dom.value = ap;
20266 this.first.setDisabled(ap == 1);
20267 this.prev.setDisabled(ap == 1);
20268 this.next.setDisabled(ap == ps);
20269 this.last.setDisabled(ap == ps);
20270 this.loading.enable();
20274 getPageData : function(){
20275 var total = this.store.getTotalCount();
20278 activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize),
20279 pages : total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)
20283 onLoadError : function(){
20284 if(!this.rendered){
20287 this.loading.enable();
20290 readPage : function(d){
20291 var v = this.field.dom.value, pageNum;
20292 if (!v || isNaN(pageNum = parseInt(v, 10))) {
20293 this.field.dom.value = d.activePage;
20299 onPagingKeydown : function(e){
20300 var k = e.getKey(), d = this.getPageData(), pageNum;
20301 if (k == e.RETURN) {
20303 if(pageNum = this.readPage(d)){
20304 pageNum = Math.min(Math.max(1, pageNum), d.pages) - 1;
20305 this.doLoad(pageNum * this.pageSize);
20307 }else if (k == e.HOME || k == e.END){
20309 pageNum = k == e.HOME ? 1 : d.pages;
20310 this.field.dom.value = pageNum;
20311 }else if (k == e.UP || k == e.PAGEUP || k == e.DOWN || k == e.PAGEDOWN){
20313 if(pageNum = this.readPage(d)){
20314 var increment = e.shiftKey ? 10 : 1;
20315 if(k == e.DOWN || k == e.PAGEDOWN){
20318 pageNum += increment;
20319 if(pageNum >= 1 & pageNum <= d.pages){
20320 this.field.dom.value = pageNum;
20326 beforeLoad : function(){
20327 if(this.rendered && this.loading){
20328 this.loading.disable();
20332 doLoad : function(start){
20333 var o = {}, pn = this.paramNames;
20334 o[pn.start] = start;
20335 o[pn.limit] = this.pageSize;
20336 this.store.load({params:o});
20339 onClick : function(which){
20340 var store = this.store;
20346 this.doLoad(Math.max(0, this.cursor-this.pageSize));
20349 this.doLoad(this.cursor+this.pageSize);
20352 var total = store.getTotalCount();
20353 var extra = total % this.pageSize;
20354 var lastStart = extra ? (total - extra) : total-this.pageSize;
20355 this.doLoad(lastStart);
20358 this.doLoad(this.cursor);
20364 unbind : function(store){
20365 store = Ext.StoreMgr.lookup(store);
20366 store.un("beforeload", this.beforeLoad, this);
20367 store.un("load", this.onLoad, this);
20368 store.un("loadexception", this.onLoadError, this);
20369 this.store = undefined;
20373 bind : function(store){
20374 store = Ext.StoreMgr.lookup(store);
20375 store.on("beforeload", this.beforeLoad, this);
20376 store.on("load", this.onLoad, this);
20377 store.on("loadexception", this.onLoadError, this);
20378 this.store = store;
20381 Ext.reg('paging', Ext.PagingToolbar);
20383 Ext.Resizable = function(el, config){
\r
20384 this.el = Ext.get(el);
\r
20386 if(config && config.wrap){
\r
20387 config.resizeChild = this.el;
\r
20388 this.el = this.el.wrap(typeof config.wrap == "object" ? config.wrap : {cls:"xresizable-wrap"});
\r
20389 this.el.id = this.el.dom.id = config.resizeChild.id + "-rzwrap";
\r
20390 this.el.setStyle("overflow", "hidden");
\r
20391 this.el.setPositioning(config.resizeChild.getPositioning());
\r
20392 config.resizeChild.clearPositioning();
\r
20393 if(!config.width || !config.height){
\r
20394 var csize = config.resizeChild.getSize();
\r
20395 this.el.setSize(csize.width, csize.height);
\r
20397 if(config.pinned && !config.adjustments){
\r
20398 config.adjustments = "auto";
\r
20402 this.proxy = this.el.createProxy({tag: "div", cls: "x-resizable-proxy", id: this.el.id + "-rzproxy"});
\r
20403 this.proxy.unselectable();
\r
20404 this.proxy.enableDisplayMode('block');
\r
20406 Ext.apply(this, config);
\r
20409 this.disableTrackOver = true;
\r
20410 this.el.addClass("x-resizable-pinned");
\r
20413 var position = this.el.getStyle("position");
\r
20414 if(position != "absolute" && position != "fixed"){
\r
20415 this.el.setStyle("position", "relative");
\r
20418 this.handles = 's,e,se';
\r
20419 if(this.multiDirectional){
\r
20420 this.handles += ',n,w';
\r
20423 if(this.handles == "all"){
\r
20424 this.handles = "n s e w ne nw se sw";
\r
20426 var hs = this.handles.split(/\s*?[,;]\s*?| /);
\r
20427 var ps = Ext.Resizable.positions;
\r
20428 for(var i = 0, len = hs.length; i < len; i++){
\r
20429 if(hs[i] && ps[hs[i]]){
\r
20430 var pos = ps[hs[i]];
\r
20431 this[pos] = new Ext.Resizable.Handle(this, pos, this.disableTrackOver, this.transparent);
\r
20435 this.corner = this.southeast;
\r
20437 if(this.handles.indexOf("n") != -1 || this.handles.indexOf("w") != -1){
\r
20438 this.updateBox = true;
\r
20441 this.activeHandle = null;
\r
20443 if(this.resizeChild){
\r
20444 if(typeof this.resizeChild == "boolean"){
\r
20445 this.resizeChild = Ext.get(this.el.dom.firstChild, true);
\r
20447 this.resizeChild = Ext.get(this.resizeChild, true);
\r
20451 if(this.adjustments == "auto"){
\r
20452 var rc = this.resizeChild;
\r
20453 var hw = this.west, he = this.east, hn = this.north, hs = this.south;
\r
20454 if(rc && (hw || hn)){
\r
20455 rc.position("relative");
\r
20456 rc.setLeft(hw ? hw.el.getWidth() : 0);
\r
20457 rc.setTop(hn ? hn.el.getHeight() : 0);
\r
20459 this.adjustments = [
\r
20460 (he ? -he.el.getWidth() : 0) + (hw ? -hw.el.getWidth() : 0),
\r
20461 (hn ? -hn.el.getHeight() : 0) + (hs ? -hs.el.getHeight() : 0) -1
\r
20465 if(this.draggable){
\r
20466 this.dd = this.dynamic ?
\r
20467 this.el.initDD(null) : this.el.initDDProxy(null, {dragElId: this.proxy.id});
\r
20468 this.dd.setHandleElId(this.resizeChild ? this.resizeChild.id : this.el.id);
\r
20477 if(this.width !== null && this.height !== null){
\r
20478 this.resizeTo(this.width, this.height);
\r
20480 this.updateChildSize();
\r
20483 this.el.dom.style.zoom = 1;
\r
20485 Ext.Resizable.superclass.constructor.call(this);
\r
20488 Ext.extend(Ext.Resizable, Ext.util.Observable, {
\r
20489 resizeChild : false,
\r
20490 adjustments : [0, 0],
\r
20493 maxWidth : 10000,
\r
20494 maxHeight : 10000,
\r
20500 multiDirectional : false,
\r
20501 disableTrackOver : false,
\r
20502 easing : 'easeOutStrong',
\r
20503 widthIncrement : 0,
\r
20504 heightIncrement : 0,
\r
20508 preserveRatio : false,
\r
20509 transparent: false,
\r
20512 draggable: false,
\r
20521 resizeTo : function(width, height){
\r
20522 this.el.setSize(width, height);
\r
20523 this.updateChildSize();
\r
20524 this.fireEvent("resize", this, width, height, null);
\r
20528 startSizing : function(e, handle){
\r
20529 this.fireEvent("beforeresize", this, e);
\r
20532 if(!this.overlay){
\r
20533 this.overlay = this.el.createProxy({tag: "div", cls: "x-resizable-overlay", html: " "}, Ext.getBody());
\r
20534 this.overlay.unselectable();
\r
20535 this.overlay.enableDisplayMode("block");
\r
20536 this.overlay.on("mousemove", this.onMouseMove, this);
\r
20537 this.overlay.on("mouseup", this.onMouseUp, this);
\r
20539 this.overlay.setStyle("cursor", handle.el.getStyle("cursor"));
\r
20541 this.resizing = true;
\r
20542 this.startBox = this.el.getBox();
\r
20543 this.startPoint = e.getXY();
\r
20544 this.offsets = [(this.startBox.x + this.startBox.width) - this.startPoint[0],
\r
20545 (this.startBox.y + this.startBox.height) - this.startPoint[1]];
\r
20547 this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
\r
20548 this.overlay.show();
\r
20550 if(this.constrainTo) {
\r
20551 var ct = Ext.get(this.constrainTo);
\r
20552 this.resizeRegion = ct.getRegion().adjust(
\r
20553 ct.getFrameWidth('t'),
\r
20554 ct.getFrameWidth('l'),
\r
20555 -ct.getFrameWidth('b'),
\r
20556 -ct.getFrameWidth('r')
\r
20560 this.proxy.setStyle('visibility', 'hidden');
20561 this.proxy.show();
\r
20562 this.proxy.setBox(this.startBox);
\r
20563 if(!this.dynamic){
\r
20564 this.proxy.setStyle('visibility', 'visible');
\r
20570 onMouseDown : function(handle, e){
\r
20571 if(this.enabled){
\r
20573 this.activeHandle = handle;
\r
20574 this.startSizing(e, handle);
\r
20579 onMouseUp : function(e){
\r
20580 var size = this.resizeElement();
\r
20581 this.resizing = false;
\r
20582 this.handleOut();
\r
20583 this.overlay.hide();
\r
20584 this.proxy.hide();
\r
20585 this.fireEvent("resize", this, size.width, size.height, e);
\r
20589 updateChildSize : function(){
\r
20590 if(this.resizeChild){
\r
20591 var el = this.el;
\r
20592 var child = this.resizeChild;
\r
20593 var adj = this.adjustments;
\r
20594 if(el.dom.offsetWidth){
\r
20595 var b = el.getSize(true);
\r
20596 child.setSize(b.width+adj[0], b.height+adj[1]);
\r
20603 setTimeout(function(){
\r
20604 if(el.dom.offsetWidth){
\r
20605 var b = el.getSize(true);
\r
20606 child.setSize(b.width+adj[0], b.height+adj[1]);
\r
20614 snap : function(value, inc, min){
\r
20615 if(!inc || !value) return value;
\r
20616 var newValue = value;
\r
20617 var m = value % inc;
\r
20620 newValue = value + (inc-m);
\r
20622 newValue = value - m;
\r
20625 return Math.max(min, newValue);
\r
20629 resizeElement : function(){
\r
20630 var box = this.proxy.getBox();
\r
20631 if(this.updateBox){
\r
20632 this.el.setBox(box, false, this.animate, this.duration, null, this.easing);
\r
20634 this.el.setSize(box.width, box.height, this.animate, this.duration, null, this.easing);
\r
20636 this.updateChildSize();
\r
20637 if(!this.dynamic){
\r
20638 this.proxy.hide();
\r
20644 constrain : function(v, diff, m, mx){
\r
20645 if(v - diff < m){
\r
20647 }else if(v - diff > mx){
\r
20654 onMouseMove : function(e){
\r
20655 if(this.enabled){
\r
20658 if(this.resizeRegion && !this.resizeRegion.contains(e.getPoint())) {
\r
20663 var curSize = this.curSize || this.startBox;
\r
20664 var x = this.startBox.x, y = this.startBox.y;
\r
20665 var ox = x, oy = y;
\r
20666 var w = curSize.width, h = curSize.height;
\r
20667 var ow = w, oh = h;
\r
20668 var mw = this.minWidth, mh = this.minHeight;
\r
20669 var mxw = this.maxWidth, mxh = this.maxHeight;
\r
20670 var wi = this.widthIncrement;
\r
20671 var hi = this.heightIncrement;
\r
20673 var eventXY = e.getXY();
\r
20674 var diffX = -(this.startPoint[0] - Math.max(this.minX, eventXY[0]));
\r
20675 var diffY = -(this.startPoint[1] - Math.max(this.minY, eventXY[1]));
\r
20677 var pos = this.activeHandle.position;
\r
20682 w = Math.min(Math.max(mw, w), mxw);
\r
20686 h = Math.min(Math.max(mh, h), mxh);
\r
20688 case "southeast":
\r
20691 w = Math.min(Math.max(mw, w), mxw);
\r
20692 h = Math.min(Math.max(mh, h), mxh);
\r
20695 diffY = this.constrain(h, diffY, mh, mxh);
\r
20700 diffX = this.constrain(w, diffX, mw, mxw);
\r
20704 case "northeast":
\r
20706 w = Math.min(Math.max(mw, w), mxw);
\r
20707 diffY = this.constrain(h, diffY, mh, mxh);
\r
20711 case "northwest":
\r
20712 diffX = this.constrain(w, diffX, mw, mxw);
\r
20713 diffY = this.constrain(h, diffY, mh, mxh);
\r
20719 case "southwest":
\r
20720 diffX = this.constrain(w, diffX, mw, mxw);
\r
20722 h = Math.min(Math.max(mh, h), mxh);
\r
20728 var sw = this.snap(w, wi, mw);
\r
20729 var sh = this.snap(h, hi, mh);
\r
20730 if(sw != w || sh != h){
\r
20732 case "northeast":
\r
20738 case "southwest":
\r
20744 case "northwest":
\r
20753 if(this.preserveRatio){
\r
20755 case "southeast":
\r
20758 h = Math.min(Math.max(mh, h), mxh);
\r
20763 w = Math.min(Math.max(mw, w), mxw);
\r
20766 case "northeast":
\r
20768 w = Math.min(Math.max(mw, w), mxw);
\r
20774 w = Math.min(Math.max(mw, w), mxw);
\r
20776 x += (tw - w) / 2;
\r
20778 case "southwest":
\r
20780 h = Math.min(Math.max(mh, h), mxh);
\r
20788 h = Math.min(Math.max(mh, h), mxh);
\r
20789 y += (th - h) / 2;
\r
20794 case "northwest":
\r
20798 h = Math.min(Math.max(mh, h), mxh);
\r
20806 this.proxy.setBounds(x, y, w, h);
\r
20807 if(this.dynamic){
\r
20808 this.resizeElement();
\r
20815 handleOver : function(){
\r
20816 if(this.enabled){
\r
20817 this.el.addClass("x-resizable-over");
\r
20822 handleOut : function(){
\r
20823 if(!this.resizing){
\r
20824 this.el.removeClass("x-resizable-over");
\r
20829 getEl : function(){
\r
20834 getResizeChild : function(){
\r
20835 return this.resizeChild;
\r
20839 destroy : function(removeEl){
\r
20840 this.proxy.remove();
\r
20841 if(this.overlay){
\r
20842 this.overlay.removeAllListeners();
\r
20843 this.overlay.remove();
\r
20845 var ps = Ext.Resizable.positions;
\r
20846 for(var k in ps){
\r
20847 if(typeof ps[k] != "function" && this[ps[k]]){
\r
20848 var h = this[ps[k]];
\r
20849 h.el.removeAllListeners();
\r
20854 this.el.update("");
\r
20855 this.el.remove();
\r
20859 syncHandleHeight : function(){
\r
20860 var h = this.el.getHeight(true);
\r
20862 this.west.el.setHeight(h);
\r
20865 this.east.el.setHeight(h);
\r
20872 Ext.Resizable.positions = {
\r
20873 n: "north", s: "south", e: "east", w: "west", se: "southeast", sw: "southwest", nw: "northwest", ne: "northeast"
\r
20877 Ext.Resizable.Handle = function(rz, pos, disableTrackOver, transparent){
\r
20880 var tpl = Ext.DomHelper.createTemplate(
\r
20881 {tag: "div", cls: "x-resizable-handle x-resizable-handle-{0}"}
\r
20884 Ext.Resizable.Handle.prototype.tpl = tpl;
\r
20886 this.position = pos;
\r
20888 this.el = this.tpl.append(rz.el.dom, [this.position], true);
\r
20889 this.el.unselectable();
\r
20891 this.el.setOpacity(0);
\r
20893 this.el.on("mousedown", this.onMouseDown, this);
\r
20894 if(!disableTrackOver){
\r
20895 this.el.on("mouseover", this.onMouseOver, this);
\r
20896 this.el.on("mouseout", this.onMouseOut, this);
\r
20901 Ext.Resizable.Handle.prototype = {
\r
20902 afterResize : function(rz){
\r
20906 onMouseDown : function(e){
\r
20907 this.rz.onMouseDown(this, e);
\r
20910 onMouseOver : function(e){
\r
20911 this.rz.handleOver(this, e);
\r
20914 onMouseOut : function(e){
\r
20915 this.rz.handleOut(this, e);
\r
20923 Ext.Editor = function(field, config){
20924 this.field = field;
20925 Ext.Editor.superclass.constructor.call(this, config);
20928 Ext.extend(Ext.Editor, Ext.Component, {
20942 swallowKeys : true,
20944 completeOnEnter : false,
20946 cancelOnEsc : false,
20950 initComponent : function(){
20951 Ext.Editor.superclass.initComponent.call(this);
20966 onRender : function(ct, position){
20967 this.el = new Ext.Layer({
20968 shadow: this.shadow,
20974 constrain: this.constrain
20976 this.el.setStyle("overflow", Ext.isGecko ? "auto" : "hidden");
20977 if(this.field.msgTarget != 'title'){
20978 this.field.msgTarget = 'qtip';
20980 this.field.inEditor = true;
20981 this.field.render(this.el);
20983 this.field.el.dom.setAttribute('autocomplete', 'off');
20985 this.field.on("specialkey", this.onSpecialKey, this);
20986 if(this.swallowKeys){
20987 this.field.el.swallowEvent(['keydown','keypress']);
20990 this.field.on("blur", this.onBlur, this);
20991 if(this.field.grow){
20992 this.field.on("autosize", this.el.sync, this.el, {delay:1});
20996 onSpecialKey : function(field, e){
20997 if(this.completeOnEnter && e.getKey() == e.ENTER){
20999 this.completeEdit();
21000 }else if(this.cancelOnEsc && e.getKey() == e.ESC){
21003 this.fireEvent('specialkey', field, e);
21008 startEdit : function(el, value){
21010 this.completeEdit();
21012 this.boundEl = Ext.get(el);
21013 var v = value !== undefined ? value : this.boundEl.dom.innerHTML;
21014 if(!this.rendered){
21015 this.render(this.parentEl || document.body);
21017 if(this.fireEvent("beforestartedit", this, this.boundEl, v) === false){
21020 this.startValue = v;
21021 this.field.setValue(v);
21023 this.el.alignTo(this.boundEl, this.alignment);
21024 this.editing = true;
21028 doAutoSize : function(){
21030 var sz = this.boundEl.getSize();
21031 switch(this.autoSize){
21033 this.setSize(sz.width, "");
21036 this.setSize("", sz.height);
21039 this.setSize(sz.width, sz.height);
21045 setSize : function(w, h){
21046 delete this.field.lastSize;
21047 this.field.setSize(w, h);
21054 realign : function(){
21055 this.el.alignTo(this.boundEl, this.alignment);
21059 completeEdit : function(remainVisible){
21063 var v = this.getValue();
21064 if(this.revertInvalid !== false && !this.field.isValid()){
21065 v = this.startValue;
21066 this.cancelEdit(true);
21068 if(String(v) === String(this.startValue) && this.ignoreNoChange){
21069 this.editing = false;
21073 if(this.fireEvent("beforecomplete", this, v, this.startValue) !== false){
21074 this.editing = false;
21075 if(this.updateEl && this.boundEl){
21076 this.boundEl.update(v);
21078 if(remainVisible !== true){
21081 this.fireEvent("complete", this, v, this.startValue);
21085 onShow : function(){
21087 if(this.hideEl !== false){
21088 this.boundEl.hide();
21091 if(Ext.isIE && !this.fixIEFocus){ this.fixIEFocus = true;
21092 this.deferredFocus.defer(50, this);
21094 this.field.focus();
21096 this.fireEvent("startedit", this.boundEl, this.startValue);
21099 deferredFocus : function(){
21101 this.field.focus();
21106 cancelEdit : function(remainVisible){
21108 this.setValue(this.startValue);
21109 if(remainVisible !== true){
21115 onBlur : function(){
21116 if(this.allowBlur !== true && this.editing){
21117 this.completeEdit();
21121 onHide : function(){
21123 this.completeEdit();
21127 if(this.field.collapse){
21128 this.field.collapse();
21131 if(this.hideEl !== false){
21132 this.boundEl.show();
21137 setValue : function(v){
21138 this.field.setValue(v);
21142 getValue : function(){
21143 return this.field.getValue();
21146 beforeDestroy : function(){
21147 this.field.destroy();
21151 Ext.reg('editor', Ext.Editor);
21153 Ext.MessageBox = function(){
\r
21154 var dlg, opt, mask, waitTimer;
\r
21155 var bodyEl, msgEl, textboxEl, textareaEl, progressBar, pp, iconEl, spacerEl;
\r
21156 var buttons, activeTextEl, bwidth, iconCls = '';
\r
21159 var handleButton = function(button){
\r
21161 Ext.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value], 1);
\r
21165 var handleHide = function(){
\r
21166 if(opt && opt.cls){
\r
21167 dlg.el.removeClass(opt.cls);
\r
21169 progressBar.reset();
\r
21173 var handleEsc = function(d, k, e){
\r
21174 if(opt && opt.closable !== false){
\r
21183 var updateButtons = function(b){
\r
21186 buttons["ok"].hide();
\r
21187 buttons["cancel"].hide();
\r
21188 buttons["yes"].hide();
\r
21189 buttons["no"].hide();
\r
21192 dlg.footer.dom.style.display = '';
\r
21193 for(var k in buttons){
\r
21194 if(typeof buttons[k] != "function"){
\r
21196 buttons[k].show();
\r
21197 buttons[k].setText(typeof b[k] == "string" ? b[k] : Ext.MessageBox.buttonText[k]);
\r
21198 width += buttons[k].el.getWidth()+15;
\r
21200 buttons[k].hide();
\r
21209 getDialog : function(titleText){
\r
21211 dlg = new Ext.Window({
\r
21212 autoCreate : true,
\r
21216 constrainHeader:true,
\r
21217 minimizable : false,
\r
21218 maximizable : false,
\r
21222 buttonAlign:"center",
\r
21229 close : function(){
\r
21230 if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){
\r
21231 handleButton("no");
\r
21233 handleButton("cancel");
\r
21238 var bt = this.buttonText;
\r
21240 buttons["ok"] = dlg.addButton(bt["ok"], handleButton.createCallback("ok"));
\r
21241 buttons["yes"] = dlg.addButton(bt["yes"], handleButton.createCallback("yes"));
\r
21242 buttons["no"] = dlg.addButton(bt["no"], handleButton.createCallback("no"));
\r
21243 buttons["cancel"] = dlg.addButton(bt["cancel"], handleButton.createCallback("cancel"));
\r
21244 buttons["ok"].hideMode = buttons["yes"].hideMode = buttons["no"].hideMode = buttons["cancel"].hideMode = 'offsets';
\r
21245 dlg.render(document.body);
\r
21246 dlg.getEl().addClass('x-window-dlg');
\r
21248 bodyEl = dlg.body.createChild({
\r
21249 html:'<div class="ext-mb-icon"></div><div class="ext-mb-content"><span class="ext-mb-text"></span><br /><input type="text" class="ext-mb-input" /><textarea class="ext-mb-textarea"></textarea></div>'
\r
21251 iconEl = Ext.get(bodyEl.dom.firstChild);
\r
21252 var contentEl = bodyEl.dom.childNodes[1];
\r
21253 msgEl = Ext.get(contentEl.firstChild);
\r
21254 textboxEl = Ext.get(contentEl.childNodes[2]);
\r
21255 textboxEl.enableDisplayMode();
\r
21256 textboxEl.addKeyListener([10,13], function(){
\r
21257 if(dlg.isVisible() && opt && opt.buttons){
\r
21258 if(opt.buttons.ok){
\r
21259 handleButton("ok");
\r
21260 }else if(opt.buttons.yes){
\r
21261 handleButton("yes");
\r
21265 textareaEl = Ext.get(contentEl.childNodes[3]);
\r
21266 textareaEl.enableDisplayMode();
\r
21267 progressBar = new Ext.ProgressBar({
\r
21270 bodyEl.createChild({cls:'x-clear'});
\r
21276 updateText : function(text){
\r
21277 if(!dlg.isVisible() && !opt.width){
\r
21278 dlg.setSize(this.maxWidth, 100);
21280 msgEl.update(text || ' ');
\r
21282 var iw = iconCls != '' ? (iconEl.getWidth() + iconEl.getMargins('lr')) : 0;
\r
21283 var mw = msgEl.getWidth() + msgEl.getMargins('lr');
\r
21284 var fw = dlg.getFrameWidth('lr');
\r
21285 var bw = dlg.body.getFrameWidth('lr');
\r
21286 if (Ext.isIE && iw > 0){
\r
21291 var w = Math.max(Math.min(opt.width || iw+mw+fw+bw, this.maxWidth),
\r
21292 Math.max(opt.minWidth || this.minWidth, bwidth || 0));
\r
21294 if(opt.prompt === true){
\r
21295 activeTextEl.setWidth(w-iw-fw-bw);
\r
21297 if(opt.progress === true || opt.wait === true){
\r
21298 progressBar.setSize(w-iw-fw-bw);
\r
21300 dlg.setSize(w, 'auto').center();
\r
21305 updateProgress : function(value, progressText, msg){
\r
21306 progressBar.updateProgress(value, progressText);
\r
21308 this.updateText(msg);
\r
21314 isVisible : function(){
\r
21315 return dlg && dlg.isVisible();
\r
21319 hide : function(){
\r
21320 if(this.isVisible()){
\r
21328 show : function(options){
\r
21329 if(this.isVisible()){
\r
21333 var d = this.getDialog(opt.title || " ");
\r
21335 d.setTitle(opt.title || " ");
\r
21336 var allowClose = (opt.closable !== false && opt.progress !== true && opt.wait !== true);
\r
21337 d.tools.close.setDisplayed(allowClose);
\r
21338 activeTextEl = textboxEl;
\r
21339 opt.prompt = opt.prompt || (opt.multiline ? true : false);
\r
21341 if(opt.multiline){
\r
21342 textboxEl.hide();
\r
21343 textareaEl.show();
\r
21344 textareaEl.setHeight(typeof opt.multiline == "number" ?
\r
21345 opt.multiline : this.defaultTextHeight);
\r
21346 activeTextEl = textareaEl;
\r
21348 textboxEl.show();
\r
21349 textareaEl.hide();
\r
21352 textboxEl.hide();
\r
21353 textareaEl.hide();
\r
21355 activeTextEl.dom.value = opt.value || "";
\r
21357 d.focusEl = activeTextEl;
\r
21359 var bs = opt.buttons;
\r
21362 db = buttons["ok"];
\r
21363 }else if(bs && bs.yes){
\r
21364 db = buttons["yes"];
\r
21370 this.setIcon(opt.icon);
\r
21371 bwidth = updateButtons(opt.buttons);
\r
21372 progressBar.setVisible(opt.progress === true || opt.wait === true);
\r
21373 this.updateProgress(0, opt.progressText);
\r
21374 this.updateText(opt.msg);
\r
21376 d.el.addClass(opt.cls);
\r
21378 d.proxyDrag = opt.proxyDrag === true;
\r
21379 d.modal = opt.modal !== false;
\r
21380 d.mask = opt.modal !== false ? mask : false;
\r
21381 if(!d.isVisible()){
\r
21383 document.body.appendChild(dlg.el.dom);
\r
21384 d.setAnimateTarget(opt.animEl);
\r
21385 d.show(opt.animEl);
\r
21389 d.on('show', function(){
\r
21390 if(allowClose === true){
\r
21391 d.keyMap.enable();
\r
21393 d.keyMap.disable();
\r
21395 }, this, {single:true});
\r
21397 if(opt.wait === true){
\r
21398 progressBar.wait(opt.waitConfig);
\r
21404 setIcon : function(icon){
\r
21405 if(icon && icon != ''){
\r
21406 iconEl.removeClass('x-hidden');
\r
21407 iconEl.replaceClass(iconCls, icon);
\r
21410 iconEl.replaceClass(iconCls, 'x-hidden');
\r
21417 progress : function(title, msg, progressText){
\r
21424 minWidth: this.minProgressWidth,
\r
21425 progressText: progressText
\r
21431 wait : function(msg, title, config){
\r
21439 minWidth: this.minProgressWidth,
\r
21440 waitConfig: config
\r
21446 alert : function(title, msg, fn, scope){
\r
21450 buttons: this.OK,
\r
21458 confirm : function(title, msg, fn, scope){
\r
21462 buttons: this.YESNO,
\r
21465 icon: this.QUESTION
\r
21471 prompt : function(title, msg, fn, scope, multiline){
\r
21475 buttons: this.OKCANCEL,
\r
21480 multiline: multiline
\r
21488 CANCEL : {cancel:true},
\r
21490 OKCANCEL : {ok:true, cancel:true},
\r
21492 YESNO : {yes:true, no:true},
\r
21494 YESNOCANCEL : {yes:true, no:true, cancel:true},
\r
21496 INFO : 'ext-mb-info',
\r
21498 WARNING : 'ext-mb-warning',
\r
21500 QUESTION : 'ext-mb-question',
\r
21502 ERROR : 'ext-mb-error',
\r
21505 defaultTextHeight : 75,
\r
21511 minProgressWidth : 250,
\r
21515 cancel : "Cancel",
\r
21523 Ext.Msg = Ext.MessageBox;
21525 Ext.Tip = Ext.extend(Ext.Panel, {
\r
21533 shadow : "sides",
\r
21535 defaultAlign : "tl-bl?",
\r
21536 autoRender: true,
\r
21537 quickShowInterval : 250,
\r
21542 baseCls: 'x-tip',
\r
21543 floating:{shadow:true,shim:true,useDisplay:true,constrain:false},
\r
21547 initComponent : function(){
\r
21548 Ext.Tip.superclass.initComponent.call(this);
\r
21549 if(this.closable && !this.title){
\r
21550 this.elements += ',header';
\r
21555 afterRender : function(){
\r
21556 Ext.Tip.superclass.afterRender.call(this);
\r
21557 if(this.closable){
\r
21560 handler: this.hide,
\r
21567 showAt : function(xy){
\r
21568 Ext.Tip.superclass.show.call(this);
\r
21569 if(this.measureWidth !== false && (!this.initialConfig || typeof this.initialConfig.width != 'number')){
\r
21570 var bw = this.body.getTextWidth();
\r
21572 bw = Math.max(bw, this.header.child('span').getTextWidth(this.title));
\r
21574 bw += this.getFrameWidth() + (this.closable ? 20 : 0) + this.body.getPadding("lr");
\r
21575 this.setWidth(bw.constrain(this.minWidth, this.maxWidth));
\r
21577 if(this.constrainPosition){
\r
21578 xy = this.el.adjustForConstraints(xy);
\r
21580 this.setPagePosition(xy[0], xy[1]);
\r
21584 showBy : function(el, pos){
\r
21585 if(!this.rendered){
\r
21586 this.render(Ext.getBody());
\r
21588 this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign));
\r
21591 initDraggable : function(){
\r
21592 this.dd = new Ext.Tip.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);
\r
21593 this.header.addClass('x-tip-draggable');
\r
21598 Ext.Tip.DD = function(tip, config){
\r
21599 Ext.apply(this, config);
\r
21601 Ext.Tip.DD.superclass.constructor.call(this, tip.el.id, 'WindowDD-'+tip.id);
\r
21602 this.setHandleElId(tip.header.id);
\r
21603 this.scroll = false;
\r
21606 Ext.extend(Ext.Tip.DD, Ext.dd.DD, {
\r
21609 headerOffsets:[100, 25],
\r
21610 startDrag : function(){
\r
21611 this.tip.el.disableShadow();
\r
21613 endDrag : function(e){
\r
21614 this.tip.el.enableShadow(true);
\r
21618 Ext.ToolTip = Ext.extend(Ext.Tip, {
\r
21626 dismissDelay: 5000,
\r
21628 mouseOffset: [15,18],
\r
21630 trackMouse : false,
\r
21631 constrainPosition: true,
\r
21634 initComponent: function(){
\r
21635 Ext.ToolTip.superclass.initComponent.call(this);
\r
21636 this.lastActive = new Date();
\r
21637 this.initTarget();
\r
21641 initTarget : function(){
\r
21643 this.target = Ext.get(this.target);
\r
21644 this.target.on('mouseover', this.onTargetOver, this);
\r
21645 this.target.on('mouseout', this.onTargetOut, this);
\r
21646 this.target.on('mousemove', this.onMouseMove, this);
\r
21651 onMouseMove : function(e){
\r
21652 this.targetXY = e.getXY();
\r
21653 if(!this.hidden && this.trackMouse){
\r
21654 this.setPagePosition(this.getTargetXY());
\r
21659 getTargetXY : function(){
\r
21660 return [this.targetXY[0]+this.mouseOffset[0], this.targetXY[1]+this.mouseOffset[1]];
\r
21664 onTargetOver : function(e){
\r
21665 if(this.disabled || e.within(this.target.dom, true)){
\r
21668 this.clearTimer('hide');
\r
21669 this.targetXY = e.getXY();
\r
21670 this.delayShow();
\r
21674 delayShow : function(){
\r
21675 if(this.hidden && !this.showTimer){
\r
21676 if(this.lastActive.getElapsed() < this.quickShowInterval){
\r
21679 this.showTimer = this.show.defer(this.showDelay, this);
\r
21681 }else if(!this.hidden && this.autoHide !== false){
\r
21687 onTargetOut : function(e){
\r
21688 if(this.disabled || e.within(this.target.dom, true)){
\r
21691 this.clearTimer('show');
\r
21692 if(this.autoHide !== false){
\r
21693 this.delayHide();
\r
21698 delayHide : function(){
\r
21699 if(!this.hidden && !this.hideTimer){
\r
21700 this.hideTimer = this.hide.defer(this.hideDelay, this);
\r
21705 hide: function(){
\r
21706 this.clearTimer('dismiss');
\r
21707 this.lastActive = new Date();
\r
21708 Ext.ToolTip.superclass.hide.call(this);
\r
21712 show : function(){
\r
21713 this.showAt(this.getTargetXY());
\r
21717 showAt : function(xy){
\r
21718 this.lastActive = new Date();
\r
21719 this.clearTimers();
\r
21720 Ext.ToolTip.superclass.showAt.call(this, xy);
\r
21721 if(this.dismissDelay && this.autoHide !== false){
\r
21722 this.dismissTimer = this.hide.defer(this.dismissDelay, this);
\r
21727 clearTimer : function(name){
\r
21728 name = name + 'Timer';
\r
21729 clearTimeout(this[name]);
\r
21730 delete this[name];
\r
21734 clearTimers : function(){
\r
21735 this.clearTimer('show');
\r
21736 this.clearTimer('dismiss');
\r
21737 this.clearTimer('hide');
\r
21741 onShow : function(){
\r
21742 Ext.ToolTip.superclass.onShow.call(this);
\r
21743 Ext.getDoc().on('mousedown', this.onDocMouseDown, this);
\r
21747 onHide : function(){
\r
21748 Ext.ToolTip.superclass.onHide.call(this);
\r
21749 Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
\r
21753 onDocMouseDown : function(e){
\r
21754 if(this.autoHide !== false && !e.within(this.el.dom)){
\r
21756 this.enable.defer(100, this);
\r
21761 onDisable : function(){
\r
21762 this.clearTimers();
\r
21767 adjustPosition : function(x, y){
\r
21769 var ay = this.targetXY[1], h = this.getSize().height;
\r
21770 if(this.constrainPosition && y <= ay && (y+h) >= ay){
\r
21773 return {x : x, y: y};
\r
21777 onDestroy : function(){
\r
21778 Ext.ToolTip.superclass.onDestroy.call(this);
\r
21780 this.target.un('mouseover', this.onTargetOver, this);
\r
21781 this.target.un('mouseout', this.onTargetOut, this);
\r
21782 this.target.un('mousemove', this.onMouseMove, this);
\r
21787 Ext.QuickTip = Ext.extend(Ext.ToolTip, {
\r
21790 interceptTitles : false,
\r
21794 namespace : "ext",
\r
21795 attribute : "qtip",
\r
21796 width : "qwidth",
\r
21797 target : "target",
\r
21798 title : "qtitle",
\r
21805 initComponent : function(){
\r
21806 this.target = this.target || Ext.getDoc();
\r
21807 this.targets = this.targets || {};
\r
21808 Ext.QuickTip.superclass.initComponent.call(this);
\r
21812 register : function(config){
\r
21813 var cs = Ext.isArray(config) ? config : arguments;
\r
21814 for(var i = 0, len = cs.length; i < len; i++){
\r
21816 var target = c.target;
\r
21818 if(Ext.isArray(target)){
\r
21819 for(var j = 0, jlen = target.length; j < jlen; j++){
\r
21820 this.targets[Ext.id(target[j])] = c;
\r
21823 this.targets[Ext.id(target)] = c;
\r
21830 unregister : function(el){
\r
21831 delete this.targets[Ext.id(el)];
\r
21835 onTargetOver : function(e){
\r
21836 if(this.disabled){
\r
21839 this.targetXY = e.getXY();
\r
21840 var t = e.getTarget();
\r
21841 if(!t || t.nodeType !== 1 || t == document || t == document.body){
\r
21844 if(this.activeTarget && t == this.activeTarget.el){
\r
21845 this.clearTimer('hide');
\r
21849 if(t && this.targets[t.id]){
\r
21850 this.activeTarget = this.targets[t.id];
\r
21851 this.activeTarget.el = t;
\r
21852 this.delayShow();
\r
21855 var ttp, et = Ext.fly(t), cfg = this.tagConfig;
\r
21856 var ns = cfg.namespace;
\r
21857 if(this.interceptTitles && t.title){
\r
21860 t.removeAttribute("title");
\r
21861 e.preventDefault();
\r
21863 ttp = t.qtip || et.getAttributeNS(ns, cfg.attribute);
\r
21866 var autoHide = et.getAttributeNS(ns, cfg.hide);
\r
21867 this.activeTarget = {
\r
21870 width: et.getAttributeNS(ns, cfg.width),
\r
21871 autoHide: autoHide != "user" && autoHide !== 'false',
\r
21872 title: et.getAttributeNS(ns, cfg.title),
\r
21873 cls: et.getAttributeNS(ns, cfg.cls),
\r
21874 align: et.getAttributeNS(ns, cfg.align)
\r
21876 this.delayShow();
\r
21881 onTargetOut : function(e){
\r
21882 this.clearTimer('show');
\r
21883 if(this.autoHide !== false){
\r
21884 this.delayHide();
\r
21889 showAt : function(xy){
\r
21890 var t = this.activeTarget;
\r
21892 if(!this.rendered){
\r
21893 this.render(Ext.getBody());
\r
21894 this.activeTarget = t;
\r
21897 this.setWidth(t.width);
\r
21898 this.body.setWidth(this.adjustBodyWidth(t.width - this.getFrameWidth()));
\r
21899 this.measureWidth = false;
\r
21901 this.measureWidth = true;
\r
21903 this.setTitle(t.title || '');
\r
21904 this.body.update(t.text);
\r
21905 this.autoHide = t.autoHide;
\r
21906 this.dismissDelay = t.dismissDelay || this.dismissDelay;
\r
21907 if(this.lastCls){
\r
21908 this.el.removeClass(this.lastCls);
\r
21909 delete this.lastCls;
\r
21912 this.el.addClass(t.cls);
\r
21913 this.lastCls = t.cls;
\r
21916 xy = this.el.getAlignToXY(t.el, t.align);
\r
21917 this.constrainPosition = false;
\r
21919 this.constrainPosition = true;
\r
21922 Ext.QuickTip.superclass.showAt.call(this, xy);
\r
21926 hide: function(){
\r
21927 delete this.activeTarget;
\r
21928 Ext.QuickTip.superclass.hide.call(this);
\r
21932 Ext.QuickTips = function(){
\r
21933 var tip, locks = [];
\r
21936 init : function(){
\r
21938 tip = new Ext.QuickTip({elements:'header,body'});
\r
21943 enable : function(){
\r
21946 if(locks.length < 1){
\r
21953 disable : function(){
\r
21961 isEnabled : function(){
\r
21962 return tip && !tip.disabled;
\r
21966 getQuickTip : function(){
\r
21971 register : function(){
\r
21972 tip.register.apply(tip, arguments);
\r
21976 unregister : function(){
\r
21977 tip.unregister.apply(tip, arguments);
\r
21981 tips :function(){
\r
21982 tip.register.apply(tip, arguments);
\r
21987 Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
\r
21988 rootVisible : true,
\r
21989 animate: Ext.enableFx,
\r
21991 enableDD : false,
\r
21992 hlDrop : Ext.enableFx,
\r
21993 pathSeparator: "/",
\r
21995 initComponent : function(){
\r
21996 Ext.tree.TreePanel.superclass.initComponent.call(this);
\r
21998 if(!this.eventModel){
\r
21999 this.eventModel = new Ext.tree.TreeEventModel(this);
\r
22002 this.nodeHash = {};
\r
22006 this.setRootNode(this.root);
\r
22024 "beforemovenode",
\r
22035 "beforeexpandnode",
\r
22037 "beforecollapsenode",
\r
22041 "disabledchange",
\r
22055 "beforechildrenrendered",
\r
22063 "beforenodedrop",
\r
22069 if(this.singleExpand){
\r
22070 this.on("beforeexpandnode", this.restrictExpand, this);
\r
22075 proxyNodeEvent : function(ename, a1, a2, a3, a4, a5, a6){
\r
22076 if(ename == 'collapse' || ename == 'expand' || ename == 'beforecollapse' || ename == 'beforeexpand' || ename == 'move' || ename == 'beforemove'){
\r
22077 ename = ename+'node';
\r
22080 return this.fireEvent(ename, a1, a2, a3, a4, a5, a6);
\r
22085 getRootNode : function(){
\r
22086 return this.root;
\r
22090 setRootNode : function(node){
\r
22091 this.root = node;
\r
22092 node.ownerTree = this;
\r
22093 node.isRoot = true;
\r
22094 this.registerNode(node);
\r
22095 if(!this.rootVisible){
\r
22096 var uiP = node.attributes.uiProvider;
\r
22097 node.ui = uiP ? new uiP(node) : new Ext.tree.RootTreeNodeUI(node);
\r
22103 getNodeById : function(id){
\r
22104 return this.nodeHash[id];
\r
22108 registerNode : function(node){
\r
22109 this.nodeHash[node.id] = node;
\r
22113 unregisterNode : function(node){
\r
22114 delete this.nodeHash[node.id];
\r
22118 toString : function(){
\r
22119 return "[Tree"+(this.id?" "+this.id:"")+"]";
\r
22123 restrictExpand : function(node){
\r
22124 var p = node.parentNode;
\r
22126 if(p.expandedChild && p.expandedChild.parentNode == p){
\r
22127 p.expandedChild.collapse();
\r
22129 p.expandedChild = node;
\r
22134 getChecked : function(a, startNode){
\r
22135 startNode = startNode || this.root;
\r
22137 var f = function(){
\r
22138 if(this.attributes.checked){
\r
22139 r.push(!a ? this : (a == 'id' ? this.id : this.attributes[a]));
\r
22142 startNode.cascade(f);
\r
22147 getEl : function(){
\r
22152 getLoader : function(){
\r
22153 return this.loader;
\r
22157 expandAll : function(){
\r
22158 this.root.expand(true);
\r
22162 collapseAll : function(){
\r
22163 this.root.collapse(true);
\r
22167 getSelectionModel : function(){
\r
22168 if(!this.selModel){
\r
22169 this.selModel = new Ext.tree.DefaultSelectionModel();
\r
22171 return this.selModel;
\r
22175 expandPath : function(path, attr, callback){
\r
22176 attr = attr || "id";
\r
22177 var keys = path.split(this.pathSeparator);
\r
22178 var curNode = this.root;
\r
22179 if(curNode.attributes[attr] != keys[1]){
22181 callback(false, null);
\r
22186 var f = function(){
\r
22187 if(++index == keys.length){
\r
22189 callback(true, curNode);
\r
22193 var c = curNode.findChild(attr, keys[index]);
\r
22196 callback(false, curNode);
\r
22201 c.expand(false, false, f);
\r
22203 curNode.expand(false, false, f);
\r
22207 selectPath : function(path, attr, callback){
\r
22208 attr = attr || "id";
\r
22209 var keys = path.split(this.pathSeparator);
\r
22210 var v = keys.pop();
\r
22211 if(keys.length > 0){
\r
22212 var f = function(success, node){
\r
22213 if(success && node){
\r
22214 var n = node.findChild(attr, v);
\r
22218 callback(true, n);
\r
22220 }else if(callback){
\r
22221 callback(false, n);
\r
22225 callback(false, n);
\r
22229 this.expandPath(keys.join(this.pathSeparator), attr, f);
\r
22231 this.root.select();
\r
22233 callback(true, this.root);
\r
22239 getTreeEl : function(){
\r
22240 return this.body;
\r
22244 onRender : function(ct, position){
\r
22245 Ext.tree.TreePanel.superclass.onRender.call(this, ct, position);
\r
22246 this.el.addClass('x-tree');
\r
22247 this.innerCt = this.body.createChild({tag:"ul",
\r
22248 cls:"x-tree-root-ct " +
\r
22249 (this.useArrows ? 'x-tree-arrows' : this.lines ? "x-tree-lines" : "x-tree-no-lines")});
\r
22253 initEvents : function(){
\r
22254 Ext.tree.TreePanel.superclass.initEvents.call(this);
\r
22256 if(this.containerScroll){
\r
22257 Ext.dd.ScrollManager.register(this.body);
\r
22259 if((this.enableDD || this.enableDrop) && !this.dropZone){
\r
22261 this.dropZone = new Ext.tree.TreeDropZone(this, this.dropConfig || {
\r
22262 ddGroup: this.ddGroup || "TreeDD", appendOnly: this.ddAppendOnly === true
\r
22265 if((this.enableDD || this.enableDrag) && !this.dragZone){
\r
22267 this.dragZone = new Ext.tree.TreeDragZone(this, this.dragConfig || {
\r
22268 ddGroup: this.ddGroup || "TreeDD",
\r
22269 scroll: this.ddScroll
\r
22272 this.getSelectionModel().init(this);
\r
22276 afterRender : function(){
\r
22277 Ext.tree.TreePanel.superclass.afterRender.call(this);
\r
22278 this.root.render();
\r
22279 if(!this.rootVisible){
\r
22280 this.root.renderChildren();
\r
22284 onDestroy : function(){
\r
22285 if(this.rendered){
\r
22286 this.body.removeAllListeners();
\r
22287 Ext.dd.ScrollManager.unregister(this.body);
\r
22288 if(this.dropZone){
\r
22289 this.dropZone.unreg();
\r
22291 if(this.dragZone){
\r
22292 this.dragZone.unreg();
\r
22295 this.root.destroy();
\r
22296 this.nodeHash = null;
\r
22297 Ext.tree.TreePanel.superclass.onDestroy.call(this);
\r
22347 Ext.reg('treepanel', Ext.tree.TreePanel);
22348 Ext.tree.TreeEventModel = function(tree){
\r
22349 this.tree = tree;
\r
22350 this.tree.on('render', this.initEvents, this);
\r
22353 Ext.tree.TreeEventModel.prototype = {
\r
22354 initEvents : function(){
\r
22355 var el = this.tree.getTreeEl();
\r
22356 el.on('click', this.delegateClick, this);
\r
22357 if(this.tree.trackMouseOver !== false){
\r
22358 el.on('mouseover', this.delegateOver, this);
\r
22359 el.on('mouseout', this.delegateOut, this);
\r
22361 el.on('dblclick', this.delegateDblClick, this);
\r
22362 el.on('contextmenu', this.delegateContextMenu, this);
\r
22365 getNode : function(e){
\r
22367 if(t = e.getTarget('.x-tree-node-el', 10)){
\r
22368 var id = Ext.fly(t, '_treeEvents').getAttributeNS('ext', 'tree-node-id');
\r
22370 return this.tree.getNodeById(id);
\r
22376 getNodeTarget : function(e){
\r
22377 var t = e.getTarget('.x-tree-node-icon', 1);
\r
22379 t = e.getTarget('.x-tree-node-el', 6);
\r
22384 delegateOut : function(e, t){
\r
22385 if(!this.beforeEvent(e)){
\r
22388 if(e.getTarget('.x-tree-ec-icon', 1)){
\r
22389 var n = this.getNode(e);
\r
22390 this.onIconOut(e, n);
\r
22391 if(n == this.lastEcOver){
\r
22392 delete this.lastEcOver;
\r
22395 if((t = this.getNodeTarget(e)) && !e.within(t, true)){
\r
22396 this.onNodeOut(e, this.getNode(e));
\r
22400 delegateOver : function(e, t){
\r
22401 if(!this.beforeEvent(e)){
\r
22404 if(this.lastEcOver){
22405 this.onIconOut(e, this.lastEcOver);
\r
22406 delete this.lastEcOver;
\r
22408 if(e.getTarget('.x-tree-ec-icon', 1)){
\r
22409 this.lastEcOver = this.getNode(e);
\r
22410 this.onIconOver(e, this.lastEcOver);
\r
22412 if(t = this.getNodeTarget(e)){
\r
22413 this.onNodeOver(e, this.getNode(e));
\r
22417 delegateClick : function(e, t){
\r
22418 if(!this.beforeEvent(e)){
\r
22422 if(e.getTarget('input[type=checkbox]', 1)){
\r
22423 this.onCheckboxClick(e, this.getNode(e));
\r
22425 else if(e.getTarget('.x-tree-ec-icon', 1)){
\r
22426 this.onIconClick(e, this.getNode(e));
\r
22428 else if(this.getNodeTarget(e)){
\r
22429 this.onNodeClick(e, this.getNode(e));
\r
22433 delegateDblClick : function(e, t){
\r
22434 if(this.beforeEvent(e) && this.getNodeTarget(e)){
\r
22435 this.onNodeDblClick(e, this.getNode(e));
\r
22439 delegateContextMenu : function(e, t){
\r
22440 if(this.beforeEvent(e) && this.getNodeTarget(e)){
\r
22441 this.onNodeContextMenu(e, this.getNode(e));
\r
22445 onNodeClick : function(e, node){
\r
22446 node.ui.onClick(e);
\r
22449 onNodeOver : function(e, node){
\r
22450 node.ui.onOver(e);
\r
22453 onNodeOut : function(e, node){
\r
22454 node.ui.onOut(e);
\r
22457 onIconOver : function(e, node){
\r
22458 node.ui.addClass('x-tree-ec-over');
\r
22461 onIconOut : function(e, node){
\r
22462 node.ui.removeClass('x-tree-ec-over');
\r
22465 onIconClick : function(e, node){
\r
22466 node.ui.ecClick(e);
\r
22469 onCheckboxClick : function(e, node){
\r
22470 node.ui.onCheckChange(e);
\r
22473 onNodeDblClick : function(e, node){
\r
22474 node.ui.onDblClick(e);
\r
22477 onNodeContextMenu : function(e, node){
\r
22478 node.ui.onContextMenu(e);
\r
22481 beforeEvent : function(e){
\r
22482 if(this.disabled){
\r
22489 disable: function(){
\r
22490 this.disabled = true;
\r
22493 enable: function(){
\r
22494 this.disabled = false;
\r
22498 Ext.tree.DefaultSelectionModel = function(config){
\r
22499 this.selNode = null;
\r
22503 "selectionchange",
\r
22509 Ext.apply(this, config);
\r
22510 Ext.tree.DefaultSelectionModel.superclass.constructor.call(this);
\r
22513 Ext.extend(Ext.tree.DefaultSelectionModel, Ext.util.Observable, {
\r
22514 init : function(tree){
\r
22515 this.tree = tree;
\r
22516 tree.getTreeEl().on("keydown", this.onKeyDown, this);
\r
22517 tree.on("click", this.onNodeClick, this);
\r
22520 onNodeClick : function(node, e){
\r
22521 this.select(node);
\r
22525 select : function(node){
\r
22526 var last = this.selNode;
\r
22527 if(last != node && this.fireEvent('beforeselect', this, node, last) !== false){
\r
22529 last.ui.onSelectedChange(false);
\r
22531 this.selNode = node;
\r
22532 node.ui.onSelectedChange(true);
\r
22533 this.fireEvent("selectionchange", this, node, last);
\r
22539 unselect : function(node){
\r
22540 if(this.selNode == node){
\r
22541 this.clearSelections();
\r
22546 clearSelections : function(){
\r
22547 var n = this.selNode;
\r
22549 n.ui.onSelectedChange(false);
\r
22550 this.selNode = null;
\r
22551 this.fireEvent("selectionchange", this, null);
\r
22557 getSelectedNode : function(){
\r
22558 return this.selNode;
\r
22562 isSelected : function(node){
\r
22563 return this.selNode == node;
\r
22567 selectPrevious : function(){
\r
22568 var s = this.selNode || this.lastSelNode;
\r
22572 var ps = s.previousSibling;
\r
22574 if(!ps.isExpanded() || ps.childNodes.length < 1){
\r
22575 return this.select(ps);
\r
22577 var lc = ps.lastChild;
\r
22578 while(lc && lc.isExpanded() && lc.childNodes.length > 0){
\r
22579 lc = lc.lastChild;
\r
22581 return this.select(lc);
\r
22583 } else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){
\r
22584 return this.select(s.parentNode);
\r
22590 selectNext : function(){
\r
22591 var s = this.selNode || this.lastSelNode;
\r
22595 if(s.firstChild && s.isExpanded()){
\r
22596 return this.select(s.firstChild);
\r
22597 }else if(s.nextSibling){
\r
22598 return this.select(s.nextSibling);
\r
22599 }else if(s.parentNode){
\r
22601 s.parentNode.bubble(function(){
\r
22602 if(this.nextSibling){
\r
22603 newS = this.getOwnerTree().selModel.select(this.nextSibling);
\r
22612 onKeyDown : function(e){
\r
22613 var s = this.selNode || this.lastSelNode;
\r
22619 var k = e.getKey();
\r
22623 this.selectNext();
\r
22627 this.selectPrevious();
\r
22630 e.preventDefault();
\r
22631 if(s.hasChildNodes()){
\r
22632 if(!s.isExpanded()){
\r
22634 }else if(s.firstChild){
\r
22635 this.select(s.firstChild, e);
\r
22640 e.preventDefault();
\r
22641 if(s.hasChildNodes() && s.isExpanded()){
\r
22643 }else if(s.parentNode && (this.tree.rootVisible || s.parentNode != this.tree.getRootNode())){
\r
22644 this.select(s.parentNode, e);
\r
22652 Ext.tree.MultiSelectionModel = function(config){
\r
22653 this.selNodes = [];
\r
22654 this.selMap = {};
\r
22657 "selectionchange"
\r
22659 Ext.apply(this, config);
\r
22660 Ext.tree.MultiSelectionModel.superclass.constructor.call(this);
\r
22663 Ext.extend(Ext.tree.MultiSelectionModel, Ext.util.Observable, {
\r
22664 init : function(tree){
\r
22665 this.tree = tree;
\r
22666 tree.getTreeEl().on("keydown", this.onKeyDown, this);
\r
22667 tree.on("click", this.onNodeClick, this);
\r
22670 onNodeClick : function(node, e){
\r
22671 this.select(node, e, e.ctrlKey);
\r
22675 select : function(node, e, keepExisting){
\r
22676 if(keepExisting !== true){
\r
22677 this.clearSelections(true);
\r
22679 if(this.isSelected(node)){
\r
22680 this.lastSelNode = node;
\r
22683 this.selNodes.push(node);
\r
22684 this.selMap[node.id] = node;
\r
22685 this.lastSelNode = node;
\r
22686 node.ui.onSelectedChange(true);
\r
22687 this.fireEvent("selectionchange", this, this.selNodes);
\r
22692 unselect : function(node){
\r
22693 if(this.selMap[node.id]){
\r
22694 node.ui.onSelectedChange(false);
\r
22695 var sn = this.selNodes;
\r
22696 var index = sn.indexOf(node);
\r
22698 this.selNodes.splice(index, 1);
\r
22700 delete this.selMap[node.id];
\r
22701 this.fireEvent("selectionchange", this, this.selNodes);
\r
22706 clearSelections : function(suppressEvent){
\r
22707 var sn = this.selNodes;
\r
22708 if(sn.length > 0){
\r
22709 for(var i = 0, len = sn.length; i < len; i++){
\r
22710 sn[i].ui.onSelectedChange(false);
\r
22712 this.selNodes = [];
\r
22713 this.selMap = {};
\r
22714 if(suppressEvent !== true){
\r
22715 this.fireEvent("selectionchange", this, this.selNodes);
\r
22721 isSelected : function(node){
\r
22722 return this.selMap[node.id] ? true : false;
\r
22726 getSelectedNodes : function(){
\r
22727 return this.selNodes;
\r
22730 onKeyDown : Ext.tree.DefaultSelectionModel.prototype.onKeyDown,
\r
22732 selectNext : Ext.tree.DefaultSelectionModel.prototype.selectNext,
\r
22734 selectPrevious : Ext.tree.DefaultSelectionModel.prototype.selectPrevious
\r
22737 Ext.tree.TreeNode = function(attributes){
\r
22738 attributes = attributes || {};
\r
22739 if(typeof attributes == "string"){
\r
22740 attributes = {text: attributes};
\r
22742 this.childrenRendered = false;
\r
22743 this.rendered = false;
\r
22744 Ext.tree.TreeNode.superclass.constructor.call(this, attributes);
\r
22745 this.expanded = attributes.expanded === true;
\r
22746 this.isTarget = attributes.isTarget !== false;
\r
22747 this.draggable = attributes.draggable !== false && attributes.allowDrag !== false;
\r
22748 this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false;
\r
22751 this.text = attributes.text;
\r
22753 this.disabled = attributes.disabled === true;
\r
22761 "beforecollapse",
\r
22765 "disabledchange",
\r
22779 "beforechildrenrendered"
\r
22782 var uiClass = this.attributes.uiProvider || this.defaultUI || Ext.tree.TreeNodeUI;
\r
22785 this.ui = new uiClass(this);
\r
22787 Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
\r
22788 preventHScroll: true,
\r
22790 isExpanded : function(){
\r
22791 return this.expanded;
\r
22795 getUI : function(){
\r
22800 setFirstChild : function(node){
\r
22801 var of = this.firstChild;
\r
22802 Ext.tree.TreeNode.superclass.setFirstChild.call(this, node);
\r
22803 if(this.childrenRendered && of && node != of){
\r
22804 of.renderIndent(true, true);
\r
22806 if(this.rendered){
\r
22807 this.renderIndent(true, true);
\r
22812 setLastChild : function(node){
\r
22813 var ol = this.lastChild;
\r
22814 Ext.tree.TreeNode.superclass.setLastChild.call(this, node);
\r
22815 if(this.childrenRendered && ol && node != ol){
\r
22816 ol.renderIndent(true, true);
\r
22818 if(this.rendered){
\r
22819 this.renderIndent(true, true);
\r
22825 appendChild : function(){
\r
22826 var node = Ext.tree.TreeNode.superclass.appendChild.apply(this, arguments);
\r
22827 if(node && this.childrenRendered){
\r
22830 this.ui.updateExpandIcon();
\r
22835 removeChild : function(node){
\r
22836 this.ownerTree.getSelectionModel().unselect(node);
\r
22837 Ext.tree.TreeNode.superclass.removeChild.apply(this, arguments);
\r
22839 if(this.childrenRendered){
\r
22840 node.ui.remove();
\r
22842 if(this.childNodes.length < 1){
\r
22843 this.collapse(false, false);
\r
22845 this.ui.updateExpandIcon();
\r
22847 if(!this.firstChild && !this.isHiddenRoot()) {
\r
22848 this.childrenRendered = false;
\r
22854 insertBefore : function(node, refNode){
\r
22855 var newNode = Ext.tree.TreeNode.superclass.insertBefore.apply(this, arguments);
\r
22856 if(newNode && refNode && this.childrenRendered){
\r
22859 this.ui.updateExpandIcon();
\r
22864 setText : function(text){
\r
22865 var oldText = this.text;
\r
22866 this.text = text;
\r
22867 this.attributes.text = text;
\r
22869 this.ui.onTextChange(this, text, oldText);
\r
22871 this.fireEvent("textchange", this, text, oldText);
\r
22875 select : function(){
\r
22876 this.getOwnerTree().getSelectionModel().select(this);
\r
22880 unselect : function(){
\r
22881 this.getOwnerTree().getSelectionModel().unselect(this);
\r
22885 isSelected : function(){
\r
22886 return this.getOwnerTree().getSelectionModel().isSelected(this);
\r
22890 expand : function(deep, anim, callback){
\r
22891 if(!this.expanded){
\r
22892 if(this.fireEvent("beforeexpand", this, deep, anim) === false){
\r
22895 if(!this.childrenRendered){
\r
22896 this.renderChildren();
\r
22898 this.expanded = true;
\r
22899 if(!this.isHiddenRoot() && (this.getOwnerTree().animate && anim !== false) || anim){
\r
22900 this.ui.animExpand(function(){
\r
22901 this.fireEvent("expand", this);
\r
22902 if(typeof callback == "function"){
\r
22905 if(deep === true){
\r
22906 this.expandChildNodes(true);
\r
22908 }.createDelegate(this));
\r
22911 this.ui.expand();
\r
22912 this.fireEvent("expand", this);
\r
22913 if(typeof callback == "function"){
\r
22918 if(typeof callback == "function"){
\r
22922 if(deep === true){
\r
22923 this.expandChildNodes(true);
\r
22927 isHiddenRoot : function(){
\r
22928 return this.isRoot && !this.getOwnerTree().rootVisible;
\r
22932 collapse : function(deep, anim){
\r
22933 if(this.expanded && !this.isHiddenRoot()){
\r
22934 if(this.fireEvent("beforecollapse", this, deep, anim) === false){
\r
22937 this.expanded = false;
\r
22938 if((this.getOwnerTree().animate && anim !== false) || anim){
\r
22939 this.ui.animCollapse(function(){
\r
22940 this.fireEvent("collapse", this);
\r
22941 if(deep === true){
\r
22942 this.collapseChildNodes(true);
\r
22944 }.createDelegate(this));
\r
22947 this.ui.collapse();
\r
22948 this.fireEvent("collapse", this);
\r
22951 if(deep === true){
\r
22952 var cs = this.childNodes;
\r
22953 for(var i = 0, len = cs.length; i < len; i++) {
\r
22954 cs[i].collapse(true, false);
\r
22960 delayedExpand : function(delay){
\r
22961 if(!this.expandProcId){
\r
22962 this.expandProcId = this.expand.defer(delay, this);
\r
22967 cancelExpand : function(){
\r
22968 if(this.expandProcId){
\r
22969 clearTimeout(this.expandProcId);
\r
22971 this.expandProcId = false;
\r
22975 toggle : function(){
\r
22976 if(this.expanded){
\r
22984 ensureVisible : function(callback){
\r
22985 var tree = this.getOwnerTree();
\r
22986 tree.expandPath(this.parentNode.getPath(), false, function(){
\r
22987 var node = tree.getNodeById(this.id);
22988 tree.getTreeEl().scrollChildIntoView(node.ui.anchor);
\r
22989 Ext.callback(callback);
\r
22990 }.createDelegate(this));
\r
22994 expandChildNodes : function(deep){
\r
22995 var cs = this.childNodes;
\r
22996 for(var i = 0, len = cs.length; i < len; i++) {
\r
22997 cs[i].expand(deep);
\r
23002 collapseChildNodes : function(deep){
\r
23003 var cs = this.childNodes;
\r
23004 for(var i = 0, len = cs.length; i < len; i++) {
\r
23005 cs[i].collapse(deep);
\r
23010 disable : function(){
\r
23011 this.disabled = true;
\r
23013 if(this.rendered && this.ui.onDisableChange){
23014 this.ui.onDisableChange(this, true);
\r
23016 this.fireEvent("disabledchange", this, true);
\r
23020 enable : function(){
\r
23021 this.disabled = false;
\r
23022 if(this.rendered && this.ui.onDisableChange){
23023 this.ui.onDisableChange(this, false);
\r
23025 this.fireEvent("disabledchange", this, false);
\r
23029 renderChildren : function(suppressEvent){
\r
23030 if(suppressEvent !== false){
\r
23031 this.fireEvent("beforechildrenrendered", this);
\r
23033 var cs = this.childNodes;
\r
23034 for(var i = 0, len = cs.length; i < len; i++){
\r
23035 cs[i].render(true);
\r
23037 this.childrenRendered = true;
\r
23041 sort : function(fn, scope){
\r
23042 Ext.tree.TreeNode.superclass.sort.apply(this, arguments);
\r
23043 if(this.childrenRendered){
\r
23044 var cs = this.childNodes;
\r
23045 for(var i = 0, len = cs.length; i < len; i++){
\r
23046 cs[i].render(true);
\r
23052 render : function(bulkRender){
\r
23053 this.ui.render(bulkRender);
\r
23054 if(!this.rendered){
\r
23056 this.getOwnerTree().registerNode(this);
\r
23057 this.rendered = true;
\r
23058 if(this.expanded){
\r
23059 this.expanded = false;
\r
23060 this.expand(false, false);
\r
23066 renderIndent : function(deep, refresh){
\r
23068 this.ui.childIndent = null;
\r
23070 this.ui.renderIndent();
\r
23071 if(deep === true && this.childrenRendered){
\r
23072 var cs = this.childNodes;
\r
23073 for(var i = 0, len = cs.length; i < len; i++){
\r
23074 cs[i].renderIndent(true, refresh);
\r
23079 beginUpdate : function(){
\r
23080 this.childrenRendered = false;
\r
23083 endUpdate : function(){
\r
23084 if(this.expanded){
\r
23085 this.renderChildren();
\r
23089 destroy : function(){
\r
23090 for(var i = 0,l = this.childNodes.length; i < l; i++){
\r
23091 this.childNodes[i].destroy();
\r
23093 this.childNodes = null;
\r
23094 if(this.ui.destroy){
\r
23095 this.ui.destroy();
\r
23100 Ext.tree.AsyncTreeNode = function(config){
\r
23101 this.loaded = false;
\r
23102 this.loading = false;
\r
23103 Ext.tree.AsyncTreeNode.superclass.constructor.apply(this, arguments);
\r
23105 this.addEvents('beforeload', 'load');
\r
23109 Ext.extend(Ext.tree.AsyncTreeNode, Ext.tree.TreeNode, {
\r
23110 expand : function(deep, anim, callback){
\r
23113 var f = function(){
\r
23115 clearInterval(timer);
\r
23116 this.expand(deep, anim, callback);
\r
23118 }.createDelegate(this);
\r
23119 timer = setInterval(f, 200);
\r
23122 if(!this.loaded){
\r
23123 if(this.fireEvent("beforeload", this) === false){
\r
23126 this.loading = true;
\r
23127 this.ui.beforeLoad(this);
\r
23128 var loader = this.loader || this.attributes.loader || this.getOwnerTree().getLoader();
\r
23130 loader.load(this, this.loadComplete.createDelegate(this, [deep, anim, callback]));
\r
23134 Ext.tree.AsyncTreeNode.superclass.expand.call(this, deep, anim, callback);
\r
23138 isLoading : function(){
\r
23139 return this.loading;
\r
23142 loadComplete : function(deep, anim, callback){
\r
23143 this.loading = false;
\r
23144 this.loaded = true;
\r
23145 this.ui.afterLoad(this);
\r
23146 this.fireEvent("load", this);
\r
23147 this.expand(deep, anim, callback);
\r
23151 isLoaded : function(){
\r
23152 return this.loaded;
\r
23155 hasChildNodes : function(){
\r
23156 if(!this.isLeaf() && !this.loaded){
\r
23159 return Ext.tree.AsyncTreeNode.superclass.hasChildNodes.call(this);
\r
23164 reload : function(callback){
\r
23165 this.collapse(false, false);
\r
23166 while(this.firstChild){
\r
23167 this.removeChild(this.firstChild);
\r
23169 this.childrenRendered = false;
\r
23170 this.loaded = false;
\r
23171 if(this.isHiddenRoot()){
\r
23172 this.expanded = false;
\r
23174 this.expand(false, false, callback);
\r
23178 Ext.tree.TreeNodeUI = function(node){
\r
23179 this.node = node;
\r
23180 this.rendered = false;
\r
23181 this.animating = false;
\r
23182 this.wasLeaf = true;
\r
23183 this.ecc = 'x-tree-ec-icon x-tree-elbow';
\r
23184 this.emptyIcon = Ext.BLANK_IMAGE_URL;
\r
23187 Ext.tree.TreeNodeUI.prototype = {
\r
23189 removeChild : function(node){
\r
23190 if(this.rendered){
\r
23191 this.ctNode.removeChild(node.ui.getEl());
\r
23196 beforeLoad : function(){
\r
23197 this.addClass("x-tree-node-loading");
\r
23201 afterLoad : function(){
\r
23202 this.removeClass("x-tree-node-loading");
\r
23206 onTextChange : function(node, text, oldText){
\r
23207 if(this.rendered){
\r
23208 this.textNode.innerHTML = text;
\r
23213 onDisableChange : function(node, state){
\r
23214 this.disabled = state;
\r
23215 if (this.checkbox) {
\r
23216 this.checkbox.disabled = state;
\r
23219 this.addClass("x-tree-node-disabled");
\r
23221 this.removeClass("x-tree-node-disabled");
\r
23226 onSelectedChange : function(state){
\r
23229 this.addClass("x-tree-selected");
\r
23232 this.removeClass("x-tree-selected");
\r
23237 onMove : function(tree, node, oldParent, newParent, index, refNode){
\r
23238 this.childIndent = null;
\r
23239 if(this.rendered){
\r
23240 var targetNode = newParent.ui.getContainer();
\r
23242 this.holder = document.createElement("div");
\r
23243 this.holder.appendChild(this.wrap);
\r
23246 var insertBefore = refNode ? refNode.ui.getEl() : null;
\r
23247 if(insertBefore){
\r
23248 targetNode.insertBefore(this.wrap, insertBefore);
\r
23250 targetNode.appendChild(this.wrap);
\r
23252 this.node.renderIndent(true);
\r
23257 addClass : function(cls){
\r
23259 Ext.fly(this.elNode).addClass(cls);
\r
23264 removeClass : function(cls){
\r
23266 Ext.fly(this.elNode).removeClass(cls);
\r
23271 remove : function(){
\r
23272 if(this.rendered){
\r
23273 this.holder = document.createElement("div");
\r
23274 this.holder.appendChild(this.wrap);
\r
23279 fireEvent : function(){
\r
23280 return this.node.fireEvent.apply(this.node, arguments);
\r
23284 initEvents : function(){
\r
23285 this.node.on("move", this.onMove, this);
\r
23287 if(this.node.disabled){
\r
23288 this.addClass("x-tree-node-disabled");
\r
23289 if (this.checkbox) {
\r
23290 this.checkbox.disabled = true;
\r
23293 if(this.node.hidden){
\r
23296 var ot = this.node.getOwnerTree();
\r
23297 var dd = ot.enableDD || ot.enableDrag || ot.enableDrop;
\r
23298 if(dd && (!this.node.isRoot || ot.rootVisible)){
\r
23299 Ext.dd.Registry.register(this.elNode, {
\r
23301 handles: this.getDDHandles(),
\r
23308 getDDHandles : function(){
\r
23309 return [this.iconNode, this.textNode, this.elNode];
\r
23313 hide : function(){
\r
23314 this.node.hidden = true;
\r
23316 this.wrap.style.display = "none";
\r
23321 show : function(){
\r
23322 this.node.hidden = false;
\r
23324 this.wrap.style.display = "";
\r
23329 onContextMenu : function(e){
\r
23330 if (this.node.hasListener("contextmenu") || this.node.getOwnerTree().hasListener("contextmenu")) {
\r
23331 e.preventDefault();
\r
23333 this.fireEvent("contextmenu", this.node, e);
\r
23338 onClick : function(e){
\r
23339 if(this.dropping){
\r
23343 if(this.fireEvent("beforeclick", this.node, e) !== false){
\r
23344 var a = e.getTarget('a');
\r
23345 if(!this.disabled && this.node.attributes.href && a){
\r
23346 this.fireEvent("click", this.node, e);
\r
23348 }else if(a && e.ctrlKey){
\r
23351 e.preventDefault();
\r
23352 if(this.disabled){
\r
23356 if(this.node.attributes.singleClickExpand && !this.animating && this.node.hasChildNodes()){
\r
23357 this.node.toggle();
\r
23360 this.fireEvent("click", this.node, e);
\r
23367 onDblClick : function(e){
\r
23368 e.preventDefault();
\r
23369 if(this.disabled){
\r
23372 if(this.checkbox){
\r
23373 this.toggleCheck();
\r
23375 if(!this.animating && this.node.hasChildNodes()){
\r
23376 this.node.toggle();
\r
23378 this.fireEvent("dblclick", this.node, e);
\r
23381 onOver : function(e){
\r
23382 this.addClass('x-tree-node-over');
\r
23385 onOut : function(e){
\r
23386 this.removeClass('x-tree-node-over');
\r
23390 onCheckChange : function(){
\r
23391 var checked = this.checkbox.checked;
\r
23392 this.node.attributes.checked = checked;
\r
23393 this.fireEvent('checkchange', this.node, checked);
\r
23397 ecClick : function(e){
\r
23398 if(!this.animating && (this.node.hasChildNodes() || this.node.attributes.expandable)){
\r
23399 this.node.toggle();
\r
23404 startDrop : function(){
\r
23405 this.dropping = true;
\r
23409 endDrop : function(){
\r
23410 setTimeout(function(){
\r
23411 this.dropping = false;
\r
23412 }.createDelegate(this), 50);
\r
23416 expand : function(){
\r
23417 this.updateExpandIcon();
\r
23418 this.ctNode.style.display = "";
\r
23422 focus : function(){
\r
23423 if(!this.node.preventHScroll){
\r
23424 try{this.anchor.focus();
\r
23426 }else if(!Ext.isIE){
\r
23428 var noscroll = this.node.getOwnerTree().getTreeEl().dom;
\r
23429 var l = noscroll.scrollLeft;
\r
23430 this.anchor.focus();
\r
23431 noscroll.scrollLeft = l;
\r
23437 toggleCheck : function(value){
\r
23438 var cb = this.checkbox;
\r
23440 cb.checked = (value === undefined ? !cb.checked : value);
\r
23445 blur : function(){
\r
23447 this.anchor.blur();
\r
23452 animExpand : function(callback){
\r
23453 var ct = Ext.get(this.ctNode);
\r
23455 if(!this.node.hasChildNodes()){
\r
23456 this.updateExpandIcon();
\r
23457 this.ctNode.style.display = "";
\r
23458 Ext.callback(callback);
\r
23461 this.animating = true;
\r
23462 this.updateExpandIcon();
\r
23464 ct.slideIn('t', {
\r
23465 callback : function(){
\r
23466 this.animating = false;
\r
23467 Ext.callback(callback);
\r
23470 duration: this.node.ownerTree.duration || .25
\r
23475 highlight : function(){
\r
23476 var tree = this.node.getOwnerTree();
\r
23477 Ext.fly(this.wrap).highlight(
\r
23478 tree.hlColor || "C3DAF9",
\r
23479 {endColor: tree.hlBaseColor}
\r
23484 collapse : function(){
\r
23485 this.updateExpandIcon();
\r
23486 this.ctNode.style.display = "none";
\r
23490 animCollapse : function(callback){
\r
23491 var ct = Ext.get(this.ctNode);
\r
23492 ct.enableDisplayMode('block');
\r
23495 this.animating = true;
\r
23496 this.updateExpandIcon();
\r
23498 ct.slideOut('t', {
\r
23499 callback : function(){
\r
23500 this.animating = false;
\r
23501 Ext.callback(callback);
\r
23504 duration: this.node.ownerTree.duration || .25
\r
23509 getContainer : function(){
\r
23510 return this.ctNode;
\r
23514 getEl : function(){
\r
23515 return this.wrap;
\r
23519 appendDDGhost : function(ghostNode){
\r
23520 ghostNode.appendChild(this.elNode.cloneNode(true));
\r
23524 getDDRepairXY : function(){
\r
23525 return Ext.lib.Dom.getXY(this.iconNode);
\r
23529 onRender : function(){
\r
23534 render : function(bulkRender){
\r
23535 var n = this.node, a = n.attributes;
\r
23536 var targetNode = n.parentNode ?
\r
23537 n.parentNode.ui.getContainer() : n.ownerTree.innerCt.dom;
\r
23539 if(!this.rendered){
\r
23540 this.rendered = true;
\r
23542 this.renderElements(n, a, targetNode, bulkRender);
\r
23545 if(this.textNode.setAttributeNS){
\r
23546 this.textNode.setAttributeNS("ext", "qtip", a.qtip);
\r
23548 this.textNode.setAttributeNS("ext", "qtitle", a.qtipTitle);
\r
23551 this.textNode.setAttribute("ext:qtip", a.qtip);
\r
23553 this.textNode.setAttribute("ext:qtitle", a.qtipTitle);
\r
23556 }else if(a.qtipCfg){
\r
23557 a.qtipCfg.target = Ext.id(this.textNode);
\r
23558 Ext.QuickTips.register(a.qtipCfg);
\r
23560 this.initEvents();
\r
23561 if(!this.node.expanded){
\r
23562 this.updateExpandIcon(true);
\r
23565 if(bulkRender === true) {
\r
23566 targetNode.appendChild(this.wrap);
\r
23572 renderElements : function(n, a, targetNode, bulkRender){
\r
23574 this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
\r
23576 var cb = typeof a.checked == 'boolean';
\r
23578 var href = a.href ? a.href : Ext.isGecko ? "" : "#";
\r
23579 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">',
\r
23580 '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
\r
23581 '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
\r
23582 '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />',
\r
23583 cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
\r
23584 '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
\r
23585 a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span unselectable="on">',n.text,"</span></a></div>",
\r
23586 '<ul class="x-tree-node-ct" style="display:none;"></ul>',
\r
23587 "</li>"].join('');
\r
23590 if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){
\r
23591 this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
\r
23593 this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
\r
23596 this.elNode = this.wrap.childNodes[0];
\r
23597 this.ctNode = this.wrap.childNodes[1];
\r
23598 var cs = this.elNode.childNodes;
\r
23599 this.indentNode = cs[0];
\r
23600 this.ecNode = cs[1];
\r
23601 this.iconNode = cs[2];
\r
23604 this.checkbox = cs[3];
\r
23607 this.anchor = cs[index];
\r
23608 this.textNode = cs[index].firstChild;
\r
23612 getAnchor : function(){
\r
23613 return this.anchor;
\r
23617 getTextEl : function(){
\r
23618 return this.textNode;
\r
23622 getIconEl : function(){
\r
23623 return this.iconNode;
\r
23627 isChecked : function(){
\r
23628 return this.checkbox ? this.checkbox.checked : false;
\r
23632 updateExpandIcon : function(){
\r
23633 if(this.rendered){
\r
23634 var n = this.node, c1, c2;
\r
23635 var cls = n.isLast() ? "x-tree-elbow-end" : "x-tree-elbow";
\r
23636 var hasChild = n.hasChildNodes();
\r
23637 if(hasChild || n.attributes.expandable){
\r
23640 c1 = "x-tree-node-collapsed";
\r
23641 c2 = "x-tree-node-expanded";
\r
23644 c1 = "x-tree-node-expanded";
\r
23645 c2 = "x-tree-node-collapsed";
\r
23647 if(this.wasLeaf){
\r
23648 this.removeClass("x-tree-node-leaf");
\r
23649 this.wasLeaf = false;
\r
23651 if(this.c1 != c1 || this.c2 != c2){
\r
23652 Ext.fly(this.elNode).replaceClass(c1, c2);
\r
23653 this.c1 = c1; this.c2 = c2;
\r
23656 if(!this.wasLeaf){
\r
23657 Ext.fly(this.elNode).replaceClass("x-tree-node-expanded", "x-tree-node-leaf");
\r
23660 this.wasLeaf = true;
\r
23663 var ecc = "x-tree-ec-icon "+cls;
\r
23664 if(this.ecc != ecc){
\r
23665 this.ecNode.className = ecc;
\r
23672 getChildIndent : function(){
\r
23673 if(!this.childIndent){
\r
23675 var p = this.node;
\r
23677 if(!p.isRoot || (p.isRoot && p.ownerTree.rootVisible)){
\r
23678 if(!p.isLast()) {
\r
23679 buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-elbow-line" />');
\r
23681 buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-icon" />');
\r
23684 p = p.parentNode;
\r
23686 this.childIndent = buf.join("");
\r
23688 return this.childIndent;
\r
23692 renderIndent : function(){
\r
23693 if(this.rendered){
\r
23695 var p = this.node.parentNode;
\r
23697 indent = p.ui.getChildIndent();
\r
23699 if(this.indentMarkup != indent){
23700 this.indentNode.innerHTML = indent;
\r
23701 this.indentMarkup = indent;
\r
23703 this.updateExpandIcon();
\r
23707 destroy : function(){
\r
23709 Ext.dd.Registry.unregister(this.elNode.id);
\r
23711 delete this.elNode;
\r
23712 delete this.ctNode;
\r
23713 delete this.indentNode;
\r
23714 delete this.ecNode;
\r
23715 delete this.iconNode;
\r
23716 delete this.checkbox;
\r
23717 delete this.anchor;
\r
23718 delete this.textNode;
\r
23719 Ext.removeNode(this.ctNode);
\r
23724 Ext.tree.RootTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
\r
23726 render : function(){
\r
23727 if(!this.rendered){
\r
23728 var targetNode = this.node.ownerTree.innerCt.dom;
\r
23729 this.node.expanded = true;
\r
23730 targetNode.innerHTML = '<div class="x-tree-root-node"></div>';
\r
23731 this.wrap = this.ctNode = targetNode.firstChild;
\r
23734 collapse : Ext.emptyFn,
\r
23735 expand : Ext.emptyFn
\r
23738 Ext.tree.TreeLoader = function(config){
\r
23739 this.baseParams = {};
\r
23740 this.requestMethod = "POST";
\r
23741 Ext.apply(this, config);
\r
23752 Ext.tree.TreeLoader.superclass.constructor.call(this);
\r
23755 Ext.extend(Ext.tree.TreeLoader, Ext.util.Observable, {
\r
23763 uiProviders : {},
\r
23766 clearOnLoad : true,
\r
23769 load : function(node, callback){
\r
23770 if(this.clearOnLoad){
\r
23771 while(node.firstChild){
\r
23772 node.removeChild(node.firstChild);
\r
23775 if(this.doPreload(node)){
23776 if(typeof callback == "function"){
\r
23779 }else if(this.dataUrl||this.url){
\r
23780 this.requestData(node, callback);
\r
23784 doPreload : function(node){
\r
23785 if(node.attributes.children){
\r
23786 if(node.childNodes.length < 1){
23787 var cs = node.attributes.children;
\r
23788 node.beginUpdate();
\r
23789 for(var i = 0, len = cs.length; i < len; i++){
\r
23790 var cn = node.appendChild(this.createNode(cs[i]));
\r
23791 if(this.preloadChildren){
\r
23792 this.doPreload(cn);
\r
23795 node.endUpdate();
\r
23803 getParams: function(node){
\r
23804 var buf = [], bp = this.baseParams;
\r
23805 for(var key in bp){
\r
23806 if(typeof bp[key] != "function"){
\r
23807 buf.push(encodeURIComponent(key), "=", encodeURIComponent(bp[key]), "&");
\r
23810 buf.push("node=", encodeURIComponent(node.id));
\r
23811 return buf.join("");
\r
23814 requestData : function(node, callback){
\r
23815 if(this.fireEvent("beforeload", this, node, callback) !== false){
\r
23816 this.transId = Ext.Ajax.request({
\r
23817 method:this.requestMethod,
\r
23818 url: this.dataUrl||this.url,
\r
23819 success: this.handleResponse,
\r
23820 failure: this.handleFailure,
\r
23822 argument: {callback: callback, node: node},
\r
23823 params: this.getParams(node)
\r
23828 if(typeof callback == "function"){
\r
23834 isLoading : function(){
\r
23835 return this.transId ? true : false;
\r
23838 abort : function(){
\r
23839 if(this.isLoading()){
\r
23840 Ext.Ajax.abort(this.transId);
\r
23845 createNode : function(attr){
\r
23847 if(this.baseAttrs){
\r
23848 Ext.applyIf(attr, this.baseAttrs);
\r
23850 if(this.applyLoader !== false){
\r
23851 attr.loader = this;
\r
23853 if(typeof attr.uiProvider == 'string'){
\r
23854 attr.uiProvider = this.uiProviders[attr.uiProvider] || eval(attr.uiProvider);
\r
23856 return(attr.leaf ?
\r
23857 new Ext.tree.TreeNode(attr) :
\r
23858 new Ext.tree.AsyncTreeNode(attr));
\r
23861 processResponse : function(response, node, callback){
\r
23862 var json = response.responseText;
\r
23864 var o = eval("("+json+")");
\r
23865 node.beginUpdate();
\r
23866 for(var i = 0, len = o.length; i < len; i++){
\r
23867 var n = this.createNode(o[i]);
\r
23869 node.appendChild(n);
\r
23872 node.endUpdate();
\r
23873 if(typeof callback == "function"){
\r
23874 callback(this, node);
\r
23877 this.handleFailure(response);
\r
23881 handleResponse : function(response){
\r
23882 this.transId = false;
\r
23883 var a = response.argument;
\r
23884 this.processResponse(response, a.node, a.callback);
\r
23885 this.fireEvent("load", this, a.node, response);
\r
23888 handleFailure : function(response){
\r
23889 this.transId = false;
\r
23890 var a = response.argument;
\r
23891 this.fireEvent("loadexception", this, a.node, response);
\r
23892 if(typeof a.callback == "function"){
\r
23893 a.callback(this, a.node);
\r
23898 Ext.tree.TreeFilter = function(tree, config){
\r
23899 this.tree = tree;
\r
23900 this.filtered = {};
\r
23901 Ext.apply(this, config);
\r
23904 Ext.tree.TreeFilter.prototype = {
\r
23905 clearBlank:false,
\r
23911 filter : function(value, attr, startNode){
\r
23912 attr = attr || "text";
\r
23914 if(typeof value == "string"){
\r
23915 var vlen = value.length;
\r
23917 if(vlen == 0 && this.clearBlank){
\r
23921 value = value.toLowerCase();
\r
23923 return n.attributes[attr].substr(0, vlen).toLowerCase() == value;
\r
23925 }else if(value.exec){
23927 return value.test(n.attributes[attr]);
\r
23930 throw 'Illegal filter type, must be string or regex';
\r
23932 this.filterBy(f, null, startNode);
\r
23936 filterBy : function(fn, scope, startNode){
\r
23937 startNode = startNode || this.tree.root;
\r
23938 if(this.autoClear){
\r
23941 var af = this.filtered, rv = this.reverse;
\r
23942 var f = function(n){
\r
23943 if(n == startNode){
\r
23949 var m = fn.call(scope || n, n);
\r
23957 startNode.cascade(f);
\r
23959 for(var id in af){
\r
23960 if(typeof id != "function"){
\r
23962 if(n && n.parentNode){
\r
23963 n.parentNode.removeChild(n);
\r
23971 clear : function(){
\r
23972 var t = this.tree;
\r
23973 var af = this.filtered;
\r
23974 for(var id in af){
\r
23975 if(typeof id != "function"){
\r
23982 this.filtered = {};
\r
23987 Ext.tree.TreeSorter = function(tree, config){
\r
23988 Ext.apply(this, config);
\r
23989 tree.on("beforechildrenrendered", this.doSort, this);
\r
23990 tree.on("append", this.updateSort, this);
\r
23991 tree.on("insert", this.updateSort, this);
\r
23992 tree.on("textchange", this.updateSortParent, this);
\r
23994 var dsc = this.dir && this.dir.toLowerCase() == "desc";
\r
23995 var p = this.property || "text";
\r
23996 var sortType = this.sortType;
\r
23997 var fs = this.folderSort;
\r
23998 var cs = this.caseSensitive === true;
\r
23999 var leafAttr = this.leafAttr || 'leaf';
\r
24001 this.sortFn = function(n1, n2){
\r
24003 if(n1.attributes[leafAttr] && !n2.attributes[leafAttr]){
\r
24006 if(!n1.attributes[leafAttr] && n2.attributes[leafAttr]){
\r
24010 var v1 = sortType ? sortType(n1) : (cs ? n1.attributes[p] : n1.attributes[p].toUpperCase());
\r
24011 var v2 = sortType ? sortType(n2) : (cs ? n2.attributes[p] : n2.attributes[p].toUpperCase());
\r
24013 return dsc ? +1 : -1;
\r
24014 }else if(v1 > v2){
\r
24015 return dsc ? -1 : +1;
\r
24022 Ext.tree.TreeSorter.prototype = {
\r
24023 doSort : function(node){
\r
24024 node.sort(this.sortFn);
\r
24027 compareNodes : function(n1, n2){
\r
24028 return (n1.text.toUpperCase() > n2.text.toUpperCase() ? 1 : -1);
\r
24031 updateSort : function(tree, node){
\r
24032 if(node.childrenRendered){
\r
24033 this.doSort.defer(1, this, [node]);
\r
24037 updateSortParent : function(node){
\r
24038 var p = node.parentNode;
\r
24039 if(p && p.childrenRendered){
\r
24040 this.doSort.defer(1, this, [p]);
\r
24045 if(Ext.dd.DropZone){
\r
24047 Ext.tree.TreeDropZone = function(tree, config){
\r
24049 this.allowParentInsert = false;
\r
24051 this.allowContainerDrop = false;
\r
24053 this.appendOnly = false;
\r
24054 Ext.tree.TreeDropZone.superclass.constructor.call(this, tree.innerCt, config);
\r
24056 this.tree = tree;
\r
24058 this.dragOverData = {};
\r
24060 this.lastInsertClass = "x-tree-no-status";
\r
24063 Ext.extend(Ext.tree.TreeDropZone, Ext.dd.DropZone, {
\r
24065 ddGroup : "TreeDD",
\r
24068 expandDelay : 1000,
\r
24071 expandNode : function(node){
\r
24072 if(node.hasChildNodes() && !node.isExpanded()){
\r
24073 node.expand(false, null, this.triggerCacheRefresh.createDelegate(this));
\r
24078 queueExpand : function(node){
\r
24079 this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]);
\r
24083 cancelExpand : function(){
\r
24084 if(this.expandProcId){
\r
24085 clearTimeout(this.expandProcId);
\r
24086 this.expandProcId = false;
\r
24091 isValidDropPoint : function(n, pt, dd, e, data){
\r
24092 if(!n || !data){ return false; }
\r
24093 var targetNode = n.node;
\r
24094 var dropNode = data.node;
\r
24096 if(!(targetNode && targetNode.isTarget && pt)){
\r
24099 if(pt == "append" && targetNode.allowChildren === false){
\r
24102 if((pt == "above" || pt == "below") && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){
\r
24105 if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){
\r
24109 var overEvent = this.dragOverData;
\r
24110 overEvent.tree = this.tree;
\r
24111 overEvent.target = targetNode;
\r
24112 overEvent.data = data;
\r
24113 overEvent.point = pt;
\r
24114 overEvent.source = dd;
\r
24115 overEvent.rawEvent = e;
\r
24116 overEvent.dropNode = dropNode;
\r
24117 overEvent.cancel = false;
\r
24118 var result = this.tree.fireEvent("nodedragover", overEvent);
\r
24119 return overEvent.cancel === false && result !== false;
\r
24123 getDropPoint : function(e, n, dd){
\r
24126 return tn.allowChildren !== false ? "append" : false;
24128 var dragEl = n.ddel;
\r
24129 var t = Ext.lib.Dom.getY(dragEl), b = t + dragEl.offsetHeight;
\r
24130 var y = Ext.lib.Event.getPageY(e);
\r
24131 var noAppend = tn.allowChildren === false || tn.isLeaf();
\r
24132 if(this.appendOnly || tn.parentNode.allowChildren === false){
\r
24133 return noAppend ? false : "append";
\r
24135 var noBelow = false;
\r
24136 if(!this.allowParentInsert){
\r
24137 noBelow = tn.hasChildNodes() && tn.isExpanded();
\r
24139 var q = (b - t) / (noAppend ? 2 : 3);
\r
24140 if(y >= t && y < (t + q)){
\r
24142 }else if(!noBelow && (noAppend || y >= b-q && y <= b)){
\r
24150 onNodeEnter : function(n, dd, e, data){
\r
24151 this.cancelExpand();
\r
24155 onNodeOver : function(n, dd, e, data){
\r
24156 var pt = this.getDropPoint(e, n, dd);
\r
24157 var node = n.node;
\r
24160 if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){
\r
24161 this.queueExpand(node);
\r
24162 }else if(pt != "append"){
\r
24163 this.cancelExpand();
\r
24167 var returnCls = this.dropNotAllowed;
\r
24168 if(this.isValidDropPoint(n, pt, dd, e, data)){
\r
24172 if(pt == "above"){
\r
24173 returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between";
\r
24174 cls = "x-tree-drag-insert-above";
\r
24175 }else if(pt == "below"){
\r
24176 returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between";
\r
24177 cls = "x-tree-drag-insert-below";
\r
24179 returnCls = "x-tree-drop-ok-append";
\r
24180 cls = "x-tree-drag-append";
\r
24182 if(this.lastInsertClass != cls){
\r
24183 Ext.fly(el).replaceClass(this.lastInsertClass, cls);
\r
24184 this.lastInsertClass = cls;
\r
24188 return returnCls;
\r
24192 onNodeOut : function(n, dd, e, data){
\r
24193 this.cancelExpand();
\r
24194 this.removeDropIndicators(n);
\r
24198 onNodeDrop : function(n, dd, e, data){
\r
24199 var point = this.getDropPoint(e, n, dd);
\r
24200 var targetNode = n.node;
\r
24201 targetNode.ui.startDrop();
\r
24202 if(!this.isValidDropPoint(n, point, dd, e, data)){
\r
24203 targetNode.ui.endDrop();
\r
24207 var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
\r
24208 var dropEvent = {
\r
24209 tree : this.tree,
\r
24210 target: targetNode,
\r
24215 dropNode: dropNode,
\r
24216 cancel: !dropNode,
\r
24217 dropStatus: false
\r
24219 var retval = this.tree.fireEvent("beforenodedrop", dropEvent);
\r
24220 if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
\r
24221 targetNode.ui.endDrop();
\r
24222 return dropEvent.dropStatus;
\r
24225 targetNode = dropEvent.target;
\r
24226 if(point == "append" && !targetNode.isExpanded()){
\r
24227 targetNode.expand(false, null, function(){
\r
24228 this.completeDrop(dropEvent);
\r
24229 }.createDelegate(this));
\r
24231 this.completeDrop(dropEvent);
\r
24237 completeDrop : function(de){
\r
24238 var ns = de.dropNode, p = de.point, t = de.target;
\r
24239 if(!Ext.isArray(ns)){
\r
24243 for(var i = 0, len = ns.length; i < len; i++){
\r
24245 if(p == "above"){
\r
24246 t.parentNode.insertBefore(n, t);
\r
24247 }else if(p == "below"){
\r
24248 t.parentNode.insertBefore(n, t.nextSibling);
\r
24250 t.appendChild(n);
\r
24254 if(this.tree.hlDrop){
\r
24255 n.ui.highlight();
\r
24258 this.tree.fireEvent("nodedrop", de);
\r
24262 afterNodeMoved : function(dd, data, e, targetNode, dropNode){
\r
24263 if(this.tree.hlDrop){
\r
24264 dropNode.ui.focus();
\r
24265 dropNode.ui.highlight();
\r
24267 this.tree.fireEvent("nodedrop", this.tree, targetNode, data, dd, e);
\r
24271 getTree : function(){
\r
24272 return this.tree;
\r
24276 removeDropIndicators : function(n){
\r
24279 Ext.fly(el).removeClass([
\r
24280 "x-tree-drag-insert-above",
\r
24281 "x-tree-drag-insert-below",
\r
24282 "x-tree-drag-append"]);
\r
24283 this.lastInsertClass = "_noclass";
\r
24288 beforeDragDrop : function(target, e, id){
\r
24289 this.cancelExpand();
\r
24294 afterRepair : function(data){
\r
24295 if(data && Ext.enableFx){
\r
24296 data.node.ui.highlight();
\r
24298 this.hideProxy();
\r
24304 if(Ext.dd.DragZone){
\r
24305 Ext.tree.TreeDragZone = function(tree, config){
\r
24306 Ext.tree.TreeDragZone.superclass.constructor.call(this, tree.getTreeEl(), config);
\r
24308 this.tree = tree;
\r
24311 Ext.extend(Ext.tree.TreeDragZone, Ext.dd.DragZone, {
\r
24313 ddGroup : "TreeDD",
\r
24316 onBeforeDrag : function(data, e){
\r
24317 var n = data.node;
\r
24318 return n && n.draggable && !n.disabled;
\r
24322 onInitDrag : function(e){
\r
24323 var data = this.dragData;
\r
24324 this.tree.getSelectionModel().select(data.node);
\r
24325 this.tree.eventModel.disable();
\r
24326 this.proxy.update("");
\r
24327 data.node.ui.appendDDGhost(this.proxy.ghost.dom);
\r
24328 this.tree.fireEvent("startdrag", this.tree, data.node, e);
\r
24332 getRepairXY : function(e, data){
\r
24333 return data.node.ui.getDDRepairXY();
\r
24337 onEndDrag : function(data, e){
\r
24338 this.tree.eventModel.enable.defer(100, this.tree.eventModel);
\r
24339 this.tree.fireEvent("enddrag", this.tree, data.node, e);
\r
24343 onValidDrop : function(dd, e, id){
\r
24344 this.tree.fireEvent("dragdrop", this.tree, this.dragData.node, dd, e);
\r
24345 this.hideProxy();
\r
24349 beforeInvalidDrop : function(e, id){
\r
24351 var sm = this.tree.getSelectionModel();
\r
24352 sm.clearSelections();
\r
24353 sm.select(this.dragData.node);
\r
24358 Ext.tree.TreeEditor = function(tree, config){
24359 config = config || {};
24360 var field = config.events ? config : new Ext.form.TextField(config);
24361 Ext.tree.TreeEditor.superclass.constructor.call(this, field);
24365 if(!tree.rendered){
24366 tree.on('render', this.initEditor, this);
24368 this.initEditor(tree);
24372 Ext.extend(Ext.tree.TreeEditor, Ext.Editor, {
24379 cls: "x-small-editor x-tree-editor",
24388 initEditor : function(tree){
24389 tree.on('beforeclick', this.beforeNodeClick, this);
24390 tree.on('dblclick', this.onNodeDblClick, this);
24391 this.on('complete', this.updateNode, this);
24392 this.on('beforestartedit', this.fitToTree, this);
24393 this.on('startedit', this.bindScroll, this, {delay:10});
24394 this.on('specialkey', this.onSpecialKey, this);
24397 fitToTree : function(ed, el){
24398 var td = this.tree.getTreeEl().dom, nd = el.dom;
24399 if(td.scrollLeft > nd.offsetLeft){ td.scrollLeft = nd.offsetLeft;
24403 (td.clientWidth > 20 ? td.clientWidth : td.offsetWidth) - Math.max(0, nd.offsetLeft-td.scrollLeft) - 5);
24404 this.setSize(w, '');
24407 triggerEdit : function(node, defer){
24408 this.completeEdit();
24409 if(node.attributes.editable !== false){
24410 this.editNode = node;
24411 this.autoEditTimer = this.startEdit.defer(this.editDelay, this, [node.ui.textNode, node.text]);
24416 bindScroll : function(){
24417 this.tree.getTreeEl().on('scroll', this.cancelEdit, this);
24420 beforeNodeClick : function(node, e){
24421 clearTimeout(this.autoEditTimer);
24422 if(this.tree.getSelectionModel().isSelected(node)){
24424 return this.triggerEdit(node);
24428 onNodeDblClick : function(node, e){
24429 clearTimeout(this.autoEditTimer);
24432 updateNode : function(ed, value){
24433 this.tree.getTreeEl().un('scroll', this.cancelEdit, this);
24434 this.editNode.setText(value);
24437 onHide : function(){
24438 Ext.tree.TreeEditor.superclass.onHide.call(this);
24440 this.editNode.ui.focus.defer(50, this.editNode.ui);
24444 onSpecialKey : function(field, e){
24445 var k = e.getKey();
24449 }else if(k == e.ENTER && !e.hasModifier()){
24451 this.completeEdit();
24456 Ext.menu.Menu = function(config){
24457 if(Ext.isArray(config)){
24458 config = {items:config};
24460 Ext.apply(this, config);
24461 this.id = this.id || Ext.id();
24480 Ext.menu.MenuMgr.register(this);
24481 Ext.menu.Menu.superclass.constructor.call(this);
24482 var mis = this.items;
24485 this.items = new Ext.util.MixedCollection();
24487 this.add.apply(this, mis);
24491 Ext.extend(Ext.menu.Menu, Ext.util.Observable, {
24499 subMenuAlign : "tl-tr?",
24501 defaultAlign : "tl-bl?",
24503 allowOtherMenus : false,
24507 createEl : function(){
24508 return new Ext.Layer({
24510 shadow:this.shadow,
24512 parentEl: this.parentEl || document.body,
24517 render : function(){
24521 var el = this.el = this.createEl();
24524 this.keyNav = new Ext.menu.MenuNav(this);
24527 el.addClass("x-menu-plain");
24530 el.addClass(this.cls);
24532 this.focusEl = el.createChild({
24533 tag: "a", cls: "x-menu-focus", href: "#", onclick: "return false;", tabIndex:"-1"
24535 var ul = el.createChild({tag: "ul", cls: "x-menu-list"});
24536 ul.on("click", this.onClick, this);
24537 ul.on("mouseover", this.onMouseOver, this);
24538 ul.on("mouseout", this.onMouseOut, this);
24539 this.items.each(function(item){
24540 var li = document.createElement("li");
24541 li.className = "x-menu-list-item";
24542 ul.dom.appendChild(li);
24543 item.render(li, this);
24549 autoWidth : function(){
24550 var el = this.el, ul = this.ul;
24554 var w = this.width;
24557 }else if(Ext.isIE){
24558 el.setWidth(this.minWidth);
24559 var t = el.dom.offsetWidth; el.setWidth(ul.getWidth()+el.getFrameWidth("lr"));
24563 delayAutoWidth : function(){
24566 this.awTask = new Ext.util.DelayedTask(this.autoWidth, this);
24568 this.awTask.delay(20);
24572 findTargetItem : function(e){
24573 var t = e.getTarget(".x-menu-list-item", this.ul, true);
24574 if(t && t.menuItemId){
24575 return this.items.get(t.menuItemId);
24579 onClick : function(e){
24581 if(t = this.findTargetItem(e)){
24583 this.fireEvent("click", this, t, e);
24587 setActiveItem : function(item, autoExpand){
24588 if(item != this.activeItem){
24589 if(this.activeItem){
24590 this.activeItem.deactivate();
24592 this.activeItem = item;
24593 item.activate(autoExpand);
24594 }else if(autoExpand){
24599 tryActivate : function(start, step){
24600 var items = this.items;
24601 for(var i = start, len = items.length; i >= 0 && i < len; i+= step){
24602 var item = items.get(i);
24603 if(!item.disabled && item.canActivate){
24604 this.setActiveItem(item, false);
24611 onMouseOver : function(e){
24613 if(t = this.findTargetItem(e)){
24614 if(t.canActivate && !t.disabled){
24615 this.setActiveItem(t, true);
24618 this.fireEvent("mouseover", this, e, t);
24621 onMouseOut : function(e){
24623 if(t = this.findTargetItem(e)){
24624 if(t == this.activeItem && t.shouldDeactivate(e)){
24625 this.activeItem.deactivate();
24626 delete this.activeItem;
24629 this.fireEvent("mouseout", this, e, t);
24633 isVisible : function(){
24634 return this.el && !this.hidden;
24638 show : function(el, pos, parentMenu){
24639 this.parentMenu = parentMenu;
24643 this.fireEvent("beforeshow", this);
24644 this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign), parentMenu, false);
24648 showAt : function(xy, parentMenu, _e){
24649 this.parentMenu = parentMenu;
24654 this.fireEvent("beforeshow", this);
24655 xy = this.el.adjustForConstraints(xy);
24659 this.hidden = false;
24661 this.fireEvent("show", this);
24666 focus : function(){
24668 this.doFocus.defer(50, this);
24672 doFocus : function(){
24674 this.focusEl.focus();
24679 hide : function(deep){
24680 if(this.el && this.isVisible()){
24681 this.fireEvent("beforehide", this);
24682 if(this.activeItem){
24683 this.activeItem.deactivate();
24684 this.activeItem = null;
24687 this.hidden = true;
24688 this.fireEvent("hide", this);
24690 if(deep === true && this.parentMenu){
24691 this.parentMenu.hide(true);
24697 var a = arguments, l = a.length, item;
24698 for(var i = 0; i < l; i++){
24700 if(el.render){ item = this.addItem(el);
24701 }else if(typeof el == "string"){ if(el == "separator" || el == "-"){
24702 item = this.addSeparator();
24704 item = this.addText(el);
24706 }else if(el.tagName || el.el){ item = this.addElement(el);
24707 }else if(typeof el == "object"){ Ext.applyIf(el, this.defaults);
24708 item = this.addMenuItem(el);
24715 getEl : function(){
24723 addSeparator : function(){
24724 return this.addItem(new Ext.menu.Separator());
24728 addElement : function(el){
24729 return this.addItem(new Ext.menu.BaseItem(el));
24733 addItem : function(item){
24734 this.items.add(item);
24736 var li = document.createElement("li");
24737 li.className = "x-menu-list-item";
24738 this.ul.dom.appendChild(li);
24739 item.render(li, this);
24740 this.delayAutoWidth();
24746 addMenuItem : function(config){
24747 if(!(config instanceof Ext.menu.Item)){
24748 if(typeof config.checked == "boolean"){ config = new Ext.menu.CheckItem(config);
24750 config = new Ext.menu.Item(config);
24753 return this.addItem(config);
24757 addText : function(text){
24758 return this.addItem(new Ext.menu.TextItem(text));
24762 insert : function(index, item){
24763 this.items.insert(index, item);
24765 var li = document.createElement("li");
24766 li.className = "x-menu-list-item";
24767 this.ul.dom.insertBefore(li, this.ul.dom.childNodes[index]);
24768 item.render(li, this);
24769 this.delayAutoWidth();
24775 remove : function(item){
24776 this.items.removeKey(item.id);
24781 removeAll : function(){
24783 while(f = this.items.first()){
24789 destroy : function(){
24790 this.beforeDestroy();
24791 Ext.menu.MenuMgr.unregister(this);
24793 this.keyNav.disable();
24797 this.ul.removeAllListeners();
24804 beforeDestroy : Ext.emptyFn
24808 Ext.menu.MenuNav = function(menu){
24809 Ext.menu.MenuNav.superclass.constructor.call(this, menu.el);
24810 this.scope = this.menu = menu;
24813 Ext.extend(Ext.menu.MenuNav, Ext.KeyNav, {
24814 doRelay : function(e, h){
24815 var k = e.getKey();
24816 if(!this.menu.activeItem && e.isNavKeyPress() && k != e.SPACE && k != e.RETURN){
24817 this.menu.tryActivate(0, 1);
24820 return h.call(this.scope || this, e, this.menu);
24823 up : function(e, m){
24824 if(!m.tryActivate(m.items.indexOf(m.activeItem)-1, -1)){
24825 m.tryActivate(m.items.length-1, -1);
24829 down : function(e, m){
24830 if(!m.tryActivate(m.items.indexOf(m.activeItem)+1, 1)){
24831 m.tryActivate(0, 1);
24835 right : function(e, m){
24837 m.activeItem.expandMenu(true);
24841 left : function(e, m){
24843 if(m.parentMenu && m.parentMenu.activeItem){
24844 m.parentMenu.activeItem.activate();
24848 enter : function(e, m){
24850 e.stopPropagation();
24851 m.activeItem.onClick(e);
24852 m.fireEvent("click", this, m.activeItem);
24858 Ext.menu.MenuMgr = function(){
24859 var menus, active, groups = {}, attached = false, lastShow = new Date();
24863 active = new Ext.util.MixedCollection();
24864 Ext.getDoc().addKeyListener(27, function(){
24865 if(active.length > 0){
24871 function hideAll(){
24872 if(active && active.length > 0){
24873 var c = active.clone();
24874 c.each(function(m){
24880 function onHide(m){
24882 if(active.length < 1){
24883 Ext.getDoc().un("mousedown", onMouseDown);
24888 function onShow(m){
24889 var last = active.last();
24890 lastShow = new Date();
24893 Ext.getDoc().on("mousedown", onMouseDown);
24897 m.getEl().setZIndex(parseInt(m.parentMenu.getEl().getStyle("z-index"), 10) + 3);
24898 m.parentMenu.activeChild = m;
24899 }else if(last && last.isVisible()){
24900 m.getEl().setZIndex(parseInt(last.getEl().getStyle("z-index"), 10) + 3);
24904 function onBeforeHide(m){
24906 m.activeChild.hide();
24908 if(m.autoHideTimer){
24909 clearTimeout(m.autoHideTimer);
24910 delete m.autoHideTimer;
24914 function onBeforeShow(m){
24915 var pm = m.parentMenu;
24916 if(!pm && !m.allowOtherMenus){
24918 }else if(pm && pm.activeChild){
24919 pm.activeChild.hide();
24923 function onMouseDown(e){
24924 if(lastShow.getElapsed() > 50 && active.length > 0 && !e.getTarget(".x-menu")){
24929 function onBeforeCheck(mi, state){
24931 var g = groups[mi.group];
24932 for(var i = 0, l = g.length; i < l; i++){
24934 g[i].setChecked(false);
24943 hideAll : function(){
24947 register : function(menu){
24951 menus[menu.id] = menu;
24952 menu.on("beforehide", onBeforeHide);
24953 menu.on("hide", onHide);
24954 menu.on("beforeshow", onBeforeShow);
24955 menu.on("show", onShow);
24956 var g = menu.group;
24957 if(g && menu.events["checkchange"]){
24961 groups[g].push(menu);
24962 menu.on("checkchange", onCheck);
24967 get : function(menu){
24968 if(typeof menu == "string"){ if(!menus){ return null;
24970 return menus[menu];
24971 }else if(menu.events){ return menu;
24972 }else if(typeof menu.length == 'number'){ return new Ext.menu.Menu({items:menu});
24973 }else{ return new Ext.menu.Menu(menu);
24977 unregister : function(menu){
24978 delete menus[menu.id];
24979 menu.un("beforehide", onBeforeHide);
24980 menu.un("hide", onHide);
24981 menu.un("beforeshow", onBeforeShow);
24982 menu.un("show", onShow);
24983 var g = menu.group;
24984 if(g && menu.events["checkchange"]){
24985 groups[g].remove(menu);
24986 menu.un("checkchange", onCheck);
24990 registerCheckable : function(menuItem){
24991 var g = menuItem.group;
24996 groups[g].push(menuItem);
24997 menuItem.on("beforecheckchange", onBeforeCheck);
25001 unregisterCheckable : function(menuItem){
25002 var g = menuItem.group;
25004 groups[g].remove(menuItem);
25005 menuItem.un("beforecheckchange", onBeforeCheck);
25009 getCheckedItem : function(groupId){
25010 var g = groups[groupId];
25012 for(var i = 0, l = g.length; i < l; i++){
25021 setCheckedItem : function(groupId, itemId){
25022 var g = groups[groupId];
25024 for(var i = 0, l = g.length; i < l; i++){
25025 if(g[i].id == itemId){
25026 g[i].setChecked(true);
25036 Ext.menu.BaseItem = function(config){
25037 Ext.menu.BaseItem.superclass.constructor.call(this, config);
25049 this.on("click", this.handler, this.scope);
25053 Ext.extend(Ext.menu.BaseItem, Ext.Component, {
25057 canActivate : false,
25059 activeClass : "x-menu-item-active",
25061 hideOnClick : true,
25065 ctype: "Ext.menu.BaseItem",
25067 actionMode : "container",
25069 render : function(container, parentMenu){
25070 this.parentMenu = parentMenu;
25071 Ext.menu.BaseItem.superclass.render.call(this, container);
25072 this.container.menuItemId = this.id;
25075 onRender : function(container, position){
25076 this.el = Ext.get(this.el);
25077 container.dom.appendChild(this.el.dom);
25081 setHandler : function(handler, scope){
25083 this.un("click", this.handler, this.scope);
25085 this.on("click", this.handler = handler, this.scope = scope);
25088 onClick : function(e){
25089 if(!this.disabled && this.fireEvent("click", this, e) !== false
25090 && this.parentMenu.fireEvent("itemclick", this, e) !== false){
25091 this.handleClick(e);
25097 activate : function(){
25101 var li = this.container;
25102 li.addClass(this.activeClass);
25103 this.region = li.getRegion().adjust(2, 2, -2, -2);
25104 this.fireEvent("activate", this);
25108 deactivate : function(){
25109 this.container.removeClass(this.activeClass);
25110 this.fireEvent("deactivate", this);
25113 shouldDeactivate : function(e){
25114 return !this.region || !this.region.contains(e.getPoint());
25117 handleClick : function(e){
25118 if(this.hideOnClick){
25119 this.parentMenu.hide.defer(this.hideDelay, this.parentMenu, [true]);
25123 expandMenu : function(autoActivate){
25126 hideMenu : function(){
25130 Ext.menu.TextItem = function(text){
25132 Ext.menu.TextItem.superclass.constructor.call(this);
25135 Ext.extend(Ext.menu.TextItem, Ext.menu.BaseItem, {
25138 hideOnClick : false,
25140 itemCls : "x-menu-text",
25142 onRender : function(){
25143 var s = document.createElement("span");
25144 s.className = this.itemCls;
25145 s.innerHTML = this.text;
25147 Ext.menu.TextItem.superclass.onRender.apply(this, arguments);
25151 Ext.menu.Separator = function(config){
25152 Ext.menu.Separator.superclass.constructor.call(this, config);
25155 Ext.extend(Ext.menu.Separator, Ext.menu.BaseItem, {
25157 itemCls : "x-menu-sep",
25159 hideOnClick : false,
25161 onRender : function(li){
25162 var s = document.createElement("span");
25163 s.className = this.itemCls;
25164 s.innerHTML = " ";
25166 li.addClass("x-menu-sep-li");
25167 Ext.menu.Separator.superclass.onRender.apply(this, arguments);
25171 Ext.menu.Item = function(config){
25172 Ext.menu.Item.superclass.constructor.call(this, config);
25174 this.menu = Ext.menu.MenuMgr.get(this.menu);
25177 Ext.extend(Ext.menu.Item, Ext.menu.BaseItem, {
25184 itemCls : "x-menu-item",
25186 canActivate : true,
25191 ctype: "Ext.menu.Item",
25193 onRender : function(container, position){
25194 var el = document.createElement("a");
25195 el.hideFocus = true;
25196 el.unselectable = "on";
25197 el.href = this.href || "#";
25198 if(this.hrefTarget){
25199 el.target = this.hrefTarget;
25201 el.className = this.itemCls + (this.menu ? " x-menu-item-arrow" : "") + (this.cls ? " " + this.cls : "");
25202 el.innerHTML = String.format(
25203 '<img src="{0}" class="x-menu-item-icon {2}" />{1}',
25204 this.icon || Ext.BLANK_IMAGE_URL, this.itemText||this.text, this.iconCls || '');
25206 Ext.menu.Item.superclass.onRender.call(this, container, position);
25210 setText : function(text){
25213 this.el.update(String.format(
25214 '<img src="{0}" class="x-menu-item-icon {2}">{1}',
25215 this.icon || Ext.BLANK_IMAGE_URL, this.text, this.iconCls || ''));
25216 this.parentMenu.autoWidth();
25221 setIconClass : function(cls){
25222 var oldCls = this.iconCls;
25223 this.iconCls = cls;
25225 this.el.child('img.x-menu-item-icon').replaceClass(oldCls, this.iconCls);
25229 handleClick : function(e){
25230 if(!this.href){ e.stopEvent();
25232 Ext.menu.Item.superclass.handleClick.apply(this, arguments);
25235 activate : function(autoExpand){
25236 if(Ext.menu.Item.superclass.activate.apply(this, arguments)){
25245 shouldDeactivate : function(e){
25246 if(Ext.menu.Item.superclass.shouldDeactivate.call(this, e)){
25247 if(this.menu && this.menu.isVisible()){
25248 return !this.menu.getEl().getRegion().contains(e.getPoint());
25255 deactivate : function(){
25256 Ext.menu.Item.superclass.deactivate.apply(this, arguments);
25260 expandMenu : function(autoActivate){
25261 if(!this.disabled && this.menu){
25262 clearTimeout(this.hideTimer);
25263 delete this.hideTimer;
25264 if(!this.menu.isVisible() && !this.showTimer){
25265 this.showTimer = this.deferExpand.defer(this.showDelay, this, [autoActivate]);
25266 }else if (this.menu.isVisible() && autoActivate){
25267 this.menu.tryActivate(0, 1);
25272 deferExpand : function(autoActivate){
25273 delete this.showTimer;
25274 this.menu.show(this.container, this.parentMenu.subMenuAlign || "tl-tr?", this.parentMenu);
25276 this.menu.tryActivate(0, 1);
25280 hideMenu : function(){
25281 clearTimeout(this.showTimer);
25282 delete this.showTimer;
25283 if(!this.hideTimer && this.menu && this.menu.isVisible()){
25284 this.hideTimer = this.deferHide.defer(this.hideDelay, this);
25288 deferHide : function(){
25289 delete this.hideTimer;
25294 Ext.menu.CheckItem = function(config){
25295 Ext.menu.CheckItem.superclass.constructor.call(this, config);
25298 "beforecheckchange" ,
25303 if(this.checkHandler){
25304 this.on('checkchange', this.checkHandler, this.scope);
25306 Ext.menu.MenuMgr.registerCheckable(this);
25308 Ext.extend(Ext.menu.CheckItem, Ext.menu.Item, {
25311 itemCls : "x-menu-item x-menu-check-item",
25313 groupClass : "x-menu-group-item",
25318 ctype: "Ext.menu.CheckItem",
25320 onRender : function(c){
25321 Ext.menu.CheckItem.superclass.onRender.apply(this, arguments);
25323 this.el.addClass(this.groupClass);
25326 this.checked = false;
25327 this.setChecked(true, true);
25331 destroy : function(){
25332 Ext.menu.MenuMgr.unregisterCheckable(this);
25333 Ext.menu.CheckItem.superclass.destroy.apply(this, arguments);
25337 setChecked : function(state, suppressEvent){
25338 if(this.checked != state && this.fireEvent("beforecheckchange", this, state) !== false){
25339 if(this.container){
25340 this.container[state ? "addClass" : "removeClass"]("x-menu-item-checked");
25342 this.checked = state;
25343 if(suppressEvent !== true){
25344 this.fireEvent("checkchange", this, state);
25349 handleClick : function(e){
25350 if(!this.disabled && !(this.checked && this.group)){ this.setChecked(!this.checked);
25352 Ext.menu.CheckItem.superclass.handleClick.apply(this, arguments);
25356 Ext.menu.Adapter = function(component, config){
25357 Ext.menu.Adapter.superclass.constructor.call(this, config);
25358 this.component = component;
25360 Ext.extend(Ext.menu.Adapter, Ext.menu.BaseItem, {
25361 canActivate : true,
25363 onRender : function(container, position){
25364 this.component.render(container);
25365 this.el = this.component.getEl();
25368 activate : function(){
25372 this.component.focus();
25373 this.fireEvent("activate", this);
25377 deactivate : function(){
25378 this.fireEvent("deactivate", this);
25381 disable : function(){
25382 this.component.disable();
25383 Ext.menu.Adapter.superclass.disable.call(this);
25386 enable : function(){
25387 this.component.enable();
25388 Ext.menu.Adapter.superclass.enable.call(this);
25392 Ext.menu.DateItem = function(config){
25393 Ext.menu.DateItem.superclass.constructor.call(this, new Ext.DatePicker(config), config);
25395 this.picker = this.component;
25396 this.addEvents('select');
25398 this.picker.on("render", function(picker){
25399 picker.getEl().swallowEvent("click");
25400 picker.container.addClass("x-menu-date-item");
25403 this.picker.on("select", this.onSelect, this);
25406 Ext.extend(Ext.menu.DateItem, Ext.menu.Adapter, {
25407 onSelect : function(picker, date){
25408 this.fireEvent("select", this, date, picker);
25409 Ext.menu.DateItem.superclass.handleClick.call(this);
25413 Ext.menu.ColorItem = function(config){
25414 Ext.menu.ColorItem.superclass.constructor.call(this, new Ext.ColorPalette(config), config);
25416 this.palette = this.component;
25417 this.relayEvents(this.palette, ["select"]);
25418 if(this.selectHandler){
25419 this.on('select', this.selectHandler, this.scope);
25422 Ext.extend(Ext.menu.ColorItem, Ext.menu.Adapter);
25424 Ext.menu.DateMenu = function(config){
25425 Ext.menu.DateMenu.superclass.constructor.call(this, config);
25427 var di = new Ext.menu.DateItem(config);
25430 this.picker = di.picker;
25432 this.relayEvents(di, ["select"]);
25434 this.on('beforeshow', function(){
25436 this.picker.hideMonthPicker(true);
25440 Ext.extend(Ext.menu.DateMenu, Ext.menu.Menu, {
25443 beforeDestroy : function() {
25444 this.picker.destroy();
25448 Ext.menu.ColorMenu = function(config){
25449 Ext.menu.ColorMenu.superclass.constructor.call(this, config);
25451 var ci = new Ext.menu.ColorItem(config);
25454 this.palette = ci.palette;
25456 this.relayEvents(ci, ["select"]);
25458 Ext.extend(Ext.menu.ColorMenu, Ext.menu.Menu);
25460 Ext.form.Field = Ext.extend(Ext.BoxComponent, {
25469 invalidClass : "x-form-invalid",
25471 invalidText : "The value in this field is invalid",
25473 focusClass : "x-form-focus",
25475 validationEvent : "keyup",
25477 validateOnBlur : true,
25479 validationDelay : 250,
25481 defaultAutoCreate : {tag: "input", type: "text", size: "20", autocomplete: "off"},
25483 fieldClass : "x-form-field",
25485 msgTarget : 'qtip',
25499 isFormField : true,
25508 initComponent : function(){
25509 Ext.form.Field.superclass.initComponent.call(this);
25527 getName: function(){
25528 return this.rendered && this.el.dom.name ? this.el.dom.name : (this.hiddenName || '');
25531 onRender : function(ct, position){
25532 Ext.form.Field.superclass.onRender.call(this, ct, position);
25534 var cfg = this.getAutoCreate();
25536 cfg.name = this.name || this.id;
25538 if(this.inputType){
25539 cfg.type = this.inputType;
25541 this.el = ct.createChild(cfg, position);
25543 var type = this.el.dom.type;
25545 if(type == 'password'){
25548 this.el.addClass('x-form-'+type);
25551 this.el.dom.readOnly = true;
25553 if(this.tabIndex !== undefined){
25554 this.el.dom.setAttribute('tabIndex', this.tabIndex);
25557 this.el.addClass([this.fieldClass, this.cls]);
25561 initValue : function(){
25562 if(this.value !== undefined){
25563 this.setValue(this.value);
25564 }else if(this.el.dom.value.length > 0){
25565 this.setValue(this.el.dom.value);
25570 isDirty : function() {
25571 if(this.disabled) {
25574 return String(this.getValue()) !== String(this.originalValue);
25577 afterRender : function(){
25578 Ext.form.Field.superclass.afterRender.call(this);
25582 fireKey : function(e){
25583 if(e.isSpecialKey()){
25584 this.fireEvent("specialkey", this, e);
25589 reset : function(){
25590 this.setValue(this.originalValue);
25591 this.clearInvalid();
25594 initEvents : function(){
25595 this.el.on(Ext.isIE ? "keydown" : "keypress", this.fireKey, this);
25596 this.el.on("focus", this.onFocus, this);
25597 this.el.on("blur", this.onBlur, this);
25599 this.originalValue = this.getValue();
25602 onFocus : function(){
25603 if(!Ext.isOpera && this.focusClass){ this.el.addClass(this.focusClass);
25605 if(!this.hasFocus){
25606 this.hasFocus = true;
25607 this.startValue = this.getValue();
25608 this.fireEvent("focus", this);
25612 beforeBlur : Ext.emptyFn,
25614 onBlur : function(){
25616 if(!Ext.isOpera && this.focusClass){ this.el.removeClass(this.focusClass);
25618 this.hasFocus = false;
25619 if(this.validationEvent !== false && this.validateOnBlur && this.validationEvent != "blur"){
25622 var v = this.getValue();
25623 if(String(v) !== String(this.startValue)){
25624 this.fireEvent('change', this, v, this.startValue);
25626 this.fireEvent("blur", this);
25630 isValid : function(preventMark){
25634 var restore = this.preventMark;
25635 this.preventMark = preventMark === true;
25636 var v = this.validateValue(this.processValue(this.getRawValue()));
25637 this.preventMark = restore;
25642 validate : function(){
25643 if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
25644 this.clearInvalid();
25650 processValue : function(value){
25654 validateValue : function(value){
25659 markInvalid : function(msg){
25660 if(!this.rendered || this.preventMark){ return;
25662 this.el.addClass(this.invalidClass);
25663 msg = msg || this.invalidText;
25664 switch(this.msgTarget){
25666 this.el.dom.qtip = msg;
25667 this.el.dom.qclass = 'x-form-invalid-tip';
25668 if(Ext.QuickTips){ Ext.QuickTips.enable();
25672 this.el.dom.title = msg;
25676 var elp = this.el.findParent('.x-form-element', 5, true);
25677 this.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
25678 this.errorEl.setWidth(elp.getWidth(true)-20);
25680 this.errorEl.update(msg);
25681 Ext.form.Field.msgFx[this.msgFx].show(this.errorEl, this);
25684 if(!this.errorIcon){
25685 var elp = this.el.findParent('.x-form-element', 5, true);
25686 this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
25688 this.alignErrorIcon();
25689 this.errorIcon.dom.qtip = msg;
25690 this.errorIcon.dom.qclass = 'x-form-invalid-tip';
25691 this.errorIcon.show();
25692 this.on('resize', this.alignErrorIcon, this);
25695 var t = Ext.getDom(this.msgTarget);
25697 t.style.display = this.msgDisplay;
25700 this.fireEvent('invalid', this, msg);
25703 alignErrorIcon : function(){
25704 this.errorIcon.alignTo(this.el, 'tl-tr', [2, 0]);
25708 clearInvalid : function(){
25709 if(!this.rendered || this.preventMark){ return;
25711 this.el.removeClass(this.invalidClass);
25712 switch(this.msgTarget){
25714 this.el.dom.qtip = '';
25717 this.el.dom.title = '';
25721 Ext.form.Field.msgFx[this.msgFx].hide(this.errorEl, this);
25725 if(this.errorIcon){
25726 this.errorIcon.dom.qtip = '';
25727 this.errorIcon.hide();
25728 this.un('resize', this.alignErrorIcon, this);
25732 var t = Ext.getDom(this.msgTarget);
25734 t.style.display = 'none';
25737 this.fireEvent('valid', this);
25741 getRawValue : function(){
25742 var v = this.rendered ? this.el.getValue() : Ext.value(this.value, '');
25743 if(v === this.emptyText){
25750 getValue : function(){
25751 if(!this.rendered) {
25754 var v = this.el.getValue();
25755 if(v === this.emptyText || v === undefined){
25762 setRawValue : function(v){
25763 return this.el.dom.value = (v === null || v === undefined ? '' : v);
25767 setValue : function(v){
25770 this.el.dom.value = (v === null || v === undefined ? '' : v);
25775 adjustSize : function(w, h){
25776 var s = Ext.form.Field.superclass.adjustSize.call(this, w, h);
25777 s.width = this.adjustWidth(this.el.dom.tagName, s.width);
25781 adjustWidth : function(tag, w){
25782 tag = tag.toLowerCase();
25783 if(typeof w == 'number' && !Ext.isSafari){
25784 if(Ext.isIE && (tag == 'input' || tag == 'textarea')){
25785 if(tag == 'input' && !Ext.isStrict){
25786 return this.inEditor ? w : w - 3;
25788 if(tag == 'input' && Ext.isStrict){
25789 return w - (Ext.isIE6 ? 4 : 1);
25791 if(tag = 'textarea' && Ext.isStrict){
25794 }else if(Ext.isOpera && Ext.isStrict){
25795 if(tag == 'input'){
25798 if(tag = 'textarea'){
25813 Ext.form.Field.msgFx = {
25815 show: function(msgEl, f){
25816 msgEl.setDisplayed('block');
25819 hide : function(msgEl, f){
25820 msgEl.setDisplayed(false).update('');
25825 show: function(msgEl, f){
25826 msgEl.slideIn('t', {stopFx:true});
25829 hide : function(msgEl, f){
25830 msgEl.slideOut('t', {stopFx:true,useDisplay:true});
25835 show: function(msgEl, f){
25836 msgEl.fixDisplay();
25837 msgEl.alignTo(f.el, 'tl-tr');
25838 msgEl.slideIn('l', {stopFx:true});
25841 hide : function(msgEl, f){
25842 msgEl.slideOut('l', {stopFx:true,useDisplay:true});
25846 Ext.reg('field', Ext.form.Field);
25849 Ext.form.TextField = Ext.extend(Ext.form.Field, {
25862 disableKeyFilter : false,
25868 maxLength : Number.MAX_VALUE,
25870 minLengthText : "The minimum length for this field is {0}",
25872 maxLengthText : "The maximum length for this field is {0}",
25874 selectOnFocus : false,
25876 blankText : "This field is required",
25886 emptyClass : 'x-form-empty-field',
25888 initComponent : function(){
25889 Ext.form.TextField.superclass.initComponent.call(this);
25896 initEvents : function(){
25897 Ext.form.TextField.superclass.initEvents.call(this);
25898 if(this.validationEvent == 'keyup'){
25899 this.validationTask = new Ext.util.DelayedTask(this.validate, this);
25900 this.el.on('keyup', this.filterValidation, this);
25902 else if(this.validationEvent !== false){
25903 this.el.on(this.validationEvent, this.validate, this, {buffer: this.validationDelay});
25905 if(this.selectOnFocus || this.emptyText){
25906 this.on("focus", this.preFocus, this);
25907 if(this.emptyText){
25908 this.on('blur', this.postBlur, this);
25909 this.applyEmptyText();
25912 if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Ext.form.VTypes[this.vtype+'Mask']))){
25913 this.el.on("keypress", this.filterKeys, this);
25916 this.el.on("keyup", this.onKeyUp, this, {buffer:50});
25917 this.el.on("click", this.autoSize, this);
25921 processValue : function(value){
25922 if(this.stripCharsRe){
25923 var newValue = value.replace(this.stripCharsRe, '');
25924 if(newValue !== value){
25925 this.setRawValue(newValue);
25932 filterValidation : function(e){
25933 if(!e.isNavKeyPress()){
25934 this.validationTask.delay(this.validationDelay);
25938 onKeyUp : function(e){
25939 if(!e.isNavKeyPress()){
25945 reset : function(){
25946 Ext.form.TextField.superclass.reset.call(this);
25947 this.applyEmptyText();
25950 applyEmptyText : function(){
25951 if(this.rendered && this.emptyText && this.getRawValue().length < 1){
25952 this.setRawValue(this.emptyText);
25953 this.el.addClass(this.emptyClass);
25957 preFocus : function(){
25958 if(this.emptyText){
25959 if(this.el.dom.value == this.emptyText){
25960 this.setRawValue('');
25962 this.el.removeClass(this.emptyClass);
25964 if(this.selectOnFocus){
25965 this.el.dom.select();
25969 postBlur : function(){
25970 this.applyEmptyText();
25973 filterKeys : function(e){
25974 var k = e.getKey();
25975 if(!Ext.isIE && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
25978 var c = e.getCharCode(), cc = String.fromCharCode(c);
25979 if(Ext.isIE && (e.isSpecialKey() || !cc)){
25982 if(!this.maskRe.test(cc)){
25987 setValue : function(v){
25988 if(this.emptyText && this.el && v !== undefined && v !== null && v !== ''){
25989 this.el.removeClass(this.emptyClass);
25991 Ext.form.TextField.superclass.setValue.apply(this, arguments);
25992 this.applyEmptyText();
25997 validateValue : function(value){
25998 if(value.length < 1 || value === this.emptyText){ if(this.allowBlank){
25999 this.clearInvalid();
26002 this.markInvalid(this.blankText);
26006 if(value.length < this.minLength){
26007 this.markInvalid(String.format(this.minLengthText, this.minLength));
26010 if(value.length > this.maxLength){
26011 this.markInvalid(String.format(this.maxLengthText, this.maxLength));
26015 var vt = Ext.form.VTypes;
26016 if(!vt[this.vtype](value, this)){
26017 this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
26021 if(typeof this.validator == "function"){
26022 var msg = this.validator(value);
26024 this.markInvalid(msg);
26028 if(this.regex && !this.regex.test(value)){
26029 this.markInvalid(this.regexText);
26036 selectText : function(start, end){
26037 var v = this.getRawValue();
26039 start = start === undefined ? 0 : start;
26040 end = end === undefined ? v.length : end;
26041 var d = this.el.dom;
26042 if(d.setSelectionRange){
26043 d.setSelectionRange(start, end);
26044 }else if(d.createTextRange){
26045 var range = d.createTextRange();
26046 range.moveStart("character", start);
26047 range.moveEnd("character", end-v.length);
26054 autoSize : function(){
26055 if(!this.grow || !this.rendered){
26059 this.metrics = Ext.util.TextMetrics.createInstance(this.el);
26062 var v = el.dom.value;
26063 var d = document.createElement('div');
26064 d.appendChild(document.createTextNode(v));
26068 var w = Math.min(this.growMax, Math.max(this.metrics.getWidth(v) + 10, this.growMin));
26069 this.el.setWidth(w);
26070 this.fireEvent("autosize", this, w);
26073 Ext.reg('textfield', Ext.form.TextField);
26076 Ext.form.TriggerField = Ext.extend(Ext.form.TextField, {
26079 defaultAutoCreate : {tag: "input", type: "text", size: "16", autocomplete: "off"},
26084 autoSize: Ext.emptyFn,
26086 deferHeight : true,
26089 onResize : function(w, h){
26090 Ext.form.TriggerField.superclass.onResize.call(this, w, h);
26091 if(typeof w == 'number'){
26092 this.el.setWidth(this.adjustWidth('input', w - this.trigger.getWidth()));
26094 this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
26097 adjustSize : Ext.BoxComponent.prototype.adjustSize,
26099 getResizeEl : function(){
26103 getPositionEl : function(){
26107 alignErrorIcon : function(){
26108 this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
26111 onRender : function(ct, position){
26112 Ext.form.TriggerField.superclass.onRender.call(this, ct, position);
26113 this.wrap = this.el.wrap({cls: "x-form-field-wrap"});
26114 this.trigger = this.wrap.createChild(this.triggerConfig ||
26115 {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.triggerClass});
26116 if(this.hideTrigger){
26117 this.trigger.setDisplayed(false);
26119 this.initTrigger();
26121 this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
26125 initTrigger : function(){
26126 this.trigger.on("click", this.onTriggerClick, this, {preventDefault:true});
26127 this.trigger.addClassOnOver('x-form-trigger-over');
26128 this.trigger.addClassOnClick('x-form-trigger-click');
26131 onDestroy : function(){
26133 this.trigger.removeAllListeners();
26134 this.trigger.remove();
26137 this.wrap.remove();
26139 Ext.form.TriggerField.superclass.onDestroy.call(this);
26142 onFocus : function(){
26143 Ext.form.TriggerField.superclass.onFocus.call(this);
26144 if(!this.mimicing){
26145 this.wrap.addClass('x-trigger-wrap-focus');
26146 this.mimicing = true;
26147 Ext.get(Ext.isIE ? document.body : document).on("mousedown", this.mimicBlur, this, {delay: 10});
26148 if(this.monitorTab){
26149 this.el.on("keydown", this.checkTab, this);
26154 checkTab : function(e){
26155 if(e.getKey() == e.TAB){
26156 this.triggerBlur();
26160 onBlur : function(){
26163 mimicBlur : function(e){
26164 if(!this.wrap.contains(e.target) && this.validateBlur(e)){
26165 this.triggerBlur();
26169 triggerBlur : function(){
26170 this.mimicing = false;
26171 Ext.get(Ext.isIE ? document.body : document).un("mousedown", this.mimicBlur);
26172 if(this.monitorTab){
26173 this.el.un("keydown", this.checkTab, this);
26176 this.wrap.removeClass('x-trigger-wrap-focus');
26177 Ext.form.TriggerField.superclass.onBlur.call(this);
26180 beforeBlur : Ext.emptyFn,
26182 validateBlur : function(e){
26186 onDisable : function(){
26187 Ext.form.TriggerField.superclass.onDisable.call(this);
26189 this.wrap.addClass('x-item-disabled');
26193 onEnable : function(){
26194 Ext.form.TriggerField.superclass.onEnable.call(this);
26196 this.wrap.removeClass('x-item-disabled');
26201 onShow : function(){
26203 this.wrap.dom.style.display = '';
26204 this.wrap.dom.style.visibility = 'visible';
26208 onHide : function(){
26209 this.wrap.dom.style.display = 'none';
26213 onTriggerClick : Ext.emptyFn
26220 Ext.form.TwinTriggerField = Ext.extend(Ext.form.TriggerField, {
26221 initComponent : function(){
26222 Ext.form.TwinTriggerField.superclass.initComponent.call(this);
26224 this.triggerConfig = {
26225 tag:'span', cls:'x-form-twin-triggers', cn:[
26226 {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger1Class},
26227 {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger2Class}
26231 getTrigger : function(index){
26232 return this.triggers[index];
26235 initTrigger : function(){
26236 var ts = this.trigger.select('.x-form-trigger', true);
26237 this.wrap.setStyle('overflow', 'hidden');
26238 var triggerField = this;
26239 ts.each(function(t, all, index){
26240 t.hide = function(){
26241 var w = triggerField.wrap.getWidth();
26242 this.dom.style.display = 'none';
26243 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
26245 t.show = function(){
26246 var w = triggerField.wrap.getWidth();
26247 this.dom.style.display = '';
26248 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
26250 var triggerIndex = 'Trigger'+(index+1);
26252 if(this['hide'+triggerIndex]){
26253 t.dom.style.display = 'none';
26255 t.on("click", this['on'+triggerIndex+'Click'], this, {preventDefault:true});
26256 t.addClassOnOver('x-form-trigger-over');
26257 t.addClassOnClick('x-form-trigger-click');
26259 this.triggers = ts.elements;
26262 onTrigger1Click : Ext.emptyFn,
26263 onTrigger2Click : Ext.emptyFn
26265 Ext.reg('trigger', Ext.form.TriggerField);
26267 Ext.form.TextArea = Ext.extend(Ext.form.TextField, {
26272 growAppend : ' \n ',
26275 enterIsSpecial : false,
26278 preventScrollbars: false,
26281 onRender : function(ct, position){
26283 this.defaultAutoCreate = {
26285 style:"width:100px;height:60px;",
26286 autocomplete: "off"
26289 Ext.form.TextArea.superclass.onRender.call(this, ct, position);
26291 this.textSizeEl = Ext.DomHelper.append(document.body, {
26292 tag: "pre", cls: "x-form-grow-sizer"
26294 if(this.preventScrollbars){
26295 this.el.setStyle("overflow", "hidden");
26297 this.el.setHeight(this.growMin);
26301 onDestroy : function(){
26302 if(this.textSizeEl){
26303 Ext.removeNode(this.textSizeEl);
26305 Ext.form.TextArea.superclass.onDestroy.call(this);
26308 fireKey : function(e){
26309 if(e.isSpecialKey() && (this.enterIsSpecial || (e.getKey() != e.ENTER || e.hasModifier()))){
26310 this.fireEvent("specialkey", this, e);
26314 onKeyUp : function(e){
26315 if(!e.isNavKeyPress() || e.getKey() == e.ENTER){
26321 autoSize : function(){
26322 if(!this.grow || !this.textSizeEl){
26326 var v = el.dom.value;
26327 var ts = this.textSizeEl;
26329 ts.appendChild(document.createTextNode(v));
26332 Ext.fly(ts).setWidth(this.el.getWidth());
26334 v = "  ";
26337 v = v.replace(/\n/g, '<p> </p>');
26339 v += this.growAppend;
26342 var h = Math.min(this.growMax, Math.max(ts.offsetHeight, this.growMin)+this.growPad);
26343 if(h != this.lastHeight){
26344 this.lastHeight = h;
26345 this.el.setHeight(h);
26346 this.fireEvent("autosize", this, h);
26350 Ext.reg('textarea', Ext.form.TextArea);
26352 Ext.form.NumberField = Ext.extend(Ext.form.TextField, {
26354 fieldClass: "x-form-field x-form-num-field",
26356 allowDecimals : true,
26358 decimalSeparator : ".",
26360 decimalPrecision : 2,
26362 allowNegative : true,
26364 minValue : Number.NEGATIVE_INFINITY,
26366 maxValue : Number.MAX_VALUE,
26368 minText : "The minimum value for this field is {0}",
26370 maxText : "The maximum value for this field is {0}",
26372 nanText : "{0} is not a valid number",
26374 baseChars : "0123456789",
26376 initEvents : function(){
26377 Ext.form.NumberField.superclass.initEvents.call(this);
26378 var allowed = this.baseChars+'';
26379 if(this.allowDecimals){
26380 allowed += this.decimalSeparator;
26382 if(this.allowNegative){
26385 this.stripCharsRe = new RegExp('[^'+allowed+']', 'gi');
26386 var keyPress = function(e){
26387 var k = e.getKey();
26388 if(!Ext.isIE && (e.isSpecialKey() || k == e.BACKSPACE || k == e.DELETE)){
26391 var c = e.getCharCode();
26392 if(allowed.indexOf(String.fromCharCode(c)) === -1){
26396 this.el.on("keypress", keyPress, this);
26399 validateValue : function(value){
26400 if(!Ext.form.NumberField.superclass.validateValue.call(this, value)){
26403 if(value.length < 1){ return true;
26405 value = String(value).replace(this.decimalSeparator, ".");
26407 this.markInvalid(String.format(this.nanText, value));
26410 var num = this.parseValue(value);
26411 if(num < this.minValue){
26412 this.markInvalid(String.format(this.minText, this.minValue));
26415 if(num > this.maxValue){
26416 this.markInvalid(String.format(this.maxText, this.maxValue));
26422 getValue : function(){
26423 return this.fixPrecision(this.parseValue(Ext.form.NumberField.superclass.getValue.call(this)));
26426 setValue : function(v){
26428 v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator);
26429 Ext.form.NumberField.superclass.setValue.call(this, v);
26432 parseValue : function(value){
26433 value = parseFloat(String(value).replace(this.decimalSeparator, "."));
26434 return isNaN(value) ? '' : value;
26437 fixPrecision : function(value){
26438 var nan = isNaN(value);
26439 if(!this.allowDecimals || this.decimalPrecision == -1 || nan || !value){
26440 return nan ? '' : value;
26442 return parseFloat(parseFloat(value).toFixed(this.decimalPrecision));
26445 beforeBlur : function(){
26446 var v = this.parseValue(this.getRawValue());
26448 this.setValue(this.fixPrecision(v));
26452 Ext.reg('numberfield', Ext.form.NumberField);
26454 Ext.form.DateField = Ext.extend(Ext.form.TriggerField, {
26458 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",
26460 disabledDays : null,
26462 disabledDaysText : "Disabled",
26464 disabledDates : null,
26466 disabledDatesText : "Disabled",
26472 minText : "The date in this field must be equal to or after {0}",
26474 maxText : "The date in this field must be equal to or before {0}",
26476 invalidText : "{0} is not a valid date - it must be in the format {1}",
26478 triggerClass : 'x-form-date-trigger',
26481 defaultAutoCreate : {tag: "input", type: "text", size: "10", autocomplete: "off"},
26483 initComponent : function(){
26484 Ext.form.DateField.superclass.initComponent.call(this);
26485 if(typeof this.minValue == "string"){
26486 this.minValue = this.parseDate(this.minValue);
26488 if(typeof this.maxValue == "string"){
26489 this.maxValue = this.parseDate(this.maxValue);
26491 this.ddMatch = null;
26492 if(this.disabledDates){
26493 var dd = this.disabledDates;
26495 for(var i = 0; i < dd.length; i++){
26497 if(i != dd.length-1) re += "|";
26499 this.ddMatch = new RegExp(re + ")");
26503 validateValue : function(value){
26504 value = this.formatDate(value);
26505 if(!Ext.form.DateField.superclass.validateValue.call(this, value)){
26508 if(value.length < 1){ return true;
26510 var svalue = value;
26511 value = this.parseDate(value);
26513 this.markInvalid(String.format(this.invalidText, svalue, this.format));
26516 var time = value.getTime();
26517 if(this.minValue && time < this.minValue.getTime()){
26518 this.markInvalid(String.format(this.minText, this.formatDate(this.minValue)));
26521 if(this.maxValue && time > this.maxValue.getTime()){
26522 this.markInvalid(String.format(this.maxText, this.formatDate(this.maxValue)));
26525 if(this.disabledDays){
26526 var day = value.getDay();
26527 for(var i = 0; i < this.disabledDays.length; i++) {
26528 if(day === this.disabledDays[i]){
26529 this.markInvalid(this.disabledDaysText);
26534 var fvalue = this.formatDate(value);
26535 if(this.ddMatch && this.ddMatch.test(fvalue)){
26536 this.markInvalid(String.format(this.disabledDatesText, fvalue));
26542 validateBlur : function(){
26543 return !this.menu || !this.menu.isVisible();
26547 getValue : function(){
26548 return this.parseDate(Ext.form.DateField.superclass.getValue.call(this)) || "";
26552 setValue : function(date){
26553 Ext.form.DateField.superclass.setValue.call(this, this.formatDate(this.parseDate(date)));
26556 parseDate : function(value){
26557 if(!value || Ext.isDate(value)){
26560 var v = Date.parseDate(value, this.format);
26561 if(!v && this.altFormats){
26562 if(!this.altFormatsArray){
26563 this.altFormatsArray = this.altFormats.split("|");
26565 for(var i = 0, len = this.altFormatsArray.length; i < len && !v; i++){
26566 v = Date.parseDate(value, this.altFormatsArray[i]);
26572 onDestroy : function(){
26574 this.menu.destroy();
26577 this.wrap.remove();
26579 Ext.form.DateField.superclass.onDestroy.call(this);
26582 formatDate : function(date){
26583 return Ext.isDate(date) ? date.dateFormat(this.format) : date;
26587 select: function(m, d){
26590 show : function(){ this.onFocus();
26593 this.focus.defer(10, this);
26594 var ml = this.menuListeners;
26595 this.menu.un("select", ml.select, this);
26596 this.menu.un("show", ml.show, this);
26597 this.menu.un("hide", ml.hide, this);
26601 onTriggerClick : function(){
26605 if(this.menu == null){
26606 this.menu = new Ext.menu.DateMenu();
26608 Ext.apply(this.menu.picker, {
26609 minDate : this.minValue,
26610 maxDate : this.maxValue,
26611 disabledDatesRE : this.ddMatch,
26612 disabledDatesText : this.disabledDatesText,
26613 disabledDays : this.disabledDays,
26614 disabledDaysText : this.disabledDaysText,
26615 format : this.format,
26616 minText : String.format(this.minText, this.formatDate(this.minValue)),
26617 maxText : String.format(this.maxText, this.formatDate(this.maxValue))
26619 this.menu.on(Ext.apply({}, this.menuListeners, {
26622 this.menu.picker.setValue(this.getValue() || new Date());
26623 this.menu.show(this.el, "tl-bl?");
26626 beforeBlur : function(){
26627 var v = this.parseDate(this.getRawValue());
26638 Ext.reg('datefield', Ext.form.DateField);
26640 Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
26647 defaultAutoCreate : {tag: "input", type: "text", size: "24", autocomplete: "off"},
26656 selectedClass: 'x-combo-selected',
26658 triggerClass : 'x-form-arrow-trigger',
26662 listAlign: 'tl-bl?',
26668 triggerAction: 'query',
26678 selectOnFocus:false,
26680 queryParam: 'query',
26682 loadingText: 'Loading...',
26696 forceSelection:false,
26698 typeAheadDelay : 250,
26704 initComponent : function(){
26705 Ext.form.ComboBox.superclass.initComponent.call(this);
26718 if(this.transform){
26719 this.allowDomMove = false;
26720 var s = Ext.getDom(this.transform);
26721 if(!this.hiddenName){
26722 this.hiddenName = s.name;
26725 this.mode = 'local';
26726 var d = [], opts = s.options;
26727 for(var i = 0, len = opts.length;i < len; i++){
26729 var value = (Ext.isIE ? o.getAttributeNode('value').specified : o.hasAttribute('value')) ? o.value : o.text;
26731 this.value = value;
26733 d.push([value, o.text]);
26735 this.store = new Ext.data.SimpleStore({
26737 fields: ['value', 'text'],
26740 this.valueField = 'value';
26741 this.displayField = 'text';
26743 s.name = Ext.id(); if(!this.lazyRender){
26744 this.target = true;
26745 this.el = Ext.DomHelper.insertBefore(s, this.autoCreate || this.defaultAutoCreate);
26746 Ext.removeNode(s); this.render(this.el.parentNode);
26748 Ext.removeNode(s); }
26751 this.selectedIndex = -1;
26752 if(this.mode == 'local'){
26753 if(this.initialConfig.queryDelay === undefined){
26754 this.queryDelay = 10;
26756 if(this.initialConfig.minChars === undefined){
26762 onRender : function(ct, position){
26763 Ext.form.ComboBox.superclass.onRender.call(this, ct, position);
26764 if(this.hiddenName){
26765 this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName, id: (this.hiddenId||this.hiddenName)},
26767 this.hiddenField.value =
26768 this.hiddenValue !== undefined ? this.hiddenValue :
26769 this.value !== undefined ? this.value : '';
26771 this.el.dom.removeAttribute('name');
26774 this.el.dom.setAttribute('autocomplete', 'off');
26777 if(!this.lazyInit){
26780 this.on('focus', this.initList, this, {single: true});
26783 if(!this.editable){
26784 this.editable = true;
26785 this.setEditable(false);
26789 initList : function(){
26791 var cls = 'x-combo-list';
26793 this.list = new Ext.Layer({
26794 shadow: this.shadow, cls: [cls, this.listClass].join(' '), constrain:false
26797 var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
26798 this.list.setWidth(lw);
26799 this.list.swallowEvent('mousewheel');
26800 this.assetHeight = 0;
26803 this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
26804 this.assetHeight += this.header.getHeight();
26807 this.innerList = this.list.createChild({cls:cls+'-inner'});
26808 this.innerList.on('mouseover', this.onViewOver, this);
26809 this.innerList.on('mousemove', this.onViewMove, this);
26810 this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
26813 this.footer = this.list.createChild({cls:cls+'-ft'});
26814 this.pageTb = new Ext.PagingToolbar({
26816 pageSize: this.pageSize,
26817 renderTo:this.footer
26819 this.assetHeight += this.footer.getHeight();
26824 this.tpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';
26828 this.view = new Ext.DataView({
26829 applyTo: this.innerList,
26831 singleSelect: true,
26832 selectedClass: this.selectedClass,
26833 itemSelector: this.itemSelector || '.' + cls + '-item'
26836 this.view.on('click', this.onViewClick, this);
26838 this.bindStore(this.store, true);
26840 if(this.resizable){
26841 this.resizer = new Ext.Resizable(this.list, {
26842 pinned:true, handles:'se'
26844 this.resizer.on('resize', function(r, w, h){
26845 this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
26846 this.listWidth = w;
26847 this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
26848 this.restrictHeight();
26850 this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
26856 bindStore : function(store, initial){
26857 if(this.store && !initial){
26858 this.store.un('beforeload', this.onBeforeLoad, this);
26859 this.store.un('load', this.onLoad, this);
26860 this.store.un('loadexception', this.collapse, this);
26864 this.view.setStore(null);
26869 this.store = Ext.StoreMgr.lookup(store);
26871 this.store.on('beforeload', this.onBeforeLoad, this);
26872 this.store.on('load', this.onLoad, this);
26873 this.store.on('loadexception', this.collapse, this);
26876 this.view.setStore(store);
26881 initEvents : function(){
26882 Ext.form.ComboBox.superclass.initEvents.call(this);
26884 this.keyNav = new Ext.KeyNav(this.el, {
26885 "up" : function(e){
26886 this.inKeyMode = true;
26890 "down" : function(e){
26891 if(!this.isExpanded()){
26892 this.onTriggerClick();
26894 this.inKeyMode = true;
26899 "enter" : function(e){
26900 this.onViewClick();
26901 this.delayedCheck = true;
26902 this.unsetDelayCheck.defer(10, this);
26905 "esc" : function(e){
26909 "tab" : function(e){
26910 this.onViewClick(false);
26916 doRelay : function(foo, bar, hname){
26917 if(hname == 'down' || this.scope.isExpanded()){
26918 return Ext.KeyNav.prototype.doRelay.apply(this, arguments);
26923 forceKeyDown : true
26925 this.queryDelay = Math.max(this.queryDelay || 10,
26926 this.mode == 'local' ? 10 : 250);
26927 this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);
26928 if(this.typeAhead){
26929 this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
26931 if(this.editable !== false){
26932 this.el.on("keyup", this.onKeyUp, this);
26934 if(this.forceSelection){
26935 this.on('blur', this.doForce, this);
26939 onDestroy : function(){
26941 this.view.el.removeAllListeners();
26942 this.view.el.remove();
26943 this.view.purgeListeners();
26946 this.list.destroy();
26948 this.bindStore(null);
26949 Ext.form.ComboBox.superclass.onDestroy.call(this);
26952 unsetDelayCheck : function(){
26953 delete this.delayedCheck;
26955 fireKey : function(e){
26956 if(e.isNavKeyPress() && !this.isExpanded() && !this.delayedCheck){
26957 this.fireEvent("specialkey", this, e);
26961 onResize: function(w, h){
26962 Ext.form.ComboBox.superclass.onResize.apply(this, arguments);
26963 if(this.list && this.listWidth === undefined){
26964 var lw = Math.max(w, this.minListWidth);
26965 this.list.setWidth(lw);
26966 this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
26970 onEnable: function(){
26971 Ext.form.ComboBox.superclass.onEnable.apply(this, arguments);
26972 if(this.hiddenField){
26973 this.hiddenField.disabled = false;
26977 onDisable: function(){
26978 Ext.form.ComboBox.superclass.onDisable.apply(this, arguments);
26979 if(this.hiddenField){
26980 this.hiddenField.disabled = true;
26985 setEditable : function(value){
26986 if(value == this.editable){
26989 this.editable = value;
26991 this.el.dom.setAttribute('readOnly', true);
26992 this.el.on('mousedown', this.onTriggerClick, this);
26993 this.el.addClass('x-combo-noedit');
26995 this.el.dom.setAttribute('readOnly', false);
26996 this.el.un('mousedown', this.onTriggerClick, this);
26997 this.el.removeClass('x-combo-noedit');
27001 onBeforeLoad : function(){
27002 if(!this.hasFocus){
27005 this.innerList.update(this.loadingText ?
27006 '<div class="loading-indicator">'+this.loadingText+'</div>' : '');
27007 this.restrictHeight();
27008 this.selectedIndex = -1;
27011 onLoad : function(){
27012 if(!this.hasFocus){
27015 if(this.store.getCount() > 0){
27017 this.restrictHeight();
27018 if(this.lastQuery == this.allQuery){
27020 this.el.dom.select();
27022 if(!this.selectByValue(this.value, true)){
27023 this.select(0, true);
27027 if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){
27028 this.taTask.delay(this.typeAheadDelay);
27032 this.onEmptyResults();
27036 onTypeAhead : function(){
27037 if(this.store.getCount() > 0){
27038 var r = this.store.getAt(0);
27039 var newValue = r.data[this.displayField];
27040 var len = newValue.length;
27041 var selStart = this.getRawValue().length;
27042 if(selStart != len){
27043 this.setRawValue(newValue);
27044 this.selectText(selStart, newValue.length);
27049 onSelect : function(record, index){
27050 if(this.fireEvent('beforeselect', this, record, index) !== false){
27051 this.setValue(record.data[this.valueField || this.displayField]);
27053 this.fireEvent('select', this, record, index);
27058 getValue : function(){
27059 if(this.valueField){
27060 return typeof this.value != 'undefined' ? this.value : '';
27062 return Ext.form.ComboBox.superclass.getValue.call(this);
27067 clearValue : function(){
27068 if(this.hiddenField){
27069 this.hiddenField.value = '';
27071 this.setRawValue('');
27072 this.lastSelectionText = '';
27073 this.applyEmptyText();
27078 setValue : function(v){
27080 if(this.valueField){
27081 var r = this.findRecord(this.valueField, v);
27083 text = r.data[this.displayField];
27084 }else if(this.valueNotFoundText !== undefined){
27085 text = this.valueNotFoundText;
27088 this.lastSelectionText = text;
27089 if(this.hiddenField){
27090 this.hiddenField.value = v;
27092 Ext.form.ComboBox.superclass.setValue.call(this, text);
27096 findRecord : function(prop, value){
27098 if(this.store.getCount() > 0){
27099 this.store.each(function(r){
27100 if(r.data[prop] == value){
27109 onViewMove : function(e, t){
27110 this.inKeyMode = false;
27113 onViewOver : function(e, t){
27114 if(this.inKeyMode){ return;
27116 var item = this.view.findItemFromChild(t);
27118 var index = this.view.indexOf(item);
27119 this.select(index, false);
27123 onViewClick : function(doFocus){
27124 var index = this.view.getSelectedIndexes()[0];
27125 var r = this.store.getAt(index);
27127 this.onSelect(r, index);
27129 if(doFocus !== false){
27134 restrictHeight : function(){
27135 this.innerList.dom.style.height = '';
27136 var inner = this.innerList.dom;
27137 var pad = this.list.getFrameWidth('tb')+(this.resizable?this.handleHeight:0)+this.assetHeight;
27138 var h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight);
27139 var ha = this.getPosition()[1]-Ext.getBody().getScroll().top;
27140 var hb = Ext.lib.Dom.getViewHeight()-ha-this.getSize().height;
27141 var space = Math.max(ha, hb, this.minHeight || 0)-this.list.shadow.offset-pad-2;
27142 h = Math.min(h, space, this.maxHeight);
27144 this.innerList.setHeight(h);
27145 this.list.beginUpdate();
27146 this.list.setHeight(h+pad);
27147 this.list.alignTo(this.el, this.listAlign);
27148 this.list.endUpdate();
27151 onEmptyResults : function(){
27156 isExpanded : function(){
27157 return this.list && this.list.isVisible();
27161 selectByValue : function(v, scrollIntoView){
27162 if(v !== undefined && v !== null){
27163 var r = this.findRecord(this.valueField || this.displayField, v);
27165 this.select(this.store.indexOf(r), scrollIntoView);
27173 select : function(index, scrollIntoView){
27174 this.selectedIndex = index;
27175 this.view.select(index);
27176 if(scrollIntoView !== false){
27177 var el = this.view.getNode(index);
27179 this.innerList.scrollChildIntoView(el, false);
27184 selectNext : function(){
27185 var ct = this.store.getCount();
27187 if(this.selectedIndex == -1){
27189 }else if(this.selectedIndex < ct-1){
27190 this.select(this.selectedIndex+1);
27195 selectPrev : function(){
27196 var ct = this.store.getCount();
27198 if(this.selectedIndex == -1){
27200 }else if(this.selectedIndex != 0){
27201 this.select(this.selectedIndex-1);
27206 onKeyUp : function(e){
27207 if(this.editable !== false && !e.isSpecialKey()){
27208 this.lastKey = e.getKey();
27209 this.dqTask.delay(this.queryDelay);
27213 validateBlur : function(){
27214 return !this.list || !this.list.isVisible();
27217 initQuery : function(){
27218 this.doQuery(this.getRawValue());
27221 doForce : function(){
27222 if(this.el.dom.value.length > 0){
27223 this.el.dom.value =
27224 this.lastSelectionText === undefined ? '' : this.lastSelectionText;
27225 this.applyEmptyText();
27230 doQuery : function(q, forceAll){
27231 if(q === undefined || q === null){
27236 forceAll: forceAll,
27240 if(this.fireEvent('beforequery', qe)===false || qe.cancel){
27244 forceAll = qe.forceAll;
27245 if(forceAll === true || (q.length >= this.minChars)){
27246 if(this.lastQuery !== q){
27247 this.lastQuery = q;
27248 if(this.mode == 'local'){
27249 this.selectedIndex = -1;
27251 this.store.clearFilter();
27253 this.store.filter(this.displayField, q);
27257 this.store.baseParams[this.queryParam] = q;
27259 params: this.getParams(q)
27264 this.selectedIndex = -1;
27270 getParams : function(q){
27274 p.limit = this.pageSize;
27280 collapse : function(){
27281 if(!this.isExpanded()){
27285 Ext.getDoc().un('mousewheel', this.collapseIf, this);
27286 Ext.getDoc().un('mousedown', this.collapseIf, this);
27287 this.fireEvent('collapse', this);
27290 collapseIf : function(e){
27291 if(!e.within(this.wrap) && !e.within(this.list)){
27297 expand : function(){
27298 if(this.isExpanded() || !this.hasFocus){
27301 this.list.alignTo(this.wrap, this.listAlign);
27303 this.innerList.setOverflow('auto'); Ext.getDoc().on('mousewheel', this.collapseIf, this);
27304 Ext.getDoc().on('mousedown', this.collapseIf, this);
27305 this.fireEvent('expand', this);
27308 onTriggerClick : function(){
27312 if(this.isExpanded()){
27317 if(this.triggerAction == 'all') {
27318 this.doQuery(this.allQuery, true);
27320 this.doQuery(this.getRawValue());
27332 Ext.reg('combo', Ext.form.ComboBox);
27334 Ext.form.Checkbox = Ext.extend(Ext.form.Field, {
27336 focusClass : undefined,
27338 fieldClass: "x-form-field",
27342 defaultAutoCreate : { tag: "input", type: 'checkbox', autocomplete: "off"},
27346 initComponent : function(){
27347 Ext.form.Checkbox.superclass.initComponent.call(this);
27354 onResize : function(){
27355 Ext.form.Checkbox.superclass.onResize.apply(this, arguments);
27356 if(!this.boxLabel){
27357 this.el.alignTo(this.wrap, 'c-c');
27361 initEvents : function(){
27362 Ext.form.Checkbox.superclass.initEvents.call(this);
27363 this.el.on("click", this.onClick, this);
27364 this.el.on("change", this.onClick, this);
27367 getResizeEl : function(){
27371 getPositionEl : function(){
27376 markInvalid : Ext.emptyFn,
27378 clearInvalid : Ext.emptyFn,
27380 onRender : function(ct, position){
27381 Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
27382 if(this.inputValue !== undefined){
27383 this.el.dom.value = this.inputValue;
27385 this.wrap = this.el.wrap({cls: "x-form-check-wrap"});
27387 this.wrap.createChild({tag: 'label', htmlFor: this.el.id, cls: 'x-form-cb-label', html: this.boxLabel});
27390 this.setValue(true);
27392 this.checked = this.el.dom.checked;
27396 onDestroy : function(){
27398 this.wrap.remove();
27400 Ext.form.Checkbox.superclass.onDestroy.call(this);
27403 initValue : Ext.emptyFn,
27406 getValue : function(){
27408 return this.el.dom.checked;
27413 onClick : function(){
27414 if(this.el.dom.checked != this.checked){
27415 this.setValue(this.el.dom.checked);
27420 setValue : function(v){
27421 this.checked = (v === true || v === 'true' || v == '1' || String(v).toLowerCase() == 'on');
27422 if(this.el && this.el.dom){
27423 this.el.dom.checked = this.checked;
27424 this.el.dom.defaultChecked = this.checked;
27426 this.fireEvent("check", this, this.checked);
27429 Ext.reg('checkbox', Ext.form.Checkbox);
27431 Ext.form.Radio = Ext.extend(Ext.form.Checkbox, {
27432 inputType: 'radio',
27435 markInvalid : Ext.emptyFn,
27437 clearInvalid : Ext.emptyFn,
27440 getGroupValue : function(){
27441 var p = this.el.up('form') || Ext.getBody();
27442 var c = p.child('input[name='+this.el.dom.name+']:checked', true);
27443 return c ? c.value : null;
27446 onClick : function(){
27447 if(this.el.dom.checked != this.checked){
27448 var p = this.el.up('form') || Ext.getBody();
27449 var els = p.select('input[name='+this.el.dom.name+']');
27450 els.each(function(el){
27451 if(el.dom.id == this.id){
27452 this.setValue(true);
27454 Ext.getCmp(el.dom.id).setValue(false);
27461 setValue : function(v){
27462 if (typeof v == 'boolean') {
27463 Ext.form.Radio.superclass.setValue.call(this, v);
27465 var r = this.el.up('form').child('input[name='+this.el.dom.name+'][value='+v+']', true);
27472 Ext.reg('radio', Ext.form.Radio);
27474 Ext.form.Hidden = Ext.extend(Ext.form.Field, {
\r
27476 inputType : 'hidden',
\r
27479 onRender : function(){
\r
27480 Ext.form.Hidden.superclass.onRender.apply(this, arguments);
\r
27484 initEvents : function(){
\r
27485 this.originalValue = this.getValue();
\r
27489 setSize : Ext.emptyFn,
\r
27490 setWidth : Ext.emptyFn,
\r
27491 setHeight : Ext.emptyFn,
\r
27492 setPosition : Ext.emptyFn,
\r
27493 setPagePosition : Ext.emptyFn,
\r
27494 markInvalid : Ext.emptyFn,
\r
27495 clearInvalid : Ext.emptyFn
\r
27497 Ext.reg('hidden', Ext.form.Hidden);
27499 Ext.form.BasicForm = function(el, config){
27500 Ext.apply(this, config);
27502 this.items = new Ext.util.MixedCollection(false, function(o){
27503 return o.id || (o.id = Ext.id());
27517 Ext.form.BasicForm.superclass.constructor.call(this);
27520 Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
27530 activeAction : null,
27533 trackResetOnLoad : false,
27538 initEl : function(el){
27539 this.el = Ext.get(el);
27540 this.id = this.el.id || Ext.id();
27541 if(!this.standardSubmit){
27542 this.el.on('submit', this.onSubmit, this);
27544 this.el.addClass('x-form');
27552 onSubmit : function(e){
27556 destroy: function() {
27557 this.items.each(function(f){
27561 this.el.removeAllListeners();
27564 this.purgeListeners();
27568 isValid : function(){
27570 this.items.each(function(f){
27579 isDirty : function(){
27581 this.items.each(function(f){
27591 doAction : function(action, options){
27592 if(typeof action == 'string'){
27593 action = new Ext.form.Action.ACTION_TYPES[action](this, options);
27595 if(this.fireEvent('beforeaction', this, action) !== false){
27596 this.beforeAction(action);
27597 action.run.defer(100, action);
27603 submit : function(options){
27604 if(this.standardSubmit){
27605 var v = this.isValid();
27607 this.el.dom.submit();
27611 this.doAction('submit', options);
27616 load : function(options){
27617 this.doAction('load', options);
27622 updateRecord : function(record){
27623 record.beginEdit();
27624 var fs = record.fields;
27625 fs.each(function(f){
27626 var field = this.findField(f.name);
27628 record.set(f.name, field.getValue());
27636 loadRecord : function(record){
27637 this.setValues(record.data);
27641 beforeAction : function(action){
27642 var o = action.options;
27644 if(this.waitMsgTarget === true){
27645 this.el.mask(o.waitMsg, 'x-mask-loading');
27646 }else if(this.waitMsgTarget){
27647 this.waitMsgTarget = Ext.get(this.waitMsgTarget);
27648 this.waitMsgTarget.mask(o.waitMsg, 'x-mask-loading');
27650 Ext.MessageBox.wait(o.waitMsg, o.waitTitle || this.waitTitle || 'Please Wait...');
27655 afterAction : function(action, success){
27656 this.activeAction = null;
27657 var o = action.options;
27659 if(this.waitMsgTarget === true){
27661 }else if(this.waitMsgTarget){
27662 this.waitMsgTarget.unmask();
27664 Ext.MessageBox.updateProgress(1);
27665 Ext.MessageBox.hide();
27672 Ext.callback(o.success, o.scope, [this, action]);
27673 this.fireEvent('actioncomplete', this, action);
27675 Ext.callback(o.failure, o.scope, [this, action]);
27676 this.fireEvent('actionfailed', this, action);
27681 findField : function(id){
27682 var field = this.items.get(id);
27684 this.items.each(function(f){
27685 if(f.isFormField && (f.dataIndex == id || f.id == id || f.getName() == id)){
27691 return field || null;
27696 markInvalid : function(errors){
27697 if(Ext.isArray(errors)){
27698 for(var i = 0, len = errors.length; i < len; i++){
27699 var fieldError = errors[i];
27700 var f = this.findField(fieldError.id);
27702 f.markInvalid(fieldError.msg);
27708 if(typeof errors[id] != 'function' && (field = this.findField(id))){
27709 field.markInvalid(errors[id]);
27717 setValues : function(values){
27718 if(Ext.isArray(values)){ for(var i = 0, len = values.length; i < len; i++){
27720 var f = this.findField(v.id);
27722 f.setValue(v.value);
27723 if(this.trackResetOnLoad){
27724 f.originalValue = f.getValue();
27728 }else{ var field, id;
27730 if(typeof values[id] != 'function' && (field = this.findField(id))){
27731 field.setValue(values[id]);
27732 if(this.trackResetOnLoad){
27733 field.originalValue = field.getValue();
27742 getValues : function(asString){
27743 var fs = Ext.lib.Ajax.serializeForm(this.el.dom);
27744 if(asString === true){
27747 return Ext.urlDecode(fs);
27751 clearInvalid : function(){
27752 this.items.each(function(f){
27759 reset : function(){
27760 this.items.each(function(f){
27768 this.items.addAll(Array.prototype.slice.call(arguments, 0));
27774 remove : function(field){
27775 this.items.remove(field);
27780 render : function(){
27781 this.items.each(function(f){
27782 if(f.isFormField && !f.rendered && document.getElementById(f.id)){ f.applyToMarkup(f.id);
27789 applyToFields : function(o){
27790 this.items.each(function(f){
27797 applyIfToFields : function(o){
27798 this.items.each(function(f){
27805 Ext.BasicForm = Ext.form.BasicForm;
27807 Ext.FormPanel = Ext.extend(Ext.Panel, {
27812 buttonAlign:'center',
27821 monitorValid : false,
27829 initComponent :function(){
27830 this.form = this.createForm();
27832 Ext.FormPanel.superclass.initComponent.call(this);
27839 this.relayEvents(this.form, ['beforeaction', 'actionfailed', 'actioncomplete']);
27842 createForm: function(){
27843 delete this.initialConfig.listeners;
27844 return new Ext.form.BasicForm(null, this.initialConfig);
27847 initFields : function(){
27849 var formPanel = this;
27850 var fn = function(c){
27851 if(c.doLayout && c != formPanel){
27853 labelAlign: c.ownerCt.labelAlign,
27854 labelWidth: c.ownerCt.labelWidth,
27855 itemCls: c.ownerCt.itemCls
27860 }else if(c.isFormField){
27864 this.items.each(fn);
27867 getLayoutTarget : function(){
27868 return this.form.el;
27872 getForm : function(){
27876 onRender : function(ct, position){
27879 Ext.FormPanel.superclass.onRender.call(this, ct, position);
27882 method : this.method || 'POST',
27883 id : this.formId || Ext.id()
27885 if(this.fileUpload) {
27886 o.enctype = 'multipart/form-data';
27888 this.form.initEl(this.body.createChild(o));
27891 beforeDestroy: function(){
27892 Ext.FormPanel.superclass.beforeDestroy.call(this);
27893 Ext.destroy(this.form);
27896 initEvents : function(){
27897 Ext.FormPanel.superclass.initEvents.call(this);
27898 this.items.on('remove', this.onRemove, this);
27899 this.items.on('add', this.onAdd, this);
27900 if(this.monitorValid){ this.startMonitoring();
27904 onAdd : function(ct, c) {
27905 if (c.isFormField) {
27910 onRemove : function(c) {
27911 if (c.isFormField) {
27912 Ext.destroy(c.container.up('.x-form-item'));
27913 this.form.remove(c);
27918 startMonitoring : function(){
27921 Ext.TaskMgr.start({
27922 run : this.bindHandler,
27923 interval : this.monitorPoll || 200,
27930 stopMonitoring : function(){
27931 this.bound = false;
27936 this.form.load.apply(this.form, arguments);
27939 onDisable : function(){
27940 Ext.FormPanel.superclass.onDisable.call(this);
27942 this.form.items.each(function(){
27948 onEnable : function(){
27949 Ext.FormPanel.superclass.onEnable.call(this);
27951 this.form.items.each(function(){
27957 bindHandler : function(){
27961 this.form.items.each(function(f){
27962 if(!f.isValid(true)){
27968 for(var i = 0, len = this.buttons.length; i < len; i++){
27969 var btn = this.buttons[i];
27970 if(btn.formBind === true && btn.disabled === valid){
27971 btn.setDisabled(!valid);
27975 this.fireEvent('clientvalidation', this, valid);
27978 Ext.reg('form', Ext.FormPanel);
27980 Ext.form.FormPanel = Ext.FormPanel;
27984 Ext.form.FieldSet = Ext.extend(Ext.Panel, {
\r
27990 baseCls:'x-fieldset',
\r
27995 onRender : function(ct, position){
\r
27997 this.el = document.createElement('fieldset');
\r
27998 this.el.id = this.id;
\r
27999 if (this.title || this.header || this.checkboxToggle) {
\r
28000 this.el.appendChild(document.createElement('legend')).className = 'x-fieldset-header';
\r
28004 Ext.form.FieldSet.superclass.onRender.call(this, ct, position);
\r
28006 if(this.checkboxToggle){
\r
28007 var o = typeof this.checkboxToggle == 'object' ?
\r
28008 this.checkboxToggle :
\r
28009 {tag: 'input', type: 'checkbox', name: this.checkboxName || this.id+'-checkbox'};
\r
28010 this.checkbox = this.header.insertFirst(o);
\r
28011 this.checkbox.dom.checked = !this.collapsed;
\r
28012 this.checkbox.on('click', this.onCheckClick, this);
\r
28017 onCollapse : function(doAnim, animArg){
\r
28018 if(this.checkbox){
\r
28019 this.checkbox.dom.checked = false;
\r
28021 this.afterCollapse();
\r
28026 onExpand : function(doAnim, animArg){
\r
28027 if(this.checkbox){
\r
28028 this.checkbox.dom.checked = true;
\r
28030 this.afterExpand();
\r
28034 onCheckClick : function(){
\r
28035 this[this.checkbox.dom.checked ? 'expand' : 'collapse']();
\r
28076 Ext.reg('fieldset', Ext.form.FieldSet);
\r
28081 Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
\r
28083 enableFormat : true,
\r
28085 enableFontSize : true,
\r
28087 enableColors : true,
\r
28089 enableAlignments : true,
\r
28091 enableLists : true,
\r
28093 enableSourceEdit : true,
\r
28095 enableLinks : true,
\r
28097 enableFont : true,
\r
28099 createLinkText : 'Please enter the URL for the link:',
\r
28101 defaultLinkValue : 'http:/'+'/',
\r
28107 'Times New Roman',
\r
28110 defaultFont: 'tahoma',
\r
28113 validationEvent : false,
\r
28114 deferHeight: true,
\r
28115 initialized : false,
\r
28116 activated : false,
\r
28117 sourceEditMode : false,
\r
28118 onFocus : Ext.emptyFn,
\r
28120 hideMode:'offsets',
\r
28121 defaultAutoCreate : {
\r
28123 style:"width:500px;height:300px;",
\r
28124 autocomplete: "off"
\r
28128 initComponent : function(){
\r
28147 createFontOptions : function(){
\r
28148 var buf = [], fs = this.fontFamilies, ff, lc;
\r
28149 for(var i = 0, len = fs.length; i< len; i++){
\r
28151 lc = ff.toLowerCase();
\r
28153 '<option value="',lc,'" style="font-family:',ff,';"',
\r
28154 (this.defaultFont == lc ? ' selected="true">' : '>'),
\r
28159 return buf.join('');
\r
28162 createToolbar : function(editor){
\r
28164 function btn(id, toggle, handler){
\r
28167 cls : 'x-btn-icon x-edit-'+id,
\r
28168 enableToggle:toggle !== false,
\r
28170 handler:handler||editor.relayBtnCmd,
\r
28171 clickEvent:'mousedown',
\r
28172 tooltip: editor.buttonTips[id] || undefined,
\r
28178 var tb = new Ext.Toolbar({
\r
28179 renderTo:this.wrap.dom.firstChild
\r
28183 tb.el.on('click', function(e){
\r
28184 e.preventDefault();
\r
28187 if(this.enableFont && !Ext.isSafari){
\r
28188 this.fontSelect = tb.el.createChild({
\r
28190 cls:'x-font-select',
\r
28191 html: this.createFontOptions()
\r
28193 this.fontSelect.on('change', function(){
\r
28194 var font = this.fontSelect.dom.value;
\r
28195 this.relayCmd('fontname', font);
\r
28196 this.deferFocus();
\r
28199 this.fontSelect.dom,
\r
28204 if(this.enableFormat){
\r
28212 if(this.enableFontSize){
\r
28215 btn('increasefontsize', false, this.adjustFont),
\r
28216 btn('decreasefontsize', false, this.adjustFont)
\r
28220 if(this.enableColors){
\r
28223 itemId:'forecolor',
\r
28224 cls:'x-btn-icon x-edit-forecolor',
\r
28225 clickEvent:'mousedown',
\r
28226 tooltip: editor.buttonTips['forecolor'] || undefined,
\r
28228 menu : new Ext.menu.ColorMenu({
\r
28229 allowReselect: true,
\r
28230 focus: Ext.emptyFn,
\r
28233 selectHandler: function(cp, color){
\r
28234 this.execCmd('forecolor', Ext.isSafari || Ext.isIE ? '#'+color : color);
\r
28235 this.deferFocus();
\r
28238 clickEvent:'mousedown'
\r
28241 itemId:'backcolor',
\r
28242 cls:'x-btn-icon x-edit-backcolor',
\r
28243 clickEvent:'mousedown',
\r
28244 tooltip: editor.buttonTips['backcolor'] || undefined,
\r
28246 menu : new Ext.menu.ColorMenu({
\r
28247 focus: Ext.emptyFn,
\r
28250 allowReselect: true,
\r
28251 selectHandler: function(cp, color){
\r
28253 this.execCmd('useCSS', false);
\r
28254 this.execCmd('hilitecolor', color);
\r
28255 this.execCmd('useCSS', true);
\r
28256 this.deferFocus();
\r
28258 this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isSafari || Ext.isIE ? '#'+color : color);
\r
28259 this.deferFocus();
\r
28263 clickEvent:'mousedown'
\r
28269 if(this.enableAlignments){
\r
28272 btn('justifyleft'),
\r
28273 btn('justifycenter'),
\r
28274 btn('justifyright')
\r
28278 if(!Ext.isSafari){
\r
28279 if(this.enableLinks){
\r
28282 btn('createlink', false, this.createLink)
\r
28286 if(this.enableLists){
\r
28289 btn('insertorderedlist'),
\r
28290 btn('insertunorderedlist')
\r
28293 if(this.enableSourceEdit){
\r
28296 btn('sourceedit', true, function(btn){
\r
28297 this.toggleSourceEdit(btn.pressed);
\r
28307 getDocMarkup : function(){
\r
28308 return '<html><head><style type="text/css">body{border:0;margin:0;padding:3px;height:98%;cursor:text;}</style></head><body></body></html>';
\r
28311 getEditorBody : function(){
\r
28312 return this.doc.body || this.doc.documentElement;
\r
28316 onRender : function(ct, position){
\r
28317 Ext.form.HtmlEditor.superclass.onRender.call(this, ct, position);
\r
28318 this.el.dom.style.border = '0 none';
\r
28319 this.el.dom.setAttribute('tabIndex', -1);
\r
28320 this.el.addClass('x-hidden');
\r
28322 this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;')
\r
28324 this.wrap = this.el.wrap({
\r
28325 cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
\r
28328 this.createToolbar(this);
\r
28330 this.tb.items.each(function(item){
\r
28331 if(item.itemId != 'sourceedit'){
\r
28336 var iframe = document.createElement('iframe');
\r
28337 iframe.name = Ext.id();
\r
28338 iframe.frameBorder = 'no';
\r
28340 iframe.src=(Ext.SSL_SECURE_URL || "javascript:false");
\r
28342 this.wrap.dom.appendChild(iframe);
\r
28344 this.iframe = iframe;
\r
28347 iframe.contentWindow.document.designMode = 'on';
\r
28348 this.doc = iframe.contentWindow.document;
\r
28349 this.win = iframe.contentWindow;
\r
28351 this.doc = (iframe.contentDocument || window.frames[iframe.name].document);
\r
28352 this.win = window.frames[iframe.name];
\r
28353 this.doc.designMode = 'on';
\r
28356 this.doc.write(this.getDocMarkup())
\r
28357 this.doc.close();
\r
28360 run : function(){
\r
28361 if(this.doc.body || this.doc.readyState == 'complete'){
\r
28362 Ext.TaskMgr.stop(task);
\r
28363 this.doc.designMode="on";
\r
28364 this.initEditor.defer(10, this);
\r
28371 Ext.TaskMgr.start(task);
\r
28374 this.setSize(this.el.getSize());
\r
28379 onResize : function(w, h){
\r
28380 Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments);
\r
28381 if(this.el && this.iframe){
\r
28382 if(typeof w == 'number'){
\r
28383 var aw = w - this.wrap.getFrameWidth('lr');
\r
28384 this.el.setWidth(this.adjustWidth('textarea', aw));
\r
28385 this.iframe.style.width = aw + 'px';
\r
28387 if(typeof h == 'number'){
\r
28388 var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight();
\r
28389 this.el.setHeight(this.adjustWidth('textarea', ah));
\r
28390 this.iframe.style.height = ah + 'px';
\r
28392 this.getEditorBody().style.height = (ah - (this.iframePad*2)) + 'px';
\r
28399 toggleSourceEdit : function(sourceEditMode){
\r
28400 if(sourceEditMode === undefined){
\r
28401 sourceEditMode = !this.sourceEditMode;
\r
28403 this.sourceEditMode = sourceEditMode === true;
\r
28404 var btn = this.tb.items.get('sourceedit');
\r
28405 if(btn.pressed !== this.sourceEditMode){
\r
28406 btn.toggle(this.sourceEditMode);
\r
28409 if(this.sourceEditMode){
\r
28410 this.tb.items.each(function(item){
\r
28411 if(item.itemId != 'sourceedit'){
\r
28415 this.syncValue();
\r
28416 this.iframe.className = 'x-hidden';
\r
28417 this.el.removeClass('x-hidden');
\r
28418 this.el.dom.removeAttribute('tabIndex');
\r
28421 if(this.initialized){
\r
28422 this.tb.items.each(function(item){
\r
28426 this.pushValue();
\r
28427 this.iframe.className = '';
\r
28428 this.el.addClass('x-hidden');
\r
28429 this.el.dom.setAttribute('tabIndex', -1);
\r
28430 this.deferFocus();
\r
28432 var lastSize = this.lastSize;
\r
28434 delete this.lastSize;
\r
28435 this.setSize(lastSize);
\r
28437 this.fireEvent('editmodechange', this, this.sourceEditMode);
\r
28441 createLink : function(){
\r
28442 var url = prompt(this.createLinkText, this.defaultLinkValue);
\r
28443 if(url && url != 'http:/'+'/'){
\r
28444 this.relayCmd('createlink', url);
\r
28449 adjustSize : Ext.BoxComponent.prototype.adjustSize,
\r
28452 getResizeEl : function(){
\r
28453 return this.wrap;
\r
28457 getPositionEl : function(){
\r
28458 return this.wrap;
\r
28462 initEvents : function(){
\r
28463 this.originalValue = this.getValue();
\r
28467 markInvalid : Ext.emptyFn,
\r
28469 clearInvalid : Ext.emptyFn,
\r
28471 setValue : function(v){
\r
28472 Ext.form.HtmlEditor.superclass.setValue.call(this, v);
\r
28473 this.pushValue();
\r
28477 cleanHtml : function(html){
\r
28478 html = String(html);
\r
28479 if(html.length > 5){
\r
28481 html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');
\r
28484 if(html == ' '){
\r
28491 syncValue : function(){
\r
28492 if(this.initialized){
\r
28493 var bd = this.getEditorBody();
\r
28494 var html = bd.innerHTML;
\r
28495 if(Ext.isSafari){
\r
28496 var bs = bd.getAttribute('style');
28497 var m = bs.match(/text-align:(.*?);/i);
\r
28499 html = '<div style="'+m[0]+'">' + html + '</div>';
\r
28502 html = this.cleanHtml(html);
\r
28503 if(this.fireEvent('beforesync', this, html) !== false){
\r
28504 this.el.dom.value = html;
\r
28505 this.fireEvent('sync', this, html);
\r
28511 pushValue : function(){
\r
28512 if(this.initialized){
\r
28513 var v = this.el.dom.value;
\r
28514 if(!this.activated && v.length < 1){
\r
28517 if(this.fireEvent('beforepush', this, v) !== false){
\r
28518 this.getEditorBody().innerHTML = v;
\r
28519 this.fireEvent('push', this, v);
\r
28525 deferFocus : function(){
\r
28526 this.focus.defer(10, this);
\r
28530 focus : function(){
\r
28531 if(this.win && !this.sourceEditMode){
\r
28532 this.win.focus();
\r
28539 initEditor : function(){
\r
28540 var dbody = this.getEditorBody();
\r
28541 var ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat');
\r
28542 ss['background-attachment'] = 'fixed';
28543 dbody.bgProperties = 'fixed';
28544 Ext.DomHelper.applyStyles(dbody, ss);
\r
28545 Ext.EventManager.on(this.doc, {
\r
28546 'mousedown': this.onEditorEvent,
\r
28547 'dblclick': this.onEditorEvent,
\r
28548 'click': this.onEditorEvent,
\r
28549 'keyup': this.onEditorEvent,
\r
28554 Ext.EventManager.on(this.doc, 'keypress', this.applyCommand, this);
\r
28556 if(Ext.isIE || Ext.isSafari || Ext.isOpera){
\r
28557 Ext.EventManager.on(this.doc, 'keydown', this.fixKeys, this);
\r
28559 this.initialized = true;
\r
28561 this.fireEvent('initialize', this);
\r
28562 this.pushValue();
\r
28566 onDestroy : function(){
\r
28567 if(this.rendered){
\r
28568 this.tb.items.each(function(item){
\r
28570 item.menu.removeAll();
\r
28571 if(item.menu.el){
\r
28572 item.menu.el.destroy();
\r
28577 this.wrap.dom.innerHTML = '';
\r
28578 this.wrap.remove();
\r
28583 onFirstFocus : function(){
\r
28584 this.activated = true;
\r
28585 this.tb.items.each(function(item){
\r
28589 this.win.focus();
\r
28590 var s = this.win.getSelection();
\r
28591 if(!s.focusNode || s.focusNode.nodeType != 3){
\r
28592 var r = s.getRangeAt(0);
\r
28593 r.selectNodeContents(this.getEditorBody());
\r
28594 r.collapse(true);
\r
28595 this.deferFocus();
\r
28598 this.execCmd('useCSS', true);
\r
28599 this.execCmd('styleWithCSS', false);
\r
28602 this.fireEvent('activate', this);
\r
28606 adjustFont: function(btn){
\r
28607 var adjust = btn.itemId == 'increasefontsize' ? 1 : -1;
\r
28609 var v = parseInt(this.doc.queryCommandValue('FontSize') || 2, 10);
\r
28610 if(Ext.isSafari3 || Ext.isAir){
\r
28615 }else if(v <= 13){
\r
28617 }else if(v <= 16){
\r
28619 }else if(v <= 18){
\r
28621 }else if(v <= 24){
\r
28626 v = v.constrain(1, 6);
\r
28631 v = Math.max(1, v+adjust) + (Ext.isSafari ? 'px' : 0);
\r
28633 this.execCmd('FontSize', v);
\r
28636 onEditorEvent : function(e){
\r
28637 this.updateToolbar();
\r
28642 updateToolbar: function(){
\r
28644 if(!this.activated){
\r
28645 this.onFirstFocus();
\r
28649 var btns = this.tb.items.map, doc = this.doc;
\r
28651 if(this.enableFont && !Ext.isSafari){
\r
28652 var name = (this.doc.queryCommandValue('FontName')||this.defaultFont).toLowerCase();
\r
28653 if(name != this.fontSelect.dom.value){
\r
28654 this.fontSelect.dom.value = name;
\r
28657 if(this.enableFormat){
\r
28658 btns.bold.toggle(doc.queryCommandState('bold'));
\r
28659 btns.italic.toggle(doc.queryCommandState('italic'));
\r
28660 btns.underline.toggle(doc.queryCommandState('underline'));
\r
28662 if(this.enableAlignments){
\r
28663 btns.justifyleft.toggle(doc.queryCommandState('justifyleft'));
\r
28664 btns.justifycenter.toggle(doc.queryCommandState('justifycenter'));
\r
28665 btns.justifyright.toggle(doc.queryCommandState('justifyright'));
\r
28667 if(!Ext.isSafari && this.enableLists){
\r
28668 btns.insertorderedlist.toggle(doc.queryCommandState('insertorderedlist'));
\r
28669 btns.insertunorderedlist.toggle(doc.queryCommandState('insertunorderedlist'));
\r
28672 Ext.menu.MenuMgr.hideAll();
\r
28674 this.syncValue();
\r
28678 relayBtnCmd : function(btn){
\r
28679 this.relayCmd(btn.itemId);
\r
28683 relayCmd : function(cmd, value){
\r
28684 this.win.focus();
\r
28685 this.execCmd(cmd, value);
\r
28686 this.updateToolbar();
\r
28687 this.deferFocus();
\r
28691 execCmd : function(cmd, value){
\r
28692 this.doc.execCommand(cmd, false, value === undefined ? null : value);
\r
28693 this.syncValue();
\r
28697 applyCommand : function(e){
\r
28699 var c = e.getCharCode(), cmd;
\r
28701 c = String.fromCharCode(c);
\r
28710 cmd = 'underline';
\r
28714 this.win.focus();
\r
28715 this.execCmd(cmd);
\r
28716 this.deferFocus();
\r
28717 e.preventDefault();
\r
28724 insertAtCursor : function(text){
\r
28725 if(!this.activated){
\r
28729 this.win.focus();
\r
28730 var r = this.doc.selection.createRange();
\r
28732 r.collapse(true);
\r
28733 r.pasteHTML(text);
\r
28734 this.syncValue();
\r
28735 this.deferFocus();
\r
28737 }else if(Ext.isGecko || Ext.isOpera){
\r
28738 this.win.focus();
\r
28739 this.execCmd('InsertHTML', text);
\r
28740 this.deferFocus();
\r
28741 }else if(Ext.isSafari){
\r
28742 this.execCmd('InsertText', text);
\r
28743 this.deferFocus();
\r
28748 fixKeys : function(){
28750 return function(e){
\r
28751 var k = e.getKey(), r;
\r
28754 r = this.doc.selection.createRange();
\r
28756 r.collapse(true);
\r
28757 r.pasteHTML(' ');
\r
28758 this.deferFocus();
\r
28760 }else if(k == e.ENTER){
\r
28761 r = this.doc.selection.createRange();
\r
28763 var target = r.parentElement();
\r
28764 if(!target || target.tagName.toLowerCase() != 'li'){
\r
28766 r.pasteHTML('<br />');
\r
28767 r.collapse(false);
\r
28773 }else if(Ext.isOpera){
\r
28774 return function(e){
\r
28775 var k = e.getKey();
\r
28778 this.win.focus();
\r
28779 this.execCmd('InsertHTML',' ');
\r
28780 this.deferFocus();
\r
28783 }else if(Ext.isSafari){
\r
28784 return function(e){
\r
28785 var k = e.getKey();
\r
28788 this.execCmd('InsertText','\t');
\r
28789 this.deferFocus();
\r
28796 getToolbar : function(){
\r
28803 title: 'Bold (Ctrl+B)',
\r
28804 text: 'Make the selected text bold.',
\r
28805 cls: 'x-html-editor-tip'
\r
28808 title: 'Italic (Ctrl+I)',
\r
28809 text: 'Make the selected text italic.',
\r
28810 cls: 'x-html-editor-tip'
\r
28813 title: 'Underline (Ctrl+U)',
\r
28814 text: 'Underline the selected text.',
\r
28815 cls: 'x-html-editor-tip'
\r
28817 increasefontsize : {
\r
28818 title: 'Grow Text',
\r
28819 text: 'Increase the font size.',
\r
28820 cls: 'x-html-editor-tip'
\r
28822 decreasefontsize : {
\r
28823 title: 'Shrink Text',
\r
28824 text: 'Decrease the font size.',
\r
28825 cls: 'x-html-editor-tip'
\r
28828 title: 'Text Highlight Color',
\r
28829 text: 'Change the background color of the selected text.',
\r
28830 cls: 'x-html-editor-tip'
\r
28833 title: 'Font Color',
\r
28834 text: 'Change the color of the selected text.',
\r
28835 cls: 'x-html-editor-tip'
\r
28838 title: 'Align Text Left',
\r
28839 text: 'Align text to the left.',
\r
28840 cls: 'x-html-editor-tip'
\r
28842 justifycenter : {
\r
28843 title: 'Center Text',
\r
28844 text: 'Center text in the editor.',
\r
28845 cls: 'x-html-editor-tip'
\r
28848 title: 'Align Text Right',
\r
28849 text: 'Align text to the right.',
\r
28850 cls: 'x-html-editor-tip'
\r
28852 insertunorderedlist : {
\r
28853 title: 'Bullet List',
\r
28854 text: 'Start a bulleted list.',
\r
28855 cls: 'x-html-editor-tip'
\r
28857 insertorderedlist : {
\r
28858 title: 'Numbered List',
\r
28859 text: 'Start a numbered list.',
\r
28860 cls: 'x-html-editor-tip'
\r
28863 title: 'Hyperlink',
\r
28864 text: 'Make the selected text a hyperlink.',
\r
28865 cls: 'x-html-editor-tip'
\r
28868 title: 'Source Edit',
\r
28869 text: 'Switch to source editing mode.',
\r
28870 cls: 'x-html-editor-tip'
\r
28908 Ext.reg('htmleditor', Ext.form.HtmlEditor);
28910 Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {
\r
28916 minText : "The time in this field must be equal to or after {0}",
\r
28918 maxText : "The time in this field must be equal to or before {0}",
\r
28920 invalidText : "{0} is not a valid time",
\r
28922 format : "g:i A",
\r
28924 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",
\r
28931 triggerAction: 'all',
\r
28933 typeAhead: false,
\r
28936 initComponent : function(){
\r
28937 Ext.form.TimeField.superclass.initComponent.call(this);
\r
28939 if(typeof this.minValue == "string"){
\r
28940 this.minValue = this.parseDate(this.minValue);
\r
28942 if(typeof this.maxValue == "string"){
\r
28943 this.maxValue = this.parseDate(this.maxValue);
\r
28947 var min = this.parseDate(this.minValue);
\r
28949 min = new Date().clearTime();
\r
28951 var max = this.parseDate(this.maxValue);
\r
28953 max = new Date().clearTime().add('mi', (24 * 60) - 1);
\r
28956 while(min <= max){
\r
28957 times.push([min.dateFormat(this.format)]);
\r
28958 min = min.add('mi', this.increment);
\r
28960 this.store = new Ext.data.SimpleStore({
\r
28961 fields: ['text'],
\r
28964 this.displayField = 'text';
\r
28969 getValue : function(){
\r
28970 var v = Ext.form.TimeField.superclass.getValue.call(this);
\r
28971 return this.formatDate(this.parseDate(v)) || '';
\r
28975 setValue : function(value){
\r
28976 Ext.form.TimeField.superclass.setValue.call(this, this.formatDate(this.parseDate(value)));
\r
28980 validateValue : Ext.form.DateField.prototype.validateValue,
\r
28981 parseDate : Ext.form.DateField.prototype.parseDate,
\r
28982 formatDate : Ext.form.DateField.prototype.formatDate,
\r
28985 beforeBlur : function(){
\r
28986 var v = this.parseDate(this.getRawValue());
\r
28988 this.setValue(v.dateFormat(this.format));
\r
28997 Ext.reg('timefield', Ext.form.TimeField);
28998 Ext.form.Label = Ext.extend(Ext.BoxComponent, {
\r
28999 onRender : function(ct, position){
\r
29001 this.el = document.createElement('label');
\r
29002 this.el.innerHTML = this.text ? Ext.util.Format.htmlEncode(this.text) : (this.html || '');
\r
29004 this.el.setAttribute('htmlFor', this.forId);
\r
29007 Ext.form.Label.superclass.onRender.call(this, ct, position);
\r
29011 Ext.reg('label', Ext.form.Label);
29013 Ext.form.Action = function(form, options){
29015 this.options = options || {};
29019 Ext.form.Action.CLIENT_INVALID = 'client';
29021 Ext.form.Action.SERVER_INVALID = 'server';
29023 Ext.form.Action.CONNECT_FAILURE = 'connect';
29025 Ext.form.Action.LOAD_FAILURE = 'load';
29027 Ext.form.Action.prototype = {
29041 run : function(options){
29045 success : function(response){
29049 handleResponse : function(response){
29053 failure : function(response){
29054 this.response = response;
29055 this.failureType = Ext.form.Action.CONNECT_FAILURE;
29056 this.form.afterAction(this, false);
29059 processResponse : function(response){
29060 this.response = response;
29061 if(!response.responseText){
29064 this.result = this.handleResponse(response);
29065 return this.result;
29068 getUrl : function(appendParams){
29069 var url = this.options.url || this.form.url || this.form.el.dom.action;
29071 var p = this.getParams();
29073 url += (url.indexOf('?') != -1 ? '&' : '?') + p;
29079 getMethod : function(){
29080 return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();
29083 getParams : function(){
29084 var bp = this.form.baseParams;
29085 var p = this.options.params;
29087 if(typeof p == "object"){
29088 p = Ext.urlEncode(Ext.applyIf(p, bp));
29089 }else if(typeof p == 'string' && bp){
29090 p += '&' + Ext.urlEncode(bp);
29093 p = Ext.urlEncode(bp);
29098 createCallback : function(opts){
29099 var opts = opts || {};
29101 success: this.success,
29102 failure: this.failure,
29104 timeout: (opts.timeout*1000) || (this.form.timeout*1000),
29105 upload: this.form.fileUpload ? this.success : undefined
29111 Ext.form.Action.Submit = function(form, options){
29112 Ext.form.Action.Submit.superclass.constructor.call(this, form, options);
29115 Ext.extend(Ext.form.Action.Submit, Ext.form.Action, {
29120 var o = this.options;
29121 var method = this.getMethod();
29122 var isPost = method == 'POST';
29123 if(o.clientValidation === false || this.form.isValid()){
29124 Ext.Ajax.request(Ext.apply(this.createCallback(o), {
29125 form:this.form.el.dom,
29126 url:this.getUrl(!isPost),
29128 params:isPost ? this.getParams() : null,
29129 isUpload: this.form.fileUpload
29132 }else if (o.clientValidation !== false){ this.failureType = Ext.form.Action.CLIENT_INVALID;
29133 this.form.afterAction(this, false);
29137 success : function(response){
29138 var result = this.processResponse(response);
29139 if(result === true || result.success){
29140 this.form.afterAction(this, true);
29144 this.form.markInvalid(result.errors);
29145 this.failureType = Ext.form.Action.SERVER_INVALID;
29147 this.form.afterAction(this, false);
29150 handleResponse : function(response){
29151 if(this.form.errorReader){
29152 var rs = this.form.errorReader.read(response);
29155 for(var i = 0, len = rs.records.length; i < len; i++) {
29156 var r = rs.records[i];
29157 errors[i] = r.data;
29160 if(errors.length < 1){
29164 success : rs.success,
29168 return Ext.decode(response.responseText);
29174 Ext.form.Action.Load = function(form, options){
29175 Ext.form.Action.Load.superclass.constructor.call(this, form, options);
29176 this.reader = this.form.reader;
29179 Ext.extend(Ext.form.Action.Load, Ext.form.Action, {
29183 Ext.Ajax.request(Ext.apply(
29184 this.createCallback(this.options), {
29185 method:this.getMethod(),
29186 url:this.getUrl(false),
29187 params:this.getParams()
29191 success : function(response){
29192 var result = this.processResponse(response);
29193 if(result === true || !result.success || !result.data){
29194 this.failureType = Ext.form.Action.LOAD_FAILURE;
29195 this.form.afterAction(this, false);
29198 this.form.clearInvalid();
29199 this.form.setValues(result.data);
29200 this.form.afterAction(this, true);
29203 handleResponse : function(response){
29204 if(this.form.reader){
29205 var rs = this.form.reader.read(response);
29206 var data = rs.records && rs.records[0] ? rs.records[0].data : null;
29208 success : rs.success,
29212 return Ext.decode(response.responseText);
29216 Ext.form.Action.ACTION_TYPES = {
29217 'load' : Ext.form.Action.Load,
29218 'submit' : Ext.form.Action.Submit
29222 Ext.form.VTypes = function(){
29223 var alpha = /^[a-zA-Z_]+$/;
29224 var alphanum = /^[a-zA-Z0-9_]+$/;
29225 var email = /^([\w]+)(.[\w]+)*@([\w-]+\.){1,5}([A-Za-z]){2,4}$/;
29226 var url = /(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
29230 'email' : function(v){
29231 return email.test(v);
29234 'emailText' : 'This field should be an e-mail address in the format "user@domain.com"',
29236 'emailMask' : /[a-z0-9_\.\-@]/i,
29239 'url' : function(v){
29240 return url.test(v);
29243 'urlText' : 'This field should be a URL in the format "http:/'+'/www.domain.com"',
29246 'alpha' : function(v){
29247 return alpha.test(v);
29250 'alphaText' : 'This field should only contain letters and _',
29252 'alphaMask' : /[a-z_]/i,
29255 'alphanum' : function(v){
29256 return alphanum.test(v);
29259 'alphanumText' : 'This field should only contain letters, numbers and _',
29261 'alphanumMask' : /[a-z0-9_]/i
29265 Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
\r
29279 ddText : "{0} selected row{1}",
\r
29281 minColumnWidth : 25,
\r
29283 trackMouseOver : true,
\r
29285 enableDragDrop : false,
\r
29287 enableColumnMove : true,
\r
29289 enableColumnHide : true,
\r
29291 enableHdMenu : true,
\r
29293 stripeRows : false,
\r
29295 autoExpandColumn : false,
\r
29297 autoExpandMin : 50,
\r
29299 autoExpandMax : 1000,
\r
29303 loadMask : false,
\r
29306 rendered : false,
\r
29308 viewReady: false,
\r
29310 stateEvents: ["columnmove", "columnresize", "sortchange"],
\r
29313 initComponent : function(){
\r
29314 Ext.grid.GridPanel.superclass.initComponent.call(this);
\r
29318 this.autoScroll = false;
\r
29319 this.autoWidth = false;
\r
29321 if(Ext.isArray(this.columns)){
\r
29322 this.colModel = new Ext.grid.ColumnModel(this.columns);
\r
29323 delete this.columns;
\r
29328 this.store = this.ds;
\r
29332 this.colModel = this.cm;
\r
29336 this.selModel = this.sm;
\r
29339 this.store = Ext.StoreMgr.lookup(this.store);
\r
29368 "headermousedown",
\r
29381 "headerdblclick",
\r
29383 "rowcontextmenu",
\r
29385 "cellcontextmenu",
\r
29387 "headercontextmenu",
\r
29400 onRender : function(ct, position){
\r
29401 Ext.grid.GridPanel.superclass.onRender.apply(this, arguments);
\r
29403 var c = this.body;
\r
29405 this.el.addClass('x-grid-panel');
\r
29407 var view = this.getView();
\r
29410 c.on("mousedown", this.onMouseDown, this);
\r
29411 c.on("click", this.onClick, this);
\r
29412 c.on("dblclick", this.onDblClick, this);
\r
29413 c.on("contextmenu", this.onContextMenu, this);
\r
29414 c.on("keydown", this.onKeyDown, this);
\r
29416 this.relayEvents(c, ["mousedown","mouseup","mouseover","mouseout","keypress"]);
\r
29418 this.getSelectionModel().init(this);
\r
29419 this.view.render();
\r
29423 initEvents : function(){
\r
29424 Ext.grid.GridPanel.superclass.initEvents.call(this);
\r
29426 if(this.loadMask){
\r
29427 this.loadMask = new Ext.LoadMask(this.bwrap,
\r
29428 Ext.apply({store:this.store}, this.loadMask));
\r
29432 initStateEvents : function(){
\r
29433 Ext.grid.GridPanel.superclass.initStateEvents.call(this);
\r
29434 this.colModel.on('hiddenchange', this.saveState, this, {delay: 100});
\r
29437 applyState : function(state){
\r
29438 var cm = this.colModel;
\r
29439 var cs = state.columns;
\r
29441 for(var i = 0, len = cs.length; i < len; i++){
\r
29443 var c = cm.getColumnById(s.id);
\r
29445 c.hidden = s.hidden;
\r
29446 c.width = s.width;
\r
29447 var oldIndex = cm.getIndexById(s.id);
\r
29448 if(oldIndex != i){
\r
29449 cm.moveColumn(oldIndex, i);
\r
29455 this.store[this.store.remoteSort ? 'setDefaultSort' : 'sort'](state.sort.field, state.sort.direction);
\r
29459 getState : function(){
\r
29460 var o = {columns: []};
\r
29461 for(var i = 0, c; c = this.colModel.config[i]; i++){
\r
29467 o.columns[i].hidden = true;
\r
29470 var ss = this.store.getSortState();
\r
29478 afterRender : function(){
\r
29479 Ext.grid.GridPanel.superclass.afterRender.call(this);
\r
29480 this.view.layout();
\r
29481 this.viewReady = true;
\r
29485 reconfigure : function(store, colModel){
\r
29486 if(this.loadMask){
\r
29487 this.loadMask.destroy();
\r
29488 this.loadMask = new Ext.LoadMask(this.bwrap,
\r
29489 Ext.apply({store:store}, this.initialConfig.loadMask));
\r
29491 this.view.bind(store, colModel);
\r
29492 this.store = store;
\r
29493 this.colModel = colModel;
\r
29494 if(this.rendered){
\r
29495 this.view.refresh(true);
\r
29500 onKeyDown : function(e){
\r
29501 this.fireEvent("keydown", e);
\r
29505 onDestroy : function(){
\r
29506 if(this.rendered){
\r
29507 if(this.loadMask){
\r
29508 this.loadMask.destroy();
\r
29510 var c = this.body;
\r
29511 c.removeAllListeners();
\r
29512 this.view.destroy();
\r
29515 this.colModel.purgeListeners();
\r
29516 Ext.grid.GridPanel.superclass.onDestroy.call(this);
\r
29520 processEvent : function(name, e){
\r
29521 this.fireEvent(name, e);
\r
29522 var t = e.getTarget();
\r
29523 var v = this.view;
\r
29524 var header = v.findHeaderIndex(t);
\r
29525 if(header !== false){
\r
29526 this.fireEvent("header" + name, this, header, e);
\r
29528 var row = v.findRowIndex(t);
\r
29529 var cell = v.findCellIndex(t);
\r
29530 if(row !== false){
\r
29531 this.fireEvent("row" + name, this, row, e);
\r
29532 if(cell !== false){
\r
29533 this.fireEvent("cell" + name, this, row, cell, e);
\r
29540 onClick : function(e){
\r
29541 this.processEvent("click", e);
\r
29545 onMouseDown : function(e){
\r
29546 this.processEvent("mousedown", e);
\r
29550 onContextMenu : function(e, t){
\r
29551 this.processEvent("contextmenu", e);
\r
29555 onDblClick : function(e){
\r
29556 this.processEvent("dblclick", e);
\r
29560 walkCells : function(row, col, step, fn, scope){
\r
29561 var cm = this.colModel, clen = cm.getColumnCount();
\r
29562 var ds = this.store, rlen = ds.getCount(), first = true;
\r
29574 if(fn.call(scope || this, row, col, cm) === true){
\r
29575 return [row, col];
\r
29586 while(row < rlen){
\r
29591 while(col < clen){
\r
29592 if(fn.call(scope || this, row, col, cm) === true){
\r
29593 return [row, col];
\r
29604 getSelections : function(){
\r
29605 return this.selModel.getSelections();
\r
29609 onResize : function(){
\r
29610 Ext.grid.GridPanel.superclass.onResize.apply(this, arguments);
\r
29611 if(this.viewReady){
\r
29612 this.view.layout();
\r
29617 getGridEl : function(){
\r
29618 return this.body;
\r
29622 stopEditing : function(){},
\r
29625 getSelectionModel : function(){
\r
29626 if(!this.selModel){
\r
29627 this.selModel = new Ext.grid.RowSelectionModel(
\r
29628 this.disableSelection ? {selectRow: Ext.emptyFn} : null);
\r
29630 return this.selModel;
\r
29634 getStore : function(){
\r
29635 return this.store;
\r
29639 getColumnModel : function(){
\r
29640 return this.colModel;
\r
29644 getView : function(){
\r
29646 this.view = new Ext.grid.GridView(this.viewConfig);
\r
29648 return this.view;
\r
29651 getDragDropText : function(){
\r
29652 var count = this.selModel.getCount();
\r
29653 return String.format(this.ddText, count, count == 1 ? '' : 's');
\r
29706 Ext.reg('grid', Ext.grid.GridPanel);
29708 Ext.grid.GridView = function(config){
29709 Ext.apply(this, config);
29712 "beforerowremoved",
29714 "beforerowsinserted",
29726 Ext.grid.GridView.superclass.constructor.call(this);
29729 Ext.extend(Ext.grid.GridView, Ext.util.Observable, {
29740 sortClasses : ["sort-asc", "sort-desc"],
29742 sortAscText : "Sort Ascending",
29744 sortDescText : "Sort Descending",
29746 columnsText : "Columns",
29752 initTemplates : function(){
29753 var ts = this.templates || {};
29755 ts.master = new Ext.Template(
29756 '<div class="x-grid3" hidefocus="true">',
29757 '<div class="x-grid3-viewport">',
29758 '<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>',
29759 '<div class="x-grid3-scroller"><div class="x-grid3-body">{body}</div><a href="#" class="x-grid3-focus" tabIndex="-1"></a></div>',
29761 '<div class="x-grid3-resize-marker"> </div>',
29762 '<div class="x-grid3-resize-proxy"> </div>',
29768 ts.header = new Ext.Template(
29769 '<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
29770 '<thead><tr class="x-grid3-hd-row">{cells}</tr></thead>',
29776 ts.hcell = new Ext.Template(
29777 '<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>' : '',
29778 '{value}<img class="x-grid3-sort-icon" src="', Ext.BLANK_IMAGE_URL, '" />',
29784 ts.body = new Ext.Template('{rows}');
29788 ts.row = new Ext.Template(
29789 '<div class="x-grid3-row {alt}" style="{tstyle}"><table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
29790 '<tbody><tr>{cells}</tr>',
29791 (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>' : ''),
29792 '</tbody></table></div>'
29797 ts.cell = new Ext.Template(
29798 '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}" tabIndex="0" {cellAttr}>',
29799 '<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr}>{value}</div>',
29806 if(t && typeof t.compile == 'function' && !t.compiled){
29807 t.disableFormats = true;
29812 this.templates = ts;
29814 this.tdClass = 'x-grid3-cell';
29815 this.cellSelector = 'td.x-grid3-cell';
29816 this.hdCls = 'x-grid3-hd';
29817 this.rowSelector = 'div.x-grid3-row';
29818 this.colRe = new RegExp("x-grid3-td-([^\\s]+)", "");
29821 fly : function(el){
29822 if(!this._flyweight){
29823 this._flyweight = new Ext.Element.Flyweight(document.body);
29825 this._flyweight.dom = el;
29826 return this._flyweight;
29829 getEditorParent : function(ed){
29830 return this.scroller.dom;
29833 initElements : function(){
29834 var E = Ext.Element;
29836 var el = this.grid.getGridEl().dom.firstChild;
29837 var cs = el.childNodes;
29839 this.el = new E(el);
29841 this.mainWrap = new E(cs[0]);
29842 this.mainHd = new E(this.mainWrap.dom.firstChild);
29844 if(this.grid.hideHeaders){
29845 this.mainHd.setDisplayed(false);
29848 this.innerHd = this.mainHd.dom.firstChild;
29849 this.scroller = new E(this.mainWrap.dom.childNodes[1]);
29851 this.scroller.setStyle('overflow-x', 'hidden');
29853 this.mainBody = new E(this.scroller.dom.firstChild);
29855 this.focusEl = new E(this.scroller.dom.childNodes[1]);
29856 this.focusEl.swallowEvent("click", true);
29858 this.resizeMarker = new E(cs[1]);
29859 this.resizeProxy = new E(cs[2]);
29862 getRows : function(){
29863 return this.hasRows() ? this.mainBody.dom.childNodes : [];
29867 findCell : function(el){
29871 return this.fly(el).findParent(this.cellSelector, 3);
29874 findCellIndex : function(el, requiredCls){
29875 var cell = this.findCell(el);
29876 if(cell && (!requiredCls || this.fly(cell).hasClass(requiredCls))){
29877 return this.getCellIndex(cell);
29882 getCellIndex : function(el){
29884 var m = el.className.match(this.colRe);
29886 return this.cm.getIndexById(m[1]);
29892 findHeaderCell : function(el){
29893 var cell = this.findCell(el);
29894 return cell && this.fly(cell).hasClass(this.hdCls) ? cell : null;
29897 findHeaderIndex : function(el){
29898 return this.findCellIndex(el, this.hdCls);
29901 findRow : function(el){
29905 return this.fly(el).findParent(this.rowSelector, 10);
29908 findRowIndex : function(el){
29909 var r = this.findRow(el);
29910 return r ? r.rowIndex : false;
29915 getRow : function(row){
29916 return this.getRows()[row];
29920 getCell : function(row, col){
29921 return this.getRow(row).getElementsByTagName('td')[col];
29925 getHeaderCell : function(index){
29926 return this.mainHd.dom.getElementsByTagName('td')[index];
29930 addRowClass : function(row, cls){
29931 var r = this.getRow(row);
29933 this.fly(r).addClass(cls);
29937 removeRowClass : function(row, cls){
29938 var r = this.getRow(row);
29940 this.fly(r).removeClass(cls);
29944 removeRow : function(row){
29945 Ext.removeNode(this.getRow(row));
29948 removeRows : function(firstRow, lastRow){
29949 var bd = this.mainBody.dom;
29950 for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
29951 Ext.removeNode(bd.childNodes[firstRow]);
29956 getScrollState : function(){
29957 var sb = this.scroller.dom;
29958 return {left: sb.scrollLeft, top: sb.scrollTop};
29961 restoreScroll : function(state){
29962 var sb = this.scroller.dom;
29963 sb.scrollLeft = state.left;
29964 sb.scrollTop = state.top;
29968 scrollToTop : function(){
29969 this.scroller.dom.scrollTop = 0;
29970 this.scroller.dom.scrollLeft = 0;
29973 syncScroll : function(){
29974 this.syncHeaderScroll();
29975 var mb = this.scroller.dom;
29976 this.grid.fireEvent("bodyscroll", mb.scrollLeft, mb.scrollTop);
29979 syncHeaderScroll : function(){
29980 var mb = this.scroller.dom;
29981 this.innerHd.scrollLeft = mb.scrollLeft;
29982 this.innerHd.scrollLeft = mb.scrollLeft; },
29984 updateSortIcon : function(col, dir){
29985 var sc = this.sortClasses;
29986 var hds = this.mainHd.select('td').removeClass(sc);
29987 hds.item(col).addClass(sc[dir == "DESC" ? 1 : 0]);
29990 updateAllColumnWidths : function(){
29991 var tw = this.getTotalWidth();
29992 var clen = this.cm.getColumnCount();
29994 for(var i = 0; i < clen; i++){
29995 ws[i] = this.getColumnWidth(i);
29998 this.innerHd.firstChild.firstChild.style.width = tw;
30000 for(var i = 0; i < clen; i++){
30001 var hd = this.getHeaderCell(i);
30002 hd.style.width = ws[i];
30005 var ns = this.getRows();
30006 for(var i = 0, len = ns.length; i < len; i++){
30007 ns[i].style.width = tw;
30008 ns[i].firstChild.style.width = tw;
30009 var row = ns[i].firstChild.rows[0];
30010 for(var j = 0; j < clen; j++){
30011 row.childNodes[j].style.width = ws[j];
30015 this.onAllColumnWidthsUpdated(ws, tw);
30018 updateColumnWidth : function(col, width){
30019 var w = this.getColumnWidth(col);
30020 var tw = this.getTotalWidth();
30022 this.innerHd.firstChild.firstChild.style.width = tw;
30023 var hd = this.getHeaderCell(col);
30024 hd.style.width = w;
30026 var ns = this.getRows();
30027 for(var i = 0, len = ns.length; i < len; i++){
30028 ns[i].style.width = tw;
30029 ns[i].firstChild.style.width = tw;
30030 ns[i].firstChild.rows[0].childNodes[col].style.width = w;
30033 this.onColumnWidthUpdated(col, w, tw);
30036 updateColumnHidden : function(col, hidden){
30037 var tw = this.getTotalWidth();
30039 this.innerHd.firstChild.firstChild.style.width = tw;
30041 var display = hidden ? 'none' : '';
30043 var hd = this.getHeaderCell(col);
30044 hd.style.display = display;
30046 var ns = this.getRows();
30047 for(var i = 0, len = ns.length; i < len; i++){
30048 ns[i].style.width = tw;
30049 ns[i].firstChild.style.width = tw;
30050 ns[i].firstChild.rows[0].childNodes[col].style.display = display;
30053 this.onColumnHiddenUpdated(col, hidden, tw);
30055 delete this.lastViewWidth; this.layout();
30058 doRender : function(cs, rs, ds, startRow, colCount, stripe){
30059 var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount-1;
30060 var tstyle = 'width:'+this.getTotalWidth()+';';
30061 var buf = [], cb, c, p = {}, rp = {tstyle: tstyle}, r;
30062 for(var j = 0, len = rs.length; j < len; j++){
30063 r = rs[j]; cb = [];
30064 var rowIndex = (j+startRow);
30065 for(var i = 0; i < colCount; i++){
30068 p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
30069 p.attr = p.cellAttr = "";
30070 p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
30072 if(p.value == undefined || p.value === "") p.value = " ";
30073 if(r.dirty && typeof r.modified[c.name] !== 'undefined'){
30074 p.css += ' x-grid3-dirty-cell';
30076 cb[cb.length] = ct.apply(p);
30079 if(stripe && ((rowIndex+1) % 2 == 0)){
30080 alt[0] = "x-grid3-row-alt";
30083 alt[1] = " x-grid3-dirty-row";
30085 rp.cols = colCount;
30086 if(this.getRowClass){
30087 alt[2] = this.getRowClass(r, rowIndex, rp, ds);
30089 rp.alt = alt.join(" ");
30090 rp.cells = cb.join("");
30091 buf[buf.length] = rt.apply(rp);
30093 return buf.join("");
30096 processRows : function(startRow, skipStripe){
30097 if(this.ds.getCount() < 1){
30100 skipStripe = skipStripe || !this.grid.stripeRows;
30101 startRow = startRow || 0;
30102 var rows = this.getRows();
30103 var cls = ' x-grid3-row-alt ';
30104 for(var i = startRow, len = rows.length; i < len; i++){
30108 var isAlt = ((i+1) % 2 == 0);
30109 var hasAlt = (' '+row.className + ' ').indexOf(cls) != -1;
30110 if(isAlt == hasAlt){
30114 row.className += " x-grid3-row-alt";
30116 row.className = row.className.replace("x-grid3-row-alt", "");
30122 renderUI : function(){
30124 var header = this.renderHeaders();
30125 var body = this.templates.body.apply({rows:''});
30128 var html = this.templates.master.apply({
30135 g.getGridEl().dom.innerHTML = html;
30137 this.initElements();
30140 this.mainBody.dom.innerHTML = this.renderRows();
30141 this.processRows(0, true);
30144 Ext.fly(this.innerHd).on("click", this.handleHdDown, this);
30145 this.mainHd.on("mouseover", this.handleHdOver, this);
30146 this.mainHd.on("mouseout", this.handleHdOut, this);
30147 this.mainHd.on("mousemove", this.handleHdMove, this);
30149 this.scroller.on('scroll', this.syncScroll, this);
30150 if(g.enableColumnResize !== false){
30151 this.splitone = new Ext.grid.GridView.SplitDragZone(g, this.mainHd.dom);
30154 if(g.enableColumnMove){
30155 this.columnDrag = new Ext.grid.GridView.ColumnDragZone(g, this.innerHd);
30156 this.columnDrop = new Ext.grid.HeaderDropZone(g, this.mainHd.dom);
30159 if(g.enableHdMenu !== false){
30160 if(g.enableColumnHide !== false){
30161 this.colMenu = new Ext.menu.Menu({id:g.id + "-hcols-menu"});
30162 this.colMenu.on("beforeshow", this.beforeColMenuShow, this);
30163 this.colMenu.on("itemclick", this.handleHdMenuClick, this);
30165 this.hmenu = new Ext.menu.Menu({id: g.id + "-hctx"});
30167 {id:"asc", text: this.sortAscText, cls: "xg-hmenu-sort-asc"},
30168 {id:"desc", text: this.sortDescText, cls: "xg-hmenu-sort-desc"}
30170 if(g.enableColumnHide !== false){
30171 this.hmenu.add('-',
30172 {id:"columns", text: this.columnsText, menu: this.colMenu, iconCls: 'x-cols-icon'}
30175 this.hmenu.on("itemclick", this.handleHdMenuClick, this);
30179 if(g.enableDragDrop || g.enableDrag){
30180 var dd = new Ext.grid.GridDragZone(g, {
30181 ddGroup : g.ddGroup || 'GridDD'
30185 this.updateHeaderSortState();
30189 layout : function(){
30190 if(!this.mainBody){
30193 var c = g.getGridEl(), cm = this.cm,
30194 expandCol = g.autoExpandColumn,
30197 var csize = c.getSize(true);
30198 var vw = csize.width;
30200 if(vw < 20 || csize.height < 20){ return;
30204 this.scroller.dom.style.overflow = 'visible';
30206 this.el.setSize(csize.width, csize.height);
30208 var hdHeight = this.mainHd.getHeight();
30209 var vh = csize.height - (hdHeight);
30211 this.scroller.setSize(vw, vh);
30213 this.innerHd.style.width = (vw)+'px';
30217 if(this.lastViewWidth != vw){
30218 this.fitColumns(false, false);
30219 this.lastViewWidth = vw;
30223 this.syncHeaderScroll();
30225 this.onLayout(vw, vh);
30228 onLayout : function(vw, vh){
30231 onColumnWidthUpdated : function(col, w, tw){
30234 onAllColumnWidthsUpdated : function(ws, tw){
30237 onColumnHiddenUpdated : function(col, hidden, tw){
30240 updateColumnText : function(col, text){
30243 afterMove : function(colIndex){
30247 init: function(grid){
30250 this.initTemplates();
30251 this.initData(grid.store, grid.colModel);
30255 getColumnId : function(index){
30256 return this.cm.getColumnId(index);
30259 renderHeaders : function(){
30260 var cm = this.cm, ts = this.templates;
30263 var cb = [], sb = [], p = {};
30265 for(var i = 0, len = cm.getColumnCount(); i < len; i++){
30266 p.id = cm.getColumnId(i);
30267 p.value = cm.getColumnHeader(i) || "";
30268 p.style = this.getColumnStyle(i, true);
30269 p.tooltip = this.getColumnTooltip(i);
30270 if(cm.config[i].align == 'right'){
30271 p.istyle = 'padding-right:16px';
30275 cb[cb.length] = ct.apply(p);
30277 return ts.header.apply({cells: cb.join(""), tstyle:'width:'+this.getTotalWidth()+';'});
30280 getColumnTooltip : function(i){
30281 var tt = this.cm.getColumnTooltip(i);
30283 if(Ext.QuickTips.isEnabled()){
30284 return 'ext:qtip="'+tt+'"';
30286 return 'title="'+tt+'"';
30292 beforeUpdate : function(){
30293 this.grid.stopEditing(true);
30296 updateHeaders : function(){
30297 this.innerHd.firstChild.innerHTML = this.renderHeaders();
30301 focusRow : function(row){
30302 this.focusCell(row, 0, false);
30306 focusCell : function(row, col, hscroll){
30307 var xy = this.ensureVisible(row, col, hscroll);
30308 this.focusEl.setXY(xy);
30310 this.focusEl.focus();
30312 this.focusEl.focus.defer(1, this.focusEl);
30316 ensureVisible : function(row, col, hscroll){
30317 if(typeof row != "number"){
30318 row = row.rowIndex;
30323 if(row < 0 || row >= this.ds.getCount()){
30326 col = (col !== undefined ? col : 0);
30328 var rowEl = this.getRow(row), cellEl;
30329 if(!(hscroll === false && col === 0)){
30330 while(this.cm.isHidden(col)){
30333 cellEl = this.getCell(row, col);
30339 var c = this.scroller.dom;
30342 var p = rowEl, stop = this.el.dom;
30343 while(p && p != stop){
30344 ctop += p.offsetTop;
30345 p = p.offsetParent;
30347 ctop -= this.mainHd.dom.offsetHeight;
30349 var cbot = ctop + rowEl.offsetHeight;
30351 var ch = c.clientHeight;
30352 var stop = parseInt(c.scrollTop, 10);
30353 var sbot = stop + ch;
30356 c.scrollTop = ctop;
30357 }else if(cbot > sbot){
30358 c.scrollTop = cbot-ch;
30361 if(hscroll !== false){
30362 var cleft = parseInt(cellEl.offsetLeft, 10);
30363 var cright = cleft + cellEl.offsetWidth;
30365 var sleft = parseInt(c.scrollLeft, 10);
30366 var sright = sleft + c.clientWidth;
30368 c.scrollLeft = cleft;
30369 }else if(cright > sright){
30370 c.scrollLeft = cright-c.clientWidth;
30373 return cellEl ? Ext.fly(cellEl).getXY() : [c.scrollLeft, Ext.fly(rowEl).getY()];
30376 insertRows : function(dm, firstRow, lastRow, isUpdate){
30377 if(!isUpdate && firstRow === 0 && lastRow == dm.getCount()-1){
30381 this.fireEvent("beforerowsinserted", this, firstRow, lastRow);
30383 var html = this.renderRows(firstRow, lastRow);
30384 var before = this.getRow(firstRow);
30386 Ext.DomHelper.insertHtml('beforeBegin', before, html);
30388 Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html);
30391 this.fireEvent("rowsinserted", this, firstRow, lastRow);
30392 this.processRows(firstRow);
30397 deleteRows : function(dm, firstRow, lastRow){
30398 if(dm.getRowCount()<1){
30401 this.fireEvent("beforerowsdeleted", this, firstRow, lastRow);
30403 this.removeRows(firstRow, lastRow);
30405 this.processRows(firstRow);
30406 this.fireEvent("rowsdeleted", this, firstRow, lastRow);
30410 getColumnStyle : function(col, isHeader){
30411 var style = !isHeader ? (this.cm.config[col].css || '') : '';
30412 style += 'width:'+this.getColumnWidth(col)+';';
30413 if(this.cm.isHidden(col)){
30414 style += 'display:none;';
30416 var align = this.cm.config[col].align;
30418 style += 'text-align:'+align+';';
30423 getColumnWidth : function(col){
30424 var w = this.cm.getColumnWidth(col);
30425 if(typeof w == 'number'){
30426 return (Ext.isBorderBox ? w : (w-this.borderWidth > 0 ? w-this.borderWidth:0)) + 'px';
30431 getTotalWidth : function(){
30432 return this.cm.getTotalWidth()+'px';
30435 fitColumns : function(preventRefresh, onlyExpand, omitColumn){
30436 var cm = this.cm, leftOver, dist, i;
30437 var tw = cm.getTotalWidth(false);
30438 var aw = this.grid.getGridEl().getWidth(true)-this.scrollOffset;
30440 if(aw < 20){ return;
30442 var extra = aw - tw;
30448 var vc = cm.getColumnCount(true);
30449 var ac = vc-(typeof omitColumn == 'number' ? 1 : 0);
30452 omitColumn = undefined;
30454 var colCount = cm.getColumnCount();
30459 for (i = 0; i < colCount; i++){
30460 if(!cm.isHidden(i) && !cm.isFixed(i) && i !== omitColumn){
30461 w = cm.getColumnWidth(i);
30468 var frac = (aw - cm.getTotalWidth())/width;
30469 while (cols.length){
30472 cm.setColumnWidth(i, Math.max(this.grid.minColumnWidth, Math.floor(w + w*frac)), true);
30475 if((tw = cm.getTotalWidth(false)) > aw){
30476 var adjustCol = ac != vc ? omitColumn : extraCol;
30477 cm.setColumnWidth(adjustCol, Math.max(1,
30478 cm.getColumnWidth(adjustCol)- (tw-aw)), true);
30481 if(preventRefresh !== true){
30482 this.updateAllColumnWidths();
30489 autoExpand : function(preventUpdate){
30490 var g = this.grid, cm = this.cm;
30491 if(!this.userResized && g.autoExpandColumn){
30492 var tw = cm.getTotalWidth(false);
30493 var aw = this.grid.getGridEl().getWidth(true)-this.scrollOffset;
30495 var ci = cm.getIndexById(g.autoExpandColumn);
30496 var currentWidth = cm.getColumnWidth(ci);
30497 var cw = Math.min(Math.max(((aw-tw)+currentWidth), g.autoExpandMin), g.autoExpandMax);
30498 if(cw != currentWidth){
30499 cm.setColumnWidth(ci, cw, true);
30500 if(preventUpdate !== true){
30501 this.updateColumnWidth(ci, cw);
30508 getColumnData : function(){
30509 var cs = [], cm = this.cm, colCount = cm.getColumnCount();
30510 for(var i = 0; i < colCount; i++){
30511 var name = cm.getDataIndex(i);
30513 name : (typeof name == 'undefined' ? this.ds.fields.get(i).name : name),
30514 renderer : cm.getRenderer(i),
30515 id : cm.getColumnId(i),
30516 style : this.getColumnStyle(i)
30522 renderRows : function(startRow, endRow){
30523 var g = this.grid, cm = g.colModel, ds = g.store, stripe = g.stripeRows;
30524 var colCount = cm.getColumnCount();
30526 if(ds.getCount() < 1){
30530 var cs = this.getColumnData();
30532 startRow = startRow || 0;
30533 endRow = typeof endRow == "undefined"? ds.getCount()-1 : endRow;
30535 var rs = ds.getRange(startRow, endRow);
30537 return this.doRender(cs, rs, ds, startRow, colCount, stripe);
30540 renderBody : function(){
30541 var markup = this.renderRows();
30542 return this.templates.body.apply({rows: markup});
30545 refreshRow : function(record){
30546 var ds = this.ds, index;
30547 if(typeof record == 'number'){
30549 record = ds.getAt(index);
30551 index = ds.indexOf(record);
30554 this.insertRows(ds, index, index, true);
30555 this.getRow(index).rowIndex = index;
30556 this.onRemove(ds, record, index+1, true);
30557 this.fireEvent("rowupdated", this, index, record);
30561 refresh : function(headersToo){
30562 this.fireEvent("beforerefresh", this);
30563 this.grid.stopEditing(true);
30565 var result = this.renderBody();
30566 this.mainBody.update(result);
30568 if(headersToo === true){
30569 this.updateHeaders();
30570 this.updateHeaderSortState();
30572 this.processRows(0, true);
30574 this.applyEmptyText();
30575 this.fireEvent("refresh", this);
30578 applyEmptyText : function(){
30579 if(this.emptyText && !this.hasRows()){
30580 this.mainBody.update('<div class="x-grid-empty">' + this.emptyText + '</div>');
30584 updateHeaderSortState : function(){
30585 var state = this.ds.getSortState();
30589 if(!this.sortState || (this.sortState.field != state.field || this.sortState.direction != state.direction)){
30590 this.grid.fireEvent('sortchange', this.grid, state);
30592 this.sortState = state;
30593 var sortColumn = this.cm.findColumnIndex(state.field);
30594 if(sortColumn != -1){
30595 var sortDir = state.direction;
30596 this.updateSortIcon(sortColumn, sortDir);
30600 destroy : function(){
30602 this.colMenu.removeAll();
30603 Ext.menu.MenuMgr.unregister(this.colMenu);
30604 this.colMenu.getEl().remove();
30605 delete this.colMenu;
30608 this.hmenu.removeAll();
30609 Ext.menu.MenuMgr.unregister(this.hmenu);
30610 this.hmenu.getEl().remove();
30613 if(this.grid.enableColumnMove){
30614 var dds = Ext.dd.DDM.ids['gridHeader' + this.grid.getGridEl().id];
30616 for(var dd in dds){
30617 if(!dds[dd].config.isTarget && dds[dd].dragElId){
30618 var elid = dds[dd].dragElId;
30620 Ext.get(elid).remove();
30621 } else if(dds[dd].config.isTarget){
30622 dds[dd].proxyTop.remove();
30623 dds[dd].proxyBottom.remove();
30626 if(Ext.dd.DDM.locationCache[dd]){
30627 delete Ext.dd.DDM.locationCache[dd];
30630 delete Ext.dd.DDM.ids['gridHeader' + this.grid.getGridEl().id];
30634 Ext.destroy(this.resizeMarker, this.resizeProxy);
30636 this.initData(null, null);
30637 Ext.EventManager.removeResizeListener(this.onWindowResize, this);
30640 onDenyColumnHide : function(){
30644 render : function(){
30647 var colCount = cm.getColumnCount();
30650 this.fitColumns(true, true);
30651 }else if(this.forceFit){
30652 this.fitColumns(true, false);
30653 }else if(this.grid.autoExpandColumn){
30654 this.autoExpand(true);
30661 initData : function(ds, cm){
30663 this.ds.un("load", this.onLoad, this);
30664 this.ds.un("datachanged", this.onDataChange, this);
30665 this.ds.un("add", this.onAdd, this);
30666 this.ds.un("remove", this.onRemove, this);
30667 this.ds.un("update", this.onUpdate, this);
30668 this.ds.un("clear", this.onClear, this);
30671 ds.on("load", this.onLoad, this);
30672 ds.on("datachanged", this.onDataChange, this);
30673 ds.on("add", this.onAdd, this);
30674 ds.on("remove", this.onRemove, this);
30675 ds.on("update", this.onUpdate, this);
30676 ds.on("clear", this.onClear, this);
30681 this.cm.un("configchange", this.onColConfigChange, this);
30682 this.cm.un("widthchange", this.onColWidthChange, this);
30683 this.cm.un("headerchange", this.onHeaderChange, this);
30684 this.cm.un("hiddenchange", this.onHiddenChange, this);
30685 this.cm.un("columnmoved", this.onColumnMove, this);
30686 this.cm.un("columnlockchange", this.onColumnLock, this);
30689 cm.on("configchange", this.onColConfigChange, this);
30690 cm.on("widthchange", this.onColWidthChange, this);
30691 cm.on("headerchange", this.onHeaderChange, this);
30692 cm.on("hiddenchange", this.onHiddenChange, this);
30693 cm.on("columnmoved", this.onColumnMove, this);
30694 cm.on("columnlockchange", this.onColumnLock, this);
30699 onDataChange : function(){
30701 this.updateHeaderSortState();
30704 onClear : function(){
30708 onUpdate : function(ds, record){
30709 this.refreshRow(record);
30712 onAdd : function(ds, records, index){
30713 this.insertRows(ds, index, index + (records.length-1));
30716 onRemove : function(ds, record, index, isUpdate){
30717 if(isUpdate !== true){
30718 this.fireEvent("beforerowremoved", this, index, record);
30720 this.removeRow(index);
30721 if(isUpdate !== true){
30722 this.processRows(index);
30723 this.applyEmptyText();
30724 this.fireEvent("rowremoved", this, index, record);
30728 onLoad : function(){
30729 this.scrollToTop();
30732 onColWidthChange : function(cm, col, width){
30733 this.updateColumnWidth(col, width);
30736 onHeaderChange : function(cm, col, text){
30737 this.updateHeaders();
30740 onHiddenChange : function(cm, col, hidden){
30741 this.updateColumnHidden(col, hidden);
30744 onColumnMove : function(cm, oldIndex, newIndex){
30745 this.indexMap = null;
30746 var s = this.getScrollState();
30747 this.refresh(true);
30748 this.restoreScroll(s);
30749 this.afterMove(newIndex);
30752 onColConfigChange : function(){
30753 delete this.lastViewWidth;
30754 this.indexMap = null;
30755 this.refresh(true);
30759 initUI : function(grid){
30760 grid.on("headerclick", this.onHeaderClick, this);
30762 if(grid.trackMouseOver){
30763 grid.on("mouseover", this.onRowOver, this);
30764 grid.on("mouseout", this.onRowOut, this);
30768 initEvents : function(){
30772 onHeaderClick : function(g, index){
30773 if(this.headersDisabled || !this.cm.isSortable(index)){
30776 g.stopEditing(true);
30777 g.store.sort(this.cm.getDataIndex(index));
30780 onRowOver : function(e, t){
30782 if((row = this.findRowIndex(t)) !== false){
30783 this.addRowClass(row, "x-grid3-row-over");
30787 onRowOut : function(e, t){
30789 if((row = this.findRowIndex(t)) !== false && row !== this.findRowIndex(e.getRelatedTarget())){
30790 this.removeRowClass(row, "x-grid3-row-over");
30794 handleWheel : function(e){
30795 e.stopPropagation();
30798 onRowSelect : function(row){
30799 this.addRowClass(row, "x-grid3-row-selected");
30802 onRowDeselect : function(row){
30803 this.removeRowClass(row, "x-grid3-row-selected");
30806 onCellSelect : function(row, col){
30807 var cell = this.getCell(row, col);
30809 this.fly(cell).addClass("x-grid3-cell-selected");
30813 onCellDeselect : function(row, col){
30814 var cell = this.getCell(row, col);
30816 this.fly(cell).removeClass("x-grid3-cell-selected");
30820 onColumnSplitterMoved : function(i, w){
30821 this.userResized = true;
30822 var cm = this.grid.colModel;
30823 cm.setColumnWidth(i, w, true);
30826 this.fitColumns(true, false, i);
30827 this.updateAllColumnWidths();
30829 this.updateColumnWidth(i, w);
30832 this.grid.fireEvent("columnresize", i, w);
30835 handleHdMenuClick : function(item){
30836 var index = this.hdCtxIndex;
30837 var cm = this.cm, ds = this.ds;
30840 ds.sort(cm.getDataIndex(index), "ASC");
30843 ds.sort(cm.getDataIndex(index), "DESC");
30846 index = cm.getIndexById(item.id.substr(4));
30848 if(item.checked && cm.getColumnsBy(this.isHideableColumn, this).length <= 1){
30849 this.onDenyColumnHide();
30852 cm.setHidden(index, item.checked);
30858 isHideableColumn : function(c){
30859 return !c.hidden && !c.fixed;
30862 beforeColMenuShow : function(){
30863 var cm = this.cm, colCount = cm.getColumnCount();
30864 this.colMenu.removeAll();
30865 for(var i = 0; i < colCount; i++){
30866 if(cm.config[i].fixed !== true && cm.config[i].hideable !== false){
30867 this.colMenu.add(new Ext.menu.CheckItem({
30868 id: "col-"+cm.getColumnId(i),
30869 text: cm.getColumnHeader(i),
30870 checked: !cm.isHidden(i),
30872 disabled: cm.config[i].hideable === false
30878 handleHdDown : function(e, t){
30879 if(Ext.fly(t).hasClass('x-grid3-hd-btn')){
30881 var hd = this.findHeaderCell(t);
30882 Ext.fly(hd).addClass('x-grid3-hd-menu-open');
30883 var index = this.getCellIndex(hd);
30884 this.hdCtxIndex = index;
30885 var ms = this.hmenu.items, cm = this.cm;
30886 ms.get("asc").setDisabled(!cm.isSortable(index));
30887 ms.get("desc").setDisabled(!cm.isSortable(index));
30888 this.hmenu.on("hide", function(){
30889 Ext.fly(hd).removeClass('x-grid3-hd-menu-open');
30890 }, this, {single:true});
30891 this.hmenu.show(t, "tl-bl?");
30895 handleHdOver : function(e, t){
30896 var hd = this.findHeaderCell(t);
30897 if(hd && !this.headersDisabled){
30898 this.activeHd = hd;
30899 this.activeHdIndex = this.getCellIndex(hd);
30900 var fly = this.fly(hd);
30901 this.activeHdRegion = fly.getRegion();
30902 if(!this.cm.isMenuDisabled(this.activeHdIndex)){
30903 fly.addClass("x-grid3-hd-over");
30904 this.activeHdBtn = fly.child('.x-grid3-hd-btn');
30905 if(this.activeHdBtn){
30906 this.activeHdBtn.dom.style.height = (hd.firstChild.offsetHeight-1)+'px';
30912 handleHdMove : function(e, t){
30913 if(this.activeHd && !this.headersDisabled){
30914 var hw = this.splitHandleWidth || 5;
30915 var r = this.activeHdRegion;
30916 var x = e.getPageX();
30917 var ss = this.activeHd.style;
30918 if(x - r.left <= hw && this.cm.isResizable(this.activeHdIndex-1)){
30919 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)){
30920 ss.cursor = Ext.isAir ? 'move' : Ext.isSafari ? 'w-resize' : 'col-resize';
30927 handleHdOut : function(e, t){
30928 var hd = this.findHeaderCell(t);
30929 if(hd && (!Ext.isIE || !e.within(hd, true))){
30930 this.activeHd = null;
30931 this.fly(hd).removeClass("x-grid3-hd-over");
30932 hd.style.cursor = '';
30936 hasRows : function(){
30937 var fc = this.mainBody.dom.firstChild;
30938 return fc && fc.className != 'x-grid-empty';
30941 bind : function(d, c){
30942 this.initData(d, c);
30947 Ext.grid.GridView.SplitDragZone = function(grid, hd){
30949 this.view = grid.getView();
30950 this.marker = this.view.resizeMarker;
30951 this.proxy = this.view.resizeProxy;
30952 Ext.grid.GridView.SplitDragZone.superclass.constructor.call(this, hd,
30953 "gridSplitters" + this.grid.getGridEl().id, {
30954 dragElId : Ext.id(this.proxy.dom), resizeFrame:false
30956 this.scroll = false;
30957 this.hw = this.view.splitHandleWidth || 5;
30959 Ext.extend(Ext.grid.GridView.SplitDragZone, Ext.dd.DDProxy, {
30961 b4StartDrag : function(x, y){
30962 this.view.headersDisabled = true;
30963 var h = this.view.mainWrap.getHeight();
30964 this.marker.setHeight(h);
30965 this.marker.show();
30966 this.marker.alignTo(this.view.getHeaderCell(this.cellIndex), 'tl-tl', [-2, 0]);
30967 this.proxy.setHeight(h);
30968 var w = this.cm.getColumnWidth(this.cellIndex);
30969 var minw = Math.max(w-this.grid.minColumnWidth, 0);
30970 this.resetConstraints();
30971 this.setXConstraint(minw, 1000);
30972 this.setYConstraint(0, 0);
30973 this.minX = x - minw;
30974 this.maxX = x + 1000;
30976 Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
30980 handleMouseDown : function(e){
30981 var t = this.view.findHeaderCell(e.getTarget());
30983 var xy = this.view.fly(t).getXY(), x = xy[0], y = xy[1];
30984 var exy = e.getXY(), ex = exy[0], ey = exy[1];
30985 var w = t.offsetWidth, adjust = false;
30986 if((ex - x) <= this.hw){
30988 }else if((x+w) - ex <= this.hw){
30991 if(adjust !== false){
30992 this.cm = this.grid.colModel;
30993 var ci = this.view.getCellIndex(t);
30995 if (ci + adjust < 0) {
30998 while(this.cm.isHidden(ci+adjust)){
31005 this.cellIndex = ci+adjust;
31006 this.split = t.dom;
31007 if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
31008 Ext.grid.GridView.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
31010 }else if(this.view.columnDrag){
31011 this.view.columnDrag.callHandleMouseDown(e);
31016 endDrag : function(e){
31017 this.marker.hide();
31019 var endX = Math.max(this.minX, e.getPageX());
31020 var diff = endX - this.startPos;
31021 v.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
31022 setTimeout(function(){
31023 v.headersDisabled = false;
31027 autoOffset : function(){
31028 this.setDelta(0,0);
31033 Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
\r
31035 hideGroupedColumn:false,
\r
31037 showGroupName:true,
\r
31039 startCollapsed:false,
\r
31041 enableGrouping:true,
\r
31043 enableGroupingMenu:true,
\r
31045 enableNoGroups:true,
\r
31047 emptyGroupText : '(None)',
\r
31049 ignoreAdd: false,
\r
31051 groupTextTpl : '{text}',
\r
31059 initTemplates : function(){
\r
31060 Ext.grid.GroupingView.superclass.initTemplates.call(this);
\r
31063 var sm = this.grid.getSelectionModel();
\r
31064 sm.on(sm.selectRow ? 'beforerowselect' : 'beforecellselect',
\r
31065 this.onBeforeRowSelect, this);
\r
31067 if(!this.startGroup){
\r
31068 this.startGroup = new Ext.XTemplate(
\r
31069 '<div id="{groupId}" class="x-grid-group {cls}">',
\r
31070 '<div id="{groupId}-hd" class="x-grid-group-hd" style="{style}"><div>', this.groupTextTpl ,'</div></div>',
\r
31071 '<div id="{groupId}-bd" class="x-grid-group-body">'
\r
31074 this.startGroup.compile();
\r
31075 this.endGroup = '</div></div>';
\r
31079 findGroup : function(el){
\r
31080 return Ext.fly(el).up('.x-grid-group', this.mainBody.dom);
\r
31084 getGroups : function(){
\r
31085 return this.hasRows() ? this.mainBody.dom.childNodes : [];
\r
31089 onAdd : function(){
\r
31090 if(this.enableGrouping && !this.ignoreAdd){
\r
31091 var ss = this.getScrollState();
\r
31093 this.restoreScroll(ss);
\r
31094 }else if(!this.enableGrouping){
\r
31095 Ext.grid.GroupingView.superclass.onAdd.apply(this, arguments);
\r
31100 onRemove : function(ds, record, index, isUpdate){
\r
31101 Ext.grid.GroupingView.superclass.onRemove.apply(this, arguments);
\r
31102 var g = document.getElementById(record._groupId);
\r
31103 if(g && g.childNodes[1].childNodes.length < 1){
\r
31104 Ext.removeNode(g);
\r
31106 this.applyEmptyText();
\r
31110 refreshRow : function(record){
\r
31111 if(this.ds.getCount()==1){
\r
31114 this.isUpdating = true;
\r
31115 Ext.grid.GroupingView.superclass.refreshRow.apply(this, arguments);
\r
31116 this.isUpdating = false;
\r
31121 beforeMenuShow : function(){
\r
31122 var field = this.getGroupField();
\r
31123 var g = this.hmenu.items.get('groupBy');
\r
31125 g.setDisabled(this.cm.config[this.hdCtxIndex].groupable === false);
\r
31127 var s = this.hmenu.items.get('showGroups');
\r
31130 s.setDisabled(this.cm.config[this.hdCtxIndex].groupable === false)
\r
31132 s.setChecked(!!field);
\r
31137 renderUI : function(){
\r
31138 Ext.grid.GroupingView.superclass.renderUI.call(this);
\r
31139 this.mainBody.on('mousedown', this.interceptMouse, this);
\r
31141 if(this.enableGroupingMenu && this.hmenu){
\r
31142 this.hmenu.add('-',{
\r
31144 text: this.groupByText,
\r
31145 handler: this.onGroupByClick,
\r
31147 iconCls:'x-group-by-icon'
\r
31149 if(this.enableNoGroups){
\r
31152 text: this.showGroupsText,
\r
31154 checkHandler: this.onShowGroupsClick,
\r
31158 this.hmenu.on('beforeshow', this.beforeMenuShow, this);
\r
31163 onGroupByClick : function(){
\r
31164 this.grid.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex));
\r
31165 this.beforeMenuShow();
31169 onShowGroupsClick : function(mi, checked){
\r
31171 this.onGroupByClick();
\r
31173 this.grid.store.clearGrouping();
\r
31178 toggleGroup : function(group, expanded){
\r
31179 this.grid.stopEditing(true);
\r
31180 group = Ext.getDom(group);
\r
31181 var gel = Ext.fly(group);
\r
31182 expanded = expanded !== undefined ?
\r
31183 expanded : gel.hasClass('x-grid-group-collapsed');
\r
31185 this.state[gel.dom.id] = expanded;
\r
31186 gel[expanded ? 'removeClass' : 'addClass']('x-grid-group-collapsed');
\r
31190 toggleAllGroups : function(expanded){
\r
31191 var groups = this.getGroups();
\r
31192 for(var i = 0, len = groups.length; i < len; i++){
\r
31193 this.toggleGroup(groups[i], expanded);
\r
31198 expandAllGroups : function(){
\r
31199 this.toggleAllGroups(true);
\r
31203 collapseAllGroups : function(){
\r
31204 this.toggleAllGroups(false);
\r
31208 interceptMouse : function(e){
\r
31209 var hd = e.getTarget('.x-grid-group-hd', this.mainBody);
\r
31212 this.toggleGroup(hd.parentNode);
\r
31217 getGroup : function(v, r, groupRenderer, rowIndex, colIndex, ds){
\r
31218 var g = groupRenderer ? groupRenderer(v, {}, r, rowIndex, colIndex, ds) : String(v);
\r
31220 g = this.cm.config[colIndex].emptyGroupText || this.emptyGroupText;
\r
31226 getGroupField : function(){
\r
31227 return this.grid.store.getGroupState();
\r
31231 renderRows : function(){
\r
31232 var groupField = this.getGroupField();
\r
31233 var eg = !!groupField;
\r
31235 if(this.hideGroupedColumn) {
\r
31236 var colIndex = this.cm.findColumnIndex(groupField);
\r
31237 if(!eg && this.lastGroupField !== undefined) {
\r
31238 this.mainBody.update('');
\r
31239 this.cm.setHidden(this.cm.findColumnIndex(this.lastGroupField), false);
\r
31240 delete this.lastGroupField;
\r
31241 }else if (eg && this.lastGroupField === undefined) {
\r
31242 this.lastGroupField = groupField;
\r
31243 this.cm.setHidden(colIndex, true);
\r
31244 }else if (eg && this.lastGroupField !== undefined && groupField !== this.lastGroupField) {
\r
31245 this.mainBody.update('');
\r
31246 var oldIndex = this.cm.findColumnIndex(this.lastGroupField);
\r
31247 this.cm.setHidden(oldIndex, false);
\r
31248 this.lastGroupField = groupField;
\r
31249 this.cm.setHidden(colIndex, true);
\r
31252 return Ext.grid.GroupingView.superclass.renderRows.apply(
\r
31253 this, arguments);
\r
31257 doRender : function(cs, rs, ds, startRow, colCount, stripe){
\r
31258 if(rs.length < 1){
\r
31261 var groupField = this.getGroupField();
\r
31262 var colIndex = this.cm.findColumnIndex(groupField);
\r
31264 this.enableGrouping = !!groupField;
\r
31266 if(!this.enableGrouping || this.isUpdating){
\r
31267 return Ext.grid.GroupingView.superclass.doRender.apply(
\r
31268 this, arguments);
\r
31270 var gstyle = 'width:'+this.getTotalWidth()+';';
\r
31272 var gidPrefix = this.grid.getGridEl().id;
\r
31273 var cfg = this.cm.config[colIndex];
\r
31274 var groupRenderer = cfg.groupRenderer || cfg.renderer;
\r
31275 var prefix = this.showGroupName ?
\r
31276 (cfg.groupName || cfg.header)+': ' : '';
\r
31278 var groups = [], curGroup, i, len, gid;
\r
31279 for(i = 0, len = rs.length; i < len; i++){
\r
31280 var rowIndex = startRow + i;
\r
31282 gvalue = r.data[groupField],
\r
31283 g = this.getGroup(gvalue, r, groupRenderer, rowIndex, colIndex, ds);
\r
31284 if(!curGroup || curGroup.group != g){
\r
31285 gid = gidPrefix + '-gp-' + groupField + '-' + Ext.util.Format.htmlEncode(g);
\r
31288 var isCollapsed = typeof this.state[gid] !== 'undefined' ? !this.state[gid] : this.startCollapsed;
\r
31289 var gcls = isCollapsed ? 'x-grid-group-collapsed' : '';
\r
31293 text: prefix + g,
\r
31295 startRow: rowIndex,
\r
31300 groups.push(curGroup);
\r
31302 curGroup.rs.push(r);
\r
31304 r._groupId = gid;
\r
31308 for(i = 0, len = groups.length; i < len; i++){
\r
31309 var g = groups[i];
\r
31310 this.doGroupStart(buf, g, cs, ds, colCount);
\r
31311 buf[buf.length] = Ext.grid.GroupingView.superclass.doRender.call(
\r
31312 this, cs, g.rs, ds, g.startRow, colCount, stripe);
\r
31314 this.doGroupEnd(buf, g, cs, ds, colCount);
\r
31316 return buf.join('');
\r
31320 getGroupId : function(value){
\r
31321 var gidPrefix = this.grid.getGridEl().id;
\r
31322 var groupField = this.getGroupField();
\r
31323 var colIndex = this.cm.findColumnIndex(groupField);
\r
31324 var cfg = this.cm.config[colIndex];
\r
31325 var groupRenderer = cfg.groupRenderer || cfg.renderer;
\r
31326 var gtext = this.getGroup(value, {data:{}}, groupRenderer, 0, colIndex, this.ds);
\r
31327 return gidPrefix + '-gp-' + groupField + '-' + Ext.util.Format.htmlEncode(value);
\r
31331 doGroupStart : function(buf, g, cs, ds, colCount){
\r
31332 buf[buf.length] = this.startGroup.apply(g);
\r
31336 doGroupEnd : function(buf, g, cs, ds, colCount){
\r
31337 buf[buf.length] = this.endGroup;
\r
31341 getRows : function(){
\r
31342 if(!this.enableGrouping){
\r
31343 return Ext.grid.GroupingView.superclass.getRows.call(this);
\r
31346 var g, gs = this.getGroups();
\r
31347 for(var i = 0, len = gs.length; i < len; i++){
\r
31348 g = gs[i].childNodes[1].childNodes;
\r
31349 for(var j = 0, jlen = g.length; j < jlen; j++){
\r
31350 r[r.length] = g[j];
\r
31357 updateGroupWidths : function(){
\r
31358 if(!this.enableGrouping || !this.hasRows()){
\r
31361 var tw = Math.max(this.cm.getTotalWidth(), this.el.dom.offsetWidth-this.scrollOffset) +'px';
\r
31362 var gs = this.getGroups();
\r
31363 for(var i = 0, len = gs.length; i < len; i++){
\r
31364 gs[i].firstChild.style.width = tw;
\r
31369 onColumnWidthUpdated : function(col, w, tw){
\r
31370 this.updateGroupWidths();
\r
31374 onAllColumnWidthsUpdated : function(ws, tw){
\r
31375 this.updateGroupWidths();
\r
31379 onColumnHiddenUpdated : function(col, hidden, tw){
\r
31380 this.updateGroupWidths();
\r
31384 onLayout : function(){
\r
31385 this.updateGroupWidths();
\r
31389 onBeforeRowSelect : function(sm, rowIndex){
\r
31390 if(!this.enableGrouping){
\r
31393 var row = this.getRow(rowIndex);
\r
31394 if(row && !row.offsetParent){
\r
31395 var g = this.findGroup(row);
\r
31396 this.toggleGroup(g, true);
\r
31401 groupByText: 'Group By This Field',
\r
31403 showGroupsText: 'Show in Groups'
\r
31406 Ext.grid.GroupingView.GROUP_ID = 1000;
31409 Ext.grid.HeaderDragZone = function(grid, hd, hd2){
\r
31410 this.grid = grid;
\r
31411 this.view = grid.getView();
\r
31412 this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
\r
31413 Ext.grid.HeaderDragZone.superclass.constructor.call(this, hd);
\r
31415 this.setHandleElId(Ext.id(hd));
\r
31416 this.setOuterHandleElId(Ext.id(hd2));
\r
31418 this.scroll = false;
\r
31420 Ext.extend(Ext.grid.HeaderDragZone, Ext.dd.DragZone, {
\r
31421 maxDragWidth: 120,
\r
31422 getDragData : function(e){
\r
31423 var t = Ext.lib.Event.getTarget(e);
\r
31424 var h = this.view.findHeaderCell(t);
\r
31426 return {ddel: h.firstChild, header:h};
\r
31431 onInitDrag : function(e){
\r
31432 this.view.headersDisabled = true;
\r
31433 var clone = this.dragData.ddel.cloneNode(true);
\r
31434 clone.id = Ext.id();
\r
31435 clone.style.width = Math.min(this.dragData.header.offsetWidth,this.maxDragWidth) + "px";
\r
31436 this.proxy.update(clone);
\r
31440 afterValidDrop : function(){
\r
31441 var v = this.view;
\r
31442 setTimeout(function(){
\r
31443 v.headersDisabled = false;
\r
31447 afterInvalidDrop : function(){
\r
31448 var v = this.view;
\r
31449 setTimeout(function(){
\r
31450 v.headersDisabled = false;
\r
31457 Ext.grid.HeaderDropZone = function(grid, hd, hd2){
\r
31458 this.grid = grid;
\r
31459 this.view = grid.getView();
\r
31461 this.proxyTop = Ext.DomHelper.append(document.body, {
\r
31462 cls:"col-move-top", html:" "
\r
31464 this.proxyBottom = Ext.DomHelper.append(document.body, {
\r
31465 cls:"col-move-bottom", html:" "
\r
31467 this.proxyTop.hide = this.proxyBottom.hide = function(){
\r
31468 this.setLeftTop(-100,-100);
\r
31469 this.setStyle("visibility", "hidden");
\r
31471 this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
\r
31474 Ext.grid.HeaderDropZone.superclass.constructor.call(this, grid.getGridEl().dom);
\r
31476 Ext.extend(Ext.grid.HeaderDropZone, Ext.dd.DropZone, {
\r
31477 proxyOffsets : [-4, -9],
\r
31478 fly: Ext.Element.fly,
\r
31480 getTargetFromEvent : function(e){
\r
31481 var t = Ext.lib.Event.getTarget(e);
\r
31482 var cindex = this.view.findCellIndex(t);
\r
31483 if(cindex !== false){
\r
31484 return this.view.getHeaderCell(cindex);
\r
31488 nextVisible : function(h){
\r
31489 var v = this.view, cm = this.grid.colModel;
\r
31490 h = h.nextSibling;
\r
31492 if(!cm.isHidden(v.getCellIndex(h))){
\r
31495 h = h.nextSibling;
\r
31500 prevVisible : function(h){
\r
31501 var v = this.view, cm = this.grid.colModel;
\r
31502 h = h.prevSibling;
\r
31504 if(!cm.isHidden(v.getCellIndex(h))){
\r
31507 h = h.prevSibling;
\r
31512 positionIndicator : function(h, n, e){
\r
31513 var x = Ext.lib.Event.getPageX(e);
\r
31514 var r = Ext.lib.Dom.getRegion(n.firstChild);
\r
31515 var px, pt, py = r.top + this.proxyOffsets[1];
\r
31516 if((r.right - x) <= (r.right-r.left)/2){
\r
31517 px = r.right+this.view.borderWidth;
\r
31523 var oldIndex = this.view.getCellIndex(h);
\r
31524 var newIndex = this.view.getCellIndex(n);
\r
31526 if(this.grid.colModel.isFixed(newIndex)){
\r
31530 var locked = this.grid.colModel.isLocked(newIndex);
\r
31532 if(pt == "after"){
\r
31535 if(oldIndex < newIndex){
\r
31538 if(oldIndex == newIndex && (locked == this.grid.colModel.isLocked(oldIndex))){
\r
31541 px += this.proxyOffsets[0];
\r
31542 this.proxyTop.setLeftTop(px, py);
\r
31543 this.proxyTop.show();
\r
31544 if(!this.bottomOffset){
\r
31545 this.bottomOffset = this.view.mainHd.getHeight();
\r
31547 this.proxyBottom.setLeftTop(px, py+this.proxyTop.dom.offsetHeight+this.bottomOffset);
\r
31548 this.proxyBottom.show();
\r
31552 onNodeEnter : function(n, dd, e, data){
\r
31553 if(data.header != n){
\r
31554 this.positionIndicator(data.header, n, e);
\r
31558 onNodeOver : function(n, dd, e, data){
\r
31559 var result = false;
\r
31560 if(data.header != n){
\r
31561 result = this.positionIndicator(data.header, n, e);
\r
31564 this.proxyTop.hide();
\r
31565 this.proxyBottom.hide();
\r
31567 return result ? this.dropAllowed : this.dropNotAllowed;
\r
31570 onNodeOut : function(n, dd, e, data){
\r
31571 this.proxyTop.hide();
\r
31572 this.proxyBottom.hide();
\r
31575 onNodeDrop : function(n, dd, e, data){
\r
31576 var h = data.header;
\r
31578 var cm = this.grid.colModel;
\r
31579 var x = Ext.lib.Event.getPageX(e);
\r
31580 var r = Ext.lib.Dom.getRegion(n.firstChild);
\r
31581 var pt = (r.right - x) <= ((r.right-r.left)/2) ? "after" : "before";
\r
31582 var oldIndex = this.view.getCellIndex(h);
\r
31583 var newIndex = this.view.getCellIndex(n);
\r
31584 var locked = cm.isLocked(newIndex);
\r
31585 if(pt == "after"){
\r
31588 if(oldIndex < newIndex){
\r
31591 if(oldIndex == newIndex && (locked == cm.isLocked(oldIndex))){
\r
31594 cm.setLocked(oldIndex, locked, true);
\r
31595 cm.moveColumn(oldIndex, newIndex);
\r
31596 this.grid.fireEvent("columnmove", oldIndex, newIndex);
\r
31604 Ext.grid.GridView.ColumnDragZone = function(grid, hd){
\r
31605 Ext.grid.GridView.ColumnDragZone.superclass.constructor.call(this, grid, hd, null);
\r
31606 this.proxy.el.addClass('x-grid3-col-dd');
\r
31609 Ext.extend(Ext.grid.GridView.ColumnDragZone, Ext.grid.HeaderDragZone, {
\r
31610 handleMouseDown : function(e){
\r
31614 callHandleMouseDown : function(e){
\r
31615 Ext.grid.GridView.ColumnDragZone.superclass.handleMouseDown.call(this, e);
\r
31618 Ext.grid.SplitDragZone = function(grid, hd, hd2){
31620 this.view = grid.getView();
31621 this.proxy = this.view.resizeProxy;
31622 Ext.grid.SplitDragZone.superclass.constructor.call(this, hd,
31623 "gridSplitters" + this.grid.getGridEl().id, {
31624 dragElId : Ext.id(this.proxy.dom), resizeFrame:false
31626 this.setHandleElId(Ext.id(hd));
31627 this.setOuterHandleElId(Ext.id(hd2));
31628 this.scroll = false;
31630 Ext.extend(Ext.grid.SplitDragZone, Ext.dd.DDProxy, {
31631 fly: Ext.Element.fly,
31633 b4StartDrag : function(x, y){
31634 this.view.headersDisabled = true;
31635 this.proxy.setHeight(this.view.mainWrap.getHeight());
31636 var w = this.cm.getColumnWidth(this.cellIndex);
31637 var minw = Math.max(w-this.grid.minColumnWidth, 0);
31638 this.resetConstraints();
31639 this.setXConstraint(minw, 1000);
31640 this.setYConstraint(0, 0);
31641 this.minX = x - minw;
31642 this.maxX = x + 1000;
31644 Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
31648 handleMouseDown : function(e){
31649 ev = Ext.EventObject.setEvent(e);
31650 var t = this.fly(ev.getTarget());
31651 if(t.hasClass("x-grid-split")){
31652 this.cellIndex = this.view.getCellIndex(t.dom);
31653 this.split = t.dom;
31654 this.cm = this.grid.colModel;
31655 if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
31656 Ext.grid.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
31661 endDrag : function(e){
31662 this.view.headersDisabled = false;
31663 var endX = Math.max(this.minX, Ext.lib.Event.getPageX(e));
31664 var diff = endX - this.startPos;
31665 this.view.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
31668 autoOffset : function(){
31669 this.setDelta(0,0);
31672 Ext.grid.GridDragZone = function(grid, config){
31673 this.view = grid.getView();
31674 Ext.grid.GridDragZone.superclass.constructor.call(this, this.view.mainBody.dom, config);
31675 if(this.view.lockedBody){
31676 this.setHandleElId(Ext.id(this.view.mainBody.dom));
31677 this.setOuterHandleElId(Ext.id(this.view.lockedBody.dom));
31679 this.scroll = false;
31681 this.ddel = document.createElement('div');
31682 this.ddel.className = 'x-grid-dd-wrap';
31685 Ext.extend(Ext.grid.GridDragZone, Ext.dd.DragZone, {
31686 ddGroup : "GridDD",
31688 getDragData : function(e){
31689 var t = Ext.lib.Event.getTarget(e);
31690 var rowIndex = this.view.findRowIndex(t);
31691 if(rowIndex !== false){
31692 var sm = this.grid.selModel;
31693 if(!sm.isSelected(rowIndex) || e.hasModifier()){
31694 sm.handleMouseDown(this.grid, rowIndex, e);
31696 return {grid: this.grid, ddel: this.ddel, rowIndex: rowIndex, selections:sm.getSelections()};
31701 onInitDrag : function(e){
31702 var data = this.dragData;
31703 this.ddel.innerHTML = this.grid.getDragDropText();
31704 this.proxy.update(this.ddel);
31707 afterRepair : function(){
31708 this.dragging = false;
31711 getRepairXY : function(e, data){
31715 onEndDrag : function(data, e){
31718 onValidDrop : function(dd, e, id){
31722 beforeInvalidDrop : function(e, id){
31728 Ext.grid.ColumnModel = function(config){
\r
31730 this.defaultWidth = 100;
\r
31733 this.defaultSortable = false;
\r
31736 if(config.columns){
\r
31737 Ext.apply(this, config);
\r
31738 this.setConfig(config.columns, true);
\r
31740 this.setConfig(config, true);
\r
31752 "columnlockchange",
\r
31756 Ext.grid.ColumnModel.superclass.constructor.call(this);
\r
31758 Ext.extend(Ext.grid.ColumnModel, Ext.util.Observable, {
\r
31776 getColumnId : function(index){
\r
31777 return this.config[index].id;
\r
31781 setConfig : function(config, initial){
\r
31783 delete this.totalWidth;
\r
31784 for(var i = 0, len = this.config.length; i < len; i++){
\r
31785 var c = this.config[i];
\r
31787 c.editor.destroy();
\r
31791 this.config = config;
\r
31792 this.lookup = {};
\r
31794 for(var i = 0, len = config.length; i < len; i++){
\r
31795 var c = config[i];
\r
31796 if(typeof c.renderer == "string"){
\r
31797 c.renderer = Ext.util.Format[c.renderer];
\r
31799 if(typeof c.id == "undefined"){
\r
31802 if(c.editor && c.editor.isFormField){
\r
31803 c.editor = new Ext.grid.GridEditor(c.editor);
\r
31805 this.lookup[c.id] = c;
\r
31808 this.fireEvent('configchange', this);
\r
31813 getColumnById : function(id){
\r
31814 return this.lookup[id];
\r
31818 getIndexById : function(id){
\r
31819 for(var i = 0, len = this.config.length; i < len; i++){
\r
31820 if(this.config[i].id == id){
\r
31828 moveColumn : function(oldIndex, newIndex){
\r
31829 var c = this.config[oldIndex];
\r
31830 this.config.splice(oldIndex, 1);
\r
31831 this.config.splice(newIndex, 0, c);
\r
31832 this.dataMap = null;
\r
31833 this.fireEvent("columnmoved", this, oldIndex, newIndex);
\r
31837 isLocked : function(colIndex){
\r
31838 return this.config[colIndex].locked === true;
\r
31842 setLocked : function(colIndex, value, suppressEvent){
\r
31843 if(this.isLocked(colIndex) == value){
\r
31846 this.config[colIndex].locked = value;
\r
31847 if(!suppressEvent){
\r
31848 this.fireEvent("columnlockchange", this, colIndex, value);
\r
31853 getTotalLockedWidth : function(){
\r
31854 var totalWidth = 0;
\r
31855 for(var i = 0; i < this.config.length; i++){
\r
31856 if(this.isLocked(i) && !this.isHidden(i)){
\r
31857 this.totalWidth += this.getColumnWidth(i);
\r
31860 return totalWidth;
\r
31864 getLockedCount : function(){
\r
31865 for(var i = 0, len = this.config.length; i < len; i++){
\r
31866 if(!this.isLocked(i)){
\r
31873 getColumnCount : function(visibleOnly){
\r
31874 if(visibleOnly === true){
\r
31876 for(var i = 0, len = this.config.length; i < len; i++){
\r
31877 if(!this.isHidden(i)){
\r
31883 return this.config.length;
\r
31887 getColumnsBy : function(fn, scope){
\r
31889 for(var i = 0, len = this.config.length; i < len; i++){
\r
31890 var c = this.config[i];
\r
31891 if(fn.call(scope||this, c, i) === true){
\r
31899 isSortable : function(col){
\r
31900 if(typeof this.config[col].sortable == "undefined"){
\r
31901 return this.defaultSortable;
\r
31903 return this.config[col].sortable;
\r
31907 isMenuDisabled : function(col){
\r
31908 return !!this.config[col].menuDisabled;
\r
31912 getRenderer : function(col){
\r
31913 if(!this.config[col].renderer){
\r
31914 return Ext.grid.ColumnModel.defaultRenderer;
\r
31916 return this.config[col].renderer;
\r
31920 setRenderer : function(col, fn){
\r
31921 this.config[col].renderer = fn;
\r
31925 getColumnWidth : function(col){
\r
31926 return this.config[col].width || this.defaultWidth;
\r
31930 setColumnWidth : function(col, width, suppressEvent){
\r
31931 this.config[col].width = width;
\r
31932 this.totalWidth = null;
\r
31933 if(!suppressEvent){
\r
31934 this.fireEvent("widthchange", this, col, width);
\r
31939 getTotalWidth : function(includeHidden){
\r
31940 if(!this.totalWidth){
\r
31941 this.totalWidth = 0;
\r
31942 for(var i = 0, len = this.config.length; i < len; i++){
\r
31943 if(includeHidden || !this.isHidden(i)){
\r
31944 this.totalWidth += this.getColumnWidth(i);
\r
31948 return this.totalWidth;
\r
31952 getColumnHeader : function(col){
\r
31953 return this.config[col].header;
\r
31957 setColumnHeader : function(col, header){
\r
31958 this.config[col].header = header;
\r
31959 this.fireEvent("headerchange", this, col, header);
\r
31963 getColumnTooltip : function(col){
\r
31964 return this.config[col].tooltip;
\r
31967 setColumnTooltip : function(col, tooltip){
\r
31968 this.config[col].tooltip = tooltip;
\r
31972 getDataIndex : function(col){
\r
31973 return this.config[col].dataIndex;
\r
31977 setDataIndex : function(col, dataIndex){
\r
31978 this.config[col].dataIndex = dataIndex;
\r
31981 findColumnIndex : function(dataIndex){
\r
31982 var c = this.config;
\r
31983 for(var i = 0, len = c.length; i < len; i++){
\r
31984 if(c[i].dataIndex == dataIndex){
\r
31992 isCellEditable : function(colIndex, rowIndex){
\r
31993 return (this.config[colIndex].editable || (typeof this.config[colIndex].editable == "undefined" && this.config[colIndex].editor)) ? true : false;
\r
31997 getCellEditor : function(colIndex, rowIndex){
\r
31998 return this.config[colIndex].editor;
\r
32002 setEditable : function(col, editable){
\r
32003 this.config[col].editable = editable;
\r
32008 isHidden : function(colIndex){
\r
32009 return this.config[colIndex].hidden;
\r
32014 isFixed : function(colIndex){
\r
32015 return this.config[colIndex].fixed;
\r
32019 isResizable : function(colIndex){
\r
32020 return colIndex >= 0 && this.config[colIndex].resizable !== false && this.config[colIndex].fixed !== true;
\r
32023 setHidden : function(colIndex, hidden){
\r
32024 var c = this.config[colIndex];
\r
32025 if(c.hidden !== hidden){
\r
32026 c.hidden = hidden;
\r
32027 this.totalWidth = null;
\r
32028 this.fireEvent("hiddenchange", this, colIndex, hidden);
\r
32033 setEditor : function(col, editor){
\r
32034 this.config[col].editor = editor;
\r
32039 Ext.grid.ColumnModel.defaultRenderer = function(value){
\r
32040 if(typeof value == "string" && value.length < 1){
\r
32047 Ext.grid.DefaultColumnModel = Ext.grid.ColumnModel;
\r
32050 Ext.grid.AbstractSelectionModel = function(){
\r
32051 this.locked = false;
\r
32052 Ext.grid.AbstractSelectionModel.superclass.constructor.call(this);
\r
32055 Ext.extend(Ext.grid.AbstractSelectionModel, Ext.util.Observable, {
\r
32057 init : function(grid){
\r
32058 this.grid = grid;
\r
32059 this.initEvents();
\r
32063 lock : function(){
\r
32064 this.locked = true;
\r
32068 unlock : function(){
\r
32069 this.locked = false;
\r
32073 isLocked : function(){
\r
32074 return this.locked;
\r
32078 Ext.grid.RowSelectionModel = function(config){
32079 Ext.apply(this, config);
32080 this.selections = new Ext.util.MixedCollection(false, function(o){
32085 this.lastActive = false;
32098 Ext.grid.RowSelectionModel.superclass.constructor.call(this);
32101 Ext.extend(Ext.grid.RowSelectionModel, Ext.grid.AbstractSelectionModel, {
32103 singleSelect : false,
32106 initEvents : function(){
32108 if(!this.grid.enableDragDrop && !this.grid.enableDrag){
32109 this.grid.on("rowmousedown", this.handleMouseDown, this);
32110 }else{ this.grid.on("rowclick", function(grid, rowIndex, e) {
32111 if(e.button === 0 && !e.shiftKey && !e.ctrlKey) {
32112 this.selectRow(rowIndex, false);
32113 grid.view.focusRow(rowIndex);
32118 this.rowNav = new Ext.KeyNav(this.grid.getGridEl(), {
32119 "up" : function(e){
32121 this.selectPrevious(e.shiftKey);
32122 }else if(this.last !== false && this.lastActive !== false){
32123 var last = this.last;
32124 this.selectRange(this.last, this.lastActive-1);
32125 this.grid.getView().focusRow(this.lastActive);
32126 if(last !== false){
32130 this.selectFirstRow();
32133 "down" : function(e){
32135 this.selectNext(e.shiftKey);
32136 }else if(this.last !== false && this.lastActive !== false){
32137 var last = this.last;
32138 this.selectRange(this.last, this.lastActive+1);
32139 this.grid.getView().focusRow(this.lastActive);
32140 if(last !== false){
32144 this.selectFirstRow();
32150 var view = this.grid.view;
32151 view.on("refresh", this.onRefresh, this);
32152 view.on("rowupdated", this.onRowUpdated, this);
32153 view.on("rowremoved", this.onRemove, this);
32156 onRefresh : function(){
32157 var ds = this.grid.store, index;
32158 var s = this.getSelections();
32159 this.clearSelections(true);
32160 for(var i = 0, len = s.length; i < len; i++){
32162 if((index = ds.indexOfId(r.id)) != -1){
32163 this.selectRow(index, true);
32166 if(s.length != this.selections.getCount()){
32167 this.fireEvent("selectionchange", this);
32171 onRemove : function(v, index, r){
32172 if(this.selections.remove(r) !== false){
32173 this.fireEvent('selectionchange', this);
32177 onRowUpdated : function(v, index, r){
32178 if(this.isSelected(r)){
32179 v.onRowSelect(index);
32184 selectRecords : function(records, keepExisting){
32186 this.clearSelections();
32188 var ds = this.grid.store;
32189 for(var i = 0, len = records.length; i < len; i++){
32190 this.selectRow(ds.indexOf(records[i]), true);
32195 getCount : function(){
32196 return this.selections.length;
32200 selectFirstRow : function(){
32205 selectLastRow : function(keepExisting){
32206 this.selectRow(this.grid.store.getCount() - 1, keepExisting);
32210 selectNext : function(keepExisting){
32211 if(this.hasNext()){
32212 this.selectRow(this.last+1, keepExisting);
32213 this.grid.getView().focusRow(this.last);
32220 selectPrevious : function(keepExisting){
32221 if(this.hasPrevious()){
32222 this.selectRow(this.last-1, keepExisting);
32223 this.grid.getView().focusRow(this.last);
32230 hasNext : function(){
32231 return this.last !== false && (this.last+1) < this.grid.store.getCount();
32235 hasPrevious : function(){
32236 return !!this.last;
32241 getSelections : function(){
32242 return [].concat(this.selections.items);
32246 getSelected : function(){
32247 return this.selections.itemAt(0);
32251 each : function(fn, scope){
32252 var s = this.getSelections();
32253 for(var i = 0, len = s.length; i < len; i++){
32254 if(fn.call(scope || this, s[i], i) === false){
32262 clearSelections : function(fast){
32263 if(this.locked) return;
32265 var ds = this.grid.store;
32266 var s = this.selections;
32267 s.each(function(r){
32268 this.deselectRow(ds.indexOfId(r.id));
32272 this.selections.clear();
32279 selectAll : function(){
32280 if(this.locked) return;
32281 this.selections.clear();
32282 for(var i = 0, len = this.grid.store.getCount(); i < len; i++){
32283 this.selectRow(i, true);
32288 hasSelection : function(){
32289 return this.selections.length > 0;
32293 isSelected : function(index){
32294 var r = typeof index == "number" ? this.grid.store.getAt(index) : index;
32295 return (r && this.selections.key(r.id) ? true : false);
32299 isIdSelected : function(id){
32300 return (this.selections.key(id) ? true : false);
32303 handleMouseDown : function(g, rowIndex, e){
32304 if(e.button !== 0 || this.isLocked()){
32307 var view = this.grid.getView();
32308 if(e.shiftKey && this.last !== false){
32309 var last = this.last;
32310 this.selectRange(last, rowIndex, e.ctrlKey);
32311 this.last = last; view.focusRow(rowIndex);
32313 var isSelected = this.isSelected(rowIndex);
32314 if(e.ctrlKey && isSelected){
32315 this.deselectRow(rowIndex);
32316 }else if(!isSelected || this.getCount() > 1){
32317 this.selectRow(rowIndex, e.ctrlKey || e.shiftKey);
32318 view.focusRow(rowIndex);
32324 selectRows : function(rows, keepExisting){
32326 this.clearSelections();
32328 for(var i = 0, len = rows.length; i < len; i++){
32329 this.selectRow(rows[i], true);
32334 selectRange : function(startRow, endRow, keepExisting){
32335 if(this.locked) return;
32337 this.clearSelections();
32339 if(startRow <= endRow){
32340 for(var i = startRow; i <= endRow; i++){
32341 this.selectRow(i, true);
32344 for(var i = startRow; i >= endRow; i--){
32345 this.selectRow(i, true);
32351 deselectRange : function(startRow, endRow, preventViewNotify){
32352 if(this.locked) return;
32353 for(var i = startRow; i <= endRow; i++){
32354 this.deselectRow(i, preventViewNotify);
32359 selectRow : function(index, keepExisting, preventViewNotify){
32360 if(this.locked || (index < 0 || index >= this.grid.store.getCount())) return;
32361 var r = this.grid.store.getAt(index);
32362 if(r && this.fireEvent("beforerowselect", this, index, keepExisting, r) !== false){
32363 if(!keepExisting || this.singleSelect){
32364 this.clearSelections();
32366 this.selections.add(r);
32367 this.last = this.lastActive = index;
32368 if(!preventViewNotify){
32369 this.grid.getView().onRowSelect(index);
32371 this.fireEvent("rowselect", this, index, r);
32372 this.fireEvent("selectionchange", this);
32377 deselectRow : function(index, preventViewNotify){
32378 if(this.locked) return;
32379 if(this.last == index){
32382 if(this.lastActive == index){
32383 this.lastActive = false;
32385 var r = this.grid.store.getAt(index);
32387 this.selections.remove(r);
32388 if(!preventViewNotify){
32389 this.grid.getView().onRowDeselect(index);
32391 this.fireEvent("rowdeselect", this, index, r);
32392 this.fireEvent("selectionchange", this);
32396 restoreLast : function(){
32398 this.last = this._last;
32402 acceptsNav : function(row, col, cm){
32403 return !cm.isHidden(col) && cm.isCellEditable(col, row);
32406 onEditorKey : function(field, e){
32407 var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor;
32408 var shift = e.shiftKey;
32413 newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
32415 newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
32417 }else if(k == e.ENTER){
32420 if(this.moveEditorOnEnter !== false){
32422 newCell = g.walkCells(ed.row - 1, ed.col, -1, this.acceptsNav, this);
32424 newCell = g.walkCells(ed.row + 1, ed.col, 1, this.acceptsNav, this);
32427 }else if(k == e.ESC){
32431 g.startEditing(newCell[0], newCell[1]);
32436 Ext.grid.CellSelectionModel = function(config){
32437 Ext.apply(this, config);
32439 this.selection = null;
32443 "beforecellselect",
32450 Ext.grid.CellSelectionModel.superclass.constructor.call(this);
32453 Ext.extend(Ext.grid.CellSelectionModel, Ext.grid.AbstractSelectionModel, {
32456 initEvents : function(){
32457 this.grid.on("cellmousedown", this.handleMouseDown, this);
32458 this.grid.getGridEl().on(Ext.isIE ? "keydown" : "keypress", this.handleKeyDown, this);
32459 var view = this.grid.view;
32460 view.on("refresh", this.onViewChange, this);
32461 view.on("rowupdated", this.onRowUpdated, this);
32462 view.on("beforerowremoved", this.clearSelections, this);
32463 view.on("beforerowsinserted", this.clearSelections, this);
32464 if(this.grid.isEditor){
32465 this.grid.on("beforeedit", this.beforeEdit, this);
32469 beforeEdit : function(e){
32470 this.select(e.row, e.column, false, true, e.record);
32473 onRowUpdated : function(v, index, r){
32474 if(this.selection && this.selection.record == r){
32475 v.onCellSelect(index, this.selection.cell[1]);
32479 onViewChange : function(){
32480 this.clearSelections(true);
32484 getSelectedCell : function(){
32485 return this.selection ? this.selection.cell : null;
32489 clearSelections : function(preventNotify){
32490 var s = this.selection;
32492 if(preventNotify !== true){
32493 this.grid.view.onCellDeselect(s.cell[0], s.cell[1]);
32495 this.selection = null;
32496 this.fireEvent("selectionchange", this, null);
32501 hasSelection : function(){
32502 return this.selection ? true : false;
32506 handleMouseDown : function(g, row, cell, e){
32507 if(e.button !== 0 || this.isLocked()){
32510 this.select(row, cell);
32514 select : function(rowIndex, colIndex, preventViewNotify, preventFocus, r){
32515 if(this.fireEvent("beforecellselect", this, rowIndex, colIndex) !== false){
32516 this.clearSelections();
32517 r = r || this.grid.store.getAt(rowIndex);
32520 cell : [rowIndex, colIndex]
32522 if(!preventViewNotify){
32523 var v = this.grid.getView();
32524 v.onCellSelect(rowIndex, colIndex);
32525 if(preventFocus !== true){
32526 v.focusCell(rowIndex, colIndex);
32529 this.fireEvent("cellselect", this, rowIndex, colIndex);
32530 this.fireEvent("selectionchange", this, this.selection);
32534 isSelectable : function(rowIndex, colIndex, cm){
32535 return !cm.isHidden(colIndex);
32539 handleKeyDown : function(e){
32540 if(!e.isNavKeyPress()){
32543 var g = this.grid, s = this.selection;
32546 var cell = g.walkCells(0, 0, 1, this.isSelectable, this);
32548 this.select(cell[0], cell[1]);
32553 var walk = function(row, col, step){
32554 return g.walkCells(row, col, step, sm.isSelectable, sm);
32556 var k = e.getKey(), r = s.cell[0], c = s.cell[1];
32562 newCell = walk(r, c-1, -1);
32564 newCell = walk(r, c+1, 1);
32568 newCell = walk(r+1, c, 1);
32571 newCell = walk(r-1, c, -1);
32574 newCell = walk(r, c+1, 1);
32577 newCell = walk(r, c-1, -1);
32580 if(g.isEditor && !g.editing){
32581 g.startEditing(r, c);
32588 this.select(newCell[0], newCell[1]);
32593 acceptsNav : function(row, col, cm){
32594 return !cm.isHidden(col) && cm.isCellEditable(col, row);
32597 onEditorKey : function(field, e){
32598 var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor;
32601 newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
32603 newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
32606 }else if(k == e.ENTER){
32609 }else if(k == e.ESC){
32614 g.startEditing(newCell[0], newCell[1]);
32619 Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, {
\r
32626 detectEdit: false,
\r
32629 autoEncode : false,
\r
32633 trackMouseOver: false,
32636 initComponent : function(){
\r
32637 Ext.grid.EditorGridPanel.superclass.initComponent.call(this);
\r
32639 if(!this.selModel){
\r
32640 this.selModel = new Ext.grid.CellSelectionModel();
\r
32643 this.activeEditor = null;
\r
32656 initEvents : function(){
\r
32657 Ext.grid.EditorGridPanel.superclass.initEvents.call(this);
\r
32659 this.on("bodyscroll", this.stopEditing, this, [true]);
\r
32661 if(this.clicksToEdit == 1){
\r
32662 this.on("cellclick", this.onCellDblClick, this);
\r
32664 if(this.clicksToEdit == 'auto' && this.view.mainBody){
\r
32665 this.view.mainBody.on("mousedown", this.onAutoEditClick, this);
\r
32667 this.on("celldblclick", this.onCellDblClick, this);
\r
32669 this.getGridEl().addClass("xedit-grid");
\r
32673 onCellDblClick : function(g, row, col){
\r
32674 this.startEditing(row, col);
\r
32678 onAutoEditClick : function(e, t){
\r
32679 if(e.button !== 0){
\r
32682 var row = this.view.findRowIndex(t);
\r
32683 var col = this.view.findCellIndex(t);
\r
32684 if(row !== false && col !== false){
\r
32685 this.stopEditing();
\r
32686 if(this.selModel.getSelectedCell){
32687 var sc = this.selModel.getSelectedCell();
\r
32688 if(sc && sc.cell[0] === row && sc.cell[1] === col){
\r
32689 this.startEditing(row, col);
\r
32692 if(this.selModel.isSelected(row)){
\r
32693 this.startEditing(row, col);
\r
32700 onEditComplete : function(ed, value, startValue){
\r
32701 this.editing = false;
\r
32702 this.activeEditor = null;
\r
32703 ed.un("specialkey", this.selModel.onEditorKey, this.selModel);
\r
32704 var r = ed.record;
\r
32705 var field = this.colModel.getDataIndex(ed.col);
\r
32706 value = this.postEditValue(value, startValue, r, field);
\r
32707 if(String(value) !== String(startValue)){
\r
32712 originalValue: startValue,
\r
32718 if(this.fireEvent("validateedit", e) !== false && !e.cancel){
\r
32719 r.set(field, e.value);
\r
32721 this.fireEvent("afteredit", e);
\r
32724 this.view.focusCell(ed.row, ed.col);
\r
32728 startEditing : function(row, col){
\r
32729 this.stopEditing();
\r
32730 if(this.colModel.isCellEditable(col, row)){
\r
32731 this.view.ensureVisible(row, col, true);
\r
32732 var r = this.store.getAt(row);
\r
32733 var field = this.colModel.getDataIndex(col);
\r
32738 value: r.data[field],
\r
32743 if(this.fireEvent("beforeedit", e) !== false && !e.cancel){
\r
32744 this.editing = true;
\r
32745 var ed = this.colModel.getCellEditor(col, row);
\r
32746 if(!ed.rendered){
\r
32747 ed.render(this.view.getEditorParent(ed));
\r
32753 ed.on("complete", this.onEditComplete, this, {single: true});
\r
32754 ed.on("specialkey", this.selModel.onEditorKey, this.selModel);
\r
32755 this.activeEditor = ed;
\r
32756 var v = this.preEditValue(r, field);
\r
32757 ed.startEdit(this.view.getCell(row, col), v);
\r
32758 }).defer(50, this);
\r
32763 preEditValue : function(r, field){
\r
32764 return this.autoEncode && typeof value == 'string' ? Ext.util.Format.htmlDecode(r.data[field]) : r.data[field];
\r
32767 postEditValue : function(value, originalValue, r, field){
\r
32768 return this.autoEncode && typeof value == 'string' ? Ext.util.Format.htmlEncode(value) : value;
\r
32772 stopEditing : function(cancel){
\r
32773 if(this.activeEditor){
\r
32774 this.activeEditor[cancel === true ? 'cancelEdit' : 'completeEdit']();
\r
32776 this.activeEditor = null;
\r
32779 Ext.reg('editorgrid', Ext.grid.EditorGridPanel);
32780 Ext.grid.GridEditor = function(field, config){
32781 Ext.grid.GridEditor.superclass.constructor.call(this, field, config);
32782 field.monitorTab = false;
32785 Ext.extend(Ext.grid.GridEditor, Ext.Editor, {
32786 alignment: "tl-tl",
32789 cls: "x-small-editor x-grid-editor",
32794 Ext.grid.PropertyRecord = Ext.data.Record.create([
32795 {name:'name',type:'string'}, 'value'
32799 Ext.grid.PropertyStore = function(grid, source){
32801 this.store = new Ext.data.Store({
32802 recordType : Ext.grid.PropertyRecord
32804 this.store.on('update', this.onUpdate, this);
32806 this.setSource(source);
32808 Ext.grid.PropertyStore.superclass.constructor.call(this);
32810 Ext.extend(Ext.grid.PropertyStore, Ext.util.Observable, {
32811 setSource : function(o){
32813 this.store.removeAll();
32816 if(this.isEditableValue(o[k])){
32817 data.push(new Ext.grid.PropertyRecord({name: k, value: o[k]}, k));
32820 this.store.loadRecords({records: data}, {}, true);
32823 onUpdate : function(ds, record, type){
32824 if(type == Ext.data.Record.EDIT){
32825 var v = record.data['value'];
32826 var oldValue = record.modified['value'];
32827 if(this.grid.fireEvent('beforepropertychange', this.source, record.id, v, oldValue) !== false){
32828 this.source[record.id] = v;
32830 this.grid.fireEvent('propertychange', this.source, record.id, v, oldValue);
32837 getProperty : function(row){
32838 return this.store.getAt(row);
32841 isEditableValue: function(val){
32842 if(Ext.isDate(val)){
32844 }else if(typeof val == 'object' || typeof val == 'function'){
32850 setValue : function(prop, value){
32851 this.source[prop] = value;
32852 this.store.getById(prop).set('value', value);
32855 getSource : function(){
32856 return this.source;
32861 Ext.grid.PropertyColumnModel = function(grid, store){
32864 g.PropertyColumnModel.superclass.constructor.call(this, [
32865 {header: this.nameText, width:50, sortable: true, dataIndex:'name', id: 'name', menuDisabled:true},
32866 {header: this.valueText, width:50, resizable:false, dataIndex: 'value', id: 'value', menuDisabled:true}
32868 this.store = store;
32869 this.bselect = Ext.DomHelper.append(document.body, {
32870 tag: 'select', cls: 'x-grid-editor x-hide-display', children: [
32871 {tag: 'option', value: 'true', html: 'true'},
32872 {tag: 'option', value: 'false', html: 'false'}
32877 var bfield = new f.Field({
32879 bselect : this.bselect,
32881 getValue : function(){
32882 return this.bselect.value == 'true';
32886 'date' : new g.GridEditor(new f.DateField({selectOnFocus:true})),
32887 'string' : new g.GridEditor(new f.TextField({selectOnFocus:true})),
32888 'number' : new g.GridEditor(new f.NumberField({selectOnFocus:true, style:'text-align:left;'})),
32889 'boolean' : new g.GridEditor(bfield)
32891 this.renderCellDelegate = this.renderCell.createDelegate(this);
32892 this.renderPropDelegate = this.renderProp.createDelegate(this);
32895 Ext.extend(Ext.grid.PropertyColumnModel, Ext.grid.ColumnModel, {
32897 valueText : 'Value',
32898 dateFormat : 'm/j/Y',
32900 renderDate : function(dateVal){
32901 return dateVal.dateFormat(this.dateFormat);
32904 renderBool : function(bVal){
32905 return bVal ? 'true' : 'false';
32908 isCellEditable : function(colIndex, rowIndex){
32909 return colIndex == 1;
32912 getRenderer : function(col){
32914 this.renderCellDelegate : this.renderPropDelegate;
32917 renderProp : function(v){
32918 return this.getPropertyName(v);
32921 renderCell : function(val){
32923 if(Ext.isDate(val)){
32924 rv = this.renderDate(val);
32925 }else if(typeof val == 'boolean'){
32926 rv = this.renderBool(val);
32928 return Ext.util.Format.htmlEncode(rv);
32931 getPropertyName : function(name){
32932 var pn = this.grid.propertyNames;
32933 return pn && pn[name] ? pn[name] : name;
32936 getCellEditor : function(colIndex, rowIndex){
32937 var p = this.store.getProperty(rowIndex);
32938 var n = p.data['name'], val = p.data['value'];
32939 if(this.grid.customEditors[n]){
32940 return this.grid.customEditors[n];
32942 if(Ext.isDate(val)){
32943 return this.editors['date'];
32944 }else if(typeof val == 'number'){
32945 return this.editors['number'];
32946 }else if(typeof val == 'boolean'){
32947 return this.editors['boolean'];
32949 return this.editors['string'];
32955 Ext.grid.PropertyGrid = Ext.extend(Ext.grid.EditorGridPanel, {
32959 enableColumnMove:false,
32961 trackMouseOver: false,
32963 enableHdMenu : false,
32968 initComponent : function(){
32969 this.customEditors = this.customEditors || {};
32970 this.lastEditRow = null;
32971 var store = new Ext.grid.PropertyStore(this);
32972 this.propStore = store;
32973 var cm = new Ext.grid.PropertyColumnModel(this, store);
32974 store.store.sort('name', 'ASC');
32977 'beforepropertychange',
32982 this.ds = store.store;
32983 Ext.grid.PropertyGrid.superclass.initComponent.call(this);
32985 this.selModel.on('beforecellselect', function(sm, rowIndex, colIndex){
32986 if(colIndex === 0){
32987 this.startEditing.defer(200, this, [rowIndex, 1]);
32993 onRender : function(){
32994 Ext.grid.PropertyGrid.superclass.onRender.apply(this, arguments);
32996 this.getGridEl().addClass('x-props-grid');
32999 afterRender: function(){
33000 Ext.grid.PropertyGrid.superclass.afterRender.apply(this, arguments);
33002 this.setSource(this.source);
33007 setSource : function(source){
33008 this.propStore.setSource(source);
33012 getSource : function(){
33013 return this.propStore.getSource();
33017 Ext.grid.RowNumberer = function(config){
\r
33018 Ext.apply(this, config);
\r
33019 if(this.rowspan){
\r
33020 this.renderer = this.renderer.createDelegate(this);
\r
33024 Ext.grid.RowNumberer.prototype = {
\r
33034 menuDisabled:true,
\r
33037 rowspan: undefined,
\r
33040 renderer : function(v, p, record, rowIndex){
\r
33041 if(this.rowspan){
\r
33042 p.cellAttr = 'rowspan="'+this.rowspan+'"';
\r
33044 return rowIndex+1;
\r
33048 Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, {
\r
33050 header: '<div class="x-grid3-hd-checker"> </div>',
\r
33057 menuDisabled:true,
\r
33063 initEvents : function(){
\r
33064 Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this);
\r
33065 this.grid.on('render', function(){
\r
33066 var view = this.grid.getView();
\r
33067 view.mainBody.on('mousedown', this.onMouseDown, this);
\r
33068 Ext.fly(view.innerHd).on('mousedown', this.onHdMouseDown, this);
\r
33074 onMouseDown : function(e, t){
\r
33075 if(e.button === 0 && t.className == 'x-grid3-row-checker'){
33077 var row = e.getTarget('.x-grid3-row');
\r
33079 var index = row.rowIndex;
\r
33080 if(this.isSelected(index)){
\r
33081 this.deselectRow(index);
\r
33083 this.selectRow(index, true);
\r
33090 onHdMouseDown : function(e, t){
\r
33091 if(t.className == 'x-grid3-hd-checker'){
\r
33093 var hd = Ext.fly(t.parentNode);
\r
33094 var isChecked = hd.hasClass('x-grid3-hd-checker-on');
\r
33096 hd.removeClass('x-grid3-hd-checker-on');
\r
33097 this.clearSelections();
\r
33099 hd.addClass('x-grid3-hd-checker-on');
\r
33100 this.selectAll();
\r
33106 renderer : function(v, p, record){
\r
33107 return '<div class="x-grid3-row-checker"> </div>';
\r
33111 Ext.LoadMask = function(el, config){
33112 this.el = Ext.get(el);
33113 Ext.apply(this, config);
33115 this.store.on('beforeload', this.onBeforeLoad, this);
33116 this.store.on('load', this.onLoad, this);
33117 this.store.on('loadexception', this.onLoad, this);
33118 this.removeMask = Ext.value(this.removeMask, false);
33120 var um = this.el.getUpdater();
33121 um.showLoadIndicator = false; um.on('beforeupdate', this.onBeforeLoad, this);
33122 um.on('update', this.onLoad, this);
33123 um.on('failure', this.onLoad, this);
33124 this.removeMask = Ext.value(this.removeMask, true);
33128 Ext.LoadMask.prototype = {
33132 msg : 'Loading...',
33134 msgCls : 'x-mask-loading',
33140 disable : function(){
33141 this.disabled = true;
33145 enable : function(){
33146 this.disabled = false;
33149 onLoad : function(){
33150 this.el.unmask(this.removeMask);
33153 onBeforeLoad : function(){
33154 if(!this.disabled){
33155 this.el.mask(this.msg, this.msgCls);
33161 this.onBeforeLoad();
33169 destroy : function(){
33171 this.store.un('beforeload', this.onBeforeLoad, this);
33172 this.store.un('load', this.onLoad, this);
33173 this.store.un('loadexception', this.onLoad, this);
33175 var um = this.el.getUpdater();
33176 um.un('beforeupdate', this.onBeforeLoad, this);
33177 um.un('update', this.onLoad, this);
33178 um.un('failure', this.onLoad, this);
33183 Ext.ProgressBar = Ext.extend(Ext.BoxComponent, {
\r
33185 baseCls : 'x-progress',
\r
33188 waitTimer : null,
\r
33191 initComponent : function(){
\r
33192 Ext.ProgressBar.superclass.initComponent.call(this);
\r
33200 onRender : function(ct, position){
\r
33201 Ext.ProgressBar.superclass.onRender.call(this, ct, position);
\r
33203 var tpl = new Ext.Template(
\r
33204 '<div class="{cls}-wrap">',
\r
33205 '<div class="{cls}-inner">',
\r
33206 '<div class="{cls}-bar">',
\r
33207 '<div class="{cls}-text">',
\r
33208 '<div> </div>',
\r
33211 '<div class="{cls}-text {cls}-text-back">',
\r
33212 '<div> </div>',
\r
33219 this.el = tpl.insertBefore(position, {cls: this.baseCls}, true);
\r
33221 this.el = tpl.append(ct, {cls: this.baseCls}, true);
\r
33224 this.el.dom.id = this.id;
\r
33226 var inner = this.el.dom.firstChild;
\r
33227 this.progressBar = Ext.get(inner.firstChild);
\r
33231 this.textEl = Ext.get(this.textEl);
\r
33232 delete this.textTopEl;
\r
33235 this.textTopEl = Ext.get(this.progressBar.dom.firstChild);
\r
33236 var textBackEl = Ext.get(inner.childNodes[1]);
\r
33237 this.textTopEl.setStyle("z-index", 99).addClass('x-hidden');
\r
33238 this.textEl = new Ext.CompositeElement([this.textTopEl.dom.firstChild, textBackEl.dom.firstChild]);
\r
33239 this.textEl.setWidth(inner.offsetWidth);
\r
33242 this.updateProgress(this.value, this.text);
\r
33244 this.updateText(this.text);
\r
33246 this.setSize(this.width || 'auto', 'auto');
\r
33247 this.progressBar.setHeight(inner.offsetHeight);
\r
33251 updateProgress : function(value, text){
\r
33252 this.value = value || 0;
\r
33254 this.updateText(text);
\r
33256 var w = Math.floor(value*this.el.dom.firstChild.offsetWidth);
\r
33257 this.progressBar.setWidth(w);
\r
33258 if(this.textTopEl){
\r
33260 this.textTopEl.removeClass('x-hidden').setWidth(w);
\r
33262 this.fireEvent('update', this, value, text);
\r
33267 wait : function(o){
\r
33268 if(!this.waitTimer){
\r
33269 var scope = this;
\r
33271 this.waitTimer = Ext.TaskMgr.start({
\r
33272 run: function(i){
\r
33273 var inc = o.increment || 10;
\r
33274 this.updateProgress(((((i+inc)%inc)+1)*(100/inc))*.01);
\r
33276 interval: o.interval || 1000,
\r
33277 duration: o.duration,
\r
33278 onStop: function(){
\r
33280 o.fn.apply(o.scope || this);
\r
33291 isWaiting : function(){
\r
33292 return this.waitTimer != null;
\r
33296 updateText : function(text){
\r
33297 this.text = text || ' ';
\r
33298 this.textEl.update(this.text);
\r
33303 setSize : function(w, h){
\r
33304 Ext.ProgressBar.superclass.setSize.call(this, w, h);
\r
33305 if(this.textTopEl){
\r
33306 var inner = this.el.dom.firstChild;
\r
33307 this.textEl.setSize(inner.offsetWidth, inner.offsetHeight);
\r
33313 reset : function(hide){
\r
33314 this.updateProgress(0);
\r
33315 if(this.textTopEl){
\r
33316 this.textTopEl.addClass('x-hidden');
\r
33318 if(this.waitTimer){
\r
33319 this.waitTimer.onStop = null;
33320 Ext.TaskMgr.stop(this.waitTimer);
\r
33321 this.waitTimer = null;
\r
33323 if(hide === true){
\r
33329 Ext.reg('progress', Ext.ProgressBar);
33336 function createConsole(){
33338 var scriptPanel = new Ext.debug.ScriptsPanel();
33339 var logView = new Ext.debug.LogPanel();
33340 var tree = new Ext.debug.DomTree();
33342 var tabs = new Ext.TabPanel({
33345 tabPosition: 'bottom',
33347 title: 'Debug Console',
33349 items: [logView, scriptPanel]
33351 title: 'DOM Inspector',
33357 cp = new Ext.Panel({
33358 id: 'x-debug-browser',
33361 animCollapse: false,
33362 style: 'position:absolute;left:0;bottom:0;',
33369 handler: function(){
33372 Ext.EventManager.removeResizeListener(handleResize);
33379 cp.render(document.body);
33381 cp.resizer = new Ext.Resizable(cp.el, {
33386 resizeElement : function(){
33387 var box = this.proxy.getBox();
33389 cp.setHeight(box.height);
33394 function handleResize(){
33395 cp.setWidth(Ext.getBody().getViewSize().width);
33397 Ext.EventManager.onWindowResize(handleResize);
33408 cp.logView.log.apply(cp.logView, arguments);
33411 logf : function(format, arg1, arg2, etc){
33412 Ext.log(String.format.apply(String, arguments));
33415 dump : function(o){
33416 if(typeof o == 'string' || typeof o == 'number' || typeof o == 'undefined' || Ext.isDate(o)){
33420 }else if(typeof o != "object"){
33421 Ext.log('Unknown return type');
33422 }else if(Ext.isArray(o)){
33423 Ext.log('['+o.join(',')+']');
33427 var to = typeof o[key];
33428 if(to != "function" && to != "object"){
33429 b.push(String.format(" {0}: {1},\n", key, o[key]));
33432 var s = b.join("");
33434 s = s.substr(0, s.length-2);
33436 Ext.log(s + "\n}");
33442 time : function(name){
33443 name = name || "def";
33444 Ext._timers[name] = new Date().getTime();
33447 timeEnd : function(name, printResults){
33448 var t = new Date().getTime();
33449 name = name || "def";
33450 var v = String.format("{0} ms", t-Ext._timers[name]);
33451 Ext._timers[name] = new Date().getTime();
33452 if(printResults !== false){
33453 Ext.log('Timer ' + (name == "def" ? v : name + ": " + v));
33462 Ext.debug.ScriptsPanel = Ext.extend(Ext.Panel, {
33463 id:'x-debug-scripts',
33470 style:'border-width:0 0 0 1px;',
33472 initComponent : function(){
33474 this.scriptField = new Ext.form.TextArea({
33475 anchor: '100% -26',
33476 style:'border-width:0;'
33479 this.trapBox = new Ext.form.Checkbox({
33480 id: 'console-trap',
33481 boxLabel: 'Trap Errors',
33485 this.toolbar = new Ext.Toolbar([{
33488 handler: this.evalScript
33492 handler: this.clear
33499 this.items = [this.toolbar, this.scriptField];
33501 Ext.debug.ScriptsPanel.superclass.initComponent.call(this);
33504 evalScript : function(){
33505 var s = this.scriptField.getValue();
33506 if(this.trapBox.getValue()){
33509 Ext.dump(rt === undefined? '(no return)' : rt);
33511 Ext.log(e.message || e.descript);
33515 Ext.dump(rt === undefined? '(no return)' : rt);
33519 clear : function(){
33520 this.scriptField.setValue('');
33521 this.scriptField.focus();
33526 Ext.debug.LogPanel = Ext.extend(Ext.Panel, {
33530 style:'border-width:0 1px 0 0',
33533 var markup = [ '<div style="padding:5px !important;border-bottom:1px solid #ccc;">',
33534 Ext.util.Format.htmlEncode(Array.prototype.join.call(arguments, ', ')).replace(/\n/g, '<br />').replace(/\s/g, ' '),
33535 '</div>'].join('');
33537 this.body.insertHtml('beforeend', markup);
33538 this.body.scrollTo('top', 100000);
33541 clear : function(){
33542 this.body.update('');
33543 this.body.dom.scrollTop = 0;
33547 Ext.debug.DomTree = Ext.extend(Ext.tree.TreePanel, {
33557 initComponent : function(){
33560 Ext.debug.DomTree.superclass.initComponent.call(this);
33562 var styles = false, hnode;
33563 var nonSpace = /^\s*$/;
33564 var html = Ext.util.Format.htmlEncode;
33565 var ellipsis = Ext.util.Format.ellipsis;
33566 var styleRe = /\s?([a-z\-]*)\:([^;]*)(?:[;\s\n\r]*)/gi;
33568 function findNode(n){
33569 if(!n || n.nodeType != 1 || n == document.body || n == document){
33572 var pn = [n], p = n;
33573 while((p = p.parentNode) && p.nodeType == 1 && p.tagName.toUpperCase() != 'HTML'){
33577 for(var i = 0, len = pn.length; i < len; i++){
33579 cn = cn.findChild('htmlNode', pn[i]);
33580 if(!cn){ return false;
33584 var a = cn.ui.anchor;
33585 treeEl.dom.scrollTop = Math.max(0 ,a.offsetTop-10);
33590 function nodeTitle(n){
33594 }else if(n.className){
33595 s += '.'+n.className;
33600 function onNodeSelect(t, n, last){
33602 if(last && last.unframe){
33606 if(n && n.htmlNode){
33607 if(frameEl.pressed){
33614 reload.setDisabled(n.leaf);
33615 var dom = n.htmlNode;
33616 stylePanel.setTitle(nodeTitle(dom));
33617 if(styles && !showAll.pressed){
33618 var s = dom.style ? dom.style.cssText : '';
33621 while ((m = styleRe.exec(s)) != null){
33622 props[m[1].toLowerCase()] = m[2];
33626 var cl = Ext.debug.cssList;
33627 var s = dom.style, fly = Ext.fly(dom);
33629 for(var i = 0, len = cl.length; i<len; i++){
33631 var v = s[st] || fly.getStyle(st);
33632 if(v != undefined && v !== null && v !== ''){
33640 if((isNaN(a+10)) && v != undefined && v !== null && v !== '' && !(Ext.isGecko && a[0] == a[0].toUpperCase())){
33649 addStyle.disable();
33652 stylesGrid.setSource(props);
33653 stylesGrid.treeNode = n;
33654 stylesGrid.view.fitColumns();
33657 this.loader = new Ext.tree.TreeLoader();
33658 this.loader.load = function(n, cb){
33659 var isBody = n.htmlNode == document.body;
33660 var cn = n.htmlNode.childNodes;
33661 for(var i = 0, c; c = cn[i]; i++){
33662 if(isBody && c.id == 'x-debug-browser'){
33665 if(c.nodeType == 1){
33666 n.appendChild(new Ext.debug.HtmlNode(c));
33667 }else if(c.nodeType == 3 && !nonSpace.test(c.nodeValue)){
33668 n.appendChild(new Ext.tree.TreeNode({
33669 text:'<em>' + ellipsis(html(String(c.nodeValue)), 35) + '</em>',
33670 cls: 'x-tree-noicon'
33678 this.root = this.setRootNode(new Ext.tree.TreeNode('Ext'));
33680 hnode = this.root.appendChild(new Ext.debug.HtmlNode(
33681 document.getElementsByTagName('html')[0]
33688 Ext.debug.HtmlNode = function(){
33689 var html = Ext.util.Format.htmlEncode;
33690 var ellipsis = Ext.util.Format.ellipsis;
33691 var nonSpace = /^\s*$/;
33694 {n: 'id', v: 'id'},
33695 {n: 'className', v: 'class'},
33696 {n: 'name', v: 'name'},
33697 {n: 'type', v: 'type'},
33698 {n: 'src', v: 'src'},
33699 {n: 'href', v: 'href'}
33702 function hasChild(n){
33703 for(var i = 0, c; c = n.childNodes[i]; i++){
33704 if(c.nodeType == 1){
33711 function renderNode(n, leaf){
33712 var tag = n.tagName.toLowerCase();
33713 var s = '<' + tag;
33714 for(var i = 0, len = attrs.length; i < len; i++){
33717 if(v && !nonSpace.test(v)){
33718 s += ' ' + a.v + '="<i>' + html(v) +'</i>"';
33721 var style = n.style ? n.style.cssText : '';
33723 s += ' style="<i>' + html(style.toLowerCase()) +'</i>"';
33725 if(leaf && n.childNodes.length > 0){
33726 s+='><em>' + ellipsis(html(String(n.innerHTML)), 35) + '</em></'+tag+'>';
33735 var HtmlNode = function(n){
33736 var leaf = !hasChild(n);
33738 this.tagName = n.tagName.toLowerCase();
33740 text : renderNode(n, leaf),
33742 cls: 'x-tree-noicon'
33744 HtmlNode.superclass.constructor.call(this, attr);
33745 this.attributes.htmlNode = n; if(!leaf){
33746 this.on('expand', this.onExpand, this);
33747 this.on('collapse', this.onCollapse, this);
33752 Ext.extend(HtmlNode, Ext.tree.AsyncTreeNode, {
33753 cls: 'x-tree-noicon',
33754 preventHScroll: true,
33755 refresh : function(highlight){
33756 var leaf = !hasChild(this.htmlNode);
33757 this.setText(renderNode(this.htmlNode, leaf));
33759 Ext.fly(this.ui.textNode).highlight();
33763 onExpand : function(){
33764 if(!this.closeNode && this.parentNode){
33765 this.closeNode = this.parentNode.insertBefore(new Ext.tree.TreeNode({
33766 text:'</' + this.tagName + '>',
33767 cls: 'x-tree-noicon'
33768 }), this.nextSibling);
33769 }else if(this.closeNode){
33770 this.closeNode.ui.show();
33774 onCollapse : function(){
33775 if(this.closeNode){
33776 this.closeNode.ui.hide();
33780 render : function(bulkRender){
33781 HtmlNode.superclass.render.call(this, bulkRender);
33784 highlightNode : function(){
33787 highlight : function(){
33790 frame : function(){
33791 this.htmlNode.style.border = '1px solid #0000ff';
33794 unframe : function(){
33795 this.htmlNode.style.border = '';