3 Ext.DomHelper = function(){
4 var tempTableEl = null,
5 emptyTags = /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i,
6 tableRe = /^table|tbody|tr|td$/i,
7 confRe = /tag|children|cn|html$/i,
8 tableElRe = /td|tr|tbody/i,
9 cssRe = /([a-z0-9-]+)\s*:\s*([^;\s]+(?:\s*[^;\s]+)*);?/gi,
13 afterbegin = 'afterbegin',
14 afterend = 'afterend',
15 beforebegin = 'beforebegin',
16 beforeend = 'beforeend',
25 function doInsert(el, o, returnElement, pos, sibling, append){
26 var newNode = pub.insertHtml(pos, Ext.getDom(el), createHtml(o));
27 return returnElement ? Ext.get(newNode, true) : newNode;
31 function createHtml(o){
39 if(typeof o == "string"){
41 } else if (Ext.isArray(o)) {
42 for (var i=0; i < o.length; i++) {
44 b += createHtml(o[i]);
48 b += '<' + (o.tag = o.tag || 'div');
51 if(!confRe.test(attr)){
52 if (typeof val == "object") {
53 b += ' ' + attr + '="';
55 b += key + ':' + val[key] + ';';
59 b += ' ' + ({cls : 'class', htmlFor : 'for'}[attr] || attr) + '="' + val + '"';
64 if (emptyTags.test(o.tag)) {
68 if ((cn = o.children || o.cn)) {
73 b += '</' + o.tag + '>';
79 function ieTable(depth, s, h, e){
80 tempTableEl.innerHTML = [s, h, e].join('');
88 if(ns = el.nextSibling){
89 var df = document.createDocumentFragment();
101 function insertIntoTable(tag, where, el, html) {
105 tempTableEl = tempTableEl || document.createElement('div');
107 if(tag == 'td' && (where == afterbegin || where == beforeend) ||
108 !tableElRe.test(tag) && (where == beforebegin || where == afterend)) {
111 before = where == beforebegin ? el :
112 where == afterend ? el.nextSibling :
113 where == afterbegin ? el.firstChild : null;
115 if (where == beforebegin || where == afterend) {
119 if (tag == 'td' || (tag == 'tr' && (where == beforeend || where == afterbegin))) {
120 node = ieTable(4, trs, html, tre);
121 } else if ((tag == 'tbody' && (where == beforeend || where == afterbegin)) ||
122 (tag == 'tr' && (where == beforebegin || where == afterend))) {
123 node = ieTable(3, tbs, html, tbe);
125 node = ieTable(2, ts, html, te);
127 el.insertBefore(node, before);
134 markup : function(o){
135 return createHtml(o);
139 applyStyles : function(el, styles){
147 if(typeof styles == "function"){
148 styles = styles.call();
150 if(typeof styles == "string"){
151 while((matches = cssRe.exec(styles))){
152 el.setStyle(matches[1], matches[2]);
154 }else if (typeof styles == "object"){
161 insertHtml : function(where, el, html){
170 where = where.toLowerCase();
172 hash[beforebegin] = ['BeforeBegin', 'previousSibling'];
173 hash[afterend] = ['AfterEnd', 'nextSibling'];
175 if (el.insertAdjacentHTML) {
176 if(tableRe.test(el.tagName) && (rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html))){
180 hash[afterbegin] = ['AfterBegin', 'firstChild'];
181 hash[beforeend] = ['BeforeEnd', 'lastChild'];
182 if ((hashVal = hash[where])) {
183 el.insertAdjacentHTML(hashVal[0], html);
184 return el[hashVal[1]];
187 range = el.ownerDocument.createRange();
188 setStart = 'setStart' + (endRe.test(where) ? 'After' : 'Before');
191 frag = range.createContextualFragment(html);
192 el.parentNode.insertBefore(frag, where == beforebegin ? el : el.nextSibling);
193 return el[(where == beforebegin ? 'previous' : 'next') + 'Sibling'];
195 rangeEl = (where == afterbegin ? 'first' : 'last') + 'Child';
197 range[setStart](el[rangeEl]);
198 frag = range.createContextualFragment(html);
199 if(where == afterbegin){
200 el.insertBefore(frag, el.firstChild);
202 el.appendChild(frag);
210 throw 'Illegal insertion point -> "' + where + '"';
214 insertBefore : function(el, o, returnElement){
215 return doInsert(el, o, returnElement, beforebegin);
219 insertAfter : function(el, o, returnElement){
220 return doInsert(el, o, returnElement, afterend, 'nextSibling');
224 insertFirst : function(el, o, returnElement){
225 return doInsert(el, o, returnElement, afterbegin, 'firstChild');
229 append : function(el, o, returnElement){
230 return doInsert(el, o, returnElement, beforeend, '', true);
234 overwrite : function(el, o, returnElement){
236 el.innerHTML = createHtml(o);
237 return returnElement ? Ext.get(el.firstChild) : el.firstChild;
240 createHtml : createHtml
245 Ext.apply(Ext.DomHelper,
248 afterbegin = 'afterbegin',
249 afterend = 'afterend',
250 beforebegin = 'beforebegin',
251 beforeend = 'beforeend',
252 confRe = /tag|children|cn|html$/i;
255 function doInsert(el, o, returnElement, pos, sibling, append){
259 newNode = createDom(o, null);
261 el.appendChild(newNode);
263 (sibling == 'firstChild' ? el : el.parentNode).insertBefore(newNode, el[sibling] || el);
266 newNode = Ext.DomHelper.insertHtml(pos, el, Ext.DomHelper.createHtml(o));
268 return returnElement ? Ext.get(newNode, true) : newNode;
273 function createDom(o, parentNode){
281 if (Ext.isArray(o)) {
282 el = doc.createDocumentFragment();
283 for (var i = 0, l = o.length; i < l; i++) {
286 } else if (typeof o == 'string') {
287 el = doc.createTextNode(o);
289 el = doc.createElement( o.tag || 'div' );
290 useSet = !!el.setAttribute;
291 for (var attr in o) {
292 if(!confRe.test(attr)){
298 el.setAttribute(attr, val);
305 Ext.DomHelper.applyStyles(el, o.style);
307 if ((cn = o.children || o.cn)) {
310 el.innerHTML = o.html;
314 parentNode.appendChild(el);
321 createTemplate : function(o){
322 var html = Ext.DomHelper.createHtml(o);
323 return new Ext.Template(html);
330 insertBefore : function(el, o, returnElement){
331 return doInsert(el, o, returnElement, beforebegin);
335 insertAfter : function(el, o, returnElement){
336 return doInsert(el, o, returnElement, afterend, 'nextSibling');
340 insertFirst : function(el, o, returnElement){
341 return doInsert(el, o, returnElement, afterbegin, 'firstChild');
345 append: function(el, o, returnElement){
346 return doInsert(el, o, returnElement, beforeend, '', true);
355 Ext.Template = function(html){
361 if (Ext.isArray(html)) {
362 html = html.join("");
363 } else if (a.length > 1) {
364 for(var i = 0, len = a.length; i < len; i++){
366 if(typeof v == 'object'){
382 Ext.Template.prototype = {
384 re : /\{([\w-]+)\}/g,
388 applyTemplate : function(values){
392 me.compiled(values) :
393 me.html.replace(me.re, function(m, name){
394 return values[name] !== undefined ? values[name] : "";
399 set : function(html, compile){
403 return compile ? me.compile() : me;
407 compile : function(){
409 sep = Ext.isGecko ? "+" : ",";
411 function fn(m, name){
412 name = "values['" + name + "']";
413 return "'"+ sep + '(' + name + " == undefined ? '' : " + name + ')' + sep + "'";
416 eval("this.compiled = function(values){ return " + (Ext.isGecko ? "'" : "['") +
417 me.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) +
418 (Ext.isGecko ? "';};" : "'].join('');};"));
423 insertFirst: function(el, values, returnElement){
424 return this.doInsert('afterBegin', el, values, returnElement);
428 insertBefore: function(el, values, returnElement){
429 return this.doInsert('beforeBegin', el, values, returnElement);
433 insertAfter : function(el, values, returnElement){
434 return this.doInsert('afterEnd', el, values, returnElement);
438 append : function(el, values, returnElement){
439 return this.doInsert('beforeEnd', el, values, returnElement);
442 doInsert : function(where, el, values, returnEl){
444 var newNode = Ext.DomHelper.insertHtml(where, el, this.applyTemplate(values));
445 return returnEl ? Ext.get(newNode, true) : newNode;
449 overwrite : function(el, values, returnElement){
451 el.innerHTML = this.applyTemplate(values);
452 return returnElement ? Ext.get(el.firstChild, true) : el.firstChild;
456 Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;
459 Ext.Template.from = function(el, config){
461 return new Ext.Template(el.value || el.innerHTML, config || '');
464 Ext.apply(Ext.Template.prototype, {
466 disableFormats : false,
470 re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
471 argsRe : /^\s*['"](.*)["']\s*$/,
473 compileBRe : /(\r\n|\n)/g,
477 * Returns an HTML fragment of this template with the specified values applied.
478 * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
479 * @return {String} The HTML fragment
482 applyTemplate : function(values){
484 useF = me.disableFormats !== true,
485 fm = Ext.util.Format,
489 return me.compiled(values);
491 function fn(m, name, format, args){
492 if (format && useF) {
493 if (format.substr(0, 5) == "this.") {
494 return tpl.call(format.substr(5), values[name], values);
497 // quoted values are required for strings in compiled templates,
498 // but for non compiled we need to strip them
499 // quoted reversed for jsmin
501 args = args.split(',');
502 for(var i = 0, len = args.length; i < len; i++){
503 args[i] = args[i].replace(re, "$1");
505 args = [values[name]].concat(args);
507 args = [values[name]];
509 return fm[format].apply(fm, args);
512 return values[name] !== undefined ? values[name] : "";
515 return me.html.replace(me.re, fn);
519 * Compiles the template into an internal function, eliminating the RegEx overhead.
520 * @return {Ext.Template} this
523 compile : function(){
525 fm = Ext.util.Format,
526 useF = me.disableFormats !== true,
527 sep = Ext.isGecko ? "+" : ",",
530 function fn(m, name, format, args){
532 args = args ? ',' + args : "";
533 if(format.substr(0, 5) != "this."){
534 format = "fm." + format + '(';
536 format = 'this.call("'+ format.substr(5) + '", ';
540 args= ''; format = "(values['" + name + "'] == undefined ? '' : ";
542 return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'";
545 // branched to use + in gecko and [].join() in others
547 body = "this.compiled = function(values){ return '" +
548 me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn) +
551 body = ["this.compiled = function(values){ return ['"];
552 body.push(me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn));
553 body.push("'].join('');};");
554 body = body.join('');
560 // private function used to call members
561 call : function(fnName, value, allValues){
562 return this[fnName](value, allValues);
565 Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;
567 * This is code is also distributed under MIT license for use
568 * with jQuery and prototype JavaScript libraries.
571 * @class Ext.DomQuery
572 Provides high performance selector/xpath processing by compiling queries into reusable functions. New pseudo classes and matchers can be plugged. It works on HTML and XML documents (if a content node is passed in).
574 DomQuery supports most of the <a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215/#selectors">CSS3 selectors spec</a>, along with some custom selectors and basic XPath.</p>
577 All selectors, attribute filters and pseudos below can be combined infinitely in any order. For example "div.foo:nth-child(odd)[@foo=bar].bar:first" would be a perfectly valid selector. Node filters are processed in the order in which they appear, which allows you to optimize your queries for your document structure.
579 <h4>Element Selectors:</h4>
581 <li> <b>*</b> any element</li>
582 <li> <b>E</b> an element with the tag E</li>
583 <li> <b>E F</b> All descendent elements of E that have the tag F</li>
584 <li> <b>E > F</b> or <b>E/F</b> all direct children elements of E that have the tag F</li>
585 <li> <b>E + F</b> all elements with the tag F that are immediately preceded by an element with the tag E</li>
586 <li> <b>E ~ F</b> all elements with the tag F that are preceded by a sibling element with the tag E</li>
588 <h4>Attribute Selectors:</h4>
589 <p>The use of @ and quotes are optional. For example, div[@foo='bar'] is also a valid attribute selector.</p>
591 <li> <b>E[foo]</b> has an attribute "foo"</li>
592 <li> <b>E[foo=bar]</b> has an attribute "foo" that equals "bar"</li>
593 <li> <b>E[foo^=bar]</b> has an attribute "foo" that starts with "bar"</li>
594 <li> <b>E[foo$=bar]</b> has an attribute "foo" that ends with "bar"</li>
595 <li> <b>E[foo*=bar]</b> has an attribute "foo" that contains the substring "bar"</li>
596 <li> <b>E[foo%=2]</b> has an attribute "foo" that is evenly divisible by 2</li>
597 <li> <b>E[foo!=bar]</b> has an attribute "foo" that does not equal "bar"</li>
599 <h4>Pseudo Classes:</h4>
601 <li> <b>E:first-child</b> E is the first child of its parent</li>
602 <li> <b>E:last-child</b> E is the last child of its parent</li>
603 <li> <b>E:nth-child(<i>n</i>)</b> E is the <i>n</i>th child of its parent (1 based as per the spec)</li>
604 <li> <b>E:nth-child(odd)</b> E is an odd child of its parent</li>
605 <li> <b>E:nth-child(even)</b> E is an even child of its parent</li>
606 <li> <b>E:only-child</b> E is the only child of its parent</li>
607 <li> <b>E:checked</b> E is an element that is has a checked attribute that is true (e.g. a radio or checkbox) </li>
608 <li> <b>E:first</b> the first E in the resultset</li>
609 <li> <b>E:last</b> the last E in the resultset</li>
610 <li> <b>E:nth(<i>n</i>)</b> the <i>n</i>th E in the resultset (1 based)</li>
611 <li> <b>E:odd</b> shortcut for :nth-child(odd)</li>
612 <li> <b>E:even</b> shortcut for :nth-child(even)</li>
613 <li> <b>E:contains(foo)</b> E's innerHTML contains the substring "foo"</li>
614 <li> <b>E:nodeValue(foo)</b> E contains a textNode with a nodeValue that equals "foo"</li>
615 <li> <b>E:not(S)</b> an E element that does not match simple selector S</li>
616 <li> <b>E:has(S)</b> an E element that has a descendent that matches simple selector S</li>
617 <li> <b>E:next(S)</b> an E element whose next sibling matches simple selector S</li>
618 <li> <b>E:prev(S)</b> an E element whose previous sibling matches simple selector S</li>
619 <li> <b>E:any(S1|S2|S2)</b> an E element which matches any of the simple selectors S1, S2 or S3
621 <h4>CSS Value Selectors:</h4>
623 <li> <b>E{display=none}</b> css value "display" that equals "none"</li>
624 <li> <b>E{display^=none}</b> css value "display" that starts with "none"</li>
625 <li> <b>E{display$=none}</b> css value "display" that ends with "none"</li>
626 <li> <b>E{display*=none}</b> css value "display" that contains the substring "none"</li>
627 <li> <b>E{display%=2}</b> css value "display" that is evenly divisible by 2</li>
628 <li> <b>E{display!=none}</b> css value "display" that does not equal "none"</li>
632 Ext.DomQuery = function(){
637 trimRe = /^\s+|\s+$/g,
638 tplRe = /\{(\d+)\}/g,
639 modeRe = /^(\s?[\/>+~]\s?|\s|$)/,
640 tagTokenRe = /^(#)?([\w-\*]+)/,
641 nthRe = /(\d*)n\+?(\d*)/,
646 isIE = window.ActiveXObject ? true : false,
651 eval("var batch = 30803;");
655 function child(parent, index){
657 n = parent.firstChild;
671 while((n = n.nextSibling) && n.nodeType != 1);
677 while((n = n.previousSibling) && n.nodeType != 1);
683 function children(parent){
684 var n = parent.firstChild,
688 nextNode = n.nextSibling;
690 if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){
691 parent.removeChild(n);
694 n.nodeIndex = ++nodeIndex;
704 function byClassName(nodeSet, cls){
708 var result = [], ri = -1;
709 for(var i = 0, ci; ci = nodeSet[i]; i++){
710 if((' '+ci.className+' ').indexOf(cls) != -1){
717 function attrValue(n, attr){
719 if(!n.tagName && typeof n.length != "undefined"){
729 if(attr == "class" || attr == "className"){
732 return n.getAttribute(attr) || n[attr];
740 function getNodes(ns, mode, tagName){
741 var result = [], ri = -1, cs;
745 tagName = tagName || "*";
747 if(typeof ns.getElementsByTagName != "undefined"){
754 for(var i = 0, ni; ni = ns[i]; i++){
755 cs = ni.getElementsByTagName(tagName);
756 for(var j = 0, ci; ci = cs[j]; j++){
762 } else if(mode == "/" || mode == ">"){
763 var utag = tagName.toUpperCase();
764 for(var i = 0, ni, cn; ni = ns[i]; i++){
766 for(var j = 0, cj; cj = cn[j]; j++){
767 if(cj.nodeName == utag || cj.nodeName == tagName || tagName == '*'){
774 }else if(mode == "+"){
775 var utag = tagName.toUpperCase();
776 for(var i = 0, n; n = ns[i]; i++){
777 while((n = n.nextSibling) && n.nodeType != 1);
778 if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){
784 }else if(mode == "~"){
785 var utag = tagName.toUpperCase();
786 for(var i = 0, n; n = ns[i]; i++){
787 while((n = n.nextSibling)){
788 if (n.nodeName == utag || n.nodeName == tagName || tagName == '*'){
797 function concat(a, b){
801 for(var i = 0, l = b.length; i < l; i++){
807 function byTag(cs, tagName){
808 if(cs.tagName || cs == document){
814 var result = [], ri = -1;
815 tagName = tagName.toLowerCase();
816 for(var i = 0, ci; ci = cs[i]; i++){
817 if(ci.nodeType == 1 && ci.tagName.toLowerCase() == tagName){
824 function byId(cs, id){
825 if(cs.tagName || cs == document){
831 var result = [], ri = -1;
832 for(var i = 0, ci; ci = cs[i]; i++){
833 if(ci && ci.id == id){
843 function byAttribute(cs, attr, value, op, custom){
846 useGetStyle = custom == "{",
847 fn = Ext.DomQuery.operators[op],
850 for(var i = 0, ci; ci = cs[i]; i++){
852 if(ci.nodeType != 1){
856 innerHTML = ci.innerHTML;
858 if(innerHTML !== null && innerHTML !== undefined){
860 a = Ext.DomQuery.getStyle(ci, attr);
861 } else if (attr == "class" || attr == "className"){
863 } else if (attr == "for"){
865 } else if (attr == "href"){
868 a = ci.getAttribute("href", 2);
870 a = ci.getAttribute(attr);
873 a = ci.getAttribute(attr);
875 if((fn && fn(a, value)) || (!fn && a)){
882 function byPseudo(cs, name, value){
883 return Ext.DomQuery.pseudos[name](cs, value);
886 function nodupIEXml(cs){
889 cs[0].setAttribute("_nodup", d);
891 for(var i = 1, len = cs.length; i < len; i++){
893 if(!c.getAttribute("_nodup") != d){
894 c.setAttribute("_nodup", d);
898 for(var i = 0, len = cs.length; i < len; i++){
899 cs[i].removeAttribute("_nodup");
908 var len = cs.length, c, i, r = cs, cj, ri = -1;
909 if(!len || typeof cs.nodeType != "undefined" || len == 1){
912 if(isIE && typeof cs[0].selectSingleNode != "undefined"){
913 return nodupIEXml(cs);
917 for(i = 1; c = cs[i]; i++){
922 for(var j = 0; j < i; j++){
925 for(j = i+1; cj = cs[j]; j++){
937 function quickDiffIEXml(c1, c2){
940 for(var i = 0, len = c1.length; i < len; i++){
941 c1[i].setAttribute("_qdiff", d);
943 for(var i = 0, len = c2.length; i < len; i++){
944 if(c2[i].getAttribute("_qdiff") != d){
948 for(var i = 0, len = c1.length; i < len; i++){
949 c1[i].removeAttribute("_qdiff");
954 function quickDiff(c1, c2){
955 var len1 = c1.length,
961 if(isIE && typeof c1[0].selectSingleNode != "undefined"){
962 return quickDiffIEXml(c1, c2);
964 for(var i = 0; i < len1; i++){
967 for(var i = 0, len = c2.length; i < len; i++){
968 if(c2[i]._qdiff != d){
975 function quickId(ns, mode, root, id){
977 var d = root.ownerDocument || root;
978 return d.getElementById(id);
980 ns = getNodes(ns, mode, "*");
985 getStyle : function(el, name){
986 return Ext.fly(el).getStyle(name);
989 compile : function(path, type){
990 type = type || "select";
993 var fn = ["var f = function(root){\n var mode; ++batch; var n = root || document;\n"],
996 matchers = Ext.DomQuery.matchers,
997 matchersLn = matchers.length,
1000 lmode = path.match(modeRe);
1002 if(lmode && lmode[1]){
1003 fn[fn.length] = 'mode="'+lmode[1].replace(trimRe, "")+'";';
1004 path = path.replace(lmode[1], "");
1008 while(path.substr(0, 1)=="/"){
1009 path = path.substr(1);
1012 while(path && lastPath != path){
1014 var tokenMatch = path.match(tagTokenRe);
1015 if(type == "select"){
1018 if(tokenMatch[1] == "#"){
1019 fn[fn.length] = 'n = quickId(n, mode, root, "'+tokenMatch[2]+'");';
1021 fn[fn.length] = 'n = getNodes(n, mode, "'+tokenMatch[2]+'");';
1023 path = path.replace(tokenMatch[0], "");
1024 }else if(path.substr(0, 1) != '@'){
1025 fn[fn.length] = 'n = getNodes(n, mode, "*");';
1030 if(tokenMatch[1] == "#"){
1031 fn[fn.length] = 'n = byId(n, "'+tokenMatch[2]+'");';
1033 fn[fn.length] = 'n = byTag(n, "'+tokenMatch[2]+'");';
1035 path = path.replace(tokenMatch[0], "");
1038 while(!(modeMatch = path.match(modeRe))){
1039 var matched = false;
1040 for(var j = 0; j < matchersLn; j++){
1041 var t = matchers[j];
1042 var m = path.match(t.re);
1044 fn[fn.length] = t.select.replace(tplRe, function(x, i){
1047 path = path.replace(m[0], "");
1054 throw 'Error parsing selector, parsing failed at "' + path + '"';
1058 fn[fn.length] = 'mode="'+modeMatch[1].replace(trimRe, "")+'";';
1059 path = path.replace(modeMatch[1], "");
1063 fn[fn.length] = "return nodup(n);\n}";
1071 jsSelect: function(path, root, type){
1073 root = root || document;
1075 if(typeof root == "string"){
1076 root = document.getElementById(root);
1078 var paths = path.split(","),
1082 for(var i = 0, len = paths.length; i < len; i++){
1083 var subPath = paths[i].replace(trimRe, "");
1085 if(!cache[subPath]){
1086 cache[subPath] = Ext.DomQuery.compile(subPath);
1087 if(!cache[subPath]){
1088 throw subPath + " is not a valid selector";
1091 var result = cache[subPath](root);
1092 if(result && result != document){
1093 results = results.concat(result);
1099 if(paths.length > 1){
1100 return nodup(results);
1104 isXml: function(el) {
1105 var docEl = (el ? el.ownerDocument || el : 0).documentElement;
1106 return docEl ? docEl.nodeName !== "HTML" : false;
1108 select : document.querySelectorAll ? function(path, root, type) {
1109 root = root || document;
1110 if (!Ext.DomQuery.isXml(root)) {
1112 var cs = root.querySelectorAll(path);
1113 return Ext.toArray(cs);
1117 return Ext.DomQuery.jsSelect.call(this, path, root, type);
1118 } : function(path, root, type) {
1119 return Ext.DomQuery.jsSelect.call(this, path, root, type);
1123 selectNode : function(path, root){
1124 return Ext.DomQuery.select(path, root)[0];
1128 selectValue : function(path, root, defaultValue){
1129 path = path.replace(trimRe, "");
1130 if(!valueCache[path]){
1131 valueCache[path] = Ext.DomQuery.compile(path, "select");
1133 var n = valueCache[path](root), v;
1134 n = n[0] ? n[0] : n;
1140 if (typeof n.normalize == 'function') n.normalize();
1142 v = (n && n.firstChild ? n.firstChild.nodeValue : null);
1143 return ((v === null||v === undefined||v==='') ? defaultValue : v);
1147 selectNumber : function(path, root, defaultValue){
1148 var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0);
1149 return parseFloat(v);
1153 is : function(el, ss){
1154 if(typeof el == "string"){
1155 el = document.getElementById(el);
1157 var isArray = Ext.isArray(el),
1158 result = Ext.DomQuery.filter(isArray ? el : [el], ss);
1159 return isArray ? (result.length == el.length) : (result.length > 0);
1163 filter : function(els, ss, nonMatches){
1164 ss = ss.replace(trimRe, "");
1165 if(!simpleCache[ss]){
1166 simpleCache[ss] = Ext.DomQuery.compile(ss, "simple");
1168 var result = simpleCache[ss](els);
1169 return nonMatches ? quickDiff(result, els) : result;
1175 select: 'n = byClassName(n, " {1} ");'
1177 re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,
1178 select: 'n = byPseudo(n, "{1}", "{2}");'
1180 re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,
1181 select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'
1184 select: 'n = byId(n, "{1}");'
1187 select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
1193 "=" : function(a, v){
1196 "!=" : function(a, v){
1199 "^=" : function(a, v){
1200 return a && a.substr(0, v.length) == v;
1202 "$=" : function(a, v){
1203 return a && a.substr(a.length-v.length) == v;
1205 "*=" : function(a, v){
1206 return a && a.indexOf(v) !== -1;
1208 "%=" : function(a, v){
1209 return (a % v) == 0;
1211 "|=" : function(a, v){
1212 return a && (a == v || a.substr(0, v.length+1) == v+'-');
1214 "~=" : function(a, v){
1215 return a && (' '+a+' ').indexOf(' '+v+' ') != -1;
1221 "first-child" : function(c){
1222 var r = [], ri = -1, n;
1223 for(var i = 0, ci; ci = n = c[i]; i++){
1224 while((n = n.previousSibling) && n.nodeType != 1);
1232 "last-child" : function(c){
1233 var r = [], ri = -1, n;
1234 for(var i = 0, ci; ci = n = c[i]; i++){
1235 while((n = n.nextSibling) && n.nodeType != 1);
1243 "nth-child" : function(c, a) {
1244 var r = [], ri = -1,
1245 m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a),
1246 f = (m[1] || 1) - 0, l = m[2] - 0;
1247 for(var i = 0, n; n = c[i]; i++){
1248 var pn = n.parentNode;
1249 if (batch != pn._batch) {
1251 for(var cn = pn.firstChild; cn; cn = cn.nextSibling){
1252 if(cn.nodeType == 1){
1259 if (l == 0 || n.nodeIndex == l){
1262 } else if ((n.nodeIndex + l) % f == 0){
1270 "only-child" : function(c){
1271 var r = [], ri = -1;;
1272 for(var i = 0, ci; ci = c[i]; i++){
1273 if(!prev(ci) && !next(ci)){
1280 "empty" : function(c){
1281 var r = [], ri = -1;
1282 for(var i = 0, ci; ci = c[i]; i++){
1283 var cns = ci.childNodes, j = 0, cn, empty = true;
1286 if(cn.nodeType == 1 || cn.nodeType == 3){
1298 "contains" : function(c, v){
1299 var r = [], ri = -1;
1300 for(var i = 0, ci; ci = c[i]; i++){
1301 if((ci.textContent||ci.innerText||'').indexOf(v) != -1){
1308 "nodeValue" : function(c, v){
1309 var r = [], ri = -1;
1310 for(var i = 0, ci; ci = c[i]; i++){
1311 if(ci.firstChild && ci.firstChild.nodeValue == v){
1318 "checked" : function(c){
1319 var r = [], ri = -1;
1320 for(var i = 0, ci; ci = c[i]; i++){
1321 if(ci.checked == true){
1328 "not" : function(c, ss){
1329 return Ext.DomQuery.filter(c, ss, true);
1332 "any" : function(c, selectors){
1333 var ss = selectors.split('|'),
1335 for(var i = 0, ci; ci = c[i]; i++){
1336 for(var j = 0; s = ss[j]; j++){
1337 if(Ext.DomQuery.is(ci, s)){
1346 "odd" : function(c){
1347 return this["nth-child"](c, "odd");
1350 "even" : function(c){
1351 return this["nth-child"](c, "even");
1354 "nth" : function(c, a){
1355 return c[a-1] || [];
1358 "first" : function(c){
1362 "last" : function(c){
1363 return c[c.length-1] || [];
1366 "has" : function(c, ss){
1367 var s = Ext.DomQuery.select,
1369 for(var i = 0, ci; ci = c[i]; i++){
1370 if(s(ss, ci).length > 0){
1377 "next" : function(c, ss){
1378 var is = Ext.DomQuery.is,
1380 for(var i = 0, ci; ci = c[i]; i++){
1389 "prev" : function(c, ss){
1390 var is = Ext.DomQuery.is,
1392 for(var i = 0, ci; ci = c[i]; i++){
1405 Ext.query = Ext.DomQuery.select;
1407 Ext.util.DelayedTask = function(fn, scope, args){
1413 fn.apply(scope, args || []);
1417 me.delay = function(delay, newFn, newScope, newArgs){
1420 scope = newScope || scope;
1421 args = newArgs || args;
1422 id = setInterval(call, delay);
1426 me.cancel = function(){
1434 var EXTUTIL = Ext.util,
1439 EXTUTIL.Observable = function(){
1441 var me = this, e = me.events;
1443 me.on(me.listeners);
1444 delete me.listeners;
1446 me.events = e || {};
1449 EXTUTIL.Observable.prototype = {
1451 filterOptRe : /^(?:scope|delay|buffer|single)$/,
1454 fireEvent : function(){
1455 var a = Array.prototype.slice.call(arguments, 0),
1456 ename = a[0].toLowerCase(),
1459 ce = me.events[ename],
1463 if (me.eventsSuspended === TRUE) {
1464 if (q = me.eventQueue) {
1468 else if(typeof ce == 'object') {
1470 if(ce.fire.apply(ce, a.slice(1)) === FALSE) {
1473 c = me.getBubbleTarget && me.getBubbleTarget();
1474 if(c && c.enableBubble) {
1475 cc = c.events[ename];
1476 if(!cc || typeof cc != 'object' || !cc.bubble) {
1477 c.enableBubble(ename);
1479 return c.fireEvent.apply(c, a);
1484 ret = ce.fire.apply(ce, a);
1491 addListener : function(eventName, fn, scope, o){
1497 if (typeof eventName == 'object') {
1501 if (!me.filterOptRe.test(e)) {
1502 me.addListener(e, oe.fn || oe, oe.scope || o.scope, oe.fn ? oe : o);
1506 eventName = eventName.toLowerCase();
1507 ce = me.events[eventName] || TRUE;
1508 if (typeof ce == 'boolean') {
1509 me.events[eventName] = ce = new EXTUTIL.Event(me, eventName);
1511 ce.addListener(fn, scope, typeof o == 'object' ? o : {});
1516 removeListener : function(eventName, fn, scope){
1517 var ce = this.events[eventName.toLowerCase()];
1518 if (typeof ce == 'object') {
1519 ce.removeListener(fn, scope);
1524 purgeListeners : function(){
1525 var events = this.events,
1530 if(typeof evt == 'object'){
1531 evt.clearListeners();
1537 addEvents : function(o){
1539 me.events = me.events || {};
1540 if (typeof o == 'string') {
1544 me.events[a[i]] = me.events[a[i]] || TRUE;
1547 Ext.applyIf(me.events, o);
1552 hasListener : function(eventName){
1553 var e = this.events[eventName.toLowerCase()];
1554 return typeof e == 'object' && e.listeners.length > 0;
1558 suspendEvents : function(queueSuspended){
1559 this.eventsSuspended = TRUE;
1560 if(queueSuspended && !this.eventQueue){
1561 this.eventQueue = [];
1566 resumeEvents : function(){
1568 queued = me.eventQueue || [];
1569 me.eventsSuspended = FALSE;
1570 delete me.eventQueue;
1571 EACH(queued, function(e) {
1572 me.fireEvent.apply(me, e);
1577 var OBSERVABLE = EXTUTIL.Observable.prototype;
1579 OBSERVABLE.on = OBSERVABLE.addListener;
1581 OBSERVABLE.un = OBSERVABLE.removeListener;
1584 EXTUTIL.Observable.releaseCapture = function(o){
1585 o.fireEvent = OBSERVABLE.fireEvent;
1588 function createTargeted(h, o, scope){
1590 if(o.target == arguments[0]){
1591 h.apply(scope, Array.prototype.slice.call(arguments, 0));
1596 function createBuffered(h, o, l, scope){
1597 l.task = new EXTUTIL.DelayedTask();
1599 l.task.delay(o.buffer, h, scope, Array.prototype.slice.call(arguments, 0));
1603 function createSingle(h, e, fn, scope){
1605 e.removeListener(fn, scope);
1606 return h.apply(scope, arguments);
1610 function createDelayed(h, o, l, scope){
1612 var task = new EXTUTIL.DelayedTask();
1617 task.delay(o.delay || 10, h, scope, Array.prototype.slice.call(arguments, 0));
1621 EXTUTIL.Event = function(obj, name){
1624 this.listeners = [];
1627 EXTUTIL.Event.prototype = {
1628 addListener : function(fn, scope, options){
1631 scope = scope || me.obj;
1632 if(!me.isListening(fn, scope)){
1633 l = me.createListener(fn, scope, options);
1635 me.listeners = me.listeners.slice(0);
1637 me.listeners.push(l);
1641 createListener: function(fn, scope, o){
1642 o = o || {}, scope = scope || this.obj;
1649 h = createTargeted(h, o, scope);
1652 h = createDelayed(h, o, l, scope);
1655 h = createSingle(h, this, fn, scope);
1658 h = createBuffered(h, o, l, scope);
1664 findListener : function(fn, scope){
1665 var list = this.listeners,
1669 scope = scope || this.obj;
1673 if(l.fn == fn && l.scope == scope){
1681 isListening : function(fn, scope){
1682 return this.findListener(fn, scope) != -1;
1685 removeListener : function(fn, scope){
1691 if((index = me.findListener(fn, scope)) != -1){
1693 me.listeners = me.listeners.slice(0);
1695 l = me.listeners[index];
1700 k = l.tasks && l.tasks.length;
1703 l.tasks[k].cancel();
1707 me.listeners.splice(index, 1);
1714 clearListeners : function(){
1719 me.removeListener(l[i].fn, l[i].scope);
1725 listeners = me.listeners,
1726 len = listeners.length,
1732 var args = Array.prototype.slice.call(arguments, 0);
1733 for (; i < len; i++) {
1735 if(l && l.fireFn.apply(l.scope || me.obj || window, args) === FALSE) {
1736 return (me.firing = FALSE);
1747 Ext.apply(Ext.util.Observable.prototype, function(){
1751 function getMethodEvent(method){
1752 var e = (this.methodEvents = this.methodEvents ||
1753 {})[method], returnValue, v, cancel, obj = this;
1756 this.methodEvents[method] = e = {};
1757 e.originalFn = this[method];
1758 e.methodName = method;
1762 var makeCall = function(fn, scope, args){
1763 if((v = fn.apply(scope || obj, args)) !== undefined){
1764 if (typeof v == 'object') {
1765 if(v.returnValue !== undefined){
1766 returnValue = v.returnValue;
1770 cancel = !!v.cancel;
1782 this[method] = function(){
1783 var args = Array.prototype.slice.call(arguments, 0),
1785 returnValue = v = undefined;
1788 for(var i = 0, len = e.before.length; i < len; i++){
1790 makeCall(b.fn, b.scope, args);
1796 if((v = e.originalFn.apply(obj, args)) !== undefined){
1800 for(var i = 0, len = e.after.length; i < len; i++){
1802 makeCall(b.fn, b.scope, args);
1817 beforeMethod : function(method, fn, scope){
1818 getMethodEvent.call(this, method).before.push({
1825 afterMethod : function(method, fn, scope){
1826 getMethodEvent.call(this, method).after.push({
1832 removeMethodListener: function(method, fn, scope){
1833 var e = this.getMethodEvent(method);
1834 for(var i = 0, len = e.before.length; i < len; i++){
1835 if(e.before[i].fn == fn && e.before[i].scope == scope){
1836 e.before.splice(i, 1);
1840 for(var i = 0, len = e.after.length; i < len; i++){
1841 if(e.after[i].fn == fn && e.after[i].scope == scope){
1842 e.after.splice(i, 1);
1849 relayEvents : function(o, events){
1851 function createHandler(ename){
1853 return me.fireEvent.apply(me, [ename].concat(Array.prototype.slice.call(arguments, 0)));
1856 for(var i = 0, len = events.length; i < len; i++){
1857 var ename = events[i];
1858 me.events[ename] = me.events[ename] || true;
1859 o.on(ename, createHandler(ename), me);
1864 enableBubble : function(events){
1866 if(!Ext.isEmpty(events)){
1867 events = Ext.isArray(events) ? events : Array.prototype.slice.call(arguments, 0);
1868 for(var i = 0, len = events.length; i < len; i++){
1869 var ename = events[i];
1870 ename = ename.toLowerCase();
1871 var ce = me.events[ename] || true;
1872 if (typeof ce == 'boolean') {
1873 ce = new Ext.util.Event(me, ename);
1874 me.events[ename] = ce;
1885 Ext.util.Observable.capture = function(o, fn, scope){
1886 o.fireEvent = o.fireEvent.createInterceptor(fn, scope);
1891 Ext.util.Observable.observeClass = function(c, listeners){
1894 Ext.apply(c, new Ext.util.Observable());
1895 Ext.util.Observable.capture(c.prototype, c.fireEvent, c);
1897 if(typeof listeners == 'object'){
1905 Ext.EventManager = function(){
1908 docReadyState = false,
1909 DETECT_NATIVE = Ext.isGecko || Ext.isWebKit || Ext.isSafari,
1914 DOMCONTENTLOADED = "DOMContentLoaded",
1915 COMPLETE = 'complete',
1916 propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,
1918 specialElCache = [];
1923 len = specialElCache.length,
1928 if(el.getElementById || el.navigator){
1930 for(; i < len; ++i){
1931 o = specialElCache[i];
1940 specialElCache.push({
1949 if(!Ext.elCache[id]){
1950 Ext.Element.addToCache(new Ext.Element(el), id);
1952 Ext.elCache[id].skipGC = true;
1960 function addListener(el, ename, fn, task, wrap, scope){
1961 el = Ext.getDom(el);
1963 es = Ext.elCache[id].events,
1966 wfn = E.on(el, ename, wrap);
1967 es[ename] = es[ename] || [];
1970 es[ename].push([fn, wrap, scope, wfn, task]);
1976 if(el.addEventListener && ename == "mousewheel"){
1977 var args = ["DOMMouseScroll", wrap, false];
1978 el.addEventListener.apply(el, args);
1979 Ext.EventManager.addListener(WINDOW, 'unload', function(){
1980 el.removeEventListener.apply(el, args);
1985 if(el == DOC && ename == "mousedown"){
1986 Ext.EventManager.stoppedMouseDownEvent.addListener(wrap);
1990 function doScrollChk(){
1997 DOC.documentElement.doScroll('left');
2006 function checkReadyState(e){
2008 if(Ext.isIE && doScrollChk()){
2011 if(DOC.readyState == COMPLETE){
2015 docReadyState || (docReadyProcId = setTimeout(arguments.callee, 2));
2020 function checkStyleSheets(e){
2021 styles || (styles = Ext.query('style, link[rel=stylesheet]'));
2022 if(styles.length == DOC.styleSheets.length){
2026 docReadyState || (docReadyProcId = setTimeout(arguments.callee, 2));
2030 function OperaDOMContentLoaded(e){
2031 DOC.removeEventListener(DOMCONTENTLOADED, arguments.callee, false);
2035 function fireDocReady(e){
2037 docReadyState = true;
2040 clearTimeout(docReadyProcId);
2043 DOC.removeEventListener(DOMCONTENTLOADED, fireDocReady, false);
2045 if(Ext.isIE && checkReadyState.bindIE){
2046 DOC.detachEvent('onreadystatechange', checkReadyState);
2048 E.un(WINDOW, "load", arguments.callee);
2050 if(docReadyEvent && !Ext.isReady){
2052 docReadyEvent.fire();
2053 docReadyEvent.listeners = [];
2058 function initDocReady(){
2059 docReadyEvent || (docReadyEvent = new Ext.util.Event());
2060 if (DETECT_NATIVE) {
2061 DOC.addEventListener(DOMCONTENTLOADED, fireDocReady, false);
2067 if(!checkReadyState()){
2068 checkReadyState.bindIE = true;
2069 DOC.attachEvent('onreadystatechange', checkReadyState);
2072 }else if(Ext.isOpera ){
2076 (DOC.readyState == COMPLETE && checkStyleSheets()) ||
2077 DOC.addEventListener(DOMCONTENTLOADED, OperaDOMContentLoaded, false);
2079 }else if (Ext.isWebKit){
2084 E.on(WINDOW, "load", fireDocReady);
2087 function createTargeted(h, o){
2089 var args = Ext.toArray(arguments);
2090 if(o.target == Ext.EventObject.setEvent(args[0]).target){
2091 h.apply(this, args);
2096 function createBuffered(h, o, task){
2099 task.delay(o.buffer, h, null, [new Ext.EventObjectImpl(e)]);
2103 function createSingle(h, el, ename, fn, scope){
2105 Ext.EventManager.removeListener(el, ename, fn, scope);
2110 function createDelayed(h, o, fn){
2112 var task = new Ext.util.DelayedTask(h);
2116 fn.tasks.push(task);
2117 task.delay(o.delay || 10, h, null, [new Ext.EventObjectImpl(e)]);
2121 function listen(element, ename, opt, fn, scope){
2122 var o = (!opt || typeof opt == "boolean") ? {} : opt,
2123 el = Ext.getDom(element), task;
2126 scope = scope || o.scope;
2129 throw "Error listening for \"" + ename + '\". Element "' + element + '" doesn\'t exist.';
2136 e = Ext.EventObject.setEvent(e);
2139 if(!(t = e.getTarget(o.delegate, el))){
2148 if (o.preventDefault) {
2151 if (o.stopPropagation) {
2152 e.stopPropagation();
2158 fn.call(scope || el, e, t, o);
2161 h = createTargeted(h, o);
2164 h = createDelayed(h, o, fn);
2167 h = createSingle(h, el, ename, fn, scope);
2170 task = new Ext.util.DelayedTask(h);
2171 h = createBuffered(h, o, task);
2174 addListener(el, ename, fn, task, h, scope);
2180 addListener : function(element, eventName, fn, scope, options){
2181 if(typeof eventName == 'object'){
2182 var o = eventName, e, val;
2185 if(!propRe.test(e)){
2186 if(Ext.isFunction(val)){
2188 listen(element, e, o, val, o.scope);
2191 listen(element, e, val);
2196 listen(element, eventName, options, fn, scope);
2201 removeListener : function(el, eventName, fn, scope){
2202 el = Ext.getDom(el);
2204 f = el && (Ext.elCache[id].events)[eventName] || [],
2205 wrap, i, l, k, len, fnc;
2207 for (i = 0, len = f.length; i < len; i++) {
2210 if (Ext.isArray(fnc = f[i]) && fnc[0] == fn && (!scope || fnc[2] == scope)) {
2214 k = fn.tasks && fn.tasks.length;
2217 fn.tasks[k].cancel();
2222 E.un(el, eventName, E.extAdapter ? fnc[3] : wrap);
2225 if(wrap && el.addEventListener && eventName == "mousewheel"){
2226 el.removeEventListener("DOMMouseScroll", wrap, false);
2230 if(wrap && el == DOC && eventName == "mousedown"){
2231 Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
2235 if (f.length === 0) {
2236 delete Ext.elCache[id].events[eventName];
2238 for (k in Ext.elCache[id].events) {
2241 Ext.elCache[id].events = {};
2248 removeAll : function(el){
2249 el = Ext.getDom(el);
2251 ec = Ext.elCache[id] || {},
2252 es = ec.events || {},
2253 f, i, len, ename, fn, k, wrap;
2256 if(es.hasOwnProperty(ename)){
2259 for (i = 0, len = f.length; i < len; i++) {
2264 if(fn[0].tasks && (k = fn[0].tasks.length)) {
2266 fn[0].tasks[k].cancel();
2271 E.un(el, ename, E.extAdapter ? fn[3] : wrap);
2274 if(el.addEventListener && wrap && ename == "mousewheel"){
2275 el.removeEventListener("DOMMouseScroll", wrap, false);
2279 if(wrap && el == DOC && ename == "mousedown"){
2280 Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
2285 if (Ext.elCache[id]) {
2286 Ext.elCache[id].events = {};
2290 getListeners : function(el, eventName) {
2291 el = Ext.getDom(el);
2293 ec = Ext.elCache[id] || {},
2294 es = ec.events || {},
2296 if (es && es[eventName]) {
2297 return es[eventName];
2303 purgeElement : function(el, recurse, eventName) {
2304 el = Ext.getDom(el);
2306 ec = Ext.elCache[id] || {},
2307 es = ec.events || {},
2310 if (es && es.hasOwnProperty(eventName)) {
2312 for (i = 0, len = f.length; i < len; i++) {
2313 Ext.EventManager.removeListener(el, eventName, f[i][0]);
2317 Ext.EventManager.removeAll(el);
2319 if (recurse && el && el.childNodes) {
2320 for (i = 0, len = el.childNodes.length; i < len; i++) {
2321 Ext.EventManager.purgeElement(el.childNodes[i], recurse, eventName);
2326 _unload : function() {
2328 for (el in Ext.elCache) {
2329 Ext.EventManager.removeAll(el);
2332 delete Ext.Element._flyweights;
2338 ajax = Ext.lib.Ajax;
2339 (typeof ajax.conn == 'object') ? conn = ajax.conn : conn = {};
2343 ajax.abort({conn: c, tId: tid});
2348 onDocumentReady : function(fn, scope, options){
2350 docReadyEvent || (docReadyEvent = new Ext.util.Event());
2351 docReadyEvent.addListener(fn, scope, options);
2352 docReadyEvent.fire();
2353 docReadyEvent.listeners = [];
2358 options = options || {};
2359 options.delay = options.delay || 1;
2360 docReadyEvent.addListener(fn, scope, options);
2365 fireDocReady : fireDocReady
2368 pub.on = pub.addListener;
2370 pub.un = pub.removeListener;
2372 pub.stoppedMouseDownEvent = new Ext.util.Event();
2376 Ext.onReady = Ext.EventManager.onDocumentReady;
2382 var initExtCss = function(){
2384 var bd = document.body || document.getElementsByTagName('body')[0];
2385 if(!bd){ return false; }
2387 Ext.isIE ? "ext-ie " + (Ext.isIE6 ? 'ext-ie6' : (Ext.isIE7 ? 'ext-ie7' : 'ext-ie8'))
2388 : Ext.isGecko ? "ext-gecko " + (Ext.isGecko2 ? 'ext-gecko2' : 'ext-gecko3')
2389 : Ext.isOpera ? "ext-opera"
2390 : Ext.isWebKit ? "ext-webkit" : ""];
2393 cls.push("ext-safari " + (Ext.isSafari2 ? 'ext-safari2' : (Ext.isSafari3 ? 'ext-safari3' : 'ext-safari4')));
2394 }else if(Ext.isChrome){
2395 cls.push("ext-chrome");
2399 cls.push("ext-mac");
2402 cls.push("ext-linux");
2405 if(Ext.isStrict || Ext.isBorderBox){
2406 var p = bd.parentNode;
2408 p.className += Ext.isStrict ? ' ext-strict' : ' ext-border-box';
2411 bd.className += cls.join(' ');
2416 Ext.onReady(initExtCss);
2422 Ext.EventObject = function(){
2423 var E = Ext.lib.Event,
2438 btnMap = Ext.isIE ? {1:0,4:1,2:2} :
2439 (Ext.isWebKit ? {1:0,2:1,3:2} : {0:0,1:1,2:2});
2441 Ext.EventObjectImpl = function(e){
2443 this.setEvent(e.browserEvent || e);
2447 Ext.EventObjectImpl.prototype = {
2449 setEvent : function(e){
2451 if(e == me || (e && e.browserEvent)){
2454 me.browserEvent = e;
2457 me.button = e.button ? btnMap[e.button] : (e.which ? e.which - 1 : -1);
2458 if(e.type == 'click' && me.button == -1){
2462 me.shiftKey = e.shiftKey;
2464 me.ctrlKey = e.ctrlKey || e.metaKey || false;
2465 me.altKey = e.altKey;
2467 me.keyCode = e.keyCode;
2468 me.charCode = e.charCode;
2470 me.target = E.getTarget(e);
2475 me.shiftKey = false;
2487 stopEvent : function(){
2489 if(me.browserEvent){
2490 if(me.browserEvent.type == 'mousedown'){
2491 Ext.EventManager.stoppedMouseDownEvent.fire(me);
2493 E.stopEvent(me.browserEvent);
2498 preventDefault : function(){
2499 if(this.browserEvent){
2500 E.preventDefault(this.browserEvent);
2505 stopPropagation : function(){
2507 if(me.browserEvent){
2508 if(me.browserEvent.type == 'mousedown'){
2509 Ext.EventManager.stoppedMouseDownEvent.fire(me);
2511 E.stopPropagation(me.browserEvent);
2516 getCharCode : function(){
2517 return this.charCode || this.keyCode;
2521 getKey : function(){
2522 return this.normalizeKey(this.keyCode || this.charCode)
2526 normalizeKey: function(k){
2527 return Ext.isSafari ? (safariKeys[k] || k) : k;
2531 getPageX : function(){
2536 getPageY : function(){
2546 getTarget : function(selector, maxDepth, returnEl){
2547 return selector ? Ext.fly(this.target).findParent(selector, maxDepth, returnEl) : (returnEl ? Ext.get(this.target) : this.target);
2551 getRelatedTarget : function(){
2552 return this.browserEvent ? E.getRelatedTarget(this.browserEvent) : null;
2556 getWheelDelta : function(){
2557 var e = this.browserEvent;
2560 delta = e.wheelDelta/120;
2562 delta = -e.detail/3;
2568 within : function(el, related, allowEl){
2570 var t = this[related ? "getRelatedTarget" : "getTarget"]();
2571 return t && ((allowEl ? (t == Ext.getDom(el)) : false) || Ext.fly(el).contains(t));
2577 return new Ext.EventObjectImpl();
2580 Ext.apply(Ext.EventManager, function(){
2586 propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,
2592 useKeydown = Ext.isWebKit ?
2593 Ext.num(navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1]) >= 525 :
2594 !((Ext.isGecko && !Ext.isWindows) || Ext.isOpera);
2598 doResizeEvent: function(){
2599 var h = D.getViewHeight(),
2600 w = D.getViewWidth();
2603 if(curHeight != h || curWidth != w){
2604 resizeEvent.fire(curWidth = w, curHeight = h);
2609 onWindowResize : function(fn, scope, options){
2611 resizeEvent = new Ext.util.Event();
2612 resizeTask = new Ext.util.DelayedTask(this.doResizeEvent);
2613 Ext.EventManager.on(window, "resize", this.fireWindowResize, this);
2615 resizeEvent.addListener(fn, scope, options);
2619 fireWindowResize : function(){
2621 resizeTask.delay(100);
2626 onTextResize : function(fn, scope, options){
2628 textEvent = new Ext.util.Event();
2629 var textEl = new Ext.Element(document.createElement('div'));
2630 textEl.dom.className = 'x-text-resize';
2631 textEl.dom.innerHTML = 'X';
2632 textEl.appendTo(document.body);
2633 textSize = textEl.dom.offsetHeight;
2634 setInterval(function(){
2635 if(textEl.dom.offsetHeight != textSize){
2636 textEvent.fire(textSize, textSize = textEl.dom.offsetHeight);
2638 }, this.textResizeInterval);
2640 textEvent.addListener(fn, scope, options);
2644 removeResizeListener : function(fn, scope){
2646 resizeEvent.removeListener(fn, scope);
2651 fireResize : function(){
2653 resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
2658 textResizeInterval : 50,
2665 useKeydown: useKeydown
2669 Ext.EventManager.on = Ext.EventManager.addListener;
2672 Ext.apply(Ext.EventObjectImpl.prototype, {
2852 isNavKeyPress : function(){
2854 k = this.normalizeKey(me.keyCode);
2855 return (k >= 33 && k <= 40) ||
2861 isSpecialKey : function(){
2862 var k = this.normalizeKey(this.keyCode);
2863 return (this.type == 'keypress' && this.ctrlKey) ||
2864 this.isNavKeyPress() ||
2865 (k == this.BACKSPACE) ||
2866 (k >= 16 && k <= 20) ||
2867 (k >= 44 && k <= 46);
2870 getPoint : function(){
2871 return new Ext.lib.Point(this.xy[0], this.xy[1]);
2875 hasModifier : function(){
2876 return ((this.ctrlKey || this.altKey) || this.shiftKey);
2882 Ext.Element = function(element, forceNew){
2883 var dom = typeof element == "string" ?
2884 DOC.getElementById(element) : element,
2887 if(!dom) return null;
2891 if(!forceNew && id && Ext.elCache[id]){
2892 return Ext.elCache[id].el;
2899 this.id = id || Ext.id(dom);
2902 var D = Ext.lib.Dom,
2911 set : function(o, useSet){
2915 useSet = (useSet !== false) && !!el.setAttribute;
2918 if (o.hasOwnProperty(attr)) {
2920 if (attr == 'style') {
2921 DH.applyStyles(el, val);
2922 } else if (attr == 'cls') {
2924 } else if (useSet) {
2925 el.setAttribute(attr, val);
2986 is : function(simpleSelector){
2987 return Ext.DomQuery.is(this.dom, simpleSelector);
2991 focus : function(defer, dom) {
2993 dom = dom || me.dom;
2996 me.focus.defer(defer, null, [null, dom]);
3013 getValue : function(asNumber){
3014 var val = this.dom.value;
3015 return asNumber ? parseInt(val, 10) : val;
3019 addListener : function(eventName, fn, scope, options){
3020 Ext.EventManager.on(this.dom, eventName, fn, scope || this, options);
3025 removeListener : function(eventName, fn, scope){
3026 Ext.EventManager.removeListener(this.dom, eventName, fn, scope || this);
3031 removeAllListeners : function(){
3032 Ext.EventManager.removeAll(this.dom);
3037 purgeAllListeners : function() {
3038 Ext.EventManager.purgeElement(this, true);
3042 addUnits : function(size){
3043 if(size === "" || size == "auto" || size === undefined){
3045 } else if(!isNaN(size) || !unitPattern.test(size)){
3046 size = size + (this.defaultUnit || 'px');
3052 load : function(url, params, cb){
3053 Ext.Ajax.request(Ext.apply({
3055 url: url.url || url,
3058 indicatorText: url.indicatorText || ''
3059 }, Ext.isObject(url) ? url : {}));
3064 isBorderBox : function(){
3065 return noBoxAdjust[(this.dom.tagName || "").toLowerCase()] || Ext.isBorderBox;
3069 remove : function(){
3075 Ext.removeNode(dom);
3080 hover : function(overFn, outFn, scope, options){
3082 me.on('mouseenter', overFn, scope || me.dom, options);
3083 me.on('mouseleave', outFn, scope || me.dom, options);
3088 contains : function(el){
3089 return !el ? false : Ext.lib.Dom.isAncestor(this.dom, el.dom ? el.dom : el);
3093 getAttributeNS : function(ns, name){
3094 return this.getAttribute(name, ns);
3098 getAttribute : Ext.isIE ? function(name, ns){
3100 type = typeof d[ns + ":" + name];
3102 if(['undefined', 'unknown'].indexOf(type) == -1){
3103 return d[ns + ":" + name];
3106 } : function(name, ns){
3108 return d.getAttributeNS(ns, name) || d.getAttribute(ns + ":" + name) || d.getAttribute(name) || d[name];
3112 update : function(html) {
3114 this.dom.innerHTML = html;
3120 var ep = El.prototype;
3122 El.addMethods = function(o){
3127 ep.on = ep.addListener;
3130 ep.un = ep.removeListener;
3133 ep.autoBoxAdjust = true;
3136 var unitPattern = /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i,
3142 El.get = function(el){
3146 if(!el){ return null; }
3147 if (typeof el == "string") {
3148 if (!(elm = DOC.getElementById(el))) {
3151 if (EC[el] && EC[el].el) {
3155 ex = El.addToCache(new El(elm));
3158 } else if (el.tagName) {
3162 if (EC[id] && EC[id].el) {
3166 ex = El.addToCache(new El(el));
3169 } else if (el instanceof El) {
3175 if (Ext.isIE && (el.id == undefined || el.id == '')) {
3178 el.dom = DOC.getElementById(el.id) || el.dom;
3182 } else if(el.isComposite) {
3184 } else if(Ext.isArray(el)) {
3185 return El.select(el);
3186 } else if(el == DOC) {
3189 var f = function(){};
3190 f.prototype = El.prototype;
3199 El.addToCache = function(el, id){
3210 El.data = function(el, key, value){
3215 var c = EC[el.id].data;
3216 if(arguments.length == 2){
3219 return (c[key] = value);
3226 function garbageCollect(){
3227 if(!Ext.enableGarbageCollector){
3228 clearInterval(El.collectorThreadId);
3259 if(!d || !d.parentNode || (!d.offsetParent && !DOC.getElementById(eid))){
3260 if(Ext.enableListenerCollection){
3261 Ext.EventManager.removeAll(d);
3272 EC = Ext.elCache = t;
3276 El.collectorThreadId = setInterval(garbageCollect, 30000);
3278 var flyFn = function(){};
3279 flyFn.prototype = El.prototype;
3282 El.Flyweight = function(dom){
3286 El.Flyweight.prototype = new flyFn();
3287 El.Flyweight.prototype.isFlyweight = true;
3288 El._flyweights = {};
3291 El.fly = function(el, named){
3293 named = named || '_global';
3295 if (el = Ext.getDom(el)) {
3296 (El._flyweights[named] = El._flyweights[named] || new El.Flyweight()).dom = el;
3297 ret = El._flyweights[named];
3309 var noBoxAdjust = Ext.isStrict ? {
3312 input:1, select:1, textarea:1
3314 if(Ext.isIE || Ext.isGecko){
3315 noBoxAdjust['button'] = 1;
3320 Ext.Element.addMethods({
3322 swallowEvent : function(eventName, preventDefault){
3325 e.stopPropagation();
3330 if(Ext.isArray(eventName)){
3331 Ext.each(eventName, function(e) {
3336 me.on(eventName, fn);
3341 relayEvent : function(eventName, observable){
3342 this.on(eventName, function(e){
3343 observable.fireEvent(eventName, e);
3348 clean : function(forceReclean){
3354 if(Ext.Element.data(dom, 'isCleaned') && forceReclean !== true){
3359 var nx = n.nextSibling;
3360 if(n.nodeType == 3 && !/\S/.test(n.nodeValue)){
3367 Ext.Element.data(dom, 'isCleaned', true);
3373 var um = this.getUpdater();
3374 um.update.apply(um, arguments);
3379 getUpdater : function(){
3380 return this.updateManager || (this.updateManager = new Ext.Updater(this));
3384 update : function(html, loadScripts, callback){
3390 if(loadScripts !== true){
3391 this.dom.innerHTML = html;
3392 if(typeof callback == 'function'){
3401 html += '<span id="' + id + '"></span>';
3403 Ext.lib.Event.onAvailable(id, function(){
3405 hd = DOC.getElementsByTagName("head")[0],
3406 re = /(?:<script([^>]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig,
3407 srcRe = /\ssrc=([\'\"])(.*?)\1/i,
3408 typeRe = /\stype=([\'\"])(.*?)\1/i,
3416 while((match = re.exec(html))){
3418 srcMatch = attrs ? attrs.match(srcRe) : false;
3419 if(srcMatch && srcMatch[2]){
3420 s = DOC.createElement("script");
3421 s.src = srcMatch[2];
3422 typeMatch = attrs.match(typeRe);
3423 if(typeMatch && typeMatch[2]){
3424 s.type = typeMatch[2];
3427 }else if(match[2] && match[2].length > 0){
3428 if(window.execScript) {
3429 window.execScript(match[2]);
3431 window.eval(match[2]);
3435 el = DOC.getElementById(id);
3436 if(el){Ext.removeNode(el);}
3437 if(typeof callback == 'function'){
3441 dom.innerHTML = html.replace(/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig, "");
3446 removeAllListeners : function(){
3447 this.removeAnchor();
3448 Ext.EventManager.removeAll(this.dom);
3453 createProxy : function(config, renderTo, matchBox){
3454 config = (typeof config == 'object') ? config : {tag : "div", cls: config};
3457 proxy = renderTo ? Ext.DomHelper.append(renderTo, config, true) :
3458 Ext.DomHelper.insertBefore(me.dom, config, true);
3460 if(matchBox && me.setBox && me.getBox){
3461 proxy.setBox(me.getBox());
3467 Ext.Element.prototype.getUpdateManager = Ext.Element.prototype.getUpdater;
3469 Ext.Element.addMethods({
3471 getAnchorXY : function(anchor, local, s){
3474 anchor = (anchor || "tl").toLowerCase();
3478 vp = me.dom == document.body || me.dom == document,
3479 w = s.width || vp ? Ext.lib.Dom.getViewWidth() : me.getWidth(),
3480 h = s.height || vp ? Ext.lib.Dom.getViewHeight() : me.getHeight(),
3484 scroll = me.getScroll(),
3485 extraX = vp ? scroll.left : !local ? o[0] : 0,
3486 extraY = vp ? scroll.top : !local ? o[1] : 0,
3488 c : [r(w * 0.5), r(h * 0.5)],
3489 t : [r(w * 0.5), 0],
3490 l : [0, r(h * 0.5)],
3491 r : [w, r(h * 0.5)],
3492 b : [r(w * 0.5), h],
3500 return [xy[0] + extraX, xy[1] + extraY];
3504 anchorTo : function(el, alignment, offsets, animate, monitorScroll, callback){
3507 scroll = !Ext.isEmpty(monitorScroll),
3508 action = function(){
3509 Ext.fly(dom).alignTo(el, alignment, offsets, animate);
3510 Ext.callback(callback, Ext.fly(dom));
3512 anchor = this.getAnchor();
3515 this.removeAnchor();
3521 Ext.EventManager.onWindowResize(action, null);
3524 Ext.EventManager.on(window, 'scroll', action, null,
3525 {buffer: !isNaN(monitorScroll) ? monitorScroll : 50});
3532 removeAnchor : function(){
3534 anchor = this.getAnchor();
3536 if(anchor && anchor.fn){
3537 Ext.EventManager.removeResizeListener(anchor.fn);
3539 Ext.EventManager.un(window, 'scroll', anchor.fn);
3547 getAnchor : function(){
3548 var data = Ext.Element.data,
3553 var anchor = data(dom, '_anchor');
3556 anchor = data(dom, '_anchor', {});
3562 getAlignToXY : function(el, p, o){
3566 throw "Element.alignToXY with an element that doesn't exist";
3570 p = (!p || p == "?" ? "tl-bl?" : (!/-/.test(p) && p !== "" ? "tl-" + p : p || "tl-bl")).toLowerCase();
3582 dw = Ext.lib.Dom.getViewWidth() -10,
3583 dh = Ext.lib.Dom.getViewHeight()-10,
3591 docElement = doc.documentElement,
3593 scrollX = (docElement.scrollLeft || docBody.scrollLeft || 0)+5,
3594 scrollY = (docElement.scrollTop || docBody.scrollTop || 0)+5,
3598 m = p.match(/^([a-z]+)-([a-z]+)(\?)?$/);
3601 throw "Element.alignTo with an invalid alignment " + p;
3610 a1 = me.getAnchorXY(p1, true);
3611 a2 = el.getAnchorXY(p2, false);
3613 x = a2[0] - a1[0] + o[0];
3614 y = a2[1] - a1[1] + o[1];
3624 p1x = p1.charAt(p1.length-1);
3626 p2x = p2.charAt(p2.length-1);
3627 swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t"));
3628 swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r"));
3631 if (x + w > dw + scrollX) {
3632 x = swapX ? r.left-w : dw+scrollX-w;
3635 x = swapX ? r.right : scrollX;
3637 if (y + h > dh + scrollY) {
3638 y = swapY ? r.top-h : dh+scrollY-h;
3641 y = swapY ? r.bottom : scrollY;
3648 alignTo : function(element, position, offsets, animate){
3650 return me.setXY(me.getAlignToXY(element, position, offsets),
3651 me.preanim && !!animate ? me.preanim(arguments, 3) : false);
3655 adjustForConstraints : function(xy, parent, offsets){
3656 return this.getConstrainToXY(parent || document, false, offsets, xy) || xy;
3660 getConstrainToXY : function(el, local, offsets, proposedXY){
3661 var os = {top:0, left:0, bottom:0, right: 0};
3663 return function(el, local, offsets, proposedXY){
3665 offsets = offsets ? Ext.applyIf(offsets, os) : os;
3667 var vw, vh, vx = 0, vy = 0;
3668 if(el.dom == document.body || el.dom == document){
3669 vw =Ext.lib.Dom.getViewWidth();
3670 vh = Ext.lib.Dom.getViewHeight();
3672 vw = el.dom.clientWidth;
3673 vh = el.dom.clientHeight;
3675 var vxy = el.getXY();
3681 var s = el.getScroll();
3683 vx += offsets.left + s.left;
3684 vy += offsets.top + s.top;
3686 vw -= offsets.right;
3687 vh -= offsets.bottom;
3692 var xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]);
3693 var x = xy[0], y = xy[1];
3694 var w = this.dom.offsetWidth, h = this.dom.offsetHeight;
3717 return moved ? [x, y] : false;
3777 getCenterXY : function(){
3778 return this.getAlignToXY(document, 'c-c');
3782 center : function(centerIn){
3783 return this.alignTo(centerIn || document, 'c-c');
3787 Ext.Element.addMethods(function(){
3788 var PARENTNODE = 'parentNode',
3789 NEXTSIBLING = 'nextSibling',
3790 PREVIOUSSIBLING = 'previousSibling',
3796 findParent : function(simpleSelector, maxDepth, returnEl){
3801 if(Ext.isGecko && Object.prototype.toString.call(p) == '[object XULElement]') {
3804 maxDepth = maxDepth || 50;
3805 if (isNaN(maxDepth)) {
3806 stopEl = Ext.getDom(maxDepth);
3807 maxDepth = Number.MAX_VALUE;
3809 while(p && p.nodeType == 1 && depth < maxDepth && p != b && p != stopEl){
3810 if(DQ.is(p, simpleSelector)){
3811 return returnEl ? GET(p) : p;
3820 findParentNode : function(simpleSelector, maxDepth, returnEl){
3821 var p = Ext.fly(this.dom.parentNode, '_internal');
3822 return p ? p.findParent(simpleSelector, maxDepth, returnEl) : null;
3826 up : function(simpleSelector, maxDepth){
3827 return this.findParentNode(simpleSelector, maxDepth, true);
3831 select : function(selector){
3832 return Ext.Element.select(selector, this.dom);
3836 query : function(selector){
3837 return DQ.select(selector, this.dom);
3841 child : function(selector, returnDom){
3842 var n = DQ.selectNode(selector, this.dom);
3843 return returnDom ? n : GET(n);
3847 down : function(selector, returnDom){
3848 var n = DQ.selectNode(" > " + selector, this.dom);
3849 return returnDom ? n : GET(n);
3853 parent : function(selector, returnDom){
3854 return this.matchNode(PARENTNODE, PARENTNODE, selector, returnDom);
3858 next : function(selector, returnDom){
3859 return this.matchNode(NEXTSIBLING, NEXTSIBLING, selector, returnDom);
3863 prev : function(selector, returnDom){
3864 return this.matchNode(PREVIOUSSIBLING, PREVIOUSSIBLING, selector, returnDom);
3869 first : function(selector, returnDom){
3870 return this.matchNode(NEXTSIBLING, 'firstChild', selector, returnDom);
3874 last : function(selector, returnDom){
3875 return this.matchNode(PREVIOUSSIBLING, 'lastChild', selector, returnDom);
3878 matchNode : function(dir, start, selector, returnDom){
3879 var n = this.dom[start];
3881 if(n.nodeType == 1 && (!selector || DQ.is(n, selector))){
3882 return !returnDom ? GET(n) : n;
3890 Ext.Element.addMethods({
3892 select : function(selector, unique){
3893 return Ext.Element.select(selector, unique, this.dom);
3896 Ext.Element.addMethods(
3898 var GETDOM = Ext.getDom,
3904 appendChild: function(el){
3905 return GET(el).appendTo(this);
3909 appendTo: function(el){
3910 GETDOM(el).appendChild(this.dom);
3915 insertBefore: function(el){
3916 (el = GETDOM(el)).parentNode.insertBefore(this.dom, el);
3921 insertAfter: function(el){
3922 (el = GETDOM(el)).parentNode.insertBefore(this.dom, el.nextSibling);
3927 insertFirst: function(el, returnDom){
3929 if(el.nodeType || el.dom || typeof el == 'string'){
3931 this.dom.insertBefore(el, this.dom.firstChild);
3932 return !returnDom ? GET(el) : el;
3934 return this.createChild(el, this.dom.firstChild, returnDom);
3939 replace: function(el){
3941 this.insertBefore(el);
3947 replaceWith: function(el){
3950 if(el.nodeType || el.dom || typeof el == 'string'){
3952 me.dom.parentNode.insertBefore(el, me.dom);
3954 el = DH.insertBefore(me.dom, el);
3957 delete Ext.elCache[me.id];
3958 Ext.removeNode(me.dom);
3959 me.id = Ext.id(me.dom = el);
3960 Ext.Element.addToCache(me.isFlyweight ? new Ext.Element(me.dom) : me);
3965 createChild: function(config, insertBefore, returnDom){
3966 config = config || {tag:'div'};
3967 return insertBefore ?
3968 DH.insertBefore(insertBefore, config, returnDom !== true) :
3969 DH[!this.dom.firstChild ? 'overwrite' : 'append'](this.dom, config, returnDom !== true);
3973 wrap: function(config, returnDom){
3974 var newEl = DH.insertBefore(this.dom, config || {tag: "div"}, !returnDom);
3975 newEl.dom ? newEl.dom.appendChild(this.dom) : newEl.appendChild(this.dom);
3980 insertHtml : function(where, html, returnEl){
3981 var el = DH.insertHtml(where, this.dom, html);
3982 return returnEl ? Ext.get(el) : el;
3986 Ext.apply(Ext.Element.prototype, function() {
3987 var GETDOM = Ext.getDom,
3993 insertSibling: function(el, where, returnDom){
3996 isAfter = (where || 'before').toLowerCase() == 'after',
3999 if(Ext.isArray(el)){
4001 Ext.each(el, function(e) {
4002 rt = Ext.fly(insertEl, '_internal').insertSibling(e, where, returnDom);
4012 if(el.nodeType || el.dom){
4013 rt = me.dom.parentNode.insertBefore(GETDOM(el), isAfter ? me.dom.nextSibling : me.dom);
4018 if (isAfter && !me.dom.nextSibling) {
4019 rt = DH.append(me.dom.parentNode, el, !returnDom);
4021 rt = DH[isAfter ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom);
4028 Ext.Element.addMethods(function(){
4031 camelRe = /(-[a-z])/gi,
4033 view = document.defaultView,
4034 propFloat = Ext.isIE ? 'styleFloat' : 'cssFloat',
4035 opacityRe = /alpha\(opacity=(.*)\)/i,
4036 trimRe = /^\s+|\s+$/g,
4040 PADDING = "padding",
4050 ISCLIPPED = 'isClipped',
4051 OVERFLOW = 'overflow',
4052 OVERFLOWX = 'overflow-x',
4053 OVERFLOWY = 'overflow-y',
4054 ORIGINALCLIP = 'originalClip',
4056 borders = {l: BORDER + LEFT + WIDTH, r: BORDER + RIGHT + WIDTH, t: BORDER + TOP + WIDTH, b: BORDER + BOTTOM + WIDTH},
4057 paddings = {l: PADDING + LEFT, r: PADDING + RIGHT, t: PADDING + TOP, b: PADDING + BOTTOM},
4058 margins = {l: MARGIN + LEFT, r: MARGIN + RIGHT, t: MARGIN + TOP, b: MARGIN + BOTTOM},
4059 data = Ext.Element.data;
4063 function camelFn(m, a) {
4064 return a.charAt(1).toUpperCase();
4067 function chkCache(prop) {
4068 return propCache[prop] || (propCache[prop] = prop == 'float' ? propFloat : prop.replace(camelRe, camelFn));
4073 adjustWidth : function(width) {
4075 var isNum = (typeof width == "number");
4076 if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
4077 width -= (me.getBorderWidth("lr") + me.getPadding("lr"));
4079 return (isNum && width < 0) ? 0 : width;
4083 adjustHeight : function(height) {
4085 var isNum = (typeof height == "number");
4086 if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
4087 height -= (me.getBorderWidth("tb") + me.getPadding("tb"));
4089 return (isNum && height < 0) ? 0 : height;
4094 addClass : function(className){
4101 if (!Ext.isArray(className)) {
4102 if (typeof className == 'string' && !this.hasClass(className)) {
4103 me.dom.className += " " + className;
4107 for (i = 0, len = className.length; i < len; i++) {
4109 if (typeof v == 'string' && (' ' + me.dom.className + ' ').indexOf(' ' + v + ' ') == -1) {
4114 me.dom.className += " " + cls.join(" ");
4121 removeClass : function(className){
4128 if (!Ext.isArray(className)){
4129 className = [className];
4131 if (me.dom && me.dom.className) {
4132 elClasses = me.dom.className.replace(trimRe, '').split(spacesRe);
4133 for (i = 0, len = className.length; i < len; i++) {
4135 if (typeof cls == 'string') {
4136 cls = cls.replace(trimRe, '');
4137 idx = elClasses.indexOf(cls);
4139 elClasses.splice(idx, 1);
4143 me.dom.className = elClasses.join(" ");
4149 radioClass : function(className){
4150 var cn = this.dom.parentNode.childNodes,
4154 className = Ext.isArray(className) ? className : [className];
4155 for (i = 0, len = cn.length; i < len; i++) {
4157 if (v && v.nodeType == 1) {
4158 Ext.fly(v, '_internal').removeClass(className);
4161 return this.addClass(className);
4165 toggleClass : function(className){
4166 return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);
4170 hasClass : function(className){
4171 return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1;
4175 replaceClass : function(oldClassName, newClassName){
4176 return this.removeClass(oldClassName).addClass(newClassName);
4179 isStyle : function(style, val) {
4180 return this.getStyle(style) == val;
4184 getStyle : function(){
4185 return view && view.getComputedStyle ?
4198 prop = chkCache(prop);
4200 if(wk && /marginRight/.test(prop)){
4201 display = this.getStyle('display');
4202 el.style.display = 'inline-block';
4204 out = (v = el.style[prop]) ? v :
4205 (cs = view.getComputedStyle(el, "")) ? cs[prop] : null;
4209 if(out == 'rgba(0, 0, 0, 0)'){
4210 out = 'transparent';
4212 el.style.display = display;
4222 if(el == document) return null;
4223 if (prop == 'opacity') {
4224 if (el.style.filter.match) {
4225 if(m = el.style.filter.match(opacityRe)){
4226 var fv = parseFloat(m[1]);
4228 return fv ? fv / 100 : 0;
4234 prop = chkCache(prop);
4235 return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);
4240 getColor : function(attr, defaultValue, prefix){
4241 var v = this.getStyle(attr),
4242 color = (typeof prefix != 'undefined') ? prefix : '#',
4245 if(!v || /transparent|inherit/.test(v)){
4246 return defaultValue;
4249 Ext.each(v.slice(4, v.length -1).split(','), function(s){
4250 h = parseInt(s, 10);
4251 color += (h < 16 ? '0' : '') + h.toString(16);
4254 v = v.replace('#', '');
4255 color += v.length == 3 ? v.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : v;
4257 return(color.length > 5 ? color.toLowerCase() : defaultValue);
4261 setStyle : function(prop, value){
4265 if (typeof prop != 'object') {
4270 for (style in prop) {
4271 value = prop[style];
4272 style == 'opacity' ?
4273 this.setOpacity(value) :
4274 this.dom.style[chkCache(style)] = value;
4280 setOpacity : function(opacity, animate){
4284 if(!animate || !me.anim){
4286 var opac = opacity < 1 ? 'alpha(opacity=' + opacity * 100 + ')' : '',
4287 val = s.filter.replace(opacityRe, '').replace(trimRe, '');
4290 s.filter = val + (val.length > 0 ? ' ' : '') + opac;
4292 s.opacity = opacity;
4295 me.anim({opacity: {to: opacity}}, me.preanim(arguments, 1), null, .35, 'easeIn');
4301 clearOpacity : function(){
4302 var style = this.dom.style;
4304 if(!Ext.isEmpty(style.filter)){
4305 style.filter = style.filter.replace(opacityRe, '').replace(trimRe, '');
4308 style.opacity = style['-moz-opacity'] = style['-khtml-opacity'] = '';
4314 getHeight : function(contentHeight){
4317 hidden = Ext.isIE && me.isStyle('display', 'none'),
4318 h = MATH.max(dom.offsetHeight, hidden ? 0 : dom.clientHeight) || 0;
4320 h = !contentHeight ? h : h - me.getBorderWidth("tb") - me.getPadding("tb");
4321 return h < 0 ? 0 : h;
4325 getWidth : function(contentWidth){
4328 hidden = Ext.isIE && me.isStyle('display', 'none'),
4329 w = MATH.max(dom.offsetWidth, hidden ? 0 : dom.clientWidth) || 0;
4330 w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");
4331 return w < 0 ? 0 : w;
4335 setWidth : function(width, animate){
4337 width = me.adjustWidth(width);
4338 !animate || !me.anim ?
4339 me.dom.style.width = me.addUnits(width) :
4340 me.anim({width : {to : width}}, me.preanim(arguments, 1));
4345 setHeight : function(height, animate){
4347 height = me.adjustHeight(height);
4348 !animate || !me.anim ?
4349 me.dom.style.height = me.addUnits(height) :
4350 me.anim({height : {to : height}}, me.preanim(arguments, 1));
4355 getBorderWidth : function(side){
4356 return this.addStyles(side, borders);
4360 getPadding : function(side){
4361 return this.addStyles(side, paddings);
4369 if(!data(dom, ISCLIPPED)){
4370 data(dom, ISCLIPPED, true);
4371 data(dom, ORIGINALCLIP, {
4372 o: me.getStyle(OVERFLOW),
4373 x: me.getStyle(OVERFLOWX),
4374 y: me.getStyle(OVERFLOWY)
4376 me.setStyle(OVERFLOW, HIDDEN);
4377 me.setStyle(OVERFLOWX, HIDDEN);
4378 me.setStyle(OVERFLOWY, HIDDEN);
4384 unclip : function(){
4388 if(data(dom, ISCLIPPED)){
4389 data(dom, ISCLIPPED, false);
4390 var o = data(dom, ORIGINALCLIP);
4392 me.setStyle(OVERFLOW, o.o);
4395 me.setStyle(OVERFLOWX, o.x);
4398 me.setStyle(OVERFLOWY, o.y);
4405 addStyles : function(sides, styles){
4407 sidesArr = sides.match(wordsRe),
4411 len = sidesArr.length;
4412 for (i = 0; i < len; i++) {
4414 size = side && parseInt(this.getStyle(styles[side]), 10);
4416 ttlSize += MATH.abs(size);
4429 Ext.Element.boxMarkup = '<div class="{0}-tl"><div class="{0}-tr"><div class="{0}-tc"></div></div></div><div class="{0}-ml"><div class="{0}-mr"><div class="{0}-mc"></div></div></div><div class="{0}-bl"><div class="{0}-br"><div class="{0}-bc"></div></div></div>';
4431 Ext.Element.addMethods(function(){
4432 var INTERNAL = "_internal",
4433 pxMatch = /(\d+\.?\d+)px/;
4436 applyStyles : function(style){
4437 Ext.DomHelper.applyStyles(this.dom, style);
4442 getStyles : function(){
4444 Ext.each(arguments, function(v) {
4445 ret[v] = this.getStyle(v);
4452 setOverflow : function(v){
4454 if(v=='auto' && Ext.isMac && Ext.isGecko2){
4455 dom.style.overflow = 'hidden';
4456 (function(){dom.style.overflow = 'auto';}).defer(1);
4458 dom.style.overflow = v;
4463 boxWrap : function(cls){
4464 cls = cls || 'x-box';
4465 var el = Ext.get(this.insertHtml("beforeBegin", "<div class='" + cls + "'>" + String.format(Ext.Element.boxMarkup, cls) + "</div>"));
4466 Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom);
4471 setSize : function(width, height, animate){
4473 if(typeof width == 'object'){
4474 height = width.height;
4475 width = width.width;
4477 width = me.adjustWidth(width);
4478 height = me.adjustHeight(height);
4479 if(!animate || !me.anim){
4480 me.dom.style.width = me.addUnits(width);
4481 me.dom.style.height = me.addUnits(height);
4483 me.anim({width: {to: width}, height: {to: height}}, me.preanim(arguments, 2));
4489 getComputedHeight : function(){
4491 h = Math.max(me.dom.offsetHeight, me.dom.clientHeight);
4493 h = parseFloat(me.getStyle('height')) || 0;
4494 if(!me.isBorderBox()){
4495 h += me.getFrameWidth('tb');
4502 getComputedWidth : function(){
4503 var w = Math.max(this.dom.offsetWidth, this.dom.clientWidth);
4505 w = parseFloat(this.getStyle('width')) || 0;
4506 if(!this.isBorderBox()){
4507 w += this.getFrameWidth('lr');
4514 getFrameWidth : function(sides, onlyContentBox){
4515 return onlyContentBox && this.isBorderBox() ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides));
4519 addClassOnOver : function(className){
4522 Ext.fly(this, INTERNAL).addClass(className);
4525 Ext.fly(this, INTERNAL).removeClass(className);
4532 addClassOnFocus : function(className){
4533 this.on("focus", function(){
4534 Ext.fly(this, INTERNAL).addClass(className);
4536 this.on("blur", function(){
4537 Ext.fly(this, INTERNAL).removeClass(className);
4543 addClassOnClick : function(className){
4545 this.on("mousedown", function(){
4546 Ext.fly(dom, INTERNAL).addClass(className);
4547 var d = Ext.getDoc(),
4549 Ext.fly(dom, INTERNAL).removeClass(className);
4550 d.removeListener("mouseup", fn);
4552 d.on("mouseup", fn);
4559 getViewSize : function(){
4562 isDoc = (d == doc || d == doc.body);
4566 var extdom = Ext.lib.Dom;
4568 width : extdom.getViewWidth(),
4569 height : extdom.getViewHeight()
4575 width : d.clientWidth,
4576 height : d.clientHeight
4583 getStyleSize : function(){
4588 isDoc = (d == doc || d == doc.body),
4593 var extdom = Ext.lib.Dom;
4595 width : extdom.getViewWidth(),
4596 height : extdom.getViewHeight()
4600 if(s.width && s.width != 'auto'){
4601 w = parseFloat(s.width);
4602 if(me.isBorderBox()){
4603 w -= me.getFrameWidth('lr');
4607 if(s.height && s.height != 'auto'){
4608 h = parseFloat(s.height);
4609 if(me.isBorderBox()){
4610 h -= me.getFrameWidth('tb');
4614 return {width: w || me.getWidth(true), height: h || me.getHeight(true)};
4618 getSize : function(contentSize){
4619 return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)};
4623 repaint : function(){
4625 this.addClass("x-repaint");
4626 setTimeout(function(){
4627 Ext.fly(dom).removeClass("x-repaint");
4633 unselectable : function(){
4634 this.dom.unselectable = "on";
4635 return this.swallowEvent("selectstart", true).
4636 applyStyles("-moz-user-select:none;-khtml-user-select:none;").
4637 addClass("x-unselectable");
4641 getMargins : function(side){
4644 hash = {t:"top", l:"left", r:"right", b: "bottom"},
4648 for (key in me.margins){
4649 o[hash[key]] = parseFloat(me.getStyle(me.margins[key])) || 0;
4653 return me.addStyles.call(me, side, me.margins);
4660 var D = Ext.lib.Dom,
4665 POSITION = "position",
4667 RELATIVE = "relative",
4671 Ext.Element.addMethods({
4674 return D.getX(this.dom);
4679 return D.getY(this.dom);
4684 return D.getXY(this.dom);
4688 getOffsetsTo : function(el){
4689 var o = this.getXY(),
4690 e = Ext.fly(el, '_internal').getXY();
4691 return [o[0]-e[0],o[1]-e[1]];
4695 setX : function(x, animate){
4696 return this.setXY([x, this.getY()], this.animTest(arguments, animate, 1));
4700 setY : function(y, animate){
4701 return this.setXY([this.getX(), y], this.animTest(arguments, animate, 1));
4705 setLeft : function(left){
4706 this.setStyle(LEFT, this.addUnits(left));
4711 setTop : function(top){
4712 this.setStyle(TOP, this.addUnits(top));
4717 setRight : function(right){
4718 this.setStyle(RIGHT, this.addUnits(right));
4723 setBottom : function(bottom){
4724 this.setStyle(BOTTOM, this.addUnits(bottom));
4729 setXY : function(pos, animate){
4731 if(!animate || !me.anim){
4732 D.setXY(me.dom, pos);
4734 me.anim({points: {to: pos}}, me.preanim(arguments, 1), 'motion');
4740 setLocation : function(x, y, animate){
4741 return this.setXY([x, y], this.animTest(arguments, animate, 2));
4745 moveTo : function(x, y, animate){
4746 return this.setXY([x, y], this.animTest(arguments, animate, 2));
4750 getLeft : function(local){
4751 return !local ? this.getX() : parseInt(this.getStyle(LEFT), 10) || 0;
4755 getRight : function(local){
4757 return !local ? me.getX() + me.getWidth() : (me.getLeft(true) + me.getWidth()) || 0;
4761 getTop : function(local) {
4762 return !local ? this.getY() : parseInt(this.getStyle(TOP), 10) || 0;
4766 getBottom : function(local){
4768 return !local ? me.getY() + me.getHeight() : (me.getTop(true) + me.getHeight()) || 0;
4772 position : function(pos, zIndex, x, y){
4775 if(!pos && me.isStyle(POSITION, STATIC)){
4776 me.setStyle(POSITION, RELATIVE);
4778 me.setStyle(POSITION, pos);
4781 me.setStyle(ZINDEX, zIndex);
4783 if(x || y) me.setXY([x || false, y || false]);
4787 clearPositioning : function(value){
4788 value = value || '';
4801 getPositioning : function(){
4802 var l = this.getStyle(LEFT);
4803 var t = this.getStyle(TOP);
4805 "position" : this.getStyle(POSITION),
4807 "right" : l ? "" : this.getStyle(RIGHT),
4809 "bottom" : t ? "" : this.getStyle(BOTTOM),
4810 "z-index" : this.getStyle(ZINDEX)
4815 setPositioning : function(pc){
4817 style = me.dom.style;
4821 if(pc.right == AUTO){
4824 if(pc.bottom == AUTO){
4832 translatePoints : function(x, y){
4833 y = isNaN(x[1]) ? y : x[1];
4834 x = isNaN(x[0]) ? x : x[0];
4836 relative = me.isStyle(POSITION, RELATIVE),
4838 l = parseInt(me.getStyle(LEFT), 10),
4839 t = parseInt(me.getStyle(TOP), 10);
4841 l = !isNaN(l) ? l : (relative ? 0 : me.dom.offsetLeft);
4842 t = !isNaN(t) ? t : (relative ? 0 : me.dom.offsetTop);
4844 return {left: (x - o[0] + l), top: (y - o[1] + t)};
4847 animTest : function(args, animate, i) {
4848 return !!animate && this.preanim ? this.preanim(args, i) : false;
4852 Ext.Element.addMethods({
4854 setBox : function(box, adjust, animate){
4858 if((adjust && !me.autoBoxAdjust) && !me.isBorderBox()){
4859 w -= (me.getBorderWidth("lr") + me.getPadding("lr"));
4860 h -= (me.getBorderWidth("tb") + me.getPadding("tb"));
4862 me.setBounds(box.x, box.y, w, h, me.animTest.call(me, arguments, animate, 2));
4867 getBox : function(contentBox, local) {
4872 getBorderWidth = me.getBorderWidth,
4873 getPadding = me.getPadding,
4881 left = parseInt(me.getStyle("left"), 10) || 0;
4882 top = parseInt(me.getStyle("top"), 10) || 0;
4885 var el = me.dom, w = el.offsetWidth, h = el.offsetHeight, bx;
4887 bx = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: w, height: h};
4889 l = getBorderWidth.call(me, "l") + getPadding.call(me, "l");
4890 r = getBorderWidth.call(me, "r") + getPadding.call(me, "r");
4891 t = getBorderWidth.call(me, "t") + getPadding.call(me, "t");
4892 b = getBorderWidth.call(me, "b") + getPadding.call(me, "b");
4893 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)};
4895 bx.right = bx.x + bx.width;
4896 bx.bottom = bx.y + bx.height;
4901 move : function(direction, distance, animate){
4906 left = [x - distance, y],
4907 right = [x + distance, y],
4908 top = [x, y - distance],
4909 bottom = [x, y + distance],
4923 direction = direction.toLowerCase();
4924 me.moveTo(hash[direction][0], hash[direction][1], me.animTest.call(me, arguments, animate, 2));
4928 setLeftTop : function(left, top){
4930 style = me.dom.style;
4931 style.left = me.addUnits(left);
4932 style.top = me.addUnits(top);
4937 getRegion : function(){
4938 return Ext.lib.Dom.getRegion(this.dom);
4942 setBounds : function(x, y, width, height, animate){
4944 if (!animate || !me.anim) {
4945 me.setSize(width, height);
4946 me.setLocation(x, y);
4948 me.anim({points: {to: [x, y]},
4949 width: {to: me.adjustWidth(width)},
4950 height: {to: me.adjustHeight(height)}},
4951 me.preanim(arguments, 4),
4958 setRegion : function(region, animate) {
4959 return this.setBounds(region.left, region.top, region.right-region.left, region.bottom-region.top, this.animTest.call(this, arguments, animate, 1));
4962 Ext.Element.addMethods({
4964 isScrollable : function(){
4966 return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth;
4970 scrollTo : function(side, value){
4971 this.dom["scroll" + (/top/i.test(side) ? "Top" : "Left")] = value;
4976 getScroll : function(){
4980 docElement = doc.documentElement,
4985 if(d == doc || d == body){
4986 if(Ext.isIE && Ext.isStrict){
4987 l = docElement.scrollLeft;
4988 t = docElement.scrollTop;
4990 l = window.pageXOffset;
4991 t = window.pageYOffset;
4993 ret = {left: l || (body ? body.scrollLeft : 0), top: t || (body ? body.scrollTop : 0)};
4995 ret = {left: d.scrollLeft, top: d.scrollTop};
5000 Ext.Element.addMethods({
5002 scrollTo : function(side, value, animate){
5003 var top = /top/i.test(side),
5007 if (!animate || !me.anim) {
5008 prop = 'scroll' + (top ? 'Top' : 'Left'),
5011 prop = 'scroll' + (top ? 'Left' : 'Top'),
5012 me.anim({scroll: {to: top ? [dom[prop], value] : [value, dom[prop]]}},
5013 me.preanim(arguments, 2), 'scroll');
5019 scrollIntoView : function(container, hscroll){
5020 var c = Ext.getDom(container) || Ext.getBody().dom,
5022 o = this.getOffsetsTo(c),
5023 l = o[0] + c.scrollLeft,
5024 t = o[1] + c.scrollTop,
5025 b = t + el.offsetHeight,
5026 r = l + el.offsetWidth,
5027 ch = c.clientHeight,
5028 ct = parseInt(c.scrollTop, 10),
5029 cl = parseInt(c.scrollLeft, 10),
5031 cr = cl + c.clientWidth;
5033 if (el.offsetHeight > ch || t < ct) {
5038 c.scrollTop = c.scrollTop;
5040 if(hscroll !== false){
5041 if(el.offsetWidth > c.clientWidth || l < cl){
5044 c.scrollLeft = r - c.clientWidth;
5046 c.scrollLeft = c.scrollLeft;
5052 scrollChildIntoView : function(child, hscroll){
5053 Ext.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll);
5057 scroll : function(direction, distance, animate){
5058 if(!this.isScrollable()){
5062 l = el.scrollLeft, t = el.scrollTop,
5063 w = el.scrollWidth, h = el.scrollHeight,
5064 cw = el.clientWidth, ch = el.clientHeight,
5065 scrolled = false, v,
5067 l: Math.min(l + distance, w-cw),
5068 r: v = Math.max(l - distance, 0),
5069 t: Math.max(t - distance, 0),
5070 b: Math.min(t + distance, h-ch)
5075 direction = direction.substr(0, 1);
5076 if((v = hash[direction]) > -1){
5078 this.scrollTo(direction == 'l' || direction == 'r' ? 'left' : 'top', v, this.preanim(arguments, 2));
5084 Ext.Element.VISIBILITY = 1;
5086 Ext.Element.DISPLAY = 2;
5088 Ext.Element.addMethods(function(){
5089 var VISIBILITY = "visibility",
5090 DISPLAY = "display",
5092 OFFSETS = "offsets",
5094 ORIGINALDISPLAY = 'originalDisplay',
5095 VISMODE = 'visibilityMode',
5096 ELDISPLAY = Ext.Element.DISPLAY,
5097 data = Ext.Element.data,
5098 getDisplay = function(dom){
5099 var d = data(dom, ORIGINALDISPLAY);
5100 if(d === undefined){
5101 data(dom, ORIGINALDISPLAY, d = '');
5105 getVisMode = function(dom){
5106 var m = data(dom, VISMODE);
5107 if(m === undefined){
5108 data(dom, VISMODE, m = 1);
5115 originalDisplay : "",
5119 setVisibilityMode : function(visMode){
5120 data(this.dom, VISMODE, visMode);
5125 animate : function(args, duration, onComplete, easing, animType){
5126 this.anim(args, {duration: duration, callback: onComplete, easing: easing}, animType);
5131 anim : function(args, opt, animType, defaultDur, defaultEase, cb){
5132 animType = animType || 'run';
5135 anim = Ext.lib.Anim[animType](
5138 (opt.duration || defaultDur) || .35,
5139 (opt.easing || defaultEase) || 'easeOut',
5142 if(opt.callback) opt.callback.call(opt.scope || me, me, opt);
5151 preanim : function(a, i){
5152 return !a[i] ? false : (typeof a[i] == 'object' ? a[i]: {duration: a[i+1], callback: a[i+2], easing: a[i+3]});
5156 isVisible : function() {
5157 return !this.isStyle(VISIBILITY, HIDDEN) && !this.isStyle(DISPLAY, NONE);
5161 setVisible : function(visible, animate){
5162 var me = this, isDisplay, isVisible, isOffsets,
5166 if (typeof animate == 'string'){
5167 isDisplay = animate == DISPLAY;
5168 isVisible = animate == VISIBILITY;
5169 isOffsets = animate == OFFSETS;
5172 isDisplay = getVisMode(this.dom) == ELDISPLAY;
5173 isVisible = !isDisplay;
5176 if (!animate || !me.anim) {
5178 me.setDisplayed(visible);
5179 } else if (isOffsets){
5181 me.hideModeStyles = {
5182 position: me.getStyle('position'),
5183 top: me.getStyle('top'),
5184 left: me.getStyle('left')
5187 me.applyStyles({position: 'absolute', top: '-10000px', left: '-10000px'});
5189 me.applyStyles(me.hideModeStyles || {position: '', top: '', left: ''});
5193 dom.style.visibility = visible ? "visible" : HIDDEN;
5199 me.setVisible(true);
5201 me.anim({opacity: { to: (visible?1:0) }},
5202 me.preanim(arguments, 1),
5208 dom.style[isDisplay ? DISPLAY : VISIBILITY] = (isDisplay) ? NONE : HIDDEN;
5209 Ext.fly(dom).setOpacity(1);
5217 toggle : function(animate){
5219 me.setVisible(!me.isVisible(), me.preanim(arguments, 0));
5224 setDisplayed : function(value) {
5225 if(typeof value == "boolean"){
5226 value = value ? getDisplay(this.dom) : NONE;
5228 this.setStyle(DISPLAY, value);
5233 fixDisplay : function(){
5235 if(me.isStyle(DISPLAY, NONE)){
5236 me.setStyle(VISIBILITY, HIDDEN);
5237 me.setStyle(DISPLAY, getDisplay(this.dom));
5238 if(me.isStyle(DISPLAY, NONE)){
5239 me.setStyle(DISPLAY, "block");
5245 hide : function(animate){
5247 if (typeof animate == 'string'){
5248 this.setVisible(false, animate);
5251 this.setVisible(false, this.preanim(arguments, 0));
5256 show : function(animate){
5258 if (typeof animate == 'string'){
5259 this.setVisible(true, animate);
5262 this.setVisible(true, this.preanim(arguments, 0));
5268 Ext.Element.addMethods(
5270 var VISIBILITY = "visibility",
5271 DISPLAY = "display",
5274 XMASKED = "x-masked",
5275 XMASKEDRELATIVE = "x-masked-relative",
5276 data = Ext.Element.data;
5280 isVisible : function(deep) {
5281 var vis = !this.isStyle(VISIBILITY,HIDDEN) && !this.isStyle(DISPLAY,NONE),
5282 p = this.dom.parentNode;
5283 if(deep !== true || !vis){
5286 while(p && !/^body/i.test(p.tagName)){
5287 if(!Ext.fly(p, '_isVisible').isVisible()){
5296 isDisplayed : function() {
5297 return !this.isStyle(DISPLAY, NONE);
5301 enableDisplayMode : function(display){
5302 this.setVisibilityMode(Ext.Element.DISPLAY);
5303 if(!Ext.isEmpty(display)){
5304 data(this.dom, 'originalDisplay', display);
5310 mask : function(msg, msgCls){
5314 EXTELMASKMSG = "ext-el-mask-msg",
5318 if(!/^body/i.test(dom.tagName) && me.getStyle('position') == 'static'){
5319 me.addClass(XMASKEDRELATIVE);
5321 if((el = data(dom, 'maskMsg'))){
5324 if((el = data(dom, 'mask'))){
5328 mask = dh.append(dom, {cls : "ext-el-mask"}, true);
5329 data(dom, 'mask', mask);
5331 me.addClass(XMASKED);
5332 mask.setDisplayed(true);
5333 if(typeof msg == 'string'){
5334 var mm = dh.append(dom, {cls : EXTELMASKMSG, cn:{tag:'div'}}, true);
5335 data(dom, 'maskMsg', mm);
5336 mm.dom.className = msgCls ? EXTELMASKMSG + " " + msgCls : EXTELMASKMSG;
5337 mm.dom.firstChild.innerHTML = msg;
5338 mm.setDisplayed(true);
5341 if(Ext.isIE && !(Ext.isIE7 && Ext.isStrict) && me.getStyle('height') == 'auto'){
5342 mask.setSize(undefined, me.getHeight());
5348 unmask : function(){
5351 mask = data(dom, 'mask'),
5352 maskMsg = data(dom, 'maskMsg');
5356 data(dom, 'maskMsg', undefined);
5359 data(dom, 'mask', undefined);
5361 me.removeClass([XMASKED, XMASKEDRELATIVE]);
5365 isMasked : function(){
5366 var m = data(this.dom, 'mask');
5367 return m && m.isVisible();
5371 createShim : function(){
5372 var el = document.createElement('iframe'),
5374 el.frameBorder = '0';
5375 el.className = 'ext-shim';
5376 el.src = Ext.SSL_SECURE_URL;
5377 shim = Ext.get(this.dom.parentNode.insertBefore(el, this.dom));
5378 shim.autoBoxAdjust = false;
5383 Ext.Element.addMethods({
5385 addKeyListener : function(key, fn, scope){
5387 if(typeof key != 'object' || Ext.isArray(key)){
5403 return new Ext.KeyMap(this, config);
5407 addKeyMap : function(config){
5408 return new Ext.KeyMap(this, config);
5414 UNDEFINED = undefined,
5428 ABSOLUTE = "absolute",
5429 VISIBLE = "visible",
5431 POSITION = "position",
5432 EASEOUT = "easeOut",
5434 flyEl = new Ext.Element.Flyweight(),
5436 getObject = function(o){
5439 fly = function(dom){
5441 flyEl.id = Ext.id(dom);
5445 getQueue = function(id){
5451 setQueue = function(id, value){
5456 Ext.enableFx = TRUE;
5463 switchStatements : function(key, fn, argHash){
5464 return fn.apply(this, argHash[key]);
5468 slideIn : function(anchor, o){
5484 anchor = anchor || "t";
5486 me.queueFx(o, function(){
5487 xy = fly(dom).getXY();
5489 fly(dom).fixDisplay();
5492 r = fly(dom).getFxRestore();
5493 b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight};
5494 b.right = b.x + b.width;
5495 b.bottom = b.y + b.height;
5498 fly(dom).setWidth(b.width).setHeight(b.height);
5501 wrap = fly(dom).fxWrap(r.pos, o, HIDDEN);
5503 st.visibility = VISIBLE;
5504 st.position = ABSOLUTE;
5508 fly(dom).fxUnwrap(wrap, r.pos, o);
5510 st.height = r.height;
5511 fly(dom).afterFx(o);
5515 pt = {to: [b.x, b.y]};
5517 bh = {to: b.height};
5519 function argCalc(wrap, style, ww, wh, sXY, sXYval, s1, s2, w, h, p){
5521 fly(wrap).setWidth(ww).setHeight(wh);
5523 fly(wrap)[sXY](sXYval);
5525 style[s1] = style[s2] = "0";
5538 args = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, {
5539 t : [wrap, st, b.width, 0, NULL, NULL, LEFT, BOTTOM, NULL, bh, NULL],
5540 l : [wrap, st, 0, b.height, NULL, NULL, RIGHT, TOP, bw, NULL, NULL],
5541 r : [wrap, st, b.width, b.height, SETX, b.right, LEFT, TOP, NULL, NULL, pt],
5542 b : [wrap, st, b.width, b.height, SETY, b.bottom, LEFT, TOP, NULL, bh, pt],
5543 tl : [wrap, st, 0, 0, NULL, NULL, RIGHT, BOTTOM, bw, bh, pt],
5544 bl : [wrap, st, 0, 0, SETY, b.y + b.height, RIGHT, TOP, bw, bh, pt],
5545 br : [wrap, st, 0, 0, SETXY, [b.right, b.bottom], LEFT, TOP, bw, bh, pt],
5546 tr : [wrap, st, 0, 0, SETX, b.x + b.width, LEFT, BOTTOM, bw, bh, pt]
5549 st.visibility = VISIBLE;
5552 arguments.callee.anim = fly(wrap).fxanim(args,
5563 slideOut : function(anchor, o){
5575 anchor = anchor || "t";
5577 me.queueFx(o, function(){
5580 r = fly(dom).getFxRestore();
5581 b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight};
5582 b.right = b.x + b.width;
5583 b.bottom = b.y + b.height;
5586 fly(dom).setWidth(b.width).setHeight(b.height);
5589 wrap = fly(dom).fxWrap(r.pos, o, VISIBLE);
5591 st.visibility = VISIBLE;
5592 st.position = ABSOLUTE;
5593 fly(wrap).setWidth(b.width).setHeight(b.height);
5596 o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();
5597 fly(dom).fxUnwrap(wrap, r.pos, o);
5599 st.height = r.height;
5600 fly(dom).afterFx(o);
5603 function argCalc(style, s1, s2, p1, v1, p2, v2, p3, v3){
5606 style[s1] = style[s2] = "0";
5618 a = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, {
5619 t : [st, LEFT, BOTTOM, HEIGHT, zero],
5620 l : [st, RIGHT, TOP, WIDTH, zero],
5621 r : [st, LEFT, TOP, WIDTH, zero, POINTS, {to : [b.right, b.y]}],
5622 b : [st, LEFT, TOP, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}],
5623 tl : [st, RIGHT, BOTTOM, WIDTH, zero, HEIGHT, zero],
5624 bl : [st, RIGHT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}],
5625 br : [st, LEFT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x + b.width, b.bottom]}],
5626 tr : [st, LEFT, BOTTOM, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.right, b.y]}]
5629 arguments.callee.anim = fly(wrap).fxanim(a,
5649 me.queueFx(o, function(){
5650 width = fly(dom).getWidth();
5651 height = fly(dom).getHeight();
5652 fly(dom).clearOpacity();
5656 r = fly(dom).getFxRestore();
5659 o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();
5660 fly(dom).clearOpacity();
5661 fly(dom).setPositioning(r.pos);
5663 st.height = r.height;
5665 fly(dom).afterFx(o);
5668 arguments.callee.anim = fly(dom).fxanim({
5669 width : {to : fly(dom).adjustWidth(width * 2)},
5670 height : {to : fly(dom).adjustHeight(height * 2)},
5671 points : {by : [-width * .5, -height * .5]},
5673 fontSize: {to : 200, unit: "%"}
5685 switchOff : function(o){
5692 me.queueFx(o, function(){
5693 fly(dom).clearOpacity();
5697 r = fly(dom).getFxRestore();
5700 o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();
5701 fly(dom).clearOpacity();
5702 fly(dom).setPositioning(r.pos);
5704 st.height = r.height;
5705 fly(dom).afterFx(o);
5708 fly(dom).fxanim({opacity : {to : 0.3}},
5714 fly(dom).clearOpacity();
5718 points : {by : [0, fly(dom).getHeight() * .5]}
5732 highlight : function(color, o){
5736 attr = o.attr || "backgroundColor",
5740 me.queueFx(o, function(){
5741 fly(dom).clearOpacity();
5745 dom.style[attr] = restore;
5746 fly(dom).afterFx(o);
5748 restore = dom.style[attr];
5749 a[attr] = {from: color || "ffff9c", to: o.endColor || fly(dom).getColor(attr) || "ffffff"};
5750 arguments.callee.anim = fly(dom).fxanim(a,
5761 frame : function(color, count, o){
5768 me.queueFx(o, function(){
5769 color = color || '#C3DAF9';
5770 if(color.length == 6){
5771 color = '#' + color;
5776 var xy = fly(dom).getXY(),
5777 b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight},
5779 proxy = fly(document.body || document.documentElement).createChild({
5781 position : ABSOLUTE,
5783 border : '0px solid ' + color
5786 return proxy.queueFx({}, animFn);
5790 arguments.callee.anim = {
5799 var scale = Ext.isBorderBox ? 2 : 1;
5800 active = proxy.anim({
5801 top : {from : b.y, to : b.y - 20},
5802 left : {from : b.x, to : b.x - 20},
5803 borderWidth : {from : 0, to : 10},
5804 opacity : {from : 1, to : 0},
5805 height : {from : b.height, to : b.height + 20 * scale},
5806 width : {from : b.width, to : b.width + 20 * scale}
5808 duration: o.duration || 1,
5809 callback: function() {
5811 --count > 0 ? queue() : fly(dom).afterFx(o);
5814 arguments.callee.anim = {
5827 pause : function(seconds){
5831 this.queueFx({}, function(){
5832 t = setTimeout(function(){
5833 fly(dom).afterFx({});
5835 arguments.callee.anim = {
5839 fly(dom).afterFx({});
5847 fadeIn : function(o){
5851 to = o.endOpacity || 1;
5853 me.queueFx(o, function(){
5854 fly(dom).setOpacity(0);
5855 fly(dom).fixDisplay();
5856 dom.style.visibility = VISIBLE;
5857 arguments.callee.anim = fly(dom).fxanim({opacity:{to:to}},
5858 o, NULL, .5, EASEOUT, function(){
5860 fly(dom).clearOpacity();
5862 fly(dom).afterFx(o);
5869 fadeOut : function(o){
5874 to = o.endOpacity || 0;
5876 me.queueFx(o, function(){
5877 arguments.callee.anim = fly(dom).fxanim({
5878 opacity : {to : to}},
5885 Ext.Element.data(dom, 'visibilityMode') == Ext.Element.DISPLAY || o.useDisplay ?
5886 style.display = "none" :
5887 style.visibility = HIDDEN;
5889 fly(dom).clearOpacity();
5891 fly(dom).afterFx(o);
5898 scale : function(w, h, o){
5899 this.shift(Ext.apply({}, o, {
5907 shift : function(o){
5912 this.queueFx(o, function(){
5913 for (var prop in o) {
5914 if (o[prop] != UNDEFINED) {
5915 a[prop] = {to : o[prop]};
5919 a.width ? a.width.to = fly(dom).adjustWidth(o.width) : a;
5920 a.height ? a.height.to = fly(dom).adjustWidth(o.height) : a;
5922 if (a.x || a.y || a.xy) {
5924 {to : [ a.x ? a.x.to : fly(dom).getX(),
5925 a.y ? a.y.to : fly(dom).getY()]};
5928 arguments.callee.anim = fly(dom).fxanim(a,
5934 fly(dom).afterFx(o);
5941 ghost : function(anchor, o){
5946 a = {opacity: {to: 0}, points: {}},
5952 anchor = anchor || "b";
5954 me.queueFx(o, function(){
5956 r = fly(dom).getFxRestore();
5957 w = fly(dom).getWidth();
5958 h = fly(dom).getHeight();
5961 o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();
5962 fly(dom).clearOpacity();
5963 fly(dom).setPositioning(r.pos);
5965 st.height = r.height;
5966 fly(dom).afterFx(o);
5969 pt.by = fly(dom).switchStatements(anchor.toLowerCase(), function(v1,v2){ return [v1, v2];}, {
5980 arguments.callee.anim = fly(dom).fxanim(a,
5990 syncFx : function(){
5992 me.fxDefaults = Ext.apply(me.fxDefaults || {}, {
6001 sequenceFx : function(){
6003 me.fxDefaults = Ext.apply(me.fxDefaults || {}, {
6012 nextFx : function(){
6013 var ef = getQueue(this.dom.id)[0];
6020 hasActiveFx : function(){
6021 return getQueue(this.dom.id)[0];
6025 stopFx : function(finish){
6028 if(me.hasActiveFx()){
6029 var cur = getQueue(id)[0];
6030 if(cur && cur.anim){
6031 if(cur.anim.isAnimated){
6032 setQueue(id, [cur]);
6033 cur.anim.stop(finish !== undefined ? finish : TRUE);
6043 beforeFx : function(o){
6044 if(this.hasActiveFx() && !o.concurrent){
6055 hasFxBlock : function(){
6056 var q = getQueue(this.dom.id);
6057 return q && q[0] && q[0].block;
6061 queueFx : function(o, fn){
6062 var me = fly(this.dom);
6063 if(!me.hasFxBlock()){
6064 Ext.applyIf(o, me.fxDefaults);
6066 var run = me.beforeFx(o);
6068 getQueue(me.dom.id).push(fn);
6080 fxWrap : function(pos, o, vis){
6084 if(!o.wrap || !(wrap = Ext.getDom(o.wrap))){
6086 wrapXY = fly(dom).getXY();
6088 var div = document.createElement("div");
6089 div.style.visibility = vis;
6090 wrap = dom.parentNode.insertBefore(div, dom);
6091 fly(wrap).setPositioning(pos);
6092 if(fly(wrap).isStyle(POSITION, "static")){
6093 fly(wrap).position("relative");
6095 fly(dom).clearPositioning('auto');
6097 wrap.appendChild(dom);
6099 fly(wrap).setXY(wrapXY);
6106 fxUnwrap : function(wrap, pos, o){
6108 fly(dom).clearPositioning();
6109 fly(dom).setPositioning(pos);
6111 var pn = fly(wrap).dom.parentNode;
6112 pn.insertBefore(dom, wrap);
6118 getFxRestore : function(){
6119 var st = this.dom.style;
6120 return {pos: this.getPositioning(), width: st.width, height : st.height};
6124 afterFx : function(o){
6128 fly(dom).setStyle(o.afterStyle);
6131 fly(dom).addClass(o.afterCls);
6133 if(o.remove == TRUE){
6137 o.callback.call(o.scope, fly(dom));
6140 getQueue(id).shift();
6146 fxanim : function(args, opt, animType, defaultDur, defaultEase, cb){
6147 animType = animType || 'run';
6149 var anim = Ext.lib.Anim[animType](
6152 (opt.duration || defaultDur) || .35,
6153 (opt.easing || defaultEase) || EASEOUT,
6163 Ext.Fx.resize = Ext.Fx.scale;
6167 Ext.Element.addMethods(Ext.Fx);
6170 Ext.CompositeElementLite = function(els, root){
6173 this.add(els, root);
6174 this.el = new Ext.Element.Flyweight();
6177 Ext.CompositeElementLite.prototype = {
6181 getElement : function(el){
6190 transformElement : function(el){
6191 return Ext.getDom(el);
6195 getCount : function(){
6196 return this.elements.length;
6199 add : function(els, root){
6201 elements = me.elements;
6205 if(typeof els == "string"){
6206 els = Ext.Element.selectorFunction(els, root);
6207 }else if(els.isComposite){
6209 }else if(!Ext.isIterable(els)){
6213 for(var i = 0, len = els.length; i < len; ++i){
6214 elements.push(me.transformElement(els[i]));
6219 invoke : function(fn, args){
6226 for(i = 0; i < len; i++) {
6229 Ext.Element.prototype[fn].apply(me.getElement(e), args);
6235 item : function(index){
6237 el = me.elements[index],
6241 out = me.getElement(el);
6247 addListener : function(eventName, handler, scope, opt){
6248 var els = this.elements,
6252 for(i = 0; i<len; i++) {
6255 Ext.EventManager.on(e, eventName, handler, scope || e, opt);
6261 each : function(fn, scope){
6267 for(i = 0; i<len; i++) {
6270 e = this.getElement(e);
6271 if(fn.call(scope || e, e, me, i) === false){
6280 fill : function(els){
6288 filter : function(selector){
6291 elements = me.elements,
6292 fn = Ext.isFunction(selector) ? selector
6294 return el.is(selector);
6298 me.each(function(el, self, i){
6299 if(fn(el, i) !== false){
6300 els[els.length] = me.transformElement(el);
6308 indexOf : function(el){
6309 return this.elements.indexOf(this.transformElement(el));
6313 replaceElement : function(el, replacement, domReplace){
6314 var index = !isNaN(el) ? el : this.indexOf(el),
6317 replacement = Ext.getDom(replacement);
6319 d = this.elements[index];
6320 d.parentNode.insertBefore(replacement, d);
6323 this.elements.splice(index, 1, replacement);
6334 Ext.CompositeElementLite.prototype.on = Ext.CompositeElementLite.prototype.addListener;
6338 ElProto = Ext.Element.prototype,
6339 CelProto = Ext.CompositeElementLite.prototype;
6341 for(fnName in ElProto){
6342 if(Ext.isFunction(ElProto[fnName])){
6344 CelProto[fnName] = CelProto[fnName] || function(){
6345 return this.invoke(fnName, arguments);
6347 }).call(CelProto, fnName);
6354 Ext.Element.selectorFunction = Ext.DomQuery.select;
6358 Ext.Element.select = function(selector, root){
6360 if(typeof selector == "string"){
6361 els = Ext.Element.selectorFunction(selector, root);
6362 }else if(selector.length !== undefined){
6365 throw "Invalid selector";
6367 return new Ext.CompositeElementLite(els);
6370 Ext.select = Ext.Element.select;
6372 Ext.apply(Ext.CompositeElementLite.prototype, {
6373 addElements : function(els, root){
6377 if(typeof els == "string"){
6378 els = Ext.Element.selectorFunction(els, root);
6380 var yels = this.elements;
6381 Ext.each(els, function(e) {
6382 yels.push(Ext.get(e));
6389 return this.item(0);
6394 return this.item(this.getCount()-1);
6398 contains : function(el){
6399 return this.indexOf(el) != -1;
6403 removeElement : function(keys, removeDom){
6405 els = this.elements,
6407 Ext.each(keys, function(val){
6408 if ((el = (els[val] || els[val = me.indexOf(val)]))) {
6423 Ext.CompositeElement = Ext.extend(Ext.CompositeElementLite, {
6425 constructor : function(els, root){
6427 this.add(els, root);
6431 getElement : function(el){
6437 transformElement : function(el){
6449 Ext.Element.select = function(selector, unique, root){
6451 if(typeof selector == "string"){
6452 els = Ext.Element.selectorFunction(selector, root);
6453 }else if(selector.length !== undefined){
6456 throw "Invalid selector";
6459 return (unique === true) ? new Ext.CompositeElement(els) : new Ext.CompositeElementLite(els);
6463 Ext.select = Ext.Element.select;(function(){
6464 var BEFOREREQUEST = "beforerequest",
6465 REQUESTCOMPLETE = "requestcomplete",
6466 REQUESTEXCEPTION = "requestexception",
6467 UNDEFINED = undefined,
6474 Ext.data.Connection = function(config){
6475 Ext.apply(this, config);
6484 Ext.data.Connection.superclass.constructor.call(this);
6487 Ext.extend(Ext.data.Connection, Ext.util.Observable, {
6498 disableCaching: true,
6501 disableCachingParam: '_dc',
6504 request : function(o){
6506 if(me.fireEvent(BEFOREREQUEST, me, o)){
6508 if(!Ext.isEmpty(o.indicatorText)){
6509 me.indicatorText = '<div class="loading-indicator">'+o.indicatorText+"</div>";
6511 if(me.indicatorText) {
6512 Ext.getDom(o.el).innerHTML = me.indicatorText;
6514 o.success = (Ext.isFunction(o.success) ? o.success : function(){}).createInterceptor(function(response) {
6515 Ext.getDom(o.el).innerHTML = response.responseText;
6520 url = o.url || me.url,
6522 cb = {success: me.handleResponse,
6523 failure: me.handleFailure,
6525 argument: {options: o},
6526 timeout : o.timeout || me.timeout
6532 if (Ext.isFunction(p)) {
6533 p = p.call(o.scope||WINDOW, o);
6536 p = Ext.urlEncode(me.extraParams, Ext.isObject(p) ? Ext.urlEncode(p) : p);
6538 if (Ext.isFunction(url)) {
6539 url = url.call(o.scope || WINDOW, o);
6542 if((form = Ext.getDom(o.form))){
6543 url = url || form.action;
6544 if(o.isUpload || /multipart\/form-data/i.test(form.getAttribute("enctype"))) {
6545 return me.doFormUpload.call(me, o, p, url);
6547 serForm = Ext.lib.Ajax.serializeForm(form);
6548 p = p ? (p + '&' + serForm) : serForm;
6551 method = o.method || me.method || ((p || o.xmlData || o.jsonData) ? POST : GET);
6553 if(method === GET && (me.disableCaching && o.disableCaching !== false) || o.disableCaching === true){
6554 var dcp = o.disableCachingParam || me.disableCachingParam;
6555 url = Ext.urlAppend(url, dcp + '=' + (new Date().getTime()));
6558 o.headers = Ext.apply(o.headers || {}, me.defaultHeaders || {});
6560 if(o.autoAbort === true || me.autoAbort) {
6564 if((method == GET || o.xmlData || o.jsonData) && p){
6565 url = Ext.urlAppend(url, p);
6568 return (me.transId = Ext.lib.Ajax.request(method, url, cb, p, o));
6570 return o.callback ? o.callback.apply(o.scope, [o,UNDEFINED,UNDEFINED]) : null;
6575 isLoading : function(transId){
6576 return transId ? Ext.lib.Ajax.isCallInProgress(transId) : !! this.transId;
6580 abort : function(transId){
6581 if(transId || this.isLoading()){
6582 Ext.lib.Ajax.abort(transId || this.transId);
6587 handleResponse : function(response){
6588 this.transId = false;
6589 var options = response.argument.options;
6590 response.argument = options ? options.argument : null;
6591 this.fireEvent(REQUESTCOMPLETE, this, response, options);
6592 if(options.success){
6593 options.success.call(options.scope, response, options);
6595 if(options.callback){
6596 options.callback.call(options.scope, options, true, response);
6601 handleFailure : function(response, e){
6602 this.transId = false;
6603 var options = response.argument.options;
6604 response.argument = options ? options.argument : null;
6605 this.fireEvent(REQUESTEXCEPTION, this, response, options, e);
6606 if(options.failure){
6607 options.failure.call(options.scope, response, options);
6609 if(options.callback){
6610 options.callback.call(options.scope, options, false, response);
6615 doFormUpload : function(o, ps, url){
6618 frame = doc.createElement('iframe'),
6619 form = Ext.getDom(o.form),
6622 encoding = 'multipart/form-data',
6624 target: form.target,
6625 method: form.method,
6626 encoding: form.encoding,
6627 enctype: form.enctype,
6632 Ext.fly(frame).set({
6636 src: Ext.SSL_SECURE_URL
6639 doc.body.appendChild(frame);
6643 document.frames[id].name = id;
6652 action: url || buf.action
6656 Ext.iterate(Ext.urlDecode(ps, false), function(k, v){
6657 hd = doc.createElement('input');
6663 form.appendChild(hd);
6670 r = {responseText : '',
6672 argument : o.argument},
6677 doc = frame.contentWindow.document || frame.contentDocument || WINDOW.frames[id].document;
6680 if(/textarea/i.test((firstChild = doc.body.firstChild || {}).tagName)){
6681 r.responseText = firstChild.value;
6683 r.responseText = doc.body.innerHTML;
6687 r.responseXML = doc.XMLDocument || doc;
6692 Ext.EventManager.removeListener(frame, LOAD, cb, me);
6694 me.fireEvent(REQUESTCOMPLETE, me, r, o);
6696 function runCallback(fn, scope, args){
6697 if(Ext.isFunction(fn)){
6698 fn.apply(scope, args);
6702 runCallback(o.success, o.scope, [r, o]);
6703 runCallback(o.callback, o.scope, [o, true, r]);
6705 if(!me.debugUploads){
6706 setTimeout(function(){Ext.removeNode(frame);}, 100);
6710 Ext.EventManager.on(frame, LOAD, cb, this);
6713 Ext.fly(form).set(buf);
6714 Ext.each(hiddens, function(h) {
6722 Ext.Ajax = new Ext.data.Connection({
6743 serializeForm : function(form){
6744 return Ext.lib.Ajax.serializeForm(form);
6748 Ext.UpdateManager = Ext.Updater = Ext.extend(Ext.util.Observable,
6750 var BEFOREUPDATE = "beforeupdate",
6752 FAILURE = "failure";
6755 function processSuccess(response){
6757 me.transaction = null;
6758 if (response.argument.form && response.argument.reset) {
6760 response.argument.form.reset();
6763 if (me.loadScripts) {
6764 me.renderer.render(me.el, response, me,
6765 updateComplete.createDelegate(me, [response]));
6767 me.renderer.render(me.el, response, me);
6768 updateComplete.call(me, response);
6773 function updateComplete(response, type, success){
6774 this.fireEvent(type || UPDATE, this.el, response);
6775 if(Ext.isFunction(response.argument.callback)){
6776 response.argument.callback.call(response.argument.scope, this.el, Ext.isEmpty(success) ? true : false, response, response.argument.options);
6781 function processFailure(response){
6782 updateComplete.call(this, response, FAILURE, !!(this.transaction = null));
6786 constructor: function(el, forceNew){
6789 if(!forceNew && el.updateManager){
6790 return el.updateManager;
6795 me.defaultUrl = null;
6806 Ext.apply(me, Ext.Updater.defaults);
6815 me.transaction = null;
6817 me.refreshDelegate = me.refresh.createDelegate(me);
6819 me.updateDelegate = me.update.createDelegate(me);
6821 me.formUpdateDelegate = (me.formUpdate || function(){}).createDelegate(me);
6824 me.renderer = me.renderer || me.getDefaultRenderer();
6826 Ext.Updater.superclass.constructor.call(me);
6830 setRenderer : function(renderer){
6831 this.renderer = renderer;
6835 getRenderer : function(){
6836 return this.renderer;
6840 getDefaultRenderer: function() {
6841 return new Ext.Updater.BasicRenderer();
6845 setDefaultUrl : function(defaultUrl){
6846 this.defaultUrl = defaultUrl;
6855 update : function(url, params, callback, discardUrl){
6860 if(me.fireEvent(BEFOREUPDATE, me.el, url, params) !== false){
6861 if(Ext.isObject(url)){
6864 params = params || cfg.params;
6865 callback = callback || cfg.callback;
6866 discardUrl = discardUrl || cfg.discardUrl;
6867 callerScope = cfg.scope;
6868 if(!Ext.isEmpty(cfg.nocache)){me.disableCaching = cfg.nocache;};
6869 if(!Ext.isEmpty(cfg.text)){me.indicatorText = '<div class="loading-indicator">'+cfg.text+"</div>";};
6870 if(!Ext.isEmpty(cfg.scripts)){me.loadScripts = cfg.scripts;};
6871 if(!Ext.isEmpty(cfg.timeout)){me.timeout = cfg.timeout;};
6876 me.defaultUrl = url;
6878 if(Ext.isFunction(url)){
6882 var o = Ext.apply({}, {
6884 params: (Ext.isFunction(params) && callerScope) ? params.createDelegate(callerScope) : params,
6885 success: processSuccess,
6886 failure: processFailure,
6888 callback: undefined,
6889 timeout: (me.timeout*1000),
6890 disableCaching: me.disableCaching,
6895 "callback": callback,
6896 "scope": callerScope || window,
6901 me.transaction = Ext.Ajax.request(o);
6906 formUpdate : function(form, url, reset, callback){
6908 if(me.fireEvent(BEFOREUPDATE, me.el, form, url) !== false){
6909 if(Ext.isFunction(url)){
6912 form = Ext.getDom(form);
6913 me.transaction = Ext.Ajax.request({
6916 success: processSuccess,
6917 failure: processFailure,
6919 timeout: (me.timeout*1000),
6923 "callback": callback,
6927 me.showLoading.defer(1, me);
6932 startAutoRefresh : function(interval, url, params, callback, refreshNow){
6935 me.update(url || me.defaultUrl, params, callback, true);
6937 if(me.autoRefreshProcId){
6938 clearInterval(me.autoRefreshProcId);
6940 me.autoRefreshProcId = setInterval(me.update.createDelegate(me, [url || me.defaultUrl, params, callback, true]), interval * 1000);
6944 stopAutoRefresh : function(){
6945 if(this.autoRefreshProcId){
6946 clearInterval(this.autoRefreshProcId);
6947 delete this.autoRefreshProcId;
6952 isAutoRefreshing : function(){
6953 return !!this.autoRefreshProcId;
6957 showLoading : function(){
6958 if(this.showLoadIndicator){
6959 this.el.dom.innerHTML = this.indicatorText;
6965 if(this.transaction){
6966 Ext.Ajax.abort(this.transaction);
6971 isUpdating : function(){
6972 return this.transaction ? Ext.Ajax.isLoading(this.transaction) : false;
6976 refresh : function(callback){
6977 if(this.defaultUrl){
6978 this.update(this.defaultUrl, null, callback, true);
6985 Ext.Updater.defaults = {
6989 disableCaching : false,
6991 showLoadIndicator : true,
6993 indicatorText : '<div class="loading-indicator">Loading...</div>',
6995 loadScripts : false,
6997 sslBlankUrl : Ext.SSL_SECURE_URL
7002 Ext.Updater.updateElement = function(el, url, params, options){
7003 var um = Ext.get(el).getUpdater();
7004 Ext.apply(um, options);
7005 um.update(url, params, options ? options.callback : null);
7009 Ext.Updater.BasicRenderer = function(){};
7011 Ext.Updater.BasicRenderer.prototype = {
7013 render : function(el, response, updateManager, callback){
7014 el.update(response.responseText, updateManager.loadScripts, callback);
7023 Date.useStrict = false;
7029 function xf(format) {
7030 var args = Array.prototype.slice.call(arguments, 1);
7031 return format.replace(/\{(\d+)\}/g, function(m, i) {
7038 Date.formatCodeToRegex = function(character, currentGroup) {
7040 var p = Date.parseCodes[character];
7043 p = typeof p == 'function'? p() : p;
7044 Date.parseCodes[character] = p;
7047 return p ? Ext.applyIf({
7048 c: p.c ? xf(p.c, currentGroup || "{0}") : p.c
7052 s:Ext.escapeRe(character)
7057 var $f = Date.formatCodeToRegex;
7062 "M$": function(input, strict) {
7065 var re = new RegExp('\\/Date\\(([-+])?(\\d+)(?:[+-]\\d{4})?\\)\\/');
7066 var r = (input || '').match(re);
7067 return r? new Date(((r[1] || '') + r[2]) * 1) : null;
7076 return '\\/Date(' + this.getTime() + ')\\/';
7150 getShortMonthName : function(month) {
7151 return Date.monthNames[month].substring(0, 3);
7155 getShortDayName : function(day) {
7156 return Date.dayNames[day].substring(0, 3);
7160 getMonthNumber : function(name) {
7162 return Date.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()];
7167 d: "String.leftPad(this.getDate(), 2, '0')",
7168 D: "Date.getShortDayName(this.getDay())",
7169 j: "this.getDate()",
7170 l: "Date.dayNames[this.getDay()]",
7171 N: "(this.getDay() ? this.getDay() : 7)",
7172 S: "this.getSuffix()",
7174 z: "this.getDayOfYear()",
7175 W: "String.leftPad(this.getWeekOfYear(), 2, '0')",
7176 F: "Date.monthNames[this.getMonth()]",
7177 m: "String.leftPad(this.getMonth() + 1, 2, '0')",
7178 M: "Date.getShortMonthName(this.getMonth())",
7179 n: "(this.getMonth() + 1)",
7180 t: "this.getDaysInMonth()",
7181 L: "(this.isLeapYear() ? 1 : 0)",
7182 o: "(this.getFullYear() + (this.getWeekOfYear() == 1 && this.getMonth() > 0 ? +1 : (this.getWeekOfYear() >= 52 && this.getMonth() < 11 ? -1 : 0)))",
7183 Y: "this.getFullYear()",
7184 y: "('' + this.getFullYear()).substring(2, 4)",
7185 a: "(this.getHours() < 12 ? 'am' : 'pm')",
7186 A: "(this.getHours() < 12 ? 'AM' : 'PM')",
7187 g: "((this.getHours() % 12) ? this.getHours() % 12 : 12)",
7188 G: "this.getHours()",
7189 h: "String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0')",
7190 H: "String.leftPad(this.getHours(), 2, '0')",
7191 i: "String.leftPad(this.getMinutes(), 2, '0')",
7192 s: "String.leftPad(this.getSeconds(), 2, '0')",
7193 u: "String.leftPad(this.getMilliseconds(), 3, '0')",
7194 O: "this.getGMTOffset()",
7195 P: "this.getGMTOffset(true)",
7196 T: "this.getTimezone()",
7197 Z: "(this.getTimezoneOffset() * -60)",
7200 for (var c = "Y-m-dTH:i:sP", code = [], i = 0, l = c.length; i < l; ++i) {
7201 var e = c.charAt(i);
7202 code.push(e == "T" ? "'T'" : Date.getFormatCode(e));
7204 return code.join(" + ");
7208 U: "Math.round(this.getTime() / 1000)"
7212 isValid : function(y, m, d, h, i, s, ms) {
7219 var dt = new Date(y, m - 1, d, h, i, s, ms);
7221 return y == dt.getFullYear() &&
7222 m == dt.getMonth() + 1 &&
7223 d == dt.getDate() &&
7224 h == dt.getHours() &&
7225 i == dt.getMinutes() &&
7226 s == dt.getSeconds() &&
7227 ms == dt.getMilliseconds();
7231 parseDate : function(input, format, strict) {
7232 var p = Date.parseFunctions;
7233 if (p[format] == null) {
7234 Date.createParser(format);
7236 return p[format](input, Ext.isDefined(strict) ? strict : Date.useStrict);
7240 getFormatCode : function(character) {
7241 var f = Date.formatCodes[character];
7244 f = typeof f == 'function'? f() : f;
7245 Date.formatCodes[character] = f;
7249 return f || ("'" + String.escape(character) + "'");
7253 createFormat : function(format) {
7258 for (var i = 0; i < format.length; ++i) {
7259 ch = format.charAt(i);
7260 if (!special && ch == "\\") {
7262 } else if (special) {
7264 code.push("'" + String.escape(ch) + "'");
7266 code.push(Date.getFormatCode(ch))
7269 Date.formatFunctions[format] = new Function("return " + code.join('+'));
7273 createParser : function() {
7275 "var dt, y, m, d, h, i, s, ms, o, z, zz, u, v,",
7276 "def = Date.defaults,",
7277 "results = String(input).match(Date.parseRegexes[{0}]);",
7283 "v = new Date(u * 1000);",
7288 "dt = (new Date()).clearTime();",
7291 "y = Ext.num(y, Ext.num(def.y, dt.getFullYear()));",
7292 "m = Ext.num(m, Ext.num(def.m - 1, dt.getMonth()));",
7293 "d = Ext.num(d, Ext.num(def.d, dt.getDate()));",
7296 "h = Ext.num(h, Ext.num(def.h, dt.getHours()));",
7297 "i = Ext.num(i, Ext.num(def.i, dt.getMinutes()));",
7298 "s = Ext.num(s, Ext.num(def.s, dt.getSeconds()));",
7299 "ms = Ext.num(ms, Ext.num(def.ms, dt.getMilliseconds()));",
7301 "if(z >= 0 && y >= 0){",
7306 "v = new Date(y, 0, 1, h, i, s, ms);",
7309 "v = !strict? v : (strict === true && (z <= 364 || (v.isLeapYear() && z <= 365))? v.add(Date.DAY, z) : null);",
7310 "}else if(strict === true && !Date.isValid(y, m + 1, d, h, i, s, ms)){",
7314 "v = new Date(y, m, d, h, i, s, ms);",
7323 "v = v.add(Date.SECOND, -v.getTimezoneOffset() * 60 - zz);",
7326 "v = v.add(Date.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));",
7333 return function(format) {
7334 var regexNum = Date.parseRegexes.length,
7341 for (var i = 0; i < format.length; ++i) {
7342 ch = format.charAt(i);
7343 if (!special && ch == "\\") {
7345 } else if (special) {
7347 regex.push(String.escape(ch));
7349 var obj = $f(ch, currentGroup);
7350 currentGroup += obj.g;
7352 if (obj.g && obj.c) {
7358 Date.parseRegexes[regexNum] = new RegExp("^" + regex.join('') + "$");
7359 Date.parseFunctions[format] = new Function("input", "strict", xf(code, regexNum, calc.join('')));
7368 c:"d = parseInt(results[{0}], 10);\n",
7373 c:"d = parseInt(results[{0}], 10);\n",
7377 for (var a = [], i = 0; i < 7; a.push(Date.getShortDayName(i)), ++i);
7381 s:"(?:" + a.join("|") +")"
7388 s:"(?:" + Date.dayNames.join("|") + ")"
7408 c:"z = parseInt(results[{0}], 10);\n",
7419 c:"m = parseInt(Date.getMonthNumber(results[{0}]), 10);\n",
7420 s:"(" + Date.monthNames.join("|") + ")"
7424 for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i);
7425 return Ext.applyIf({
7426 s:"(" + a.join("|") + ")"
7431 c:"m = parseInt(results[{0}], 10) - 1;\n",
7436 c:"m = parseInt(results[{0}], 10) - 1;\n",
7454 c:"y = parseInt(results[{0}], 10);\n",
7459 c:"var ty = parseInt(results[{0}], 10);\n"
7460 + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n",
7465 c:"if (results[{0}] == 'am') {\n"
7466 + "if (!h || h == 12) { h = 0; }\n"
7467 + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",
7472 c:"if (results[{0}] == 'AM') {\n"
7473 + "if (!h || h == 12) { h = 0; }\n"
7474 + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",
7482 c:"h = parseInt(results[{0}], 10);\n",
7490 c:"h = parseInt(results[{0}], 10);\n",
7495 c:"i = parseInt(results[{0}], 10);\n",
7500 c:"s = parseInt(results[{0}], 10);\n",
7505 c:"ms = results[{0}]; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n",
7511 "o = results[{0}];",
7512 "var sn = o.substring(0,1),",
7513 "hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60),",
7514 "mn = o.substring(3,5) % 60;",
7515 "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"
7522 "o = results[{0}];",
7523 "var sn = o.substring(0,1),",
7524 "hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60),",
7525 "mn = o.substring(4,6) % 60;",
7526 "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"
7528 s: "([+\-]\\d{2}:\\d{2})"
7537 c:"zz = results[{0}] * 1;\n"
7538 + "zz = (-43200 <= zz && zz <= 50400)? zz : null;\n",
7539 s:"([+\-]?\\d{1,5})"
7550 {c:"ms = results[7] || '0'; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n"},
7553 "if(results[8] == 'Z'){",
7555 "}else if (results[8].indexOf(':') > -1){",
7564 for (var i = 0, l = arr.length; i < l; ++i) {
7565 calc.push(arr[i].c);
7573 "(?:", "-", arr[1].s,
7574 "(?:", "-", arr[2].s,
7577 arr[3].s, ":", arr[4].s,
7578 "(?::", arr[5].s, ")?",
7579 "(?:(?:\\.|,)(\\d+))?",
7580 "(Z|(?:[-+]\\d{2}(?::)?\\d{2}))?",
7589 c:"u = parseInt(results[{0}], 10);\n",
7597 Ext.apply(Date.prototype, {
7599 dateFormat : function(format) {
7600 if (Date.formatFunctions[format] == null) {
7601 Date.createFormat(format);
7603 return Date.formatFunctions[format].call(this);
7607 getTimezone : function() {
7620 return this.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, "");
7624 getGMTOffset : function(colon) {
7625 return (this.getTimezoneOffset() > 0 ? "-" : "+")
7626 + String.leftPad(Math.floor(Math.abs(this.getTimezoneOffset()) / 60), 2, "0")
7627 + (colon ? ":" : "")
7628 + String.leftPad(Math.abs(this.getTimezoneOffset() % 60), 2, "0");
7632 getDayOfYear: function() {
7635 m = this.getMonth(),
7638 for (i = 0, d.setDate(1), d.setMonth(0); i < m; d.setMonth(++i)) {
7639 num += d.getDaysInMonth();
7641 return num + this.getDate() - 1;
7645 getWeekOfYear : function() {
7651 var DC3 = Date.UTC(this.getFullYear(), this.getMonth(), this.getDate() + 3) / ms1d,
7652 AWN = Math.floor(DC3 / 7),
7653 Wyr = new Date(AWN * ms7d).getUTCFullYear();
7655 return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
7660 isLeapYear : function() {
7661 var year = this.getFullYear();
7662 return !!((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
7666 getFirstDayOfMonth : function() {
7667 var day = (this.getDay() - (this.getDate() - 1)) % 7;
7668 return (day < 0) ? (day + 7) : day;
7672 getLastDayOfMonth : function() {
7673 return this.getLastDateOfMonth().getDay();
7678 getFirstDateOfMonth : function() {
7679 return new Date(this.getFullYear(), this.getMonth(), 1);
7683 getLastDateOfMonth : function() {
7684 return new Date(this.getFullYear(), this.getMonth(), this.getDaysInMonth());
7688 getDaysInMonth: function() {
7689 var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
7692 var m = this.getMonth();
7694 return m == 1 && this.isLeapYear() ? 29 : daysInMonth[m];
7699 getSuffix : function() {
7700 switch (this.getDate()) {
7717 clone : function() {
7718 return new Date(this.getTime());
7722 isDST : function() {
7725 return new Date(this.getFullYear(), 0, 1).getTimezoneOffset() != this.getTimezoneOffset();
7729 clearTime : function(clone) {
7731 return this.clone().clearTime();
7735 var d = this.getDate();
7741 this.setMilliseconds(0);
7743 if (this.getDate() != d) {
7748 for (var hr = 1, c = this.add(Date.HOUR, hr); c.getDate() != d; hr++, c = this.add(Date.HOUR, hr));
7751 this.setHours(c.getHours());
7758 add : function(interval, value) {
7759 var d = this.clone();
7760 if (!interval || value === 0) return d;
7762 switch(interval.toLowerCase()) {
7764 d.setMilliseconds(this.getMilliseconds() + value);
7767 d.setSeconds(this.getSeconds() + value);
7770 d.setMinutes(this.getMinutes() + value);
7773 d.setHours(this.getHours() + value);
7776 d.setDate(this.getDate() + value);
7779 var day = this.getDate();
7781 day = Math.min(day, this.getFirstDateOfMonth().add('mo', value).getLastDateOfMonth().getDate());
7784 d.setMonth(this.getMonth() + value);
7787 d.setFullYear(this.getFullYear() + value);
7794 between : function(start, end) {
7795 var t = this.getTime();
7796 return start.getTime() <= t && t <= end.getTime();
7802 Date.prototype.format = Date.prototype.dateFormat;
7806 if (Ext.isSafari && (navigator.userAgent.match(/WebKit\/(\d+)/)[1] || NaN) < 420) {
7807 Ext.apply(Date.prototype, {
7808 _xMonth : Date.prototype.setMonth,
7809 _xDate : Date.prototype.setDate,
7813 setMonth : function(num) {
7815 var n = Math.ceil(-num),
7816 back_year = Math.ceil(n / 12),
7817 month = (n % 12) ? 12 - n % 12 : 0;
7819 this.setFullYear(this.getFullYear() - back_year);
7821 return this._xMonth(month);
7823 return this._xMonth(num);
7830 setDate : function(d) {
7833 return this.setTime(this.getTime() - (this.getDate() - d) * 864e5);
7842 Ext.util.MixedCollection = function(allowFunctions, keyFn){
7858 this.allowFunctions = allowFunctions === true;
7860 this.getKey = keyFn;
7862 Ext.util.MixedCollection.superclass.constructor.call(this);
7865 Ext.extend(Ext.util.MixedCollection, Ext.util.Observable, {
7868 allowFunctions : false,
7871 add : function(key, o){
7872 if(arguments.length == 1){
7874 key = this.getKey(o);
7876 if(typeof key != 'undefined' && key !== null){
7877 var old = this.map[key];
7878 if(typeof old != 'undefined'){
7879 return this.replace(key, o);
7885 this.keys.push(key);
7886 this.fireEvent('add', this.length-1, o, key);
7891 getKey : function(o){
7896 replace : function(key, o){
7897 if(arguments.length == 1){
7899 key = this.getKey(o);
7901 var old = this.map[key];
7902 if(typeof key == 'undefined' || key === null || typeof old == 'undefined'){
7903 return this.add(key, o);
7905 var index = this.indexOfKey(key);
7906 this.items[index] = o;
7908 this.fireEvent('replace', key, old, o);
7913 addAll : function(objs){
7914 if(arguments.length > 1 || Ext.isArray(objs)){
7915 var args = arguments.length > 1 ? arguments : objs;
7916 for(var i = 0, len = args.length; i < len; i++){
7920 for(var key in objs){
7921 if(this.allowFunctions || typeof objs[key] != 'function'){
7922 this.add(key, objs[key]);
7929 each : function(fn, scope){
7930 var items = [].concat(this.items);
7931 for(var i = 0, len = items.length; i < len; i++){
7932 if(fn.call(scope || items[i], items[i], i, len) === false){
7939 eachKey : function(fn, scope){
7940 for(var i = 0, len = this.keys.length; i < len; i++){
7941 fn.call(scope || window, this.keys[i], this.items[i], i, len);
7946 find : function(fn, scope){
7947 for(var i = 0, len = this.items.length; i < len; i++){
7948 if(fn.call(scope || window, this.items[i], this.keys[i])){
7949 return this.items[i];
7956 insert : function(index, key, o){
7957 if(arguments.length == 2){
7959 key = this.getKey(o);
7961 if(this.containsKey(key)){
7962 this.suspendEvents();
7963 this.removeKey(key);
7964 this.resumeEvents();
7966 if(index >= this.length){
7967 return this.add(key, o);
7970 this.items.splice(index, 0, o);
7971 if(typeof key != 'undefined' && key !== null){
7974 this.keys.splice(index, 0, key);
7975 this.fireEvent('add', index, o, key);
7980 remove : function(o){
7981 return this.removeAt(this.indexOf(o));
7985 removeAt : function(index){
7986 if(index < this.length && index >= 0){
7988 var o = this.items[index];
7989 this.items.splice(index, 1);
7990 var key = this.keys[index];
7991 if(typeof key != 'undefined'){
7992 delete this.map[key];
7994 this.keys.splice(index, 1);
7995 this.fireEvent('remove', o, key);
8002 removeKey : function(key){
8003 return this.removeAt(this.indexOfKey(key));
8007 getCount : function(){
8012 indexOf : function(o){
8013 return this.items.indexOf(o);
8017 indexOfKey : function(key){
8018 return this.keys.indexOf(key);
8022 item : function(key){
8023 var mk = this.map[key],
8024 item = mk !== undefined ? mk : (typeof key == 'number') ? this.items[key] : undefined;
8025 return typeof item != 'function' || this.allowFunctions ? item : null;
8029 itemAt : function(index){
8030 return this.items[index];
8034 key : function(key){
8035 return this.map[key];
8039 contains : function(o){
8040 return this.indexOf(o) != -1;
8044 containsKey : function(key){
8045 return typeof this.map[key] != 'undefined';
8054 this.fireEvent('clear');
8059 return this.items[0];
8064 return this.items[this.length-1];
8068 _sort : function(property, dir, fn){
8070 dsc = String(dir).toUpperCase() == 'DESC' ? -1 : 1,
8078 fn = fn || function(a, b) {
8083 for(i = 0, len = items.length; i < len; i++){
8092 c.sort(function(a, b){
8093 var v = fn(a[property], b[property]) * dsc;
8095 v = (a.index < b.index ? -1 : 1);
8101 for(i = 0, len = c.length; i < len; i++){
8102 items[i] = c[i].value;
8106 this.fireEvent('sort', this);
8110 sort : function(dir, fn){
8111 this._sort('value', dir, fn);
8115 reorder: function(mapping) {
8116 this.suspendEvents();
8118 var items = this.items,
8120 length = items.length,
8125 for (oldIndex in mapping) {
8126 order[mapping[oldIndex]] = items[oldIndex];
8129 for (index = 0; index < length; index++) {
8130 if (mapping[index] == undefined) {
8131 remaining.push(items[index]);
8135 for (index = 0; index < length; index++) {
8136 if (order[index] == undefined) {
8137 order[index] = remaining.shift();
8144 this.resumeEvents();
8145 this.fireEvent('sort', this);
8149 keySort : function(dir, fn){
8150 this._sort('key', dir, fn || function(a, b){
8151 var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase();
8152 return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
8157 getRange : function(start, end){
8158 var items = this.items;
8159 if(items.length < 1){
8163 end = Math.min(typeof end == 'undefined' ? this.length-1 : end, this.length-1);
8166 for(i = start; i <= end; i++) {
8167 r[r.length] = items[i];
8170 for(i = start; i >= end; i--) {
8171 r[r.length] = items[i];
8178 filter : function(property, value, anyMatch, caseSensitive){
8179 if(Ext.isEmpty(value, false)){
8180 return this.clone();
8182 value = this.createValueMatcher(value, anyMatch, caseSensitive);
8183 return this.filterBy(function(o){
8184 return o && value.test(o[property]);
8189 filterBy : function(fn, scope){
8190 var r = new Ext.util.MixedCollection();
8191 r.getKey = this.getKey;
8192 var k = this.keys, it = this.items;
8193 for(var i = 0, len = it.length; i < len; i++){
8194 if(fn.call(scope||this, it[i], k[i])){
8202 findIndex : function(property, value, start, anyMatch, caseSensitive){
8203 if(Ext.isEmpty(value, false)){
8206 value = this.createValueMatcher(value, anyMatch, caseSensitive);
8207 return this.findIndexBy(function(o){
8208 return o && value.test(o[property]);
8213 findIndexBy : function(fn, scope, start){
8214 var k = this.keys, it = this.items;
8215 for(var i = (start||0), len = it.length; i < len; i++){
8216 if(fn.call(scope||this, it[i], k[i])){
8224 createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) {
8226 var er = Ext.escapeRe;
8227 value = String(value);
8229 if (anyMatch === true) {
8232 value = '^' + er(value);
8233 if (exactMatch === true) {
8237 value = new RegExp(value, caseSensitive ? '' : 'i');
8244 var r = new Ext.util.MixedCollection();
8245 var k = this.keys, it = this.items;
8246 for(var i = 0, len = it.length; i < len; i++){
8249 r.getKey = this.getKey;
8254 Ext.util.MixedCollection.prototype.get = Ext.util.MixedCollection.prototype.item;
8256 Ext.util.JSON = new (function(){
8257 var useHasOwn = !!{}.hasOwnProperty,
8258 isNative = function() {
8259 var useNative = null;
8262 if (useNative === null) {
8263 useNative = Ext.USE_NATIVE_JSON && window.JSON && JSON.toString() == '[object JSON]';
8270 return n < 10 ? "0" + n : n;
8272 doDecode = function(json){
8273 return eval("(" + json + ')');
8275 doEncode = function(o){
8276 if(!Ext.isDefined(o) || o === null){
8278 }else if(Ext.isArray(o)){
8279 return encodeArray(o);
8280 }else if(Ext.isDate(o)){
8281 return Ext.util.JSON.encodeDate(o);
8282 }else if(Ext.isString(o)){
8283 return encodeString(o);
8284 }else if(typeof o == "number"){
8286 return isFinite(o) ? String(o) : "null";
8287 }else if(Ext.isBoolean(o)){
8290 var a = ["{"], b, i, v;
8293 if(!o.getElementsByTagName){
8294 if(!useHasOwn || o.hasOwnProperty(i)) {
8305 a.push(doEncode(i), ":",
8306 v === null ? "null" : doEncode(v));
8325 encodeString = function(s){
8326 if (/["\\\x00-\x1f]/.test(s)) {
8327 return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) {
8334 Math.floor(c / 16).toString(16) +
8335 (c % 16).toString(16);
8338 return '"' + s + '"';
8340 encodeArray = function(o){
8341 var a = ["["], b, i, l = o.length, v;
8342 for (i = 0; i < l; i += 1) {
8353 a.push(v === null ? "null" : Ext.util.JSON.encode(v));
8362 this.encodeDate = function(o){
8363 return '"' + o.getFullYear() + "-" +
8364 pad(o.getMonth() + 1) + "-" +
8365 pad(o.getDate()) + "T" +
8366 pad(o.getHours()) + ":" +
8367 pad(o.getMinutes()) + ":" +
8368 pad(o.getSeconds()) + '"';
8372 this.encode = function() {
8374 return function(o) {
8377 ec = isNative() ? JSON.stringify : doEncode;
8385 this.decode = function() {
8387 return function(json) {
8390 dc = isNative() ? JSON.parse : doDecode;
8398 Ext.encode = Ext.util.JSON.encode;
8400 Ext.decode = Ext.util.JSON.decode;
8402 Ext.util.Format = function(){
8403 var trimRe = /^\s+|\s+$/g,
8404 stripTagsRE = /<\/?[^>]+>/gi,
8405 stripScriptsRe = /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,
8410 ellipsis : function(value, len, word){
8411 if(value && value.length > len){
8413 var vs = value.substr(0, len - 2),
8414 index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?'));
8415 if(index == -1 || index < (len - 15)){
8416 return value.substr(0, len - 3) + "...";
8418 return vs.substr(0, index) + "...";
8421 return value.substr(0, len - 3) + "...";
8428 undef : function(value){
8429 return value !== undefined ? value : "";
8433 defaultValue : function(value, defaultValue){
8434 return value !== undefined && value !== '' ? value : defaultValue;
8438 htmlEncode : function(value){
8439 return !value ? value : String(value).replace(/&/g, "&").replace(/>/g, ">").replace(/</g, "<").replace(/"/g, """);
8443 htmlDecode : function(value){
8444 return !value ? value : String(value).replace(/>/g, ">").replace(/</g, "<").replace(/"/g, '"').replace(/&/g, "&");
8448 trim : function(value){
8449 return String(value).replace(trimRe, "");
8453 substr : function(value, start, length){
8454 return String(value).substr(start, length);
8458 lowercase : function(value){
8459 return String(value).toLowerCase();
8463 uppercase : function(value){
8464 return String(value).toUpperCase();
8468 capitalize : function(value){
8469 return !value ? value : value.charAt(0).toUpperCase() + value.substr(1).toLowerCase();
8473 call : function(value, fn){
8474 if(arguments.length > 2){
8475 var args = Array.prototype.slice.call(arguments, 2);
8476 args.unshift(value);
8477 return eval(fn).apply(window, args);
8479 return eval(fn).call(window, value);
8484 usMoney : function(v){
8485 v = (Math.round((v-0)*100))/100;
8486 v = (v == Math.floor(v)) ? v + ".00" : ((v*10 == Math.floor(v*10)) ? v + "0" : v);
8488 var ps = v.split('.'),
8490 sub = ps[1] ? '.'+ ps[1] : '.00',
8492 while (r.test(whole)) {
8493 whole = whole.replace(r, '$1' + ',' + '$2');
8496 if(v.charAt(0) == '-'){
8497 return '-$' + v.substr(1);
8503 date : function(v, format){
8508 v = new Date(Date.parse(v));
8510 return v.dateFormat(format || "m/d/Y");
8514 dateRenderer : function(format){
8516 return Ext.util.Format.date(v, format);
8521 stripTags : function(v){
8522 return !v ? v : String(v).replace(stripTagsRE, "");
8526 stripScripts : function(v){
8527 return !v ? v : String(v).replace(stripScriptsRe, "");
8531 fileSize : function(size){
8533 return size + " bytes";
8534 } else if(size < 1048576) {
8535 return (Math.round(((size*10) / 1024))/10) + " KB";
8537 return (Math.round(((size*10) / 1048576))/10) + " MB";
8544 return function(v, a){
8546 fns[a] = new Function('v', 'return v ' + a + ';');
8553 round : function(value, precision) {
8554 var result = Number(value);
8555 if (typeof precision == 'number') {
8556 precision = Math.pow(10, precision);
8557 result = Math.round(value * precision) / precision;
8563 number: function(v, format) {
8567 v = Ext.num(v, NaN);
8577 if(format.substr(format.length - 2) == '/i'){
8578 format = format.substr(0, format.length - 2);
8584 var hasComma = format.indexOf(comma) != -1,
8585 psplit = (i18n ? format.replace(/[^\d\,]/g, '') : format.replace(/[^\d\.]/g, '')).split(dec);
8587 if(1 < psplit.length){
8588 v = v.toFixed(psplit[1].length);
8589 }else if(2 < psplit.length){
8590 throw ('NumberFormatException: invalid format, formats should have no more than 1 period: ' + format);
8595 var fnum = v.toString();
8597 psplit = fnum.split('.');
8600 var cnum = psplit[0], parr = [], j = cnum.length, m = Math.floor(j / 3), n = cnum.length % 3 || 3;
8602 for (var i = 0; i < j; i += n) {
8606 parr[parr.length] = cnum.substr(i, n);
8609 fnum = parr.join(comma);
8611 fnum += dec + psplit[1];
8615 fnum = psplit[0] + dec + psplit[1];
8619 return (neg ? '-' : '') + format.replace(/[\d,?\.?]+/, fnum);
8623 numberRenderer : function(format){
8625 return Ext.util.Format.number(v, format);
8630 plural : function(v, s, p){
8631 return v +' ' + (v == 1 ? s : (p ? p : s+'s'));
8635 nl2br : function(v){
8636 return Ext.isEmpty(v) ? '' : v.replace(nl2brRe, '<br/>');
8641 Ext.XTemplate = function(){
8642 Ext.XTemplate.superclass.constructor.apply(this, arguments);
8646 re = /<tpl\b[^>]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/,
8647 nameRe = /^<tpl\b[^>]*?for="(.*?)"/,
8648 ifRe = /^<tpl\b[^>]*?if="(.*?)"/,
8649 execRe = /^<tpl\b[^>]*?exec="(.*?)"/,
8658 WITHVALUES = 'with(values){ ';
8660 s = ['<tpl>', s, '</tpl>'].join('');
8662 while((m = s.match(re))){
8663 var m2 = m[0].match(nameRe),
8664 m3 = m[0].match(ifRe),
8665 m4 = m[0].match(execRe),
8669 name = m2 && m2[1] ? m2[1] : '';
8672 exp = m3 && m3[1] ? m3[1] : null;
8674 fn = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + RETURN +(Ext.util.Format.htmlDecode(exp))+'; }');
8678 exp = m4 && m4[1] ? m4[1] : null;
8680 exec = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES +(Ext.util.Format.htmlDecode(exp))+'; }');
8685 case '.': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + VALUES + '; }'); break;
8686 case '..': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + PARENT + '; }'); break;
8687 default: name = new Function(VALUES, PARENT, WITHVALUES + RETURN + name + '; }');
8697 s = s.replace(m[0], '{xtpl'+ id + '}');
8700 for(var i = tpls.length-1; i >= 0; --i){
8701 me.compileTpl(tpls[i]);
8703 me.master = tpls[tpls.length-1];
8706 Ext.extend(Ext.XTemplate, Ext.Template, {
8708 re : /\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\\]\s?[\d\.\+\-\*\\\(\)]+)?\}/g,
8710 codeRe : /\{\[((?:\\\]|.|\n)*?)\]\}/g,
8713 applySubTemplate : function(id, values, parent, xindex, xcount){
8719 if ((t.test && !t.test.call(me, values, parent, xindex, xcount)) ||
8720 (t.exec && t.exec.call(me, values, parent, xindex, xcount))) {
8723 vs = t.target ? t.target.call(me, values, parent) : values;
8725 parent = t.target ? values : parent;
8726 if(t.target && Ext.isArray(vs)){
8727 for(var i = 0, len = vs.length; i < len; i++){
8728 buf[buf.length] = t.compiled.call(me, vs[i], parent, i+1, len);
8730 return buf.join('');
8732 return t.compiled.call(me, vs, parent, xindex, xcount);
8736 compileTpl : function(tpl){
8737 var fm = Ext.util.Format,
8738 useF = this.disableFormats !== true,
8739 sep = Ext.isGecko ? "+" : ",",
8742 function fn(m, name, format, args, math){
8743 if(name.substr(0, 4) == 'xtpl'){
8744 return "'"+ sep +'this.applySubTemplate('+name.substr(4)+', values, parent, xindex, xcount)'+sep+"'";
8749 }else if(name === '#'){
8751 }else if(name.indexOf('.') != -1){
8754 v = "values['" + name + "']";
8757 v = '(' + v + math + ')';
8759 if (format && useF) {
8760 args = args ? ',' + args : "";
8761 if(format.substr(0, 5) != "this."){
8762 format = "fm." + format + '(';
8764 format = 'this.call("'+ format.substr(5) + '", ';
8768 args= ''; format = "("+v+" === undefined ? '' : ";
8770 return "'"+ sep + format + v + args + ")"+sep+"'";
8773 function codeFn(m, code){
8775 return "'" + sep + '(' + code.replace(/\\'/g, "'") + ')' + sep + "'";
8780 body = "tpl.compiled = function(values, parent, xindex, xcount){ return '" +
8781 tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn) +
8784 body = ["tpl.compiled = function(values, parent, xindex, xcount){ return ['"];
8785 body.push(tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn));
8786 body.push("'].join('');};");
8787 body = body.join('');
8794 applyTemplate : function(values){
8795 return this.master.compiled.call(this, values, {}, 1, 1);
8799 compile : function(){return this;}
8807 Ext.XTemplate.prototype.apply = Ext.XTemplate.prototype.applyTemplate;
8810 Ext.XTemplate.from = function(el){
8811 el = Ext.getDom(el);
8812 return new Ext.XTemplate(el.value || el.innerHTML);
8815 Ext.util.CSS = function(){
8819 var camelRe = /(-[a-z])/gi;
8820 var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };
8824 createStyleSheet : function(cssText, id){
8826 var head = doc.getElementsByTagName("head")[0];
8827 var rules = doc.createElement("style");
8828 rules.setAttribute("type", "text/css");
8830 rules.setAttribute("id", id);
8833 head.appendChild(rules);
8834 ss = rules.styleSheet;
8835 ss.cssText = cssText;
8838 rules.appendChild(doc.createTextNode(cssText));
8840 rules.cssText = cssText;
8842 head.appendChild(rules);
8843 ss = rules.styleSheet ? rules.styleSheet : (rules.sheet || doc.styleSheets[doc.styleSheets.length-1]);
8845 this.cacheStyleSheet(ss);
8850 removeStyleSheet : function(id){
8851 var existing = doc.getElementById(id);
8853 existing.parentNode.removeChild(existing);
8858 swapStyleSheet : function(id, url){
8859 this.removeStyleSheet(id);
8860 var ss = doc.createElement("link");
8861 ss.setAttribute("rel", "stylesheet");
8862 ss.setAttribute("type", "text/css");
8863 ss.setAttribute("id", id);
8864 ss.setAttribute("href", url);
8865 doc.getElementsByTagName("head")[0].appendChild(ss);
8869 refreshCache : function(){
8870 return this.getRules(true);
8874 cacheStyleSheet : function(ss){
8879 var ssRules = ss.cssRules || ss.rules;
8880 for(var j = ssRules.length-1; j >= 0; --j){
8881 rules[ssRules[j].selectorText.toLowerCase()] = ssRules[j];
8887 getRules : function(refreshCache){
8888 if(rules === null || refreshCache){
8890 var ds = doc.styleSheets;
8891 for(var i =0, len = ds.length; i < len; i++){
8893 this.cacheStyleSheet(ds[i]);
8901 getRule : function(selector, refreshCache){
8902 var rs = this.getRules(refreshCache);
8903 if(!Ext.isArray(selector)){
8904 return rs[selector.toLowerCase()];
8906 for(var i = 0; i < selector.length; i++){
8907 if(rs[selector[i]]){
8908 return rs[selector[i].toLowerCase()];
8916 updateRule : function(selector, property, value){
8917 if(!Ext.isArray(selector)){
8918 var rule = this.getRule(selector);
8920 rule.style[property.replace(camelRe, camelFn)] = value;
8924 for(var i = 0; i < selector.length; i++){
8925 if(this.updateRule(selector[i], property, value)){
8934 Ext.util.ClickRepeater = function(el, config)
8936 this.el = Ext.get(el);
8937 this.el.unselectable();
8939 Ext.apply(this, config);
8951 this.disabled = true;
8957 this.on("click", this.handler, this.scope || this);
8960 Ext.util.ClickRepeater.superclass.constructor.call(this);
8963 Ext.extend(Ext.util.ClickRepeater, Ext.util.Observable, {
8966 preventDefault : true,
8967 stopDefault : false,
8973 this.el.on('mousedown', this.handleMouseDown, this);
8975 this.el.on('dblclick', this.handleDblClick, this);
8977 if(this.preventDefault || this.stopDefault){
8978 this.el.on('click', this.eventOptions, this);
8981 this.disabled = false;
8985 disable: function( force){
8986 if(force || !this.disabled){
8987 clearTimeout(this.timer);
8988 if(this.pressClass){
8989 this.el.removeClass(this.pressClass);
8991 Ext.getDoc().un('mouseup', this.handleMouseUp, this);
8992 this.el.removeAllListeners();
8994 this.disabled = true;
8998 setDisabled: function(disabled){
8999 this[disabled ? 'disable' : 'enable']();
9002 eventOptions: function(e){
9003 if(this.preventDefault){
9006 if(this.stopDefault){
9012 destroy : function() {
9014 Ext.destroy(this.el);
9015 this.purgeListeners();
9018 handleDblClick : function(){
9019 clearTimeout(this.timer);
9022 this.fireEvent("mousedown", this);
9023 this.fireEvent("click", this);
9027 handleMouseDown : function(){
9028 clearTimeout(this.timer);
9030 if(this.pressClass){
9031 this.el.addClass(this.pressClass);
9033 this.mousedownTime = new Date();
9035 Ext.getDoc().on("mouseup", this.handleMouseUp, this);
9036 this.el.on("mouseout", this.handleMouseOut, this);
9038 this.fireEvent("mousedown", this);
9039 this.fireEvent("click", this);
9042 if (this.accelerate) {
9045 this.timer = this.click.defer(this.delay || this.interval, this);
9050 this.fireEvent("click", this);
9051 this.timer = this.click.defer(this.accelerate ?
9052 this.easeOutExpo(this.mousedownTime.getElapsed(),
9056 this.interval, this);
9059 easeOutExpo : function (t, b, c, d) {
9060 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
9064 handleMouseOut : function(){
9065 clearTimeout(this.timer);
9066 if(this.pressClass){
9067 this.el.removeClass(this.pressClass);
9069 this.el.on("mouseover", this.handleMouseReturn, this);
9073 handleMouseReturn : function(){
9074 this.el.un("mouseover", this.handleMouseReturn, this);
9075 if(this.pressClass){
9076 this.el.addClass(this.pressClass);
9082 handleMouseUp : function(){
9083 clearTimeout(this.timer);
9084 this.el.un("mouseover", this.handleMouseReturn, this);
9085 this.el.un("mouseout", this.handleMouseOut, this);
9086 Ext.getDoc().un("mouseup", this.handleMouseUp, this);
9087 this.el.removeClass(this.pressClass);
9088 this.fireEvent("mouseup", this);
9091 Ext.KeyNav = function(el, config){
9092 this.el = Ext.get(el);
9093 Ext.apply(this, config);
9095 this.disabled = true;
9100 Ext.KeyNav.prototype = {
9104 defaultEventAction: "stopEvent",
9106 forceKeyDown : false,
9109 relay : function(e){
9111 var h = this.keyToHandler[k];
9113 if(this.doRelay(e, this[h], h) !== true){
9114 e[this.defaultEventAction]();
9120 doRelay : function(e, h, hname){
9121 return h.call(this.scope || this, e);
9154 stopKeyUp: function(e) {
9157 if (k >= 37 && k <= 40) {
9165 destroy: function(){
9170 enable: function() {
9171 if (this.disabled) {
9172 if (Ext.isSafari2) {
9174 this.el.on('keyup', this.stopKeyUp, this);
9177 this.el.on(this.isKeydown()? 'keydown' : 'keypress', this.relay, this);
9178 this.disabled = false;
9183 disable: function() {
9184 if (!this.disabled) {
9185 if (Ext.isSafari2) {
9187 this.el.un('keyup', this.stopKeyUp, this);
9190 this.el.un(this.isKeydown()? 'keydown' : 'keypress', this.relay, this);
9191 this.disabled = true;
9196 setDisabled : function(disabled){
9197 this[disabled ? "disable" : "enable"]();
9201 isKeydown: function(){
9202 return this.forceKeyDown || Ext.EventManager.useKeydown;
9206 Ext.KeyMap = function(el, config, eventName){
9207 this.el = Ext.get(el);
9208 this.eventName = eventName || "keydown";
9211 this.addBinding(config);
9216 Ext.KeyMap.prototype = {
9221 addBinding : function(config){
9222 if(Ext.isArray(config)){
9223 Ext.each(config, function(c){
9228 var keyCode = config.key,
9229 fn = config.fn || config.handler,
9230 scope = config.scope;
9232 if (config.stopEvent) {
9233 this.stopEvent = config.stopEvent;
9236 if(typeof keyCode == "string"){
9238 var keyString = keyCode.toUpperCase();
9239 for(var j = 0, len = keyString.length; j < len; j++){
9240 ks.push(keyString.charCodeAt(j));
9244 var keyArray = Ext.isArray(keyCode);
9246 var handler = function(e){
9247 if(this.checkModifiers(config, e)){
9250 for(var i = 0, len = keyCode.length; i < len; i++){
9251 if(keyCode[i] == k){
9255 fn.call(scope || window, k, e);
9264 fn.call(scope || window, k, e);
9269 this.bindings.push(handler);
9273 checkModifiers: function(config, e){
9274 var val, key, keys = ['shift', 'ctrl', 'alt'];
9275 for (var i = 0, len = keys.length; i < len; ++i){
9278 if(!(val === undefined || (val === e[key + 'Key']))){
9286 on : function(key, fn, scope){
9287 var keyCode, shift, ctrl, alt;
9288 if(typeof key == "object" && !Ext.isArray(key)){
9307 handleKeyDown : function(e){
9309 var b = this.bindings;
9310 for(var i = 0, len = b.length; i < len; i++){
9317 isEnabled : function(){
9318 return this.enabled;
9324 this.el.on(this.eventName, this.handleKeyDown, this);
9325 this.enabled = true;
9330 disable: function(){
9332 this.el.removeListener(this.eventName, this.handleKeyDown, this);
9333 this.enabled = false;
9338 setDisabled : function(disabled){
9339 this[disabled ? "disable" : "enable"]();
9342 Ext.util.TextMetrics = function(){
9346 measure : function(el, text, fixedWidth){
9348 shared = Ext.util.TextMetrics.Instance(el, fixedWidth);
9351 shared.setFixedWidth(fixedWidth || 'auto');
9352 return shared.getSize(text);
9356 createInstance : function(el, fixedWidth){
9357 return Ext.util.TextMetrics.Instance(el, fixedWidth);
9362 Ext.util.TextMetrics.Instance = function(bindTo, fixedWidth){
9363 var ml = new Ext.Element(document.createElement('div'));
9364 document.body.appendChild(ml.dom);
9365 ml.position('absolute');
9366 ml.setLeftTop(-1000, -1000);
9370 ml.setWidth(fixedWidth);
9375 getSize : function(text){
9377 var s = ml.getSize();
9383 bind : function(el){
9385 Ext.fly(el).getStyles('font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing')
9390 setFixedWidth : function(width){
9395 getWidth : function(text){
9396 ml.dom.style.width = 'auto';
9397 return this.getSize(text).width;
9401 getHeight : function(text){
9402 return this.getSize(text).height;
9406 instance.bind(bindTo);
9411 Ext.Element.addMethods({
9413 getTextWidth : function(text, min, max){
9414 return (Ext.util.TextMetrics.measure(this.dom, Ext.value(text, this.dom.innerHTML, true)).width).constrain(min || 0, max || 1000000);
9418 Ext.util.Cookies = {
9420 set : function(name, value){
9421 var argv = arguments;
9422 var argc = arguments.length;
9423 var expires = (argc > 2) ? argv[2] : null;
9424 var path = (argc > 3) ? argv[3] : '/';
9425 var domain = (argc > 4) ? argv[4] : null;
9426 var secure = (argc > 5) ? argv[5] : false;
9427 document.cookie = name + "=" + escape(value) + ((expires === null) ? "" : ("; expires=" + expires.toGMTString())) + ((path === null) ? "" : ("; path=" + path)) + ((domain === null) ? "" : ("; domain=" + domain)) + ((secure === true) ? "; secure" : "");
9431 get : function(name){
9432 var arg = name + "=";
9433 var alen = arg.length;
9434 var clen = document.cookie.length;
9439 if(document.cookie.substring(i, j) == arg){
9440 return Ext.util.Cookies.getCookieVal(j);
9442 i = document.cookie.indexOf(" ", i) + 1;
9451 clear : function(name){
9452 if(Ext.util.Cookies.get(name)){
9453 document.cookie = name + "=" + "; expires=Thu, 01-Jan-70 00:00:01 GMT";
9457 getCookieVal : function(offset){
9458 var endstr = document.cookie.indexOf(";", offset);
9460 endstr = document.cookie.length;
9462 return unescape(document.cookie.substring(offset, endstr));
9465 Ext.handleError = function(e) {
9470 Ext.Error = function(message) {
9472 this.message = (this.lang[message]) ? this.lang[message] : message;
9475 Ext.Error.prototype = new Error();
9476 Ext.apply(Ext.Error.prototype, {
9482 getName : function() {
9486 getMessage : function() {
9487 return this.message;
9490 toJson : function() {
9491 return Ext.encode(this);
9495 Ext.ComponentMgr = function(){
9496 var all = new Ext.util.MixedCollection();
9502 register : function(c){
9507 unregister : function(c){
9517 onAvailable : function(id, fn, scope){
9518 all.on("add", function(index, o){
9520 fn.call(scope || o, o);
9521 all.un("add", fn, scope);
9536 isRegistered : function(xtype){
9537 return types[xtype] !== undefined;
9541 isPluginRegistered : function(ptype){
9542 return ptypes[ptype] !== undefined;
9546 registerType : function(xtype, cls){
9552 create : function(config, defaultType){
9553 return config.render ? config : new types[config.xtype || defaultType](config);
9557 registerPlugin : function(ptype, cls){
9558 ptypes[ptype] = cls;
9563 createPlugin : function(config, defaultType){
9564 var PluginCls = ptypes[config.ptype || defaultType];
9565 if (PluginCls.init) {
9568 return new PluginCls(config);
9575 Ext.reg = Ext.ComponentMgr.registerType;
9577 Ext.preg = Ext.ComponentMgr.registerPlugin;
9579 Ext.create = Ext.ComponentMgr.create;
9580 Ext.Component = function(config){
9581 config = config || {};
9582 if(config.initialConfig){
9583 if(config.isAction){
9584 this.baseAction = config;
9586 config = config.initialConfig;
9587 }else if(config.tagName || config.dom || Ext.isString(config)){
9588 config = {applyTo: config, id: config.id || config};
9592 this.initialConfig = config;
9594 Ext.apply(this, config);
9623 'beforestaterestore',
9632 Ext.ComponentMgr.register(this);
9633 Ext.Component.superclass.constructor.call(this);
9635 if(this.baseAction){
9636 this.baseAction.addComponent(this);
9639 this.initComponent();
9642 if(Ext.isArray(this.plugins)){
9643 for(var i = 0, len = this.plugins.length; i < len; i++){
9644 this.plugins[i] = this.initPlugin(this.plugins[i]);
9647 this.plugins = this.initPlugin(this.plugins);
9651 if(this.stateful !== false){
9656 this.applyToMarkup(this.applyTo);
9657 delete this.applyTo;
9658 }else if(this.renderTo){
9659 this.render(this.renderTo);
9660 delete this.renderTo;
9665 Ext.Component.AUTO_ID = 1000;
9667 Ext.extend(Ext.Component, Ext.util.Observable, {
9698 disabledClass : 'x-item-disabled',
9700 allowDomMove : true,
9704 hideMode : 'display',
9720 tplWriteMode : 'overwrite',
9729 ctype : 'Ext.Component',
9735 getActionEl : function(){
9736 return this[this.actionMode];
9739 initPlugin : function(p){
9740 if(p.ptype && !Ext.isFunction(p.init)){
9741 p = Ext.ComponentMgr.createPlugin(p);
9742 }else if(Ext.isString(p)){
9743 p = Ext.ComponentMgr.createPlugin({
9752 initComponent : function(){
9755 this.on(this.listeners);
9756 delete this.listeners;
9758 this.enableBubble(this.bubbleEvents);
9762 render : function(container, position){
9763 if(!this.rendered && this.fireEvent('beforerender', this) !== false){
9764 if(!container && this.el){
9765 this.el = Ext.get(this.el);
9766 container = this.el.dom.parentNode;
9767 this.allowDomMove = false;
9769 this.container = Ext.get(container);
9771 this.container.addClass(this.ctCls);
9773 this.rendered = true;
9774 if(position !== undefined){
9775 if(Ext.isNumber(position)){
9776 position = this.container.dom.childNodes[position];
9778 position = Ext.getDom(position);
9781 this.onRender(this.container, position || null);
9783 this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]);
9786 this.el.addClass(this.cls);
9790 this.el.applyStyles(this.style);
9794 this.el.addClassOnOver(this.overCls);
9796 this.fireEvent('render', this);
9801 var contentTarget = this.getContentTarget();
9803 contentTarget.update(Ext.DomHelper.markup(this.html));
9806 if (this.contentEl){
9807 var ce = Ext.getDom(this.contentEl);
9808 Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']);
9809 contentTarget.appendChild(ce);
9812 if (!this.tpl.compile) {
9813 this.tpl = new Ext.XTemplate(this.tpl);
9816 this.tpl[this.tplWriteMode](contentTarget, this.data);
9820 this.afterRender(this.container);
9832 if(this.stateful !== false){
9833 this.initStateEvents();
9835 this.fireEvent('afterrender', this);
9842 update: function(htmlOrData, loadScripts, cb) {
9843 var contentTarget = this.getContentTarget();
9844 if (this.tpl && typeof htmlOrData !== "string") {
9845 this.tpl[this.tplWriteMode](contentTarget, htmlOrData || {});
9847 var html = Ext.isObject(htmlOrData) ? Ext.DomHelper.markup(htmlOrData) : htmlOrData;
9848 contentTarget.update(html, loadScripts, cb);
9854 onAdded : function(container, pos) {
9855 this.ownerCt = container;
9857 this.fireEvent('added', this, container, pos);
9861 onRemoved : function() {
9863 this.fireEvent('removed', this, this.ownerCt);
9864 delete this.ownerCt;
9868 initRef : function() {
9870 if(this.ref && !this.refOwner){
9871 var levels = this.ref.split('/'),
9872 last = levels.length,
9876 while(t && i < last){
9881 t[this.refName = levels[--i]] = this;
9888 removeRef : function() {
9889 if (this.refOwner && this.refName) {
9890 delete this.refOwner[this.refName];
9891 delete this.refOwner;
9896 initState : function(){
9897 if(Ext.state.Manager){
9898 var id = this.getStateId();
9900 var state = Ext.state.Manager.get(id);
9902 if(this.fireEvent('beforestaterestore', this, state) !== false){
9903 this.applyState(Ext.apply({}, state));
9904 this.fireEvent('staterestore', this, state);
9912 getStateId : function(){
9913 return this.stateId || ((/^(ext-comp-|ext-gen)/).test(String(this.id)) ? null : this.id);
9917 initStateEvents : function(){
9918 if(this.stateEvents){
9919 for(var i = 0, e; e = this.stateEvents[i]; i++){
9920 this.on(e, this.saveState, this, {delay:100});
9926 applyState : function(state){
9928 Ext.apply(this, state);
9933 getState : function(){
9938 saveState : function(){
9939 if(Ext.state.Manager && this.stateful !== false){
9940 var id = this.getStateId();
9942 var state = this.getState();
9943 if(this.fireEvent('beforestatesave', this, state) !== false){
9944 Ext.state.Manager.set(id, state);
9945 this.fireEvent('statesave', this, state);
9952 applyToMarkup : function(el){
9953 this.allowDomMove = false;
9954 this.el = Ext.get(el);
9955 this.render(this.el.dom.parentNode);
9959 addClass : function(cls){
9961 this.el.addClass(cls);
9963 this.cls = this.cls ? this.cls + ' ' + cls : cls;
9969 removeClass : function(cls){
9971 this.el.removeClass(cls);
9973 this.cls = this.cls.split(' ').remove(cls).join(' ');
9980 onRender : function(ct, position){
9981 if(!this.el && this.autoEl){
9982 if(Ext.isString(this.autoEl)){
9983 this.el = document.createElement(this.autoEl);
9985 var div = document.createElement('div');
9986 Ext.DomHelper.overwrite(div, this.autoEl);
9987 this.el = div.firstChild;
9990 this.el.id = this.getId();
9994 this.el = Ext.get(this.el);
9995 if(this.allowDomMove !== false){
9996 ct.dom.insertBefore(this.el.dom, position);
9998 Ext.removeNode(div);
10006 getAutoCreate : function(){
10007 var cfg = Ext.isObject(this.autoCreate) ?
10008 this.autoCreate : Ext.apply({}, this.defaultAutoCreate);
10009 if(this.id && !cfg.id){
10016 afterRender : Ext.emptyFn,
10019 destroy : function(){
10020 if(!this.isDestroyed){
10021 if(this.fireEvent('beforedestroy', this) !== false){
10022 this.destroying = true;
10023 this.beforeDestroy();
10024 if(this.ownerCt && this.ownerCt.remove){
10025 this.ownerCt.remove(this, false);
10029 if(this.actionMode == 'container' || this.removeMode == 'container'){
10030 this.container.remove();
10034 if(this.focusTask && this.focusTask.cancel){
10035 this.focusTask.cancel();
10038 Ext.ComponentMgr.unregister(this);
10039 this.fireEvent('destroy', this);
10040 this.purgeListeners();
10041 this.destroying = false;
10042 this.isDestroyed = true;
10047 deleteMembers : function(){
10048 var args = arguments;
10049 for(var i = 0, len = args.length; i < len; ++i){
10050 delete this[args[i]];
10055 beforeDestroy : Ext.emptyFn,
10058 onDestroy : Ext.emptyFn,
10061 getEl : function(){
10066 getContentTarget : function(){
10071 getId : function(){
10072 return this.id || (this.id = 'ext-comp-' + (++Ext.Component.AUTO_ID));
10076 getItemId : function(){
10077 return this.itemId || this.getId();
10081 focus : function(selectText, delay){
10083 this.focusTask = new Ext.util.DelayedTask(this.focus, this, [selectText, false]);
10084 this.focusTask.delay(Ext.isNumber(delay) ? delay : 10);
10087 if(this.rendered && !this.isDestroyed){
10089 if(selectText === true){
10090 this.el.dom.select();
10105 disable : function( silent){
10109 this.disabled = true;
10110 if(silent !== true){
10111 this.fireEvent('disable', this);
10117 onDisable : function(){
10118 this.getActionEl().addClass(this.disabledClass);
10119 this.el.dom.disabled = true;
10123 enable : function(){
10127 this.disabled = false;
10128 this.fireEvent('enable', this);
10133 onEnable : function(){
10134 this.getActionEl().removeClass(this.disabledClass);
10135 this.el.dom.disabled = false;
10139 setDisabled : function(disabled){
10140 return this[disabled ? 'disable' : 'enable']();
10145 if(this.fireEvent('beforeshow', this) !== false){
10146 this.hidden = false;
10147 if(this.autoRender){
10148 this.render(Ext.isBoolean(this.autoRender) ? Ext.getBody() : this.autoRender);
10153 this.fireEvent('show', this);
10159 onShow : function(){
10160 this.getVisibilityEl().removeClass('x-hide-' + this.hideMode);
10165 if(this.fireEvent('beforehide', this) !== false){
10167 this.fireEvent('hide', this);
10173 doHide: function(){
10174 this.hidden = true;
10181 onHide : function(){
10182 this.getVisibilityEl().addClass('x-hide-' + this.hideMode);
10186 getVisibilityEl : function(){
10187 return this.hideParent ? this.container : this.getActionEl();
10191 setVisible : function(visible){
10192 return this[visible ? 'show' : 'hide']();
10196 isVisible : function(){
10197 return this.rendered && this.getVisibilityEl().isVisible();
10201 cloneConfig : function(overrides){
10202 overrides = overrides || {};
10203 var id = overrides.id || Ext.id();
10204 var cfg = Ext.applyIf(overrides, this.initialConfig);
10206 return new this.constructor(cfg);
10210 getXType : function(){
10211 return this.constructor.xtype;
10215 isXType : function(xtype, shallow){
10217 if (Ext.isFunction(xtype)){
10218 xtype = xtype.xtype;
10219 }else if (Ext.isObject(xtype)){
10220 xtype = xtype.constructor.xtype;
10223 return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 : this.constructor.xtype == xtype;
10227 getXTypes : function(){
10228 var tc = this.constructor;
10230 var c = [], sc = this;
10231 while(sc && sc.constructor.xtype){
10232 c.unshift(sc.constructor.xtype);
10233 sc = sc.constructor.superclass;
10236 tc.xtypes = c.join('/');
10242 findParentBy : function(fn) {
10243 for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt);
10248 findParentByType : function(xtype) {
10249 return Ext.isFunction(xtype) ?
10250 this.findParentBy(function(p){
10251 return p.constructor === xtype;
10253 this.findParentBy(function(p){
10254 return p.constructor.xtype === xtype;
10259 getPositionEl : function(){
10260 return this.positionEl || this.el;
10264 purgeListeners : function(){
10265 Ext.Component.superclass.purgeListeners.call(this);
10267 this.on('beforedestroy', this.clearMons, this, {single: true});
10272 clearMons : function(){
10273 Ext.each(this.mons, function(m){
10274 m.item.un(m.ename, m.fn, m.scope);
10280 createMons: function(){
10283 this.on('beforedestroy', this.clearMons, this, {single: true});
10288 mon : function(item, ename, fn, scope, opt){
10290 if(Ext.isObject(ename)){
10291 var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
10295 if(propRe.test(e)){
10298 if(Ext.isFunction(o[e])){
10301 item: item, ename: e, fn: o[e], scope: o.scope
10303 item.on(e, o[e], o.scope, o);
10307 item: item, ename: e, fn: o[e], scope: o.scope
10316 item: item, ename: ename, fn: fn, scope: scope
10318 item.on(ename, fn, scope, opt);
10322 mun : function(item, ename, fn, scope){
10325 for(var i = 0, len = this.mons.length; i < len; ++i){
10326 mon = this.mons[i];
10327 if(item === mon.item && ename == mon.ename && fn === mon.fn && scope === mon.scope){
10328 this.mons.splice(i, 1);
10329 item.un(ename, fn, scope);
10338 nextSibling : function(){
10340 var index = this.ownerCt.items.indexOf(this);
10341 if(index != -1 && index+1 < this.ownerCt.items.getCount()){
10342 return this.ownerCt.items.itemAt(index+1);
10349 previousSibling : function(){
10351 var index = this.ownerCt.items.indexOf(this);
10353 return this.ownerCt.items.itemAt(index-1);
10360 getBubbleTarget : function(){
10361 return this.ownerCt;
10365 Ext.reg('component', Ext.Component);
10366 Ext.Action = Ext.extend(Object, {
10375 constructor : function(config){
10376 this.initialConfig = config;
10377 this.itemId = config.itemId = (config.itemId || config.id || Ext.id());
10385 setText : function(text){
10386 this.initialConfig.text = text;
10387 this.callEach('setText', [text]);
10391 getText : function(){
10392 return this.initialConfig.text;
10396 setIconClass : function(cls){
10397 this.initialConfig.iconCls = cls;
10398 this.callEach('setIconClass', [cls]);
10402 getIconClass : function(){
10403 return this.initialConfig.iconCls;
10407 setDisabled : function(v){
10408 this.initialConfig.disabled = v;
10409 this.callEach('setDisabled', [v]);
10413 enable : function(){
10414 this.setDisabled(false);
10418 disable : function(){
10419 this.setDisabled(true);
10423 isDisabled : function(){
10424 return this.initialConfig.disabled;
10428 setHidden : function(v){
10429 this.initialConfig.hidden = v;
10430 this.callEach('setVisible', [!v]);
10435 this.setHidden(false);
10440 this.setHidden(true);
10444 isHidden : function(){
10445 return this.initialConfig.hidden;
10449 setHandler : function(fn, scope){
10450 this.initialConfig.handler = fn;
10451 this.initialConfig.scope = scope;
10452 this.callEach('setHandler', [fn, scope]);
10456 each : function(fn, scope){
10457 Ext.each(this.items, fn, scope);
10461 callEach : function(fnName, args){
10462 var cs = this.items;
10463 for(var i = 0, len = cs.length; i < len; i++){
10464 cs[i][fnName].apply(cs[i], args);
10469 addComponent : function(comp){
10470 this.items.push(comp);
10471 comp.on('destroy', this.removeComponent, this);
10475 removeComponent : function(comp){
10476 this.items.remove(comp);
10480 execute : function(){
10481 this.initialConfig.handler.apply(this.initialConfig.scope || window, arguments);
10486 Ext.Layer = function(config, existingEl){
10487 config = config || {};
10488 var dh = Ext.DomHelper;
10489 var cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body;
10491 this.dom = Ext.getDom(existingEl);
10494 var o = config.dh || {tag: 'div', cls: 'x-layer'};
10495 this.dom = dh.append(pel, o);
10498 this.addClass(config.cls);
10500 this.constrain = config.constrain !== false;
10501 this.setVisibilityMode(Ext.Element.VISIBILITY);
10503 this.id = this.dom.id = config.id;
10505 this.id = Ext.id(this.dom);
10507 this.zindex = config.zindex || this.getZIndex();
10508 this.position('absolute', this.zindex);
10510 this.shadowOffset = config.shadowOffset || 4;
10511 this.shadow = new Ext.Shadow({
10512 offset : this.shadowOffset,
10513 mode : config.shadow
10516 this.shadowOffset = 0;
10518 this.useShim = config.shim !== false && Ext.useShims;
10519 this.useDisplay = config.useDisplay;
10523 var supr = Ext.Element.prototype;
10528 Ext.extend(Ext.Layer, Ext.Element, {
10530 getZIndex : function(){
10531 return this.zindex || parseInt((this.getShim() || this).getStyle('z-index'), 10) || 11000;
10534 getShim : function(){
10541 var shim = shims.shift();
10543 shim = this.createShim();
10544 shim.enableDisplayMode('block');
10545 shim.dom.style.display = 'none';
10546 shim.dom.style.visibility = 'visible';
10548 var pn = this.dom.parentNode;
10549 if(shim.dom.parentNode != pn){
10550 pn.insertBefore(shim.dom, this.dom);
10552 shim.setStyle('z-index', this.getZIndex()-2);
10557 hideShim : function(){
10559 this.shim.setDisplayed(false);
10560 shims.push(this.shim);
10565 disableShadow : function(){
10567 this.shadowDisabled = true;
10568 this.shadow.hide();
10569 this.lastShadowOffset = this.shadowOffset;
10570 this.shadowOffset = 0;
10574 enableShadow : function(show){
10576 this.shadowDisabled = false;
10577 this.shadowOffset = this.lastShadowOffset;
10578 delete this.lastShadowOffset;
10588 sync : function(doShow){
10589 var shadow = this.shadow;
10590 if(!this.updating && this.isVisible() && (shadow || this.useShim)){
10591 var shim = this.getShim(),
10592 w = this.getWidth(),
10593 h = this.getHeight(),
10594 l = this.getLeft(true),
10595 t = this.getTop(true);
10597 if(shadow && !this.shadowDisabled){
10598 if(doShow && !shadow.isVisible()){
10601 shadow.realign(l, t, w, h);
10608 var shadowAdj = shadow.el.getXY(), shimStyle = shim.dom.style,
10609 shadowSize = shadow.el.getSize();
10610 shimStyle.left = (shadowAdj[0])+'px';
10611 shimStyle.top = (shadowAdj[1])+'px';
10612 shimStyle.width = (shadowSize.width)+'px';
10613 shimStyle.height = (shadowSize.height)+'px';
10619 shim.setSize(w, h);
10620 shim.setLeftTop(l, t);
10626 destroy : function(){
10629 this.shadow.hide();
10631 this.removeAllListeners();
10632 Ext.removeNode(this.dom);
10636 remove : function(){
10641 beginUpdate : function(){
10642 this.updating = true;
10646 endUpdate : function(){
10647 this.updating = false;
10652 hideUnders : function(negOffset){
10654 this.shadow.hide();
10660 constrainXY : function(){
10661 if(this.constrain){
10662 var vw = Ext.lib.Dom.getViewWidth(),
10663 vh = Ext.lib.Dom.getViewHeight();
10664 var s = Ext.getDoc().getScroll();
10666 var xy = this.getXY();
10667 var x = xy[0], y = xy[1];
10668 var so = this.shadowOffset;
10669 var w = this.dom.offsetWidth+so, h = this.dom.offsetHeight+so;
10673 if((x + w) > vw+s.left){
10677 if((y + h) > vh+s.top){
10692 var ay = this.avoidY;
10693 if(y <= ay && (y+h) >= ay){
10699 supr.setXY.call(this, xy);
10706 isVisible : function(){
10707 return this.visible;
10711 showAction : function(){
10712 this.visible = true;
10713 if(this.useDisplay === true){
10714 this.setDisplayed('');
10715 }else if(this.lastXY){
10716 supr.setXY.call(this, this.lastXY);
10717 }else if(this.lastLT){
10718 supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]);
10723 hideAction : function(){
10724 this.visible = false;
10725 if(this.useDisplay === true){
10726 this.setDisplayed(false);
10728 this.setLeftTop(-10000,-10000);
10733 setVisible : function(v, a, d, c, e){
10738 var cb = function(){
10743 }.createDelegate(this);
10744 supr.setVisible.call(this, true, true, d, cb, e);
10747 this.hideUnders(true);
10756 }.createDelegate(this);
10758 supr.setVisible.call(this, v, a, d, cb, e);
10768 storeXY : function(xy){
10769 delete this.lastLT;
10773 storeLeftTop : function(left, top){
10774 delete this.lastXY;
10775 this.lastLT = [left, top];
10779 beforeFx : function(){
10780 this.beforeAction();
10781 return Ext.Layer.superclass.beforeFx.apply(this, arguments);
10785 afterFx : function(){
10786 Ext.Layer.superclass.afterFx.apply(this, arguments);
10787 this.sync(this.isVisible());
10791 beforeAction : function(){
10792 if(!this.updating && this.shadow){
10793 this.shadow.hide();
10798 setLeft : function(left){
10799 this.storeLeftTop(left, this.getTop(true));
10800 supr.setLeft.apply(this, arguments);
10805 setTop : function(top){
10806 this.storeLeftTop(this.getLeft(true), top);
10807 supr.setTop.apply(this, arguments);
10812 setLeftTop : function(left, top){
10813 this.storeLeftTop(left, top);
10814 supr.setLeftTop.apply(this, arguments);
10819 setXY : function(xy, a, d, c, e){
10821 this.beforeAction();
10823 var cb = this.createCB(c);
10824 supr.setXY.call(this, xy, a, d, cb, e);
10832 createCB : function(c){
10844 setX : function(x, a, d, c, e){
10845 this.setXY([x, this.getY()], a, d, c, e);
10850 setY : function(y, a, d, c, e){
10851 this.setXY([this.getX(), y], a, d, c, e);
10856 setSize : function(w, h, a, d, c, e){
10857 this.beforeAction();
10858 var cb = this.createCB(c);
10859 supr.setSize.call(this, w, h, a, d, cb, e);
10867 setWidth : function(w, a, d, c, e){
10868 this.beforeAction();
10869 var cb = this.createCB(c);
10870 supr.setWidth.call(this, w, a, d, cb, e);
10878 setHeight : function(h, a, d, c, e){
10879 this.beforeAction();
10880 var cb = this.createCB(c);
10881 supr.setHeight.call(this, h, a, d, cb, e);
10889 setBounds : function(x, y, w, h, a, d, c, e){
10890 this.beforeAction();
10891 var cb = this.createCB(c);
10893 this.storeXY([x, y]);
10894 supr.setXY.call(this, [x, y]);
10895 supr.setSize.call(this, w, h, a, d, cb, e);
10898 supr.setBounds.call(this, x, y, w, h, a, d, cb, e);
10904 setZIndex : function(zindex){
10905 this.zindex = zindex;
10906 this.setStyle('z-index', zindex + 2);
10908 this.shadow.setZIndex(zindex + 1);
10911 this.shim.setStyle('z-index', zindex);
10918 Ext.Shadow = function(config){
10919 Ext.apply(this, config);
10920 if(typeof this.mode != "string"){
10921 this.mode = this.defaultMode;
10923 var o = this.offset, a = {h: 0};
10924 var rad = Math.floor(this.offset/2);
10925 switch(this.mode.toLowerCase()){
10931 a.l -= this.offset + rad;
10932 a.t -= this.offset + rad;
10943 a.l -= (this.offset - rad);
10944 a.t -= this.offset + rad;
10946 a.w -= (this.offset - rad)*2;
10957 a.l -= (this.offset - rad);
10958 a.t -= (this.offset - rad);
10960 a.w -= (this.offset + rad + 1);
10961 a.h -= (this.offset + rad);
10970 Ext.Shadow.prototype = {
10976 defaultMode: "drop",
10979 show : function(target){
10980 target = Ext.get(target);
10982 this.el = Ext.Shadow.Pool.pull();
10983 if(this.el.dom.nextSibling != target.dom){
10984 this.el.insertBefore(target);
10987 this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10)-1);
10989 this.el.dom.style.filter="progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius="+(this.offset)+")";
10992 target.getLeft(true),
10993 target.getTop(true),
10997 this.el.dom.style.display = "block";
11001 isVisible : function(){
11002 return this.el ? true : false;
11006 realign : function(l, t, w, h){
11010 var a = this.adjusts, d = this.el.dom, s = d.style;
11012 s.left = (l+a.l)+"px";
11013 s.top = (t+a.t)+"px";
11014 var sw = (w+a.w), sh = (h+a.h), sws = sw +"px", shs = sh + "px";
11015 if(s.width != sws || s.height != shs){
11019 var cn = d.childNodes;
11020 var sww = Math.max(0, (sw-12))+"px";
11021 cn[0].childNodes[1].style.width = sww;
11022 cn[1].childNodes[1].style.width = sww;
11023 cn[2].childNodes[1].style.width = sww;
11024 cn[1].style.height = Math.max(0, (sh-12))+"px";
11032 this.el.dom.style.display = "none";
11033 Ext.Shadow.Pool.push(this.el);
11039 setZIndex : function(z){
11042 this.el.setStyle("z-index", z);
11048 Ext.Shadow.Pool = function(){
11050 var markup = Ext.isIE ?
11051 '<div class="x-ie-shadow"></div>' :
11052 '<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>';
11055 var sh = p.shift();
11057 sh = Ext.get(Ext.DomHelper.insertHtml("beforeBegin", document.body.firstChild, markup));
11058 sh.autoBoxAdjust = false;
11063 push : function(sh){
11068 Ext.BoxComponent = Ext.extend(Ext.Component, {
11097 initComponent : function(){
11098 Ext.BoxComponent.superclass.initComponent.call(this);
11110 deferHeight: false,
11113 setSize : function(w, h){
11116 if(typeof w == 'object'){
11120 if (Ext.isDefined(w) && Ext.isDefined(this.boxMinWidth) && (w < this.boxMinWidth)) {
11121 w = this.boxMinWidth;
11123 if (Ext.isDefined(h) && Ext.isDefined(this.boxMinHeight) && (h < this.boxMinHeight)) {
11124 h = this.boxMinHeight;
11126 if (Ext.isDefined(w) && Ext.isDefined(this.boxMaxWidth) && (w > this.boxMaxWidth)) {
11127 w = this.boxMaxWidth;
11129 if (Ext.isDefined(h) && Ext.isDefined(this.boxMaxHeight) && (h > this.boxMaxHeight)) {
11130 h = this.boxMaxHeight;
11133 if(!this.boxReady){
11140 if(this.cacheSizes !== false && this.lastSize && this.lastSize.width == w && this.lastSize.height == h){
11143 this.lastSize = {width: w, height: h};
11144 var adj = this.adjustSize(w, h),
11148 if(aw !== undefined || ah !== undefined){
11149 rz = this.getResizeEl();
11150 if(!this.deferHeight && aw !== undefined && ah !== undefined){
11151 rz.setSize(aw, ah);
11152 }else if(!this.deferHeight && ah !== undefined){
11154 }else if(aw !== undefined){
11157 this.onResize(aw, ah, w, h);
11158 this.fireEvent('resize', this, aw, ah, w, h);
11164 setWidth : function(width){
11165 return this.setSize(width);
11169 setHeight : function(height){
11170 return this.setSize(undefined, height);
11174 getSize : function(){
11175 return this.getResizeEl().getSize();
11179 getWidth : function(){
11180 return this.getResizeEl().getWidth();
11184 getHeight : function(){
11185 return this.getResizeEl().getHeight();
11189 getOuterSize : function(){
11190 var el = this.getResizeEl();
11191 return {width: el.getWidth() + el.getMargins('lr'),
11192 height: el.getHeight() + el.getMargins('tb')};
11196 getPosition : function(local){
11197 var el = this.getPositionEl();
11198 if(local === true){
11199 return [el.getLeft(true), el.getTop(true)];
11201 return this.xy || el.getXY();
11205 getBox : function(local){
11206 var pos = this.getPosition(local);
11207 var s = this.getSize();
11214 updateBox : function(box){
11215 this.setSize(box.width, box.height);
11216 this.setPagePosition(box.x, box.y);
11221 getResizeEl : function(){
11222 return this.resizeEl || this.el;
11226 setAutoScroll : function(scroll){
11228 this.getContentTarget().setOverflow(scroll ? 'auto' : '');
11230 this.autoScroll = scroll;
11235 setPosition : function(x, y){
11236 if(x && typeof x[1] == 'number'){
11242 if(!this.boxReady){
11245 var adj = this.adjustPosition(x, y);
11246 var ax = adj.x, ay = adj.y;
11248 var el = this.getPositionEl();
11249 if(ax !== undefined || ay !== undefined){
11250 if(ax !== undefined && ay !== undefined){
11251 el.setLeftTop(ax, ay);
11252 }else if(ax !== undefined){
11254 }else if(ay !== undefined){
11257 this.onPosition(ax, ay);
11258 this.fireEvent('move', this, ax, ay);
11264 setPagePosition : function(x, y){
11265 if(x && typeof x[1] == 'number'){
11271 if(!this.boxReady){
11274 if(x === undefined || y === undefined){
11277 var p = this.getPositionEl().translatePoints(x, y);
11278 this.setPosition(p.left, p.top);
11283 afterRender : function(){
11284 Ext.BoxComponent.superclass.afterRender.call(this);
11286 this.resizeEl = Ext.get(this.resizeEl);
11288 if(this.positionEl){
11289 this.positionEl = Ext.get(this.positionEl);
11291 this.boxReady = true;
11292 Ext.isDefined(this.autoScroll) && this.setAutoScroll(this.autoScroll);
11293 this.setSize(this.width, this.height);
11294 if(this.x || this.y){
11295 this.setPosition(this.x, this.y);
11296 }else if(this.pageX || this.pageY){
11297 this.setPagePosition(this.pageX, this.pageY);
11302 syncSize : function(){
11303 delete this.lastSize;
11304 this.setSize(this.autoWidth ? undefined : this.getResizeEl().getWidth(), this.autoHeight ? undefined : this.getResizeEl().getHeight());
11309 onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
11313 onPosition : function(x, y){
11318 adjustSize : function(w, h){
11319 if(this.autoWidth){
11322 if(this.autoHeight){
11325 return {width : w, height: h};
11329 adjustPosition : function(x, y){
11330 return {x : x, y: y};
11333 Ext.reg('box', Ext.BoxComponent);
11337 Ext.Spacer = Ext.extend(Ext.BoxComponent, {
11340 Ext.reg('spacer', Ext.Spacer);
11341 Ext.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){
11344 this.el = Ext.get(dragElement, true);
11345 this.el.dom.unselectable = "on";
11347 this.resizingEl = Ext.get(resizingElement, true);
11350 this.orientation = orientation || Ext.SplitBar.HORIZONTAL;
11357 this.maxSize = 2000;
11360 this.animate = false;
11363 this.useShim = false;
11368 if(!existingProxy){
11370 this.proxy = Ext.SplitBar.createProxy(this.orientation);
11372 this.proxy = Ext.get(existingProxy).dom;
11375 this.dd = new Ext.dd.DDProxy(this.el.dom.id, "XSplitBars", {dragElId : this.proxy.id});
11378 this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this);
11381 this.dd.endDrag = this.onEndProxyDrag.createDelegate(this);
11384 this.dragSpecs = {};
11387 this.adapter = new Ext.SplitBar.BasicLayoutAdapter();
11388 this.adapter.init(this);
11390 if(this.orientation == Ext.SplitBar.HORIZONTAL){
11392 this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? Ext.SplitBar.LEFT : Ext.SplitBar.RIGHT);
11393 this.el.addClass("x-splitbar-h");
11396 this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? Ext.SplitBar.TOP : Ext.SplitBar.BOTTOM);
11397 this.el.addClass("x-splitbar-v");
11411 Ext.SplitBar.superclass.constructor.call(this);
11414 Ext.extend(Ext.SplitBar, Ext.util.Observable, {
11415 onStartProxyDrag : function(x, y){
11416 this.fireEvent("beforeresize", this);
11417 this.overlay = Ext.DomHelper.append(document.body, {cls: "x-drag-overlay", html: " "}, true);
11418 this.overlay.unselectable();
11419 this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
11420 this.overlay.show();
11421 Ext.get(this.proxy).setDisplayed("block");
11422 var size = this.adapter.getElementSize(this);
11423 this.activeMinSize = this.getMinimumSize();
11424 this.activeMaxSize = this.getMaximumSize();
11425 var c1 = size - this.activeMinSize;
11426 var c2 = Math.max(this.activeMaxSize - size, 0);
11427 if(this.orientation == Ext.SplitBar.HORIZONTAL){
11428 this.dd.resetConstraints();
11429 this.dd.setXConstraint(
11430 this.placement == Ext.SplitBar.LEFT ? c1 : c2,
11431 this.placement == Ext.SplitBar.LEFT ? c2 : c1,
11434 this.dd.setYConstraint(0, 0);
11436 this.dd.resetConstraints();
11437 this.dd.setXConstraint(0, 0);
11438 this.dd.setYConstraint(
11439 this.placement == Ext.SplitBar.TOP ? c1 : c2,
11440 this.placement == Ext.SplitBar.TOP ? c2 : c1,
11444 this.dragSpecs.startSize = size;
11445 this.dragSpecs.startPoint = [x, y];
11446 Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd, x, y);
11450 onEndProxyDrag : function(e){
11451 Ext.get(this.proxy).setDisplayed(false);
11452 var endPoint = Ext.lib.Event.getXY(e);
11454 Ext.destroy(this.overlay);
11455 delete this.overlay;
11458 if(this.orientation == Ext.SplitBar.HORIZONTAL){
11459 newSize = this.dragSpecs.startSize +
11460 (this.placement == Ext.SplitBar.LEFT ?
11461 endPoint[0] - this.dragSpecs.startPoint[0] :
11462 this.dragSpecs.startPoint[0] - endPoint[0]
11465 newSize = this.dragSpecs.startSize +
11466 (this.placement == Ext.SplitBar.TOP ?
11467 endPoint[1] - this.dragSpecs.startPoint[1] :
11468 this.dragSpecs.startPoint[1] - endPoint[1]
11471 newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize);
11472 if(newSize != this.dragSpecs.startSize){
11473 if(this.fireEvent('beforeapply', this, newSize) !== false){
11474 this.adapter.setElementSize(this, newSize);
11475 this.fireEvent("moved", this, newSize);
11476 this.fireEvent("resize", this, newSize);
11482 getAdapter : function(){
11483 return this.adapter;
11487 setAdapter : function(adapter){
11488 this.adapter = adapter;
11489 this.adapter.init(this);
11493 getMinimumSize : function(){
11494 return this.minSize;
11498 setMinimumSize : function(minSize){
11499 this.minSize = minSize;
11503 getMaximumSize : function(){
11504 return this.maxSize;
11508 setMaximumSize : function(maxSize){
11509 this.maxSize = maxSize;
11513 setCurrentSize : function(size){
11514 var oldAnimate = this.animate;
11515 this.animate = false;
11516 this.adapter.setElementSize(this, size);
11517 this.animate = oldAnimate;
11521 destroy : function(removeEl){
11522 Ext.destroy(this.shim, Ext.get(this.proxy));
11527 this.purgeListeners();
11532 Ext.SplitBar.createProxy = function(dir){
11533 var proxy = new Ext.Element(document.createElement("div"));
11534 document.body.appendChild(proxy.dom);
11535 proxy.unselectable();
11536 var cls = 'x-splitbar-proxy';
11537 proxy.addClass(cls + ' ' + (dir == Ext.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v'));
11542 Ext.SplitBar.BasicLayoutAdapter = function(){
11545 Ext.SplitBar.BasicLayoutAdapter.prototype = {
11547 init : function(s){
11551 getElementSize : function(s){
11552 if(s.orientation == Ext.SplitBar.HORIZONTAL){
11553 return s.resizingEl.getWidth();
11555 return s.resizingEl.getHeight();
11560 setElementSize : function(s, newSize, onComplete){
11561 if(s.orientation == Ext.SplitBar.HORIZONTAL){
11563 s.resizingEl.setWidth(newSize);
11565 onComplete(s, newSize);
11568 s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut');
11573 s.resizingEl.setHeight(newSize);
11575 onComplete(s, newSize);
11578 s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut');
11585 Ext.SplitBar.AbsoluteLayoutAdapter = function(container){
11586 this.basic = new Ext.SplitBar.BasicLayoutAdapter();
11587 this.container = Ext.get(container);
11590 Ext.SplitBar.AbsoluteLayoutAdapter.prototype = {
11591 init : function(s){
11592 this.basic.init(s);
11595 getElementSize : function(s){
11596 return this.basic.getElementSize(s);
11599 setElementSize : function(s, newSize, onComplete){
11600 this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s]));
11603 moveSplitter : function(s){
11604 var yes = Ext.SplitBar;
11605 switch(s.placement){
11607 s.el.setX(s.resizingEl.getRight());
11610 s.el.setStyle("right", (this.container.getWidth() - s.resizingEl.getLeft()) + "px");
11613 s.el.setY(s.resizingEl.getBottom());
11616 s.el.setY(s.resizingEl.getTop() - s.el.getHeight());
11623 Ext.SplitBar.VERTICAL = 1;
11626 Ext.SplitBar.HORIZONTAL = 2;
11629 Ext.SplitBar.LEFT = 1;
11632 Ext.SplitBar.RIGHT = 2;
11635 Ext.SplitBar.TOP = 3;
11638 Ext.SplitBar.BOTTOM = 4;
11640 Ext.Container = Ext.extend(Ext.BoxComponent, {
11653 autoDestroy : true,
11656 forceLayout: false,
11660 defaultType : 'panel',
11663 resizeEvent: 'resize',
11666 bubbleEvents: ['add', 'remove'],
11669 initComponent : function(){
11670 Ext.Container.superclass.initComponent.call(this);
11686 var items = this.items;
11694 initItems : function(){
11696 this.items = new Ext.util.MixedCollection(false, this.getComponentId);
11702 setLayout : function(layout){
11703 if(this.layout && this.layout != layout){
11704 this.layout.setContainer(null);
11706 this.layout = layout;
11708 layout.setContainer(this);
11711 afterRender: function(){
11714 Ext.Container.superclass.afterRender.call(this);
11716 this.layout = 'auto';
11718 if(Ext.isObject(this.layout) && !this.layout.layout){
11719 this.layoutConfig = this.layout;
11720 this.layout = this.layoutConfig.type;
11722 if(Ext.isString(this.layout)){
11723 this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);
11725 this.setLayout(this.layout);
11728 if(this.activeItem !== undefined){
11729 var item = this.activeItem;
11730 delete this.activeItem;
11731 this.layout.setActiveItem(item);
11736 this.doLayout(false, true);
11741 if(this.monitorResize === true){
11742 Ext.EventManager.onWindowResize(this.doLayout, this, [false]);
11747 getLayoutTarget : function(){
11752 getComponentId : function(comp){
11753 return comp.getItemId();
11757 add : function(comp){
11759 var args = arguments.length > 1;
11760 if(args || Ext.isArray(comp)){
11762 Ext.each(args ? arguments : comp, function(c){
11763 result.push(this.add(c));
11767 var c = this.lookupComponent(this.applyDefaults(comp));
11768 var index = this.items.length;
11769 if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){
11772 c.onAdded(this, index);
11774 this.fireEvent('add', this, c, index);
11779 onAdd : function(c){
11784 onAdded : function(container, pos) {
11786 this.ownerCt = container;
11789 this.cascade(function(c){
11792 this.fireEvent('added', this, container, pos);
11796 insert : function(index, comp){
11798 var a = arguments, len = a.length;
11801 for(var i = len-1; i >= 1; --i) {
11802 result.push(this.insert(index, a[i]));
11806 var c = this.lookupComponent(this.applyDefaults(comp));
11807 index = Math.min(index, this.items.length);
11808 if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){
11809 if(c.ownerCt == this){
11810 this.items.remove(c);
11812 this.items.insert(index, c);
11813 c.onAdded(this, index);
11815 this.fireEvent('add', this, c, index);
11821 applyDefaults : function(c){
11822 var d = this.defaults;
11824 if(Ext.isFunction(d)){
11825 d = d.call(this, c);
11827 if(Ext.isString(c)){
11828 c = Ext.ComponentMgr.get(c);
11830 }else if(!c.events){
11840 onBeforeAdd : function(item){
11842 item.ownerCt.remove(item, false);
11844 if(this.hideBorders === true){
11845 item.border = (item.border === true);
11850 remove : function(comp, autoDestroy){
11852 var c = this.getComponent(comp);
11853 if(c && this.fireEvent('beforeremove', this, c) !== false){
11854 this.doRemove(c, autoDestroy);
11855 this.fireEvent('remove', this, c);
11860 onRemove: function(c){
11865 doRemove: function(c, autoDestroy){
11866 var l = this.layout,
11867 hasLayout = l && this.rendered;
11872 this.items.remove(c);
11875 if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){
11884 removeAll: function(autoDestroy){
11886 var item, rem = [], items = [];
11887 this.items.each(function(i){
11890 for (var i = 0, len = rem.length; i < len; ++i){
11892 this.remove(item, autoDestroy);
11893 if(item.ownerCt !== this){
11901 getComponent : function(comp){
11902 if(Ext.isObject(comp)){
11903 comp = comp.getItemId();
11905 return this.items.get(comp);
11909 lookupComponent : function(comp){
11910 if(Ext.isString(comp)){
11911 return Ext.ComponentMgr.get(comp);
11912 }else if(!comp.events){
11913 return this.createComponent(comp);
11919 createComponent : function(config, defaultType){
11920 if (config.render) {
11925 var c = Ext.create(Ext.apply({
11927 }, config), defaultType || this.defaultType);
11928 delete c.initialConfig.ownerCt;
11934 canLayout : function() {
11935 var el = this.getVisibilityEl();
11936 return el && el.dom && !el.isStyle("display", "none");
11941 doLayout : function(shallow, force){
11942 var rendered = this.rendered,
11943 forceLayout = force || this.forceLayout;
11945 if(this.collapsed || !this.canLayout()){
11946 this.deferLayout = this.deferLayout || !shallow;
11950 shallow = shallow && !this.deferLayout;
11952 delete this.deferLayout;
11954 if(rendered && this.layout){
11955 this.layout.layout();
11957 if(shallow !== true && this.items){
11958 var cs = this.items.items;
11959 for(var i = 0, len = cs.length; i < len; i++){
11962 c.doLayout(false, forceLayout);
11967 this.onLayout(shallow, forceLayout);
11970 this.hasLayout = true;
11971 delete this.forceLayout;
11974 onLayout : Ext.emptyFn,
11977 shouldBufferLayout: function(){
11979 var hl = this.hasLayout;
11982 return hl ? !this.hasLayoutPending() : false;
11989 hasLayoutPending: function(){
11991 var pending = false;
11992 this.ownerCt.bubble(function(c){
11993 if(c.layoutPending){
12001 onShow : function(){
12003 Ext.Container.superclass.onShow.call(this);
12005 if(Ext.isDefined(this.deferLayout)){
12006 delete this.deferLayout;
12007 this.doLayout(true);
12012 getLayout : function(){
12014 var layout = new Ext.layout.AutoLayout(this.layoutConfig);
12015 this.setLayout(layout);
12017 return this.layout;
12021 beforeDestroy : function(){
12024 while(c = this.items.first()){
12025 this.doRemove(c, true);
12028 if(this.monitorResize){
12029 Ext.EventManager.removeResizeListener(this.doLayout, this);
12031 Ext.destroy(this.layout);
12032 Ext.Container.superclass.beforeDestroy.call(this);
12036 bubble : function(fn, scope, args){
12039 if(fn.apply(scope || p, args || [p]) === false){
12048 cascade : function(fn, scope, args){
12049 if(fn.apply(scope || this, args || [this]) !== false){
12051 var cs = this.items.items;
12052 for(var i = 0, len = cs.length; i < len; i++){
12054 cs[i].cascade(fn, scope, args);
12056 fn.apply(scope || cs[i], args || [cs[i]]);
12065 findById : function(id){
12067 this.cascade(function(c){
12068 if(ct != c && c.id === id){
12077 findByType : function(xtype, shallow){
12078 return this.findBy(function(c){
12079 return c.isXType(xtype, shallow);
12084 find : function(prop, value){
12085 return this.findBy(function(c){
12086 return c[prop] === value;
12091 findBy : function(fn, scope){
12092 var m = [], ct = this;
12093 this.cascade(function(c){
12094 if(ct != c && fn.call(scope || c, c, ct) === true){
12102 get : function(key){
12103 return this.items.get(key);
12107 Ext.Container.LAYOUTS = {};
12108 Ext.reg('container', Ext.Container);
12110 Ext.layout.ContainerLayout = Ext.extend(Object, {
12117 monitorResize:false,
12121 constructor : function(config){
12122 this.id = Ext.id(null, 'ext-layout-');
12123 Ext.apply(this, config);
12129 IEMeasureHack : function(target, viewFlag) {
12130 var tChildren = target.dom.childNodes, tLen = tChildren.length, c, d = [], e, i, ret;
12131 for (i = 0 ; i < tLen ; i++) {
12135 d[i] = e.getStyle('display');
12136 e.setStyle({display: 'none'});
12139 ret = target ? target.getViewSize(viewFlag) : {};
12140 for (i = 0 ; i < tLen ; i++) {
12144 e.setStyle({display: d[i]});
12151 getLayoutTargetSize : Ext.EmptyFn,
12154 layout : function(){
12155 var ct = this.container, target = ct.getLayoutTarget();
12156 if(!(this.hasLayout || Ext.isEmpty(this.targetCls))){
12157 target.addClass(this.targetCls);
12159 this.onLayout(ct, target);
12160 ct.fireEvent('afterlayout', ct, this);
12164 onLayout : function(ct, target){
12165 this.renderAll(ct, target);
12169 isValidParent : function(c, target){
12170 return target && c.getPositionEl().dom.parentNode == (target.dom || target);
12174 renderAll : function(ct, target){
12175 var items = ct.items.items, i, c, len = items.length;
12176 for(i = 0; i < len; i++) {
12178 if(c && (!c.rendered || !this.isValidParent(c, target))){
12179 this.renderItem(c, i, target);
12185 renderItem : function(c, position, target){
12188 c.render(target, position);
12189 this.configureItem(c, position);
12190 } else if (!this.isValidParent(c, target)) {
12191 if (Ext.isNumber(position)) {
12192 position = target.dom.childNodes[position];
12195 target.dom.insertBefore(c.getPositionEl().dom, position || null);
12196 c.container = target;
12197 this.configureItem(c, position);
12204 getRenderedItems: function(ct){
12205 var t = ct.getLayoutTarget(), cti = ct.items.items, len = cti.length, i, c, items = [];
12206 for (i = 0; i < len; i++) {
12207 if((c = cti[i]).rendered && this.isValidParent(c, t)){
12215 configureItem: function(c, position){
12216 if (this.extraCls) {
12217 var t = c.getPositionEl ? c.getPositionEl() : c;
12218 t.addClass(this.extraCls);
12222 if (c.doLayout && this.forceLayout) {
12225 if (this.renderHidden && c != this.activeItem) {
12230 onRemove: function(c){
12231 if(this.activeItem == c){
12232 delete this.activeItem;
12234 if(c.rendered && this.extraCls){
12235 var t = c.getPositionEl ? c.getPositionEl() : c;
12236 t.removeClass(this.extraCls);
12240 afterRemove: function(c){
12241 if(c.removeRestore){
12242 c.removeMode = 'container';
12243 delete c.removeRestore;
12248 onResize: function(){
12249 var ct = this.container,
12254 if(b = ct.bufferResize && ct.shouldBufferLayout()){
12255 if(!this.resizeTask){
12256 this.resizeTask = new Ext.util.DelayedTask(this.runLayout, this);
12257 this.resizeBuffer = Ext.isNumber(b) ? b : 50;
12259 ct.layoutPending = true;
12260 this.resizeTask.delay(this.resizeBuffer);
12266 runLayout: function(){
12267 var ct = this.container;
12270 delete ct.layoutPending;
12274 setContainer : function(ct){
12276 if(this.monitorResize && ct != this.container){
12277 var old = this.container;
12279 old.un(old.resizeEvent, this.onResize, this);
12282 ct.on(ct.resizeEvent, this.onResize, this);
12285 this.container = ct;
12289 parseMargins : function(v){
12290 if (Ext.isNumber(v)) {
12293 var ms = v.split(' '),
12297 ms[1] = ms[2] = ms[3] = ms[0];
12298 } else if(len == 2) {
12301 } else if(len == 3) {
12306 top :parseInt(ms[0], 10) || 0,
12307 right :parseInt(ms[1], 10) || 0,
12308 bottom:parseInt(ms[2], 10) || 0,
12309 left :parseInt(ms[3], 10) || 0
12314 fieldTpl: (function() {
12315 var t = new Ext.Template(
12316 '<div class="x-form-item {itemCls}" tabIndex="-1">',
12317 '<label for="{id}" style="{labelStyle}" class="x-form-item-label">{label}{labelSeparator}</label>',
12318 '<div class="x-form-element" id="x-form-el-{id}" style="{elementStyle}">',
12319 '</div><div class="{clearCls}"></div>',
12322 t.disableFormats = true;
12323 return t.compile();
12327 destroy : function(){
12329 if(this.resizeTask && this.resizeTask.cancel){
12330 this.resizeTask.cancel();
12332 if(!Ext.isEmpty(this.targetCls)){
12333 var target = this.container.getLayoutTarget();
12335 target.removeClass(this.targetCls);
12340 Ext.layout.AutoLayout = Ext.extend(Ext.layout.ContainerLayout, {
12343 monitorResize: true,
12345 onLayout : function(ct, target){
12346 Ext.layout.AutoLayout.superclass.onLayout.call(this, ct, target);
12347 var cs = this.getRenderedItems(ct), len = cs.length, i, c;
12348 for(i = 0; i < len; i++){
12358 Ext.Container.LAYOUTS['auto'] = Ext.layout.AutoLayout;
12360 Ext.layout.FitLayout = Ext.extend(Ext.layout.ContainerLayout, {
12362 monitorResize:true,
12366 getLayoutTargetSize : function() {
12367 var target = this.container.getLayoutTarget();
12372 return target.getStyleSize();
12376 onLayout : function(ct, target){
12377 Ext.layout.FitLayout.superclass.onLayout.call(this, ct, target);
12379 this.setItemSize(this.activeItem || ct.items.itemAt(0), this.getLayoutTargetSize());
12384 setItemSize : function(item, size){
12385 if(item && size.height > 0){
12386 item.setSize(size);
12390 Ext.Container.LAYOUTS['fit'] = Ext.layout.FitLayout;
12391 Ext.layout.CardLayout = Ext.extend(Ext.layout.FitLayout, {
12393 deferredRender : false,
12396 layoutOnCardChange : false,
12400 renderHidden : true,
12405 setActiveItem : function(item){
12406 var ai = this.activeItem,
12407 ct = this.container;
12408 item = ct.getComponent(item);
12411 if(item && ai != item){
12416 if (ai.hidden !== true) {
12419 ai.fireEvent('deactivate', ai);
12422 var layout = item.doLayout && (this.layoutOnCardChange || !item.rendered);
12425 this.activeItem = item;
12429 delete item.deferLayout;
12439 item.fireEvent('activate', item);
12444 renderAll : function(ct, target){
12445 if(this.deferredRender){
12446 this.renderItem(this.activeItem, undefined, target);
12448 Ext.layout.CardLayout.superclass.renderAll.call(this, ct, target);
12452 Ext.Container.LAYOUTS['card'] = Ext.layout.CardLayout;
12454 Ext.layout.AnchorLayout = Ext.extend(Ext.layout.ContainerLayout, {
12458 monitorResize : true,
12463 defaultAnchor : '100%',
12465 parseAnchorRE : /^(r|right|b|bottom)$/i,
12467 getLayoutTargetSize : function() {
12468 var target = this.container.getLayoutTarget();
12473 return target.getStyleSize();
12477 onLayout : function(ct, target){
12478 Ext.layout.AnchorLayout.superclass.onLayout.call(this, ct, target);
12479 var size = this.getLayoutTargetSize();
12481 var w = size.width, h = size.height;
12483 if(w < 20 && h < 20){
12490 if(typeof ct.anchorSize == 'number'){
12491 aw = ct.anchorSize;
12493 aw = ct.anchorSize.width;
12494 ah = ct.anchorSize.height;
12497 aw = ct.initialConfig.width;
12498 ah = ct.initialConfig.height;
12501 var cs = this.getRenderedItems(ct), len = cs.length, i, c, a, cw, ch, el, vs, boxes = [];
12502 for(i = 0; i < len; i++){
12504 el = c.getPositionEl();
12507 if (!c.anchor && c.items && !Ext.isNumber(c.width) && !(Ext.isIE6 && Ext.isStrict)){
12508 c.anchor = this.defaultAnchor;
12514 vs = c.anchor.split(' ');
12515 c.anchorSpec = a = {
12516 right: this.parseAnchor(vs[0], c.initialConfig.width, aw),
12517 bottom: this.parseAnchor(vs[1], c.initialConfig.height, ah)
12520 cw = a.right ? this.adjustWidthAnchor(a.right(w) - el.getMargins('lr'), c) : undefined;
12521 ch = a.bottom ? this.adjustHeightAnchor(a.bottom(h) - el.getMargins('tb'), c) : undefined;
12526 width: cw || undefined,
12527 height: ch || undefined
12532 for (i = 0, len = boxes.length; i < len; i++) {
12534 c.comp.setSize(c.width, c.height);
12539 parseAnchor : function(a, start, cstart){
12540 if(a && a != 'none'){
12543 if(this.parseAnchorRE.test(a)){
12544 var diff = cstart - start;
12545 return function(v){
12552 }else if(a.indexOf('%') != -1){
12553 var ratio = parseFloat(a.replace('%', ''))*.01;
12554 return function(v){
12557 return Math.floor(v*ratio);
12562 a = parseInt(a, 10);
12564 return function(v){
12577 adjustWidthAnchor : function(value, comp){
12582 adjustHeightAnchor : function(value, comp){
12588 Ext.Container.LAYOUTS['anchor'] = Ext.layout.AnchorLayout;
12590 Ext.layout.ColumnLayout = Ext.extend(Ext.layout.ContainerLayout, {
12592 monitorResize:true,
12596 extraCls: 'x-column',
12602 targetCls: 'x-column-layout-ct',
12604 isValidParent : function(c, target){
12605 return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom;
12608 getLayoutTargetSize : function() {
12609 var target = this.container.getLayoutTarget(), ret;
12611 ret = target.getViewSize();
12616 if (Ext.isIE && Ext.isStrict && ret.width == 0){
12617 ret = target.getStyleSize();
12620 ret.width -= target.getPadding('lr');
12621 ret.height -= target.getPadding('tb');
12626 renderAll : function(ct, target) {
12630 this.innerCt = target.createChild({cls:'x-column-inner'});
12631 this.innerCt.createChild({cls:'x-clear'});
12633 Ext.layout.ColumnLayout.superclass.renderAll.call(this, ct, this.innerCt);
12637 onLayout : function(ct, target){
12638 var cs = ct.items.items,
12645 this.renderAll(ct, target);
12647 var size = this.getLayoutTargetSize();
12649 if(size.width < 1 && size.height < 1){
12653 var w = size.width - this.scrollOffset,
12657 this.innerCt.setWidth(w);
12662 for(i = 0; i < len; i++){
12664 m = c.getPositionEl().getMargins('lr');
12666 if(!c.columnWidth){
12667 pw -= (c.getWidth() + m);
12671 pw = pw < 0 ? 0 : pw;
12673 for(i = 0; i < len; i++){
12677 c.setSize(Math.floor(c.columnWidth * pw) - m);
12684 if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) {
12685 var ts = this.getLayoutTargetSize();
12686 if (ts.width != size.width){
12687 this.adjustmentPass = true;
12688 this.onLayout(ct, target);
12692 delete this.adjustmentPass;
12698 Ext.Container.LAYOUTS['column'] = Ext.layout.ColumnLayout;
12700 Ext.layout.BorderLayout = Ext.extend(Ext.layout.ContainerLayout, {
12702 monitorResize:true,
12708 targetCls: 'x-border-layout-ct',
12710 getLayoutTargetSize : function() {
12711 var target = this.container.getLayoutTarget();
12712 return target ? target.getViewSize() : {};
12716 onLayout : function(ct, target){
12717 var collapsed, i, c, pos, items = ct.items.items, len = items.length;
12718 if(!this.rendered){
12720 for(i = 0; i < len; i++) {
12726 c.collapsed = false;
12728 c.render(target, i);
12729 c.getPositionEl().addClass('x-border-panel');
12731 this[pos] = pos != 'center' && c.split ?
12732 new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) :
12733 new Ext.layout.BorderLayout.Region(this, c.initialConfig, pos);
12734 this[pos].render(target, c);
12736 this.rendered = true;
12739 var size = this.getLayoutTargetSize();
12740 if(size.width < 20 || size.height < 20){
12742 this.restoreCollapsed = collapsed;
12745 }else if(this.restoreCollapsed){
12746 collapsed = this.restoreCollapsed;
12747 delete this.restoreCollapsed;
12750 var w = size.width, h = size.height,
12751 centerW = w, centerH = h, centerY = 0, centerX = 0,
12752 n = this.north, s = this.south, west = this.west, e = this.east, c = this.center,
12753 b, m, totalWidth, totalHeight;
12754 if(!c && Ext.layout.BorderLayout.WARN !== false){
12755 throw 'No center region defined in BorderLayout ' + ct.id;
12758 if(n && n.isVisible()){
12760 m = n.getMargins();
12761 b.width = w - (m.left+m.right);
12764 centerY = b.height + b.y + m.bottom;
12765 centerH -= centerY;
12768 if(s && s.isVisible()){
12770 m = s.getMargins();
12771 b.width = w - (m.left+m.right);
12773 totalHeight = (b.height + m.top + m.bottom);
12774 b.y = h - totalHeight + m.top;
12775 centerH -= totalHeight;
12778 if(west && west.isVisible()){
12779 b = west.getSize();
12780 m = west.getMargins();
12781 b.height = centerH - (m.top+m.bottom);
12783 b.y = centerY + m.top;
12784 totalWidth = (b.width + m.left + m.right);
12785 centerX += totalWidth;
12786 centerW -= totalWidth;
12787 west.applyLayout(b);
12789 if(e && e.isVisible()){
12791 m = e.getMargins();
12792 b.height = centerH - (m.top+m.bottom);
12793 totalWidth = (b.width + m.left + m.right);
12794 b.x = w - totalWidth + m.left;
12795 b.y = centerY + m.top;
12796 centerW -= totalWidth;
12800 m = c.getMargins();
12802 x: centerX + m.left,
12803 y: centerY + m.top,
12804 width: centerW - (m.left+m.right),
12805 height: centerH - (m.top+m.bottom)
12807 c.applyLayout(centerBox);
12810 for(i = 0, len = collapsed.length; i < len; i++){
12811 collapsed[i].collapse(false);
12814 if(Ext.isIE && Ext.isStrict){
12818 if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) {
12819 var ts = this.getLayoutTargetSize();
12820 if (ts.width != size.width || ts.height != size.height){
12821 this.adjustmentPass = true;
12822 this.onLayout(ct, target);
12825 delete this.adjustmentPass;
12828 destroy: function() {
12829 var r = ['north', 'south', 'east', 'west'], i, region;
12830 for (i = 0; i < r.length; i++) {
12831 region = this[r[i]];
12833 if(region.destroy){
12835 }else if (region.split){
12836 region.split.destroy(true);
12840 Ext.layout.BorderLayout.superclass.destroy.call(this);
12847 Ext.layout.BorderLayout.Region = function(layout, config, pos){
12848 Ext.apply(this, config);
12849 this.layout = layout;
12850 this.position = pos;
12852 if(typeof this.margins == 'string'){
12853 this.margins = this.layout.parseMargins(this.margins);
12855 this.margins = Ext.applyIf(this.margins || {}, this.defaultMargins);
12856 if(this.collapsible){
12857 if(typeof this.cmargins == 'string'){
12858 this.cmargins = this.layout.parseMargins(this.cmargins);
12860 if(this.collapseMode == 'mini' && !this.cmargins){
12861 this.cmargins = {left:0,top:0,right:0,bottom:0};
12863 this.cmargins = Ext.applyIf(this.cmargins || {},
12864 pos == 'north' || pos == 'south' ? this.defaultNSCMargins : this.defaultEWCMargins);
12869 Ext.layout.BorderLayout.Region.prototype = {
12876 collapsible : false,
12887 defaultMargins : {left:0,top:0,right:0,bottom:0},
12889 defaultNSCMargins : {left:5,top:5,right:5,bottom:5},
12891 defaultEWCMargins : {left:5,top:0,right:5,bottom:0},
12892 floatingZIndex: 100,
12895 isCollapsed : false,
12902 render : function(ct, p){
12904 p.el.enableDisplayMode();
12905 this.targetEl = ct;
12908 var gs = p.getState, ps = this.position;
12909 p.getState = function(){
12910 return Ext.apply(gs.call(p) || {}, this.state);
12911 }.createDelegate(this);
12913 if(ps != 'center'){
12914 p.allowQueuedExpand = false;
12916 beforecollapse: this.beforeCollapse,
12917 collapse: this.onCollapse,
12918 beforeexpand: this.beforeExpand,
12919 expand: this.onExpand,
12924 if(this.collapsible || this.floatable){
12925 p.collapseEl = 'el';
12926 p.slideAnchor = this.getSlideAnchor();
12928 if(p.tools && p.tools.toggle){
12929 p.tools.toggle.addClass('x-tool-collapse-'+ps);
12930 p.tools.toggle.addClassOnOver('x-tool-collapse-'+ps+'-over');
12936 getCollapsedEl : function(){
12937 if(!this.collapsedEl){
12938 if(!this.toolTemplate){
12939 var tt = new Ext.Template(
12940 '<div class="x-tool x-tool-{id}"> </div>'
12942 tt.disableFormats = true;
12944 Ext.layout.BorderLayout.Region.prototype.toolTemplate = tt;
12946 this.collapsedEl = this.targetEl.createChild({
12947 cls: "x-layout-collapsed x-layout-collapsed-"+this.position,
12948 id: this.panel.id + '-xcollapsed'
12950 this.collapsedEl.enableDisplayMode('block');
12952 if(this.collapseMode == 'mini'){
12953 this.collapsedEl.addClass('x-layout-cmini-'+this.position);
12954 this.miniCollapsedEl = this.collapsedEl.createChild({
12955 cls: "x-layout-mini x-layout-mini-"+this.position, html: " "
12957 this.miniCollapsedEl.addClassOnOver('x-layout-mini-over');
12958 this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
12959 this.collapsedEl.on('click', this.onExpandClick, this, {stopEvent:true});
12961 if(this.collapsible !== false && !this.hideCollapseTool) {
12962 var t = this.toolTemplate.append(
12963 this.collapsedEl.dom,
12964 {id:'expand-'+this.position}, true);
12965 t.addClassOnOver('x-tool-expand-'+this.position+'-over');
12966 t.on('click', this.onExpandClick, this, {stopEvent:true});
12968 if(this.floatable !== false || this.titleCollapse){
12969 this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
12970 this.collapsedEl.on("click", this[this.floatable ? 'collapseClick' : 'onExpandClick'], this);
12974 return this.collapsedEl;
12978 onExpandClick : function(e){
12980 this.panel.expand(false);
12982 this.panel.expand();
12987 onCollapseClick : function(e){
12988 this.panel.collapse();
12992 beforeCollapse : function(p, animate){
12993 this.lastAnim = animate;
12995 this.splitEl.hide();
12997 this.getCollapsedEl().show();
12998 var el = this.panel.getEl();
12999 this.originalZIndex = el.getStyle('z-index');
13000 el.setStyle('z-index', 100);
13001 this.isCollapsed = true;
13002 this.layout.layout();
13006 onCollapse : function(animate){
13007 this.panel.el.setStyle('z-index', 1);
13008 if(this.lastAnim === false || this.panel.animCollapse === false){
13009 this.getCollapsedEl().dom.style.visibility = 'visible';
13011 this.getCollapsedEl().slideIn(this.panel.slideAnchor, {duration:.2});
13013 this.state.collapsed = true;
13014 this.panel.saveState();
13018 beforeExpand : function(animate){
13020 this.afterSlideIn();
13022 var c = this.getCollapsedEl();
13024 if(this.position == 'east' || this.position == 'west'){
13025 this.panel.setSize(undefined, c.getHeight());
13027 this.panel.setSize(c.getWidth(), undefined);
13030 c.dom.style.visibility = 'hidden';
13031 this.panel.el.setStyle('z-index', this.floatingZIndex);
13035 onExpand : function(){
13036 this.isCollapsed = false;
13038 this.splitEl.show();
13040 this.layout.layout();
13041 this.panel.el.setStyle('z-index', this.originalZIndex);
13042 this.state.collapsed = false;
13043 this.panel.saveState();
13047 collapseClick : function(e){
13049 e.stopPropagation();
13052 e.stopPropagation();
13058 onHide : function(){
13059 if(this.isCollapsed){
13060 this.getCollapsedEl().hide();
13061 }else if(this.splitEl){
13062 this.splitEl.hide();
13067 onShow : function(){
13068 if(this.isCollapsed){
13069 this.getCollapsedEl().show();
13070 }else if(this.splitEl){
13071 this.splitEl.show();
13076 isVisible : function(){
13077 return !this.panel.hidden;
13081 getMargins : function(){
13082 return this.isCollapsed && this.cmargins ? this.cmargins : this.margins;
13086 getSize : function(){
13087 return this.isCollapsed ? this.getCollapsedEl().getSize() : this.panel.getSize();
13091 setPanel : function(panel){
13092 this.panel = panel;
13096 getMinWidth: function(){
13097 return this.minWidth;
13101 getMinHeight: function(){
13102 return this.minHeight;
13106 applyLayoutCollapsed : function(box){
13107 var ce = this.getCollapsedEl();
13108 ce.setLeftTop(box.x, box.y);
13109 ce.setSize(box.width, box.height);
13113 applyLayout : function(box){
13114 if(this.isCollapsed){
13115 this.applyLayoutCollapsed(box);
13117 this.panel.setPosition(box.x, box.y);
13118 this.panel.setSize(box.width, box.height);
13123 beforeSlide: function(){
13124 this.panel.beforeEffect();
13128 afterSlide : function(){
13129 this.panel.afterEffect();
13133 initAutoHide : function(){
13134 if(this.autoHide !== false){
13135 if(!this.autoHideHd){
13136 this.autoHideSlideTask = new Ext.util.DelayedTask(this.slideIn, this);
13137 this.autoHideHd = {
13138 "mouseout": function(e){
13139 if(!e.within(this.el, true)){
13140 this.autoHideSlideTask.delay(500);
13143 "mouseover" : function(e){
13144 this.autoHideSlideTask.cancel();
13149 this.el.on(this.autoHideHd);
13150 this.collapsedEl.on(this.autoHideHd);
13155 clearAutoHide : function(){
13156 if(this.autoHide !== false){
13157 this.el.un("mouseout", this.autoHideHd.mouseout);
13158 this.el.un("mouseover", this.autoHideHd.mouseover);
13159 this.collapsedEl.un("mouseout", this.autoHideHd.mouseout);
13160 this.collapsedEl.un("mouseover", this.autoHideHd.mouseover);
13165 clearMonitor : function(){
13166 Ext.getDoc().un("click", this.slideInIf, this);
13170 slideOut : function(){
13171 if(this.isSlid || this.el.hasActiveFx()){
13174 this.isSlid = true;
13175 var ts = this.panel.tools, dh, pc;
13176 if(ts && ts.toggle){
13182 pc = this.panel.collapsed;
13183 this.panel.collapsed = false;
13185 if(this.position == 'east' || this.position == 'west'){
13187 dh = this.panel.deferHeight;
13188 this.panel.deferHeight = false;
13190 this.panel.setSize(undefined, this.collapsedEl.getHeight());
13193 this.panel.deferHeight = dh;
13195 this.panel.setSize(this.collapsedEl.getWidth(), undefined);
13199 this.panel.collapsed = pc;
13201 this.restoreLT = [this.el.dom.style.left, this.el.dom.style.top];
13202 this.el.alignTo(this.collapsedEl, this.getCollapseAnchor());
13203 this.el.setStyle("z-index", this.floatingZIndex+2);
13204 this.panel.el.replaceClass('x-panel-collapsed', 'x-panel-floating');
13205 if(this.animFloat !== false){
13206 this.beforeSlide();
13207 this.el.slideIn(this.getSlideAnchor(), {
13208 callback: function(){
13210 this.initAutoHide();
13211 Ext.getDoc().on("click", this.slideInIf, this);
13217 this.initAutoHide();
13218 Ext.getDoc().on("click", this.slideInIf, this);
13223 afterSlideIn : function(){
13224 this.clearAutoHide();
13225 this.isSlid = false;
13226 this.clearMonitor();
13227 this.el.setStyle("z-index", "");
13228 this.panel.el.replaceClass('x-panel-floating', 'x-panel-collapsed');
13229 this.el.dom.style.left = this.restoreLT[0];
13230 this.el.dom.style.top = this.restoreLT[1];
13232 var ts = this.panel.tools;
13233 if(ts && ts.toggle){
13239 slideIn : function(cb){
13240 if(!this.isSlid || this.el.hasActiveFx()){
13244 this.isSlid = false;
13245 if(this.animFloat !== false){
13246 this.beforeSlide();
13247 this.el.slideOut(this.getSlideAnchor(), {
13248 callback: function(){
13251 this.afterSlideIn();
13259 this.afterSlideIn();
13264 slideInIf : function(e){
13265 if(!e.within(this.el)){
13295 getAnchor : function(){
13296 return this.anchors[this.position];
13300 getCollapseAnchor : function(){
13301 return this.canchors[this.position];
13305 getSlideAnchor : function(){
13306 return this.sanchors[this.position];
13310 getAlignAdj : function(){
13311 var cm = this.cmargins;
13312 switch(this.position){
13329 getExpandAdj : function(){
13330 var c = this.collapsedEl, cm = this.cmargins;
13331 switch(this.position){
13333 return [-(cm.right+c.getWidth()+cm.left), 0];
13336 return [cm.right+c.getWidth()+cm.left, 0];
13339 return [0, -(cm.top+cm.bottom+c.getHeight())];
13342 return [0, cm.top+cm.bottom+c.getHeight()];
13347 destroy : function(){
13348 if (this.autoHideSlideTask && this.autoHideSlideTask.cancel){
13349 this.autoHideSlideTask.cancel();
13351 Ext.destroy(this.miniCollapsedEl, this.collapsedEl);
13356 Ext.layout.BorderLayout.SplitRegion = function(layout, config, pos){
13357 Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this, layout, config, pos);
13359 this.applyLayout = this.applyFns[pos];
13362 Ext.extend(Ext.layout.BorderLayout.SplitRegion, Ext.layout.BorderLayout.Region, {
13365 splitTip : "Drag to resize.",
13367 collapsibleSplitTip : "Drag to resize. Double click to hide.",
13369 useSplitTips : false,
13374 orientation: Ext.SplitBar.VERTICAL,
13375 placement: Ext.SplitBar.TOP,
13376 maxFn : 'getVMaxSize',
13377 minProp: 'minHeight',
13378 maxProp: 'maxHeight'
13381 orientation: Ext.SplitBar.VERTICAL,
13382 placement: Ext.SplitBar.BOTTOM,
13383 maxFn : 'getVMaxSize',
13384 minProp: 'minHeight',
13385 maxProp: 'maxHeight'
13388 orientation: Ext.SplitBar.HORIZONTAL,
13389 placement: Ext.SplitBar.RIGHT,
13390 maxFn : 'getHMaxSize',
13391 minProp: 'minWidth',
13392 maxProp: 'maxWidth'
13395 orientation: Ext.SplitBar.HORIZONTAL,
13396 placement: Ext.SplitBar.LEFT,
13397 maxFn : 'getHMaxSize',
13398 minProp: 'minWidth',
13399 maxProp: 'maxWidth'
13405 west : function(box){
13406 if(this.isCollapsed){
13407 return this.applyLayoutCollapsed(box);
13409 var sd = this.splitEl.dom, s = sd.style;
13410 this.panel.setPosition(box.x, box.y);
13411 var sw = sd.offsetWidth;
13412 s.left = (box.x+box.width-sw)+'px';
13413 s.top = (box.y)+'px';
13414 s.height = Math.max(0, box.height)+'px';
13415 this.panel.setSize(box.width-sw, box.height);
13417 east : function(box){
13418 if(this.isCollapsed){
13419 return this.applyLayoutCollapsed(box);
13421 var sd = this.splitEl.dom, s = sd.style;
13422 var sw = sd.offsetWidth;
13423 this.panel.setPosition(box.x+sw, box.y);
13424 s.left = (box.x)+'px';
13425 s.top = (box.y)+'px';
13426 s.height = Math.max(0, box.height)+'px';
13427 this.panel.setSize(box.width-sw, box.height);
13429 north : function(box){
13430 if(this.isCollapsed){
13431 return this.applyLayoutCollapsed(box);
13433 var sd = this.splitEl.dom, s = sd.style;
13434 var sh = sd.offsetHeight;
13435 this.panel.setPosition(box.x, box.y);
13436 s.left = (box.x)+'px';
13437 s.top = (box.y+box.height-sh)+'px';
13438 s.width = Math.max(0, box.width)+'px';
13439 this.panel.setSize(box.width, box.height-sh);
13441 south : function(box){
13442 if(this.isCollapsed){
13443 return this.applyLayoutCollapsed(box);
13445 var sd = this.splitEl.dom, s = sd.style;
13446 var sh = sd.offsetHeight;
13447 this.panel.setPosition(box.x, box.y+sh);
13448 s.left = (box.x)+'px';
13449 s.top = (box.y)+'px';
13450 s.width = Math.max(0, box.width)+'px';
13451 this.panel.setSize(box.width, box.height-sh);
13456 render : function(ct, p){
13457 Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p);
13459 var ps = this.position;
13461 this.splitEl = ct.createChild({
13462 cls: "x-layout-split x-layout-split-"+ps, html: " ",
13463 id: this.panel.id + '-xsplit'
13466 if(this.collapseMode == 'mini'){
13467 this.miniSplitEl = this.splitEl.createChild({
13468 cls: "x-layout-mini x-layout-mini-"+ps, html: " "
13470 this.miniSplitEl.addClassOnOver('x-layout-mini-over');
13471 this.miniSplitEl.on('click', this.onCollapseClick, this, {stopEvent:true});
13474 var s = this.splitSettings[ps];
13476 this.split = new Ext.SplitBar(this.splitEl.dom, p.el, s.orientation);
13477 this.split.tickSize = this.tickSize;
13478 this.split.placement = s.placement;
13479 this.split.getMaximumSize = this[s.maxFn].createDelegate(this);
13480 this.split.minSize = this.minSize || this[s.minProp];
13481 this.split.on("beforeapply", this.onSplitMove, this);
13482 this.split.useShim = this.useShim === true;
13483 this.maxSize = this.maxSize || this[s.maxProp];
13486 this.splitEl.hide();
13489 if(this.useSplitTips){
13490 this.splitEl.dom.title = this.collapsible ? this.collapsibleSplitTip : this.splitTip;
13492 if(this.collapsible){
13493 this.splitEl.on("dblclick", this.onCollapseClick, this);
13498 getSize : function(){
13499 if(this.isCollapsed){
13500 return this.collapsedEl.getSize();
13502 var s = this.panel.getSize();
13503 if(this.position == 'north' || this.position == 'south'){
13504 s.height += this.splitEl.dom.offsetHeight;
13506 s.width += this.splitEl.dom.offsetWidth;
13512 getHMaxSize : function(){
13513 var cmax = this.maxSize || 10000;
13514 var center = this.layout.center;
13515 return Math.min(cmax, (this.el.getWidth()+center.el.getWidth())-center.getMinWidth());
13519 getVMaxSize : function(){
13520 var cmax = this.maxSize || 10000;
13521 var center = this.layout.center;
13522 return Math.min(cmax, (this.el.getHeight()+center.el.getHeight())-center.getMinHeight());
13526 onSplitMove : function(split, newSize){
13527 var s = this.panel.getSize();
13528 this.lastSplitSize = newSize;
13529 if(this.position == 'north' || this.position == 'south'){
13530 this.panel.setSize(s.width, newSize);
13531 this.state.height = newSize;
13533 this.panel.setSize(newSize, s.height);
13534 this.state.width = newSize;
13536 this.layout.layout();
13537 this.panel.saveState();
13542 getSplitBar : function(){
13547 destroy : function() {
13548 Ext.destroy(this.miniSplitEl, this.split, this.splitEl);
13549 Ext.layout.BorderLayout.SplitRegion.superclass.destroy.call(this);
13553 Ext.Container.LAYOUTS['border'] = Ext.layout.BorderLayout;
13554 Ext.layout.FormLayout = Ext.extend(Ext.layout.AnchorLayout, {
13557 labelSeparator : ':',
13562 trackLabels: false,
13566 onRemove: function(c){
13567 Ext.layout.FormLayout.superclass.onRemove.call(this, c);
13568 if(this.trackLabels){
13569 c.un('show', this.onFieldShow, this);
13570 c.un('hide', this.onFieldHide, this);
13573 var el = c.getPositionEl(),
13574 ct = c.getItemCt && c.getItemCt();
13575 if (c.rendered && ct) {
13576 if (el && el.dom) {
13577 el.insertAfter(ct);
13580 Ext.destroyMembers(c, 'label', 'itemCt');
13581 if (c.customItemCt) {
13582 Ext.destroyMembers(c, 'getItemCt', 'customItemCt');
13588 setContainer : function(ct){
13589 Ext.layout.FormLayout.superclass.setContainer.call(this, ct);
13591 ct.addClass('x-form-label-'+ct.labelAlign);
13596 labelStyle: 'display:none',
13597 elementStyle: 'padding-left:0;',
13601 this.labelSeparator = ct.labelSeparator || this.labelSeparator;
13602 ct.labelWidth = ct.labelWidth || 100;
13603 if(Ext.isNumber(ct.labelWidth)){
13604 var pad = Ext.isNumber(ct.labelPad) ? ct.labelPad : 5;
13606 labelAdjust: ct.labelWidth + pad,
13607 labelStyle: 'width:' + ct.labelWidth + 'px;',
13608 elementStyle: 'padding-left:' + (ct.labelWidth + pad) + 'px'
13611 if(ct.labelAlign == 'top'){
13613 labelStyle: 'width:auto;',
13615 elementStyle: 'padding-left:0;'
13622 isHide: function(c){
13623 return c.hideLabel || this.container.hideLabels;
13626 onFieldShow: function(c){
13627 c.getItemCt().removeClass('x-hide-' + c.hideMode);
13630 if (c.isComposite) {
13635 onFieldHide: function(c){
13636 c.getItemCt().addClass('x-hide-' + c.hideMode);
13640 getLabelStyle: function(s){
13641 var ls = '', items = [this.labelStyle, s];
13642 for (var i = 0, len = items.length; i < len; ++i){
13645 if (ls.substr(-1, 1) != ';'){
13656 renderItem : function(c, position, target){
13657 if(c && (c.isFormField || c.fieldLabel) && c.inputType != 'hidden'){
13658 var args = this.getTemplateArgs(c);
13659 if(Ext.isNumber(position)){
13660 position = target.dom.childNodes[position] || null;
13663 c.itemCt = this.fieldTpl.insertBefore(position, args, true);
13665 c.itemCt = this.fieldTpl.append(target, args, true);
13671 getItemCt: function(){
13677 c.label = c.getItemCt().child('label.x-form-item-label');
13679 c.render('x-form-el-' + c.id);
13680 }else if(!this.isValidParent(c, target)){
13681 Ext.fly('x-form-el-' + c.id).appendChild(c.getPositionEl());
13683 if(this.trackLabels){
13685 this.onFieldHide(c);
13689 show: this.onFieldShow,
13690 hide: this.onFieldHide
13693 this.configureItem(c);
13695 Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
13700 getTemplateArgs: function(field) {
13701 var noLabelSep = !field.fieldLabel || field.hideLabel;
13705 label : field.fieldLabel,
13706 itemCls : (field.itemCls || this.container.itemCls || '') + (field.hideLabel ? ' x-hide-label' : ''),
13707 clearCls : field.clearCls || 'x-form-clear-left',
13708 labelStyle : this.getLabelStyle(field.labelStyle),
13709 elementStyle : this.elementStyle || '',
13710 labelSeparator: noLabelSep ? '' : (Ext.isDefined(field.labelSeparator) ? field.labelSeparator : this.labelSeparator)
13715 adjustWidthAnchor: function(value, c){
13716 if(c.label && !this.isHide(c) && (this.container.labelAlign != 'top')){
13717 var adjust = Ext.isIE6 || (Ext.isIE && !Ext.isStrict);
13718 return value - this.labelAdjust + (adjust ? -3 : 0);
13723 adjustHeightAnchor : function(value, c){
13724 if(c.label && !this.isHide(c) && (this.container.labelAlign == 'top')){
13725 return value - c.label.getHeight();
13731 isValidParent : function(c, target){
13732 return target && this.container.getEl().contains(c.getPositionEl());
13738 Ext.Container.LAYOUTS['form'] = Ext.layout.FormLayout;
13740 Ext.layout.AccordionLayout = Ext.extend(Ext.layout.FitLayout, {
13746 titleCollapse : true,
13748 hideCollapseTool : false,
13750 collapseFirst : false,
13756 activeOnTop : false,
13760 renderItem : function(c){
13761 if(this.animate === false){
13762 c.animCollapse = false;
13764 c.collapsible = true;
13765 if(this.autoWidth){
13766 c.autoWidth = true;
13768 if(this.titleCollapse){
13769 c.titleCollapse = true;
13771 if(this.hideCollapseTool){
13772 c.hideCollapseTool = true;
13774 if(this.collapseFirst !== undefined){
13775 c.collapseFirst = this.collapseFirst;
13777 if(!this.activeItem && !c.collapsed){
13778 this.setActiveItem(c, true);
13779 }else if(this.activeItem && this.activeItem != c){
13780 c.collapsed = true;
13782 Ext.layout.AccordionLayout.superclass.renderItem.apply(this, arguments);
13783 c.header.addClass('x-accordion-hd');
13784 c.on('beforeexpand', this.beforeExpand, this);
13787 onRemove: function(c){
13788 Ext.layout.AccordionLayout.superclass.onRemove.call(this, c);
13790 c.header.removeClass('x-accordion-hd');
13792 c.un('beforeexpand', this.beforeExpand, this);
13796 beforeExpand : function(p, anim){
13797 var ai = this.activeItem;
13800 delete this.activeItem;
13801 if (!ai.collapsed){
13802 ai.collapse({callback:function(){
13803 p.expand(anim || true);
13808 ai.collapse(this.animate);
13812 if(this.activeOnTop){
13813 p.el.dom.parentNode.insertBefore(p.el.dom, p.el.dom.parentNode.firstChild);
13820 setItemSize : function(item, size){
13821 if(this.fill && item){
13822 var hh = 0, i, ct = this.getRenderedItems(this.container), len = ct.length, p;
13824 for (i = 0; i < len; i++) {
13825 if((p = ct[i]) != item && !p.hidden){
13826 hh += p.header.getHeight();
13833 item.setSize(size);
13838 setActiveItem : function(item){
13839 this.setActive(item, true);
13843 setActive : function(item, expand){
13844 var ai = this.activeItem;
13845 item = this.container.getComponent(item);
13847 if(item.rendered && item.collapsed && expand){
13851 ai.fireEvent('deactivate', ai);
13853 this.activeItem = item;
13854 item.fireEvent('activate', item);
13859 Ext.Container.LAYOUTS.accordion = Ext.layout.AccordionLayout;
13862 Ext.layout.Accordion = Ext.layout.AccordionLayout;
13863 Ext.layout.TableLayout = Ext.extend(Ext.layout.ContainerLayout, {
13867 monitorResize:false,
13871 targetCls: 'x-table-layout-ct',
13877 setContainer : function(ct){
13878 Ext.layout.TableLayout.superclass.setContainer.call(this, ct);
13880 this.currentRow = 0;
13881 this.currentColumn = 0;
13886 onLayout : function(ct, target){
13887 var cs = ct.items.items, len = cs.length, c, i;
13890 target.addClass('x-table-layout-ct');
13892 this.table = target.createChild(
13893 Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
13895 this.renderAll(ct, target);
13899 getRow : function(index){
13900 var row = this.table.tBodies[0].childNodes[index];
13902 row = document.createElement('tr');
13903 this.table.tBodies[0].appendChild(row);
13909 getNextCell : function(c){
13910 var cell = this.getNextNonSpan(this.currentColumn, this.currentRow);
13911 var curCol = this.currentColumn = cell[0], curRow = this.currentRow = cell[1];
13912 for(var rowIndex = curRow; rowIndex < curRow + (c.rowspan || 1); rowIndex++){
13913 if(!this.cells[rowIndex]){
13914 this.cells[rowIndex] = [];
13916 for(var colIndex = curCol; colIndex < curCol + (c.colspan || 1); colIndex++){
13917 this.cells[rowIndex][colIndex] = true;
13920 var td = document.createElement('td');
13924 var cls = 'x-table-layout-cell';
13926 cls += ' ' + c.cellCls;
13928 td.className = cls;
13930 td.colSpan = c.colspan;
13933 td.rowSpan = c.rowspan;
13935 this.getRow(curRow).appendChild(td);
13940 getNextNonSpan: function(colIndex, rowIndex){
13941 var cols = this.columns;
13942 while((cols && colIndex >= cols) || (this.cells[rowIndex] && this.cells[rowIndex][colIndex])) {
13943 if(cols && colIndex >= cols){
13950 return [colIndex, rowIndex];
13954 renderItem : function(c, position, target){
13957 this.table = target.createChild(
13958 Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
13960 if(c && !c.rendered){
13961 c.render(this.getNextCell(c));
13962 this.configureItem(c, position);
13963 }else if(c && !this.isValidParent(c, target)){
13964 var container = this.getNextCell(c);
13965 container.insertBefore(c.getPositionEl().dom, null);
13966 c.container = Ext.get(container);
13967 this.configureItem(c, position);
13972 isValidParent : function(c, target){
13973 return c.getPositionEl().up('table', 5).dom.parentNode === (target.dom || target);
13979 Ext.Container.LAYOUTS['table'] = Ext.layout.TableLayout;
13980 Ext.layout.AbsoluteLayout = Ext.extend(Ext.layout.AnchorLayout, {
13982 extraCls: 'x-abs-layout-item',
13986 onLayout : function(ct, target){
13988 this.paddingLeft = target.getPadding('l');
13989 this.paddingTop = target.getPadding('t');
13990 Ext.layout.AbsoluteLayout.superclass.onLayout.call(this, ct, target);
13994 adjustWidthAnchor : function(value, comp){
13995 return value ? value - comp.getPosition(true)[0] + this.paddingLeft : value;
13999 adjustHeightAnchor : function(value, comp){
14000 return value ? value - comp.getPosition(true)[1] + this.paddingTop : value;
14004 Ext.Container.LAYOUTS['absolute'] = Ext.layout.AbsoluteLayout;
14006 Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, {
14008 defaultMargins : {left:0,top:0,right:0,bottom:0},
14015 monitorResize : true,
14018 extraCls : 'x-box-item',
14019 targetCls : 'x-box-layout-ct',
14020 innerCls : 'x-box-inner',
14022 constructor : function(config){
14023 Ext.layout.BoxLayout.superclass.constructor.call(this, config);
14025 if (Ext.isString(this.defaultMargins)) {
14026 this.defaultMargins = this.parseMargins(this.defaultMargins);
14031 onLayout: function(container, target) {
14032 Ext.layout.BoxLayout.superclass.onLayout.call(this, container, target);
14034 var items = this.getVisibleItems(container),
14035 tSize = this.getLayoutTargetSize();
14038 this.layoutTargetLastSize = tSize;
14041 this.childBoxCache = this.calculateChildBoxes(items, tSize);
14043 this.updateInnerCtSize(tSize, this.childBoxCache);
14044 this.updateChildBoxes(this.childBoxCache.boxes);
14047 this.handleTargetOverflow(tSize, container, target);
14051 updateChildBoxes: function(boxes) {
14052 for (var i = 0, length = boxes.length; i < length; i++) {
14053 var box = boxes[i],
14054 comp = box.component;
14056 if (box.dirtySize) {
14057 comp.setSize(box.width, box.height);
14060 if (isNaN(box.left) || isNaN(box.top)) {
14063 comp.setPosition(box.left, box.top);
14068 updateInnerCtSize: Ext.emptyFn,
14071 handleTargetOverflow: function(previousTargetSize, container, target) {
14072 var overflow = target.getStyle('overflow');
14074 if (overflow && overflow != 'hidden' &&!this.adjustmentPass) {
14075 var newTargetSize = this.getLayoutTargetSize();
14076 if (newTargetSize.width != previousTargetSize.width || newTargetSize.height != previousTargetSize.height){
14077 this.adjustmentPass = true;
14078 this.onLayout(container, target);
14082 delete this.adjustmentPass;
14086 isValidParent : function(c, target){
14087 return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom;
14091 getVisibleItems: function(ct) {
14092 var ct = ct || this.container,
14093 t = ct.getLayoutTarget(),
14094 cti = ct.items.items,
14099 for (i = 0; i < len; i++) {
14100 if((c = cti[i]).rendered && this.isValidParent(c, t) && c.hidden !== true && c.collapsed !== true){
14109 renderAll : function(ct, target){
14113 this.innerCt = target.createChild({cls:this.innerCls});
14114 this.padding = this.parseMargins(this.padding);
14116 Ext.layout.BoxLayout.superclass.renderAll.call(this, ct, this.innerCt);
14119 getLayoutTargetSize : function(){
14120 var target = this.container.getLayoutTarget(), ret;
14122 ret = target.getViewSize();
14127 if (Ext.isIE && Ext.isStrict && ret.width == 0){
14128 ret = target.getStyleSize();
14131 ret.width -= target.getPadding('lr');
14132 ret.height -= target.getPadding('tb');
14138 renderItem : function(c){
14139 if(Ext.isString(c.margins)){
14140 c.margins = this.parseMargins(c.margins);
14141 }else if(!c.margins){
14142 c.margins = this.defaultMargins;
14144 Ext.layout.BoxLayout.superclass.renderItem.apply(this, arguments);
14149 Ext.layout.VBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
14159 updateInnerCtSize: function(tSize, calcs) {
14160 var innerCtHeight = tSize.height,
14161 innerCtWidth = calcs.meta.maxWidth + this.padding.left + this.padding.right;
14163 if (this.align == 'stretch') {
14164 innerCtWidth = tSize.width;
14165 } else if (this.align == 'center') {
14166 innerCtWidth = Math.max(tSize.width, innerCtWidth);
14171 this.innerCt.setSize(innerCtWidth || undefined, innerCtHeight || undefined);
14175 calculateChildBoxes: function(visibleItems, targetSize) {
14176 var visibleCount = visibleItems.length,
14178 padding = this.padding,
14179 topOffset = padding.top,
14180 leftOffset = padding.left,
14181 paddingVert = topOffset + padding.bottom,
14182 paddingHoriz = leftOffset + padding.right,
14184 width = targetSize.width - this.scrollOffset,
14185 height = targetSize.height,
14186 availWidth = Math.max(0, width - paddingHoriz),
14188 isStart = this.pack == 'start',
14189 isCenter = this.pack == 'center',
14190 isEnd = this.pack == 'end',
14200 child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedHeight, horizMargins, stretchWidth;
14203 for (i = 0; i < visibleCount; i++) {
14204 child = visibleItems[i];
14205 childHeight = child.height;
14206 childWidth = child.width;
14207 canLayout = !child.hasLayout && Ext.isFunction(child.doLayout);
14211 if (!Ext.isNumber(childHeight)) {
14214 if (child.flex && !childHeight) {
14215 totalFlex += child.flex;
14221 if (!childHeight && canLayout) {
14225 childSize = child.getSize();
14226 childWidth = childSize.width;
14227 childHeight = childSize.height;
14231 childMargins = child.margins;
14233 nonFlexHeight += (childHeight || 0) + childMargins.top + childMargins.bottom;
14236 if (!Ext.isNumber(childWidth)) {
14240 childWidth = child.getWidth();
14243 maxWidth = Math.max(maxWidth, childWidth + childMargins.left + childMargins.right);
14248 height : childHeight || undefined,
14249 width : childWidth || undefined
14254 var availableHeight = Math.max(0, (height - nonFlexHeight - paddingVert));
14257 topOffset += availableHeight / 2;
14258 } else if (isEnd) {
14259 topOffset += availableHeight;
14263 var remainingHeight = availableHeight,
14264 remainingFlex = totalFlex;
14267 for (i = 0; i < visibleCount; i++) {
14268 child = visibleItems[i];
14271 childMargins = child.margins;
14272 horizMargins = childMargins.left + childMargins.right;
14274 topOffset += childMargins.top;
14276 if (isStart && child.flex && !child.height) {
14277 flexedHeight = Math.ceil((child.flex / remainingFlex) * remainingHeight);
14278 remainingHeight -= flexedHeight;
14279 remainingFlex -= child.flex;
14281 calcs.height = flexedHeight;
14282 calcs.dirtySize = true;
14285 calcs.left = leftOffset + childMargins.left;
14286 calcs.top = topOffset;
14288 switch (this.align) {
14290 stretchWidth = availWidth - horizMargins;
14291 calcs.width = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000);
14292 calcs.dirtySize = true;
14295 stretchWidth = maxWidth - horizMargins;
14296 calcs.width = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000);
14297 calcs.dirtySize = true;
14300 var diff = availWidth - calcs.width - horizMargins;
14302 calcs.left = leftOffset + horizMargins + (diff / 2);
14306 topOffset += calcs.height + childMargins.bottom;
14318 Ext.Container.LAYOUTS.vbox = Ext.layout.VBoxLayout;
14321 Ext.layout.HBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
14328 updateInnerCtSize: function(tSize, calcs) {
14329 var innerCtWidth = tSize.width,
14330 innerCtHeight = calcs.meta.maxHeight + this.padding.top + this.padding.bottom;
14332 if (this.align == 'stretch') {
14333 innerCtHeight = tSize.height;
14334 } else if (this.align == 'middle') {
14335 innerCtHeight = Math.max(tSize.height, innerCtHeight);
14338 this.innerCt.setSize(innerCtWidth || undefined, innerCtHeight || undefined);
14345 calculateChildBoxes: function(visibleItems, targetSize) {
14346 var visibleCount = visibleItems.length,
14348 padding = this.padding,
14349 topOffset = padding.top,
14350 leftOffset = padding.left,
14351 paddingVert = topOffset + padding.bottom,
14352 paddingHoriz = leftOffset + padding.right,
14354 width = targetSize.width - this.scrollOffset,
14355 height = targetSize.height,
14356 availHeight = Math.max(0, height - paddingVert),
14358 isStart = this.pack == 'start',
14359 isCenter = this.pack == 'center',
14360 isEnd = this.pack == 'end',
14371 child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedWidth, vertMargins, stretchHeight;
14374 for (i = 0; i < visibleCount; i++) {
14375 child = visibleItems[i];
14376 childHeight = child.height;
14377 childWidth = child.width;
14378 canLayout = !child.hasLayout && Ext.isFunction(child.doLayout);
14381 if (!Ext.isNumber(childWidth)) {
14384 if (child.flex && !childWidth) {
14385 totalFlex += child.flex;
14391 if (!childWidth && canLayout) {
14395 childSize = child.getSize();
14396 childWidth = childSize.width;
14397 childHeight = childSize.height;
14401 childMargins = child.margins;
14403 nonFlexWidth += (childWidth || 0) + childMargins.left + childMargins.right;
14406 if (!Ext.isNumber(childHeight)) {
14410 childHeight = child.getHeight();
14413 maxHeight = Math.max(maxHeight, childHeight + childMargins.top + childMargins.bottom);
14418 height : childHeight || undefined,
14419 width : childWidth || undefined
14424 var availableWidth = Math.max(0, (width - nonFlexWidth - paddingHoriz));
14427 leftOffset += availableWidth / 2;
14428 } else if (isEnd) {
14429 leftOffset += availableWidth;
14433 var remainingWidth = availableWidth,
14434 remainingFlex = totalFlex;
14437 for (i = 0; i < visibleCount; i++) {
14438 child = visibleItems[i];
14441 childMargins = child.margins;
14442 vertMargins = childMargins.top + childMargins.bottom;
14444 leftOffset += childMargins.left;
14446 if (isStart && child.flex && !child.width) {
14447 flexedWidth = Math.ceil((child.flex / remainingFlex) * remainingWidth);
14448 remainingWidth -= flexedWidth;
14449 remainingFlex -= child.flex;
14451 calcs.width = flexedWidth;
14452 calcs.dirtySize = true;
14455 calcs.left = leftOffset;
14456 calcs.top = topOffset + childMargins.top;
14458 switch (this.align) {
14460 stretchHeight = availHeight - vertMargins;
14461 calcs.height = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000);
14462 calcs.dirtySize = true;
14465 stretchHeight = maxHeight - vertMargins;
14466 calcs.height = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000);
14467 calcs.dirtySize = true;
14470 var diff = availHeight - calcs.height - vertMargins;
14472 calcs.top = topOffset + vertMargins + (diff / 2);
14475 leftOffset += calcs.width + childMargins.right;
14481 maxHeight: maxHeight
14487 Ext.Container.LAYOUTS.hbox = Ext.layout.HBoxLayout;
14489 Ext.layout.ToolbarLayout = Ext.extend(Ext.layout.ContainerLayout, {
14490 monitorResize : true,
14498 noItemsMenuText : '<div class="x-toolbar-no-items">(None)</div>',
14501 lastOverflow: false,
14505 '<table cellspacing="0" class="x-toolbar-ct">',
14508 '<td class="x-toolbar-left" align="{0}">',
14509 '<table cellspacing="0">',
14511 '<tr class="x-toolbar-left-row"></tr>',
14515 '<td class="x-toolbar-right" align="right">',
14516 '<table cellspacing="0" class="x-toolbar-right-ct">',
14520 '<table cellspacing="0">',
14522 '<tr class="x-toolbar-right-row"></tr>',
14527 '<table cellspacing="0">',
14529 '<tr class="x-toolbar-extras-row"></tr>',
14543 onLayout : function(ct, target) {
14545 if (!this.leftTr) {
14546 var align = ct.buttonAlign == 'center' ? 'center' : 'left';
14548 target.addClass('x-toolbar-layout-ct');
14549 target.insertHtml('beforeEnd', String.format(this.tableHTML, align));
14551 this.leftTr = target.child('tr.x-toolbar-left-row', true);
14552 this.rightTr = target.child('tr.x-toolbar-right-row', true);
14553 this.extrasTr = target.child('tr.x-toolbar-extras-row', true);
14555 if (this.hiddenItem == undefined) {
14557 this.hiddenItems = [];
14561 var side = ct.buttonAlign == 'right' ? this.rightTr : this.leftTr,
14562 items = ct.items.items,
14566 for (var i = 0, len = items.length, c; i < len; i++, position++) {
14570 side = this.rightTr;
14572 } else if (!c.rendered) {
14573 c.render(this.insertCell(c, side, position));
14575 if (!c.xtbHidden && !this.isValidParent(c, side.childNodes[position])) {
14576 var td = this.insertCell(c, side, position);
14577 td.appendChild(c.getPositionEl().dom);
14578 c.container = Ext.get(td);
14584 this.cleanup(this.leftTr);
14585 this.cleanup(this.rightTr);
14586 this.cleanup(this.extrasTr);
14587 this.fitToSize(target);
14591 cleanup : function(el) {
14592 var cn = el.childNodes, i, c;
14594 for (i = cn.length-1; i >= 0 && (c = cn[i]); i--) {
14595 if (!c.firstChild) {
14602 insertCell : function(c, target, position) {
14603 var td = document.createElement('td');
14604 td.className = 'x-toolbar-cell';
14606 target.insertBefore(td, target.childNodes[position] || null);
14612 hideItem : function(item) {
14613 this.hiddenItems.push(item);
14615 item.xtbHidden = true;
14616 item.xtbWidth = item.getPositionEl().dom.parentNode.offsetWidth;
14621 unhideItem : function(item) {
14623 item.xtbHidden = false;
14624 this.hiddenItems.remove(item);
14628 getItemWidth : function(c) {
14629 return c.hidden ? (c.xtbWidth || 0) : c.getPositionEl().dom.parentNode.offsetWidth;
14633 fitToSize : function(target) {
14634 if (this.container.enableOverflow === false) {
14638 var width = target.dom.clientWidth,
14639 tableWidth = target.dom.firstChild.offsetWidth,
14640 clipWidth = width - this.triggerWidth,
14641 lastWidth = this.lastWidth || 0,
14643 hiddenItems = this.hiddenItems,
14644 hasHiddens = hiddenItems.length != 0,
14645 isLarger = width >= lastWidth;
14647 this.lastWidth = width;
14649 if (tableWidth > width || (hasHiddens && isLarger)) {
14650 var items = this.container.items.items,
14651 len = items.length,
14655 for (var i = 0; i < len; i++) {
14658 if (!item.isFill) {
14659 loopWidth += this.getItemWidth(item);
14660 if (loopWidth > clipWidth) {
14661 if (!(item.hidden || item.xtbHidden)) {
14662 this.hideItem(item);
14664 } else if (item.xtbHidden) {
14665 this.unhideItem(item);
14672 hasHiddens = hiddenItems.length != 0;
14677 if (!this.lastOverflow) {
14678 this.container.fireEvent('overflowchange', this.container, true);
14679 this.lastOverflow = true;
14681 } else if (this.more) {
14683 this.more.destroy();
14686 if (this.lastOverflow) {
14687 this.container.fireEvent('overflowchange', this.container, false);
14688 this.lastOverflow = false;
14694 createMenuConfig : function(component, hideOnClick){
14695 var config = Ext.apply({}, component.initialConfig),
14696 group = component.toggleGroup;
14698 Ext.copyTo(config, component, [
14699 'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu'
14702 Ext.apply(config, {
14703 text : component.overflowText || component.text,
14704 hideOnClick: hideOnClick
14707 if (group || component.enableToggle) {
14708 Ext.apply(config, {
14710 checked: component.pressed,
14712 checkchange: function(item, checked){
14713 component.toggle(checked);
14719 delete config.ownerCt;
14720 delete config.xtype;
14727 addComponentToMenu : function(menu, component) {
14728 if (component instanceof Ext.Toolbar.Separator) {
14731 } else if (Ext.isFunction(component.isXType)) {
14732 if (component.isXType('splitbutton')) {
14733 menu.add(this.createMenuConfig(component, true));
14735 } else if (component.isXType('button')) {
14736 menu.add(this.createMenuConfig(component, !component.menu));
14738 } else if (component.isXType('buttongroup')) {
14739 component.items.each(function(item){
14740 this.addComponentToMenu(menu, item);
14747 clearMenu : function(){
14748 var menu = this.moreMenu;
14749 if (menu && menu.items) {
14750 menu.items.each(function(item){
14757 beforeMoreShow : function(menu) {
14758 var items = this.container.items.items,
14759 len = items.length,
14763 var needsSep = function(group, item){
14764 return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator);
14769 for (var i = 0; i < len; i++) {
14771 if (item.xtbHidden) {
14772 if (prev && (needsSep(item, prev) || needsSep(prev, item))) {
14775 this.addComponentToMenu(menu, item);
14781 if (menu.items.length < 1) {
14782 menu.add(this.noItemsMenuText);
14787 initMore : function(){
14790 this.moreMenu = new Ext.menu.Menu({
14791 ownerCt : this.container,
14793 beforeshow: this.beforeMoreShow,
14799 this.more = new Ext.Button({
14800 iconCls: 'x-toolbar-more-icon',
14801 cls : 'x-toolbar-more',
14802 menu : this.moreMenu,
14803 ownerCt: this.container
14806 var td = this.insertCell(this.more, this.extrasTr, 100);
14807 this.more.render(td);
14811 destroy : function(){
14812 Ext.destroy(this.more, this.moreMenu);
14813 delete this.leftTr;
14814 delete this.rightTr;
14815 delete this.extrasTr;
14816 Ext.layout.ToolbarLayout.superclass.destroy.call(this);
14820 Ext.Container.LAYOUTS.toolbar = Ext.layout.ToolbarLayout;
14822 Ext.layout.MenuLayout = Ext.extend(Ext.layout.ContainerLayout, {
14823 monitorResize : true,
14827 setContainer : function(ct){
14828 this.monitorResize = !ct.floating;
14831 ct.on('autosize', this.doAutoSize, this);
14832 Ext.layout.MenuLayout.superclass.setContainer.call(this, ct);
14835 renderItem : function(c, position, target){
14836 if (!this.itemTpl) {
14837 this.itemTpl = Ext.layout.MenuLayout.prototype.itemTpl = new Ext.XTemplate(
14838 '<li id="{itemId}" class="{itemCls}">',
14839 '<tpl if="needsIcon">',
14840 '<img src="{icon}" class="{iconCls}"/>',
14846 if(c && !c.rendered){
14847 if(Ext.isNumber(position)){
14848 position = target.dom.childNodes[position];
14850 var a = this.getItemArgs(c);
14853 c.render(c.positionEl = position ?
14854 this.itemTpl.insertBefore(position, a, true) :
14855 this.itemTpl.append(target, a, true));
14858 c.positionEl.menuItemId = c.getItemId();
14862 if (!a.isMenuItem && a.needsIcon) {
14863 c.positionEl.addClass('x-menu-list-item-indent');
14865 this.configureItem(c, position);
14866 }else if(c && !this.isValidParent(c, target)){
14867 if(Ext.isNumber(position)){
14868 position = target.dom.childNodes[position];
14870 target.dom.insertBefore(c.getActionEl().dom, position || null);
14874 getItemArgs : function(c) {
14875 var isMenuItem = c instanceof Ext.menu.Item;
14877 isMenuItem: isMenuItem,
14878 needsIcon: !isMenuItem && (c.icon || c.iconCls),
14879 icon: c.icon || Ext.BLANK_IMAGE_URL,
14880 iconCls: 'x-menu-item-icon ' + (c.iconCls || ''),
14881 itemId: 'x-menu-el-' + c.id,
14882 itemCls: 'x-menu-list-item '
14887 isValidParent : function(c, target) {
14888 return c.el.up('li.x-menu-list-item', 5).dom.parentNode === (target.dom || target);
14891 onLayout : function(ct, target){
14892 Ext.layout.MenuLayout.superclass.onLayout.call(this, ct, target);
14896 doAutoSize : function(){
14897 var ct = this.container, w = ct.width;
14901 }else if(Ext.isIE){
14902 ct.setWidth(Ext.isStrict && (Ext.isIE7 || Ext.isIE8) ? 'auto' : ct.minWidth);
14903 var el = ct.getEl(), t = el.dom.offsetWidth;
14904 ct.setWidth(ct.getLayoutTarget().getWidth() + el.getFrameWidth('lr'));
14909 Ext.Container.LAYOUTS['menu'] = Ext.layout.MenuLayout;
14911 Ext.Viewport = Ext.extend(Ext.Container, {
14925 initComponent : function() {
14926 Ext.Viewport.superclass.initComponent.call(this);
14927 document.getElementsByTagName('html')[0].className += ' x-viewport';
14928 this.el = Ext.getBody();
14929 this.el.setHeight = Ext.emptyFn;
14930 this.el.setWidth = Ext.emptyFn;
14931 this.el.setSize = Ext.emptyFn;
14932 this.el.dom.scroll = 'no';
14933 this.allowDomMove = false;
14934 this.autoWidth = true;
14935 this.autoHeight = true;
14936 Ext.EventManager.onWindowResize(this.fireResize, this);
14937 this.renderTo = this.el;
14940 fireResize : function(w, h){
14941 this.fireEvent('resize', this, w, h, w, h);
14944 Ext.reg('viewport', Ext.Viewport);
14946 Ext.Panel = Ext.extend(Ext.Container, {
14991 baseCls : 'x-panel',
14993 collapsedCls : 'x-panel-collapsed',
14995 maskDisabled : true,
14997 animCollapse : Ext.enableFx,
14999 headerAsText : true,
15001 buttonAlign : 'right',
15005 collapseFirst : true,
15007 minButtonWidth : 75,
15012 preventBodyReset : false,
15015 padding: undefined,
15018 resizeEvent: 'bodyresize',
15023 toolTarget : 'header',
15024 collapseEl : 'bwrap',
15026 disabledClass : '',
15029 deferHeight : true,
15035 collapseDefaults : {
15040 initComponent : function(){
15041 Ext.Panel.superclass.initComponent.call(this);
15069 this.baseCls = 'x-plain';
15073 this.toolbars = [];
15076 this.elements += ',tbar';
15077 this.topToolbar = this.createToolbar(this.tbar);
15082 this.elements += ',bbar';
15083 this.bottomToolbar = this.createToolbar(this.bbar);
15087 if(this.header === true){
15088 this.elements += ',header';
15089 this.header = null;
15090 }else if(this.headerCfg || (this.title && this.header !== false)){
15091 this.elements += ',header';
15094 if(this.footerCfg || this.footer === true){
15095 this.elements += ',footer';
15096 this.footer = null;
15100 this.fbar = this.buttons;
15101 this.buttons = null;
15104 this.createFbar(this.fbar);
15107 this.on('render', this.doAutoLoad, this, {delay:10});
15112 createFbar : function(fbar){
15113 var min = this.minButtonWidth;
15114 this.elements += ',footer';
15115 this.fbar = this.createToolbar(fbar, {
15116 buttonAlign: this.buttonAlign,
15117 toolbarCls: 'x-panel-fbar',
15118 enableOverflow: false,
15119 defaults: function(c){
15121 minWidth: c.minWidth || min
15128 this.fbar.items.each(function(c){
15129 c.minWidth = c.minWidth || this.minButtonWidth;
15131 this.buttons = this.fbar.items.items;
15135 createToolbar: function(tb, options){
15138 if(Ext.isArray(tb)){
15143 result = tb.events ? Ext.apply(tb, options) : this.createComponent(Ext.apply({}, tb, options), 'toolbar');
15144 this.toolbars.push(result);
15149 createElement : function(name, pnode){
15151 pnode.appendChild(this[name].dom);
15155 if(name === 'bwrap' || this.elements.indexOf(name) != -1){
15156 if(this[name+'Cfg']){
15157 this[name] = Ext.fly(pnode).createChild(this[name+'Cfg']);
15159 var el = document.createElement('div');
15160 el.className = this[name+'Cls'];
15161 this[name] = Ext.get(pnode.appendChild(el));
15163 if(this[name+'CssClass']){
15164 this[name].addClass(this[name+'CssClass']);
15166 if(this[name+'Style']){
15167 this[name].applyStyles(this[name+'Style']);
15173 onRender : function(ct, position){
15174 Ext.Panel.superclass.onRender.call(this, ct, position);
15175 this.createClasses();
15183 if(this.collapsible && !this.hideCollapseTool){
15184 this.tools = this.tools ? this.tools.slice(0) : [];
15185 this.tools[this.collapseFirst?'unshift':'push']({
15187 handler : this.toggleCollapse,
15194 this.elements += (this.header !== false) ? ',header' : '';
15198 el.addClass(this.baseCls);
15200 this.header = el.down('.'+this.headerCls);
15201 this.bwrap = el.down('.'+this.bwrapCls);
15202 var cp = this.bwrap ? this.bwrap : el;
15203 this.tbar = cp.down('.'+this.tbarCls);
15204 this.body = cp.down('.'+this.bodyCls);
15205 this.bbar = cp.down('.'+this.bbarCls);
15206 this.footer = cp.down('.'+this.footerCls);
15207 this.fromMarkup = true;
15209 if (this.preventBodyReset === true) {
15210 el.addClass('x-panel-reset');
15213 el.addClass(this.cls);
15217 this.elements += ',footer';
15224 el.insertHtml('afterBegin', String.format(Ext.Element.boxMarkup, this.baseCls));
15226 this.createElement('header', d.firstChild.firstChild.firstChild);
15227 this.createElement('bwrap', d);
15230 bw = this.bwrap.dom;
15231 var ml = d.childNodes[1], bl = d.childNodes[2];
15232 bw.appendChild(ml);
15233 bw.appendChild(bl);
15235 var mc = bw.firstChild.firstChild.firstChild;
15236 this.createElement('tbar', mc);
15237 this.createElement('body', mc);
15238 this.createElement('bbar', mc);
15239 this.createElement('footer', bw.lastChild.firstChild.firstChild);
15242 this.bwrap.dom.lastChild.className += ' x-panel-nofooter';
15245 this.ft = Ext.get(this.bwrap.dom.lastChild);
15246 this.mc = Ext.get(mc);
15248 this.createElement('header', d);
15249 this.createElement('bwrap', d);
15252 bw = this.bwrap.dom;
15253 this.createElement('tbar', bw);
15254 this.createElement('body', bw);
15255 this.createElement('bbar', bw);
15256 this.createElement('footer', bw);
15259 this.body.addClass(this.bodyCls + '-noheader');
15261 this.tbar.addClass(this.tbarCls + '-noheader');
15266 if(Ext.isDefined(this.padding)){
15267 this.body.setStyle('padding', this.body.addUnits(this.padding));
15270 if(this.border === false){
15271 this.el.addClass(this.baseCls + '-noborder');
15272 this.body.addClass(this.bodyCls + '-noborder');
15274 this.header.addClass(this.headerCls + '-noborder');
15277 this.footer.addClass(this.footerCls + '-noborder');
15280 this.tbar.addClass(this.tbarCls + '-noborder');
15283 this.bbar.addClass(this.bbarCls + '-noborder');
15287 if(this.bodyBorder === false){
15288 this.body.addClass(this.bodyCls + '-noborder');
15291 this.bwrap.enableDisplayMode('block');
15294 this.header.unselectable();
15297 if(this.headerAsText){
15298 this.header.dom.innerHTML =
15299 '<span class="' + this.headerTextCls + '">'+this.header.dom.innerHTML+'</span>';
15302 this.setIconClass(this.iconCls);
15308 this.makeFloating(this.floating);
15311 if(this.collapsible && this.titleCollapse && this.header){
15312 this.mon(this.header, 'click', this.toggleCollapse, this);
15313 this.header.setStyle('cursor', 'pointer');
15316 this.addTool.apply(this, ts);
15321 this.footer.addClass('x-panel-btns');
15322 this.fbar.ownerCt = this;
15323 this.fbar.render(this.footer);
15324 this.footer.createChild({cls:'x-clear'});
15326 if(this.tbar && this.topToolbar){
15327 this.topToolbar.ownerCt = this;
15328 this.topToolbar.render(this.tbar);
15330 if(this.bbar && this.bottomToolbar){
15331 this.bottomToolbar.ownerCt = this;
15332 this.bottomToolbar.render(this.bbar);
15337 setIconClass : function(cls){
15338 var old = this.iconCls;
15339 this.iconCls = cls;
15340 if(this.rendered && this.header){
15342 this.header.addClass('x-panel-icon');
15343 this.header.replaceClass(old, this.iconCls);
15345 var hd = this.header,
15346 img = hd.child('img.x-panel-inline-icon');
15348 Ext.fly(img).replaceClass(old, this.iconCls);
15350 var hdspan = hd.child('span.' + this.headerTextCls);
15352 Ext.DomHelper.insertBefore(hdspan.dom, {
15353 tag:'img', src: Ext.BLANK_IMAGE_URL, cls:'x-panel-inline-icon '+this.iconCls
15359 this.fireEvent('iconchange', this, cls, old);
15363 makeFloating : function(cfg){
15364 this.floating = true;
15365 this.el = new Ext.Layer(Ext.apply({}, cfg, {
15366 shadow: Ext.isDefined(this.shadow) ? this.shadow : 'sides',
15367 shadowOffset: this.shadowOffset,
15369 shim: this.shim === false ? false : undefined
15374 getTopToolbar : function(){
15375 return this.topToolbar;
15379 getBottomToolbar : function(){
15380 return this.bottomToolbar;
15384 getFooterToolbar : function() {
15389 addButton : function(config, handler, scope){
15391 this.createFbar([]);
15394 if(Ext.isString(config)){
15395 config = {text: config};
15397 config = Ext.apply({
15402 return this.fbar.add(config);
15406 addTool : function(){
15407 if(!this.rendered){
15411 Ext.each(arguments, function(arg){
15412 this.tools.push(arg);
15417 if(!this[this.toolTarget]){
15420 if(!this.toolTemplate){
15422 var tt = new Ext.Template(
15423 '<div class="x-tool x-tool-{id}"> </div>'
15425 tt.disableFormats = true;
15427 Ext.Panel.prototype.toolTemplate = tt;
15429 for(var i = 0, a = arguments, len = a.length; i < len; i++) {
15431 if(!this.tools[tc.id]){
15432 var overCls = 'x-tool-'+tc.id+'-over';
15433 var t = this.toolTemplate.insertFirst(this[this.toolTarget], tc, true);
15434 this.tools[tc.id] = t;
15435 t.enableDisplayMode('block');
15436 this.mon(t, 'click', this.createToolHandler(t, tc, overCls, this));
15438 this.mon(t, tc.on);
15444 if(Ext.isObject(tc.qtip)){
15445 Ext.QuickTips.register(Ext.apply({
15449 t.dom.qtip = tc.qtip;
15452 t.addClassOnOver(overCls);
15457 onLayout : function(shallow, force){
15458 Ext.Panel.superclass.onLayout.apply(this, arguments);
15459 if(this.hasLayout && this.toolbars.length > 0){
15460 Ext.each(this.toolbars, function(tb){
15461 tb.doLayout(undefined, force);
15467 syncHeight : function(){
15468 var h = this.toolbarHeight,
15470 lsh = this.lastSize.height,
15473 if(this.autoHeight || !Ext.isDefined(lsh) || lsh == 'auto'){
15478 if(h != this.getToolbarHeight()){
15479 h = Math.max(0, lsh - this.getFrameHeight());
15482 this.toolbarHeight = this.getToolbarHeight();
15483 this.onBodyResize(sz.width, sz.height);
15488 onShow : function(){
15490 return this.el.show();
15492 Ext.Panel.superclass.onShow.call(this);
15496 onHide : function(){
15498 return this.el.hide();
15500 Ext.Panel.superclass.onHide.call(this);
15504 createToolHandler : function(t, tc, overCls, panel){
15505 return function(e){
15506 t.removeClass(overCls);
15507 if(tc.stopEvent !== false){
15511 tc.handler.call(tc.scope || t, e, t, panel, tc);
15517 afterRender : function(){
15518 if(this.floating && !this.hidden){
15522 this.setTitle(this.title);
15524 Ext.Panel.superclass.afterRender.call(this);
15525 if (this.collapsed) {
15526 this.collapsed = false;
15527 this.collapse(false);
15533 getKeyMap : function(){
15535 this.keyMap = new Ext.KeyMap(this.el, this.keys);
15537 return this.keyMap;
15541 initEvents : function(){
15545 if(this.draggable){
15546 this.initDraggable();
15548 if(this.toolbars.length > 0){
15549 Ext.each(this.toolbars, function(tb){
15553 afterlayout: this.syncHeight,
15554 remove: this.syncHeight
15563 initDraggable : function(){
15565 this.dd = new Ext.Panel.DD(this, Ext.isBoolean(this.draggable) ? null : this.draggable);
15569 beforeEffect : function(anim){
15571 this.el.beforeAction();
15573 if(anim !== false){
15574 this.el.addClass('x-panel-animated');
15579 afterEffect : function(anim){
15581 this.el.removeClass('x-panel-animated');
15585 createEffect : function(a, cb, scope){
15593 }else if(!a.callback){
15596 o.callback = function(){
15598 Ext.callback(a.callback, a.scope);
15601 return Ext.applyIf(o, a);
15605 collapse : function(animate){
15606 if(this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforecollapse', this, animate) === false){
15609 var doAnim = animate === true || (animate !== false && this.animCollapse);
15610 this.beforeEffect(doAnim);
15611 this.onCollapse(doAnim, animate);
15616 onCollapse : function(doAnim, animArg){
15618 this[this.collapseEl].slideOut(this.slideAnchor,
15619 Ext.apply(this.createEffect(animArg||true, this.afterCollapse, this),
15620 this.collapseDefaults));
15622 this[this.collapseEl].hide(this.hideMode);
15623 this.afterCollapse(false);
15628 afterCollapse : function(anim){
15629 this.collapsed = true;
15630 this.el.addClass(this.collapsedCls);
15631 if(anim !== false){
15632 this[this.collapseEl].hide(this.hideMode);
15634 this.afterEffect(anim);
15637 this.cascade(function(c) {
15639 c.lastSize = { width: undefined, height: undefined };
15642 this.fireEvent('collapse', this);
15646 expand : function(animate){
15647 if(!this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforeexpand', this, animate) === false){
15650 var doAnim = animate === true || (animate !== false && this.animCollapse);
15651 this.el.removeClass(this.collapsedCls);
15652 this.beforeEffect(doAnim);
15653 this.onExpand(doAnim, animate);
15658 onExpand : function(doAnim, animArg){
15660 this[this.collapseEl].slideIn(this.slideAnchor,
15661 Ext.apply(this.createEffect(animArg||true, this.afterExpand, this),
15662 this.expandDefaults));
15664 this[this.collapseEl].show(this.hideMode);
15665 this.afterExpand(false);
15670 afterExpand : function(anim){
15671 this.collapsed = false;
15672 if(anim !== false){
15673 this[this.collapseEl].show(this.hideMode);
15675 this.afterEffect(anim);
15676 if (this.deferLayout) {
15677 delete this.deferLayout;
15678 this.doLayout(true);
15680 this.fireEvent('expand', this);
15684 toggleCollapse : function(animate){
15685 this[this.collapsed ? 'expand' : 'collapse'](animate);
15690 onDisable : function(){
15691 if(this.rendered && this.maskDisabled){
15694 Ext.Panel.superclass.onDisable.call(this);
15698 onEnable : function(){
15699 if(this.rendered && this.maskDisabled){
15702 Ext.Panel.superclass.onEnable.call(this);
15706 onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
15710 if(Ext.isDefined(w) || Ext.isDefined(h)){
15711 if(!this.collapsed){
15716 if(Ext.isNumber(w)){
15717 this.body.setWidth(w = this.adjustBodyWidth(w - this.getFrameWidth()));
15718 } else if (w == 'auto') {
15719 w = this.body.setWidth('auto').dom.offsetWidth;
15721 w = this.body.dom.offsetWidth;
15725 this.tbar.setWidth(w);
15726 if(this.topToolbar){
15727 this.topToolbar.setSize(w);
15731 this.bbar.setWidth(w);
15732 if(this.bottomToolbar){
15733 this.bottomToolbar.setSize(w);
15736 this.bbar.setStyle('position', 'static');
15737 this.bbar.setStyle('position', '');
15742 this.footer.setWidth(w);
15744 this.fbar.setSize(Ext.isIE ? (w - this.footer.getFrameWidth('lr')) : 'auto');
15749 if(Ext.isNumber(h)){
15750 h = Math.max(0, h - this.getFrameHeight());
15752 this.body.setHeight(h);
15753 }else if(h == 'auto'){
15754 this.body.setHeight(h);
15757 if(this.disabled && this.el._mask){
15758 this.el._mask.setSize(this.el.dom.clientWidth, this.el.getHeight());
15762 this.queuedBodySize = {width: w, height: h};
15763 if(!this.queuedExpand && this.allowQueuedExpand !== false){
15764 this.queuedExpand = true;
15765 this.on('expand', function(){
15766 delete this.queuedExpand;
15767 this.onResize(this.queuedBodySize.width, this.queuedBodySize.height);
15768 }, this, {single:true});
15771 this.onBodyResize(w, h);
15774 Ext.Panel.superclass.onResize.call(this, adjWidth, adjHeight, rawWidth, rawHeight);
15779 onBodyResize: function(w, h){
15780 this.fireEvent('bodyresize', this, w, h);
15784 getToolbarHeight: function(){
15787 Ext.each(this.toolbars, function(tb){
15788 h += tb.getHeight();
15795 adjustBodyHeight : function(h){
15800 adjustBodyWidth : function(w){
15805 onPosition : function(){
15810 getFrameWidth : function(){
15811 var w = this.el.getFrameWidth('lr') + this.bwrap.getFrameWidth('lr');
15814 var l = this.bwrap.dom.firstChild;
15815 w += (Ext.fly(l).getFrameWidth('l') + Ext.fly(l.firstChild).getFrameWidth('r'));
15816 w += this.mc.getFrameWidth('lr');
15822 getFrameHeight : function() {
15823 var h = Math.max(0, this.getHeight() - this.body.getHeight());
15834 getInnerWidth : function(){
15835 return this.getSize().width - this.getFrameWidth();
15839 getInnerHeight : function(){
15840 return this.body.getHeight();
15845 syncShadow : function(){
15847 this.el.sync(true);
15852 getLayoutTarget : function(){
15857 getContentTarget : function(){
15862 setTitle : function(title, iconCls){
15863 this.title = title;
15864 if(this.header && this.headerAsText){
15865 this.header.child('span').update(title);
15868 this.setIconClass(iconCls);
15870 this.fireEvent('titlechange', this, title);
15875 getUpdater : function(){
15876 return this.body.getUpdater();
15881 var um = this.body.getUpdater();
15882 um.update.apply(um, arguments);
15887 beforeDestroy : function(){
15888 Ext.Panel.superclass.beforeDestroy.call(this);
15890 this.header.removeAllListeners();
15893 for(var k in this.tools){
15894 Ext.destroy(this.tools[k]);
15897 if(this.toolbars.length > 0){
15898 Ext.each(this.toolbars, function(tb){
15899 tb.un('afterlayout', this.syncHeight, this);
15900 tb.un('remove', this.syncHeight, this);
15903 if(Ext.isArray(this.buttons)){
15904 while(this.buttons.length) {
15905 Ext.destroy(this.buttons[0]);
15927 Ext.destroy(this.toolbars);
15931 createClasses : function(){
15932 this.headerCls = this.baseCls + '-header';
15933 this.headerTextCls = this.baseCls + '-header-text';
15934 this.bwrapCls = this.baseCls + '-bwrap';
15935 this.tbarCls = this.baseCls + '-tbar';
15936 this.bodyCls = this.baseCls + '-body';
15937 this.bbarCls = this.baseCls + '-bbar';
15938 this.footerCls = this.baseCls + '-footer';
15942 createGhost : function(cls, useShim, appendTo){
15943 var el = document.createElement('div');
15944 el.className = 'x-panel-ghost ' + (cls ? cls : '');
15946 el.appendChild(this.el.dom.firstChild.cloneNode(true));
15948 Ext.fly(el.appendChild(document.createElement('ul'))).setHeight(this.bwrap.getHeight());
15949 el.style.width = this.el.dom.offsetWidth + 'px';;
15951 this.container.dom.appendChild(el);
15953 Ext.getDom(appendTo).appendChild(el);
15955 if(useShim !== false && this.el.useShim !== false){
15956 var layer = new Ext.Layer({shadow:false, useDisplay:true, constrain:false}, el);
15960 return new Ext.Element(el);
15965 doAutoLoad : function(){
15966 var u = this.body.getUpdater();
15968 u.setRenderer(this.renderer);
15970 u.update(Ext.isObject(this.autoLoad) ? this.autoLoad : {url: this.autoLoad});
15974 getTool : function(id) {
15975 return this.tools[id];
15980 Ext.reg('panel', Ext.Panel);
15982 Ext.Editor = function(field, config){
15984 this.field = Ext.create(field.field, 'textfield');
15985 config = Ext.apply({}, field);
15986 delete config.field;
15988 this.field = field;
15990 Ext.Editor.superclass.constructor.call(this, config);
15993 Ext.extend(Ext.Editor, Ext.Component, {
16012 swallowKeys : true,
16014 completeOnEnter : true,
16016 cancelOnEsc : true,
16020 initComponent : function(){
16021 Ext.Editor.superclass.initComponent.call(this);
16039 onRender : function(ct, position){
16040 this.el = new Ext.Layer({
16041 shadow: this.shadow,
16045 shadowOffset: this.shadowOffset || 4,
16047 constrain: this.constrain
16050 this.el.setZIndex(this.zIndex);
16052 this.el.setStyle("overflow", Ext.isGecko ? "auto" : "hidden");
16053 if(this.field.msgTarget != 'title'){
16054 this.field.msgTarget = 'qtip';
16056 this.field.inEditor = true;
16057 this.mon(this.field, {
16060 specialkey: this.onSpecialKey
16062 if(this.field.grow){
16063 this.mon(this.field, "autosize", this.el.sync, this.el, {delay:1});
16065 this.field.render(this.el).show();
16066 this.field.getEl().dom.name = '';
16067 if(this.swallowKeys){
16068 this.field.el.swallowEvent([
16076 onSpecialKey : function(field, e){
16077 var key = e.getKey(),
16078 complete = this.completeOnEnter && key == e.ENTER,
16079 cancel = this.cancelOnEsc && key == e.ESC;
16080 if(complete || cancel){
16083 this.completeEdit();
16087 if(field.triggerBlur){
16088 field.triggerBlur();
16091 this.fireEvent('specialkey', field, e);
16095 startEdit : function(el, value){
16097 this.completeEdit();
16099 this.boundEl = Ext.get(el);
16100 var v = value !== undefined ? value : this.boundEl.dom.innerHTML;
16101 if(!this.rendered){
16102 this.render(this.parentEl || document.body);
16104 if(this.fireEvent("beforestartedit", this, this.boundEl, v) !== false){
16105 this.startValue = v;
16106 this.field.reset();
16107 this.field.setValue(v);
16108 this.realign(true);
16109 this.editing = true;
16115 doAutoSize : function(){
16117 var sz = this.boundEl.getSize(),
16118 fs = this.field.getSize();
16120 switch(this.autoSize){
16122 this.setSize(sz.width, fs.height);
16125 this.setSize(fs.width, sz.height);
16128 this.setSize(fs.width, fs.height);
16131 this.setSize(sz.width, sz.height);
16137 setSize : function(w, h){
16138 delete this.field.lastSize;
16139 this.field.setSize(w, h);
16141 if(Ext.isGecko2 || Ext.isOpera){
16143 this.el.setSize(w, h);
16150 realign : function(autoSize){
16151 if(autoSize === true){
16154 this.el.alignTo(this.boundEl, this.alignment, this.offsets);
16158 completeEdit : function(remainVisible){
16163 if (this.field.assertValue) {
16164 this.field.assertValue();
16166 var v = this.getValue();
16167 if(!this.field.isValid()){
16168 if(this.revertInvalid !== false){
16169 this.cancelEdit(remainVisible);
16173 if(String(v) === String(this.startValue) && this.ignoreNoChange){
16174 this.hideEdit(remainVisible);
16177 if(this.fireEvent("beforecomplete", this, v, this.startValue) !== false){
16178 v = this.getValue();
16179 if(this.updateEl && this.boundEl){
16180 this.boundEl.update(v);
16182 this.hideEdit(remainVisible);
16183 this.fireEvent("complete", this, v, this.startValue);
16188 onShow : function(){
16190 if(this.hideEl !== false){
16191 this.boundEl.hide();
16193 this.field.show().focus(false, true);
16194 this.fireEvent("startedit", this.boundEl, this.startValue);
16198 cancelEdit : function(remainVisible){
16200 var v = this.getValue();
16201 this.setValue(this.startValue);
16202 this.hideEdit(remainVisible);
16203 this.fireEvent("canceledit", this, v, this.startValue);
16208 hideEdit: function(remainVisible){
16209 if(remainVisible !== true){
16210 this.editing = false;
16216 onBlur : function(){
16218 if(this.allowBlur === true && this.editing && this.selectSameEditor !== true){
16219 this.completeEdit();
16224 onHide : function(){
16226 this.completeEdit();
16230 if(this.field.collapse){
16231 this.field.collapse();
16234 if(this.hideEl !== false){
16235 this.boundEl.show();
16240 setValue : function(v){
16241 this.field.setValue(v);
16245 getValue : function(){
16246 return this.field.getValue();
16249 beforeDestroy : function(){
16250 Ext.destroyMembers(this, 'field');
16252 delete this.parentEl;
16253 delete this.boundEl;
16256 Ext.reg('editor', Ext.Editor);
16258 Ext.ColorPalette = Ext.extend(Ext.Component, {
16261 itemCls : 'x-color-palette',
16265 clickEvent :'click',
16267 ctype : 'Ext.ColorPalette',
16270 allowReselect : false,
16274 '000000', '993300', '333300', '003300', '003366', '000080', '333399', '333333',
16275 '800000', 'FF6600', '808000', '008000', '008080', '0000FF', '666699', '808080',
16276 'FF0000', 'FF9900', '99CC00', '339966', '33CCCC', '3366FF', '800080', '969696',
16277 'FF00FF', 'FFCC00', 'FFFF00', '00FF00', '00FFFF', '00CCFF', '993366', 'C0C0C0',
16278 'FF99CC', 'FFCC99', 'FFFF99', 'CCFFCC', 'CCFFFF', '99CCFF', 'CC99FF', 'FFFFFF'
16285 initComponent : function(){
16286 Ext.ColorPalette.superclass.initComponent.call(this);
16293 this.on('select', this.handler, this.scope, true);
16298 onRender : function(container, position){
16303 Ext.ColorPalette.superclass.onRender.call(this, container, position);
16304 var t = this.tpl || new Ext.XTemplate(
16305 '<tpl for="."><a href="#" class="color-{.}" hidefocus="on"><em><span style="background:#{.}" unselectable="on"> </span></em></a></tpl>'
16307 t.overwrite(this.el, this.colors);
16308 this.mon(this.el, this.clickEvent, this.handleClick, this, {delegate: 'a'});
16309 if(this.clickEvent != 'click'){
16310 this.mon(this.el, 'click', Ext.emptyFn, this, {delegate: 'a', preventDefault: true});
16315 afterRender : function(){
16316 Ext.ColorPalette.superclass.afterRender.call(this);
16318 var s = this.value;
16320 this.select(s, true);
16325 handleClick : function(e, t){
16326 e.preventDefault();
16327 if(!this.disabled){
16328 var c = t.className.match(/(?:^|\s)color-(.{6})(?:\s|$)/)[1];
16329 this.select(c.toUpperCase());
16334 select : function(color, suppressEvent){
16335 color = color.replace('#', '');
16336 if(color != this.value || this.allowReselect){
16339 el.child('a.color-'+this.value).removeClass('x-color-palette-sel');
16341 el.child('a.color-'+color).addClass('x-color-palette-sel');
16342 this.value = color;
16343 if(suppressEvent !== true){
16344 this.fireEvent('select', this, color);
16351 Ext.reg('colorpalette', Ext.ColorPalette);
16352 Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
16354 todayText : 'Today',
16356 okText : ' OK ',
16358 cancelText : 'Cancel',
16362 todayTip : '{0} (Spacebar)',
16364 minText : 'This date is before the minimum date',
16366 maxText : 'This date is after the maximum date',
16370 disabledDaysText : 'Disabled',
16372 disabledDatesText : 'Disabled',
16374 monthNames : Date.monthNames,
16376 dayNames : Date.dayNames,
16378 nextText : 'Next Month (Control+Right)',
16380 prevText : 'Previous Month (Control+Left)',
16382 monthYearText : 'Choose a month (Control+Up/Down to move years)',
16395 focusOnSelect: true,
16402 initComponent : function(){
16403 Ext.DatePicker.superclass.initComponent.call(this);
16405 this.value = this.value ?
16406 this.value.clearTime(true) : new Date().clearTime();
16414 this.on('select', this.handler, this.scope || this);
16417 this.initDisabledDays();
16421 initDisabledDays : function(){
16422 if(!this.disabledDatesRE && this.disabledDates){
16423 var dd = this.disabledDates,
16424 len = dd.length - 1,
16427 Ext.each(dd, function(d, i){
16428 re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i];
16433 this.disabledDatesRE = new RegExp(re + ')');
16438 setDisabledDates : function(dd){
16439 if(Ext.isArray(dd)){
16440 this.disabledDates = dd;
16441 this.disabledDatesRE = null;
16443 this.disabledDatesRE = dd;
16445 this.initDisabledDays();
16446 this.update(this.value, true);
16450 setDisabledDays : function(dd){
16451 this.disabledDays = dd;
16452 this.update(this.value, true);
16456 setMinDate : function(dt){
16458 this.update(this.value, true);
16462 setMaxDate : function(dt){
16464 this.update(this.value, true);
16468 setValue : function(value){
16469 this.value = value.clearTime(true);
16470 this.update(this.value);
16474 getValue : function(){
16479 focus : function(){
16480 this.update(this.activeDate);
16484 onEnable: function(initial){
16485 Ext.DatePicker.superclass.onEnable.call(this);
16486 this.doDisabled(false);
16487 this.update(initial ? this.value : this.activeDate);
16495 onDisable : function(){
16496 Ext.DatePicker.superclass.onDisable.call(this);
16497 this.doDisabled(true);
16498 if(Ext.isIE && !Ext.isIE8){
16500 Ext.each([].concat(this.textNodes, this.el.query('th span')), function(el){
16501 Ext.fly(el).repaint();
16507 doDisabled : function(disabled){
16508 this.keyNav.setDisabled(disabled);
16509 this.prevRepeater.setDisabled(disabled);
16510 this.nextRepeater.setDisabled(disabled);
16511 if(this.showToday){
16512 this.todayKeyListener.setDisabled(disabled);
16513 this.todayBtn.setDisabled(disabled);
16518 onRender : function(container, position){
16520 '<table cellspacing="0">',
16521 '<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>',
16522 '<tr><td colspan="3"><table class="x-date-inner" cellspacing="0"><thead><tr>'],
16523 dn = this.dayNames,
16525 for(i = 0; i < 7; i++){
16526 var d = this.startDay+i;
16530 m.push('<th><span>', dn[d].substr(0,1), '</span></th>');
16532 m[m.length] = '</tr></thead><tbody><tr>';
16533 for(i = 0; i < 42; i++) {
16534 if(i % 7 === 0 && i !== 0){
16535 m[m.length] = '</tr><tr>';
16537 m[m.length] = '<td><a href="#" hidefocus="on" class="x-date-date" tabIndex="1"><em><span></span></em></a></td>';
16539 m.push('</tr></tbody></table></td></tr>',
16540 this.showToday ? '<tr><td colspan="3" class="x-date-bottom" align="center"></td></tr>' : '',
16541 '</table><div class="x-date-mp"></div>');
16543 var el = document.createElement('div');
16544 el.className = 'x-date-picker';
16545 el.innerHTML = m.join('');
16547 container.dom.insertBefore(el, position);
16549 this.el = Ext.get(el);
16550 this.eventEl = Ext.get(el.firstChild);
16552 this.prevRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-left a'), {
16553 handler: this.showPrevMonth,
16555 preventDefault:true,
16559 this.nextRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-right a'), {
16560 handler: this.showNextMonth,
16562 preventDefault:true,
16566 this.monthPicker = this.el.down('div.x-date-mp');
16567 this.monthPicker.enableDisplayMode('block');
16569 this.keyNav = new Ext.KeyNav(this.eventEl, {
16570 'left' : function(e){
16572 this.showPrevMonth();
16574 this.update(this.activeDate.add('d', -1));
16578 'right' : function(e){
16580 this.showNextMonth();
16582 this.update(this.activeDate.add('d', 1));
16586 'up' : function(e){
16588 this.showNextYear();
16590 this.update(this.activeDate.add('d', -7));
16594 'down' : function(e){
16596 this.showPrevYear();
16598 this.update(this.activeDate.add('d', 7));
16602 'pageUp' : function(e){
16603 this.showNextMonth();
16606 'pageDown' : function(e){
16607 this.showPrevMonth();
16610 'enter' : function(e){
16611 e.stopPropagation();
16618 this.el.unselectable();
16620 this.cells = this.el.select('table.x-date-inner tbody td');
16621 this.textNodes = this.el.query('table.x-date-inner tbody span');
16623 this.mbtn = new Ext.Button({
16625 tooltip: this.monthYearText,
16626 renderTo: this.el.child('td.x-date-middle', true)
16628 this.mbtn.el.child('em').addClass('x-btn-arrow');
16630 if(this.showToday){
16631 this.todayKeyListener = this.eventEl.addKeyListener(Ext.EventObject.SPACE, this.selectToday, this);
16632 var today = (new Date()).dateFormat(this.format);
16633 this.todayBtn = new Ext.Button({
16634 renderTo: this.el.child('td.x-date-bottom', true),
16635 text: String.format(this.todayText, today),
16636 tooltip: String.format(this.todayTip, today),
16637 handler: this.selectToday,
16641 this.mon(this.eventEl, 'mousewheel', this.handleMouseWheel, this);
16642 this.mon(this.eventEl, 'click', this.handleDateClick, this, {delegate: 'a.x-date-date'});
16643 this.mon(this.mbtn, 'click', this.showMonthPicker, this);
16644 this.onEnable(true);
16648 createMonthPicker : function(){
16649 if(!this.monthPicker.dom.firstChild){
16650 var buf = ['<table border="0" cellspacing="0">'];
16651 for(var i = 0; i < 6; i++){
16653 '<tr><td class="x-date-mp-month"><a href="#">', Date.getShortMonthName(i), '</a></td>',
16654 '<td class="x-date-mp-month x-date-mp-sep"><a href="#">', Date.getShortMonthName(i + 6), '</a></td>',
16656 '<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>' :
16657 '<td class="x-date-mp-year"><a href="#"></a></td><td class="x-date-mp-year"><a href="#"></a></td></tr>'
16661 '<tr class="x-date-mp-btns"><td colspan="4"><button type="button" class="x-date-mp-ok">',
16663 '</button><button type="button" class="x-date-mp-cancel">',
16665 '</button></td></tr>',
16668 this.monthPicker.update(buf.join(''));
16670 this.mon(this.monthPicker, 'click', this.onMonthClick, this);
16671 this.mon(this.monthPicker, 'dblclick', this.onMonthDblClick, this);
16673 this.mpMonths = this.monthPicker.select('td.x-date-mp-month');
16674 this.mpYears = this.monthPicker.select('td.x-date-mp-year');
16676 this.mpMonths.each(function(m, a, i){
16679 m.dom.xmonth = 5 + Math.round(i * 0.5);
16681 m.dom.xmonth = Math.round((i-1) * 0.5);
16688 showMonthPicker : function(){
16689 if(!this.disabled){
16690 this.createMonthPicker();
16691 var size = this.el.getSize();
16692 this.monthPicker.setSize(size);
16693 this.monthPicker.child('table').setSize(size);
16695 this.mpSelMonth = (this.activeDate || this.value).getMonth();
16696 this.updateMPMonth(this.mpSelMonth);
16697 this.mpSelYear = (this.activeDate || this.value).getFullYear();
16698 this.updateMPYear(this.mpSelYear);
16700 this.monthPicker.slideIn('t', {duration:0.2});
16705 updateMPYear : function(y){
16707 var ys = this.mpYears.elements;
16708 for(var i = 1; i <= 10; i++){
16709 var td = ys[i-1], y2;
16711 y2 = y + Math.round(i * 0.5);
16712 td.firstChild.innerHTML = y2;
16715 y2 = y - (5-Math.round(i * 0.5));
16716 td.firstChild.innerHTML = y2;
16719 this.mpYears.item(i-1)[y2 == this.mpSelYear ? 'addClass' : 'removeClass']('x-date-mp-sel');
16724 updateMPMonth : function(sm){
16725 this.mpMonths.each(function(m, a, i){
16726 m[m.dom.xmonth == sm ? 'addClass' : 'removeClass']('x-date-mp-sel');
16731 selectMPMonth : function(m){
16736 onMonthClick : function(e, t){
16738 var el = new Ext.Element(t), pn;
16739 if(el.is('button.x-date-mp-cancel')){
16740 this.hideMonthPicker();
16742 else if(el.is('button.x-date-mp-ok')){
16743 var d = new Date(this.mpSelYear, this.mpSelMonth, (this.activeDate || this.value).getDate());
16744 if(d.getMonth() != this.mpSelMonth){
16746 d = new Date(this.mpSelYear, this.mpSelMonth, 1).getLastDateOfMonth();
16749 this.hideMonthPicker();
16751 else if((pn = el.up('td.x-date-mp-month', 2))){
16752 this.mpMonths.removeClass('x-date-mp-sel');
16753 pn.addClass('x-date-mp-sel');
16754 this.mpSelMonth = pn.dom.xmonth;
16756 else if((pn = el.up('td.x-date-mp-year', 2))){
16757 this.mpYears.removeClass('x-date-mp-sel');
16758 pn.addClass('x-date-mp-sel');
16759 this.mpSelYear = pn.dom.xyear;
16761 else if(el.is('a.x-date-mp-prev')){
16762 this.updateMPYear(this.mpyear-10);
16764 else if(el.is('a.x-date-mp-next')){
16765 this.updateMPYear(this.mpyear+10);
16770 onMonthDblClick : function(e, t){
16772 var el = new Ext.Element(t), pn;
16773 if((pn = el.up('td.x-date-mp-month', 2))){
16774 this.update(new Date(this.mpSelYear, pn.dom.xmonth, (this.activeDate || this.value).getDate()));
16775 this.hideMonthPicker();
16777 else if((pn = el.up('td.x-date-mp-year', 2))){
16778 this.update(new Date(pn.dom.xyear, this.mpSelMonth, (this.activeDate || this.value).getDate()));
16779 this.hideMonthPicker();
16784 hideMonthPicker : function(disableAnim){
16785 if(this.monthPicker){
16786 if(disableAnim === true){
16787 this.monthPicker.hide();
16789 this.monthPicker.slideOut('t', {duration:0.2});
16795 showPrevMonth : function(e){
16796 this.update(this.activeDate.add('mo', -1));
16800 showNextMonth : function(e){
16801 this.update(this.activeDate.add('mo', 1));
16805 showPrevYear : function(){
16806 this.update(this.activeDate.add('y', -1));
16810 showNextYear : function(){
16811 this.update(this.activeDate.add('y', 1));
16815 handleMouseWheel : function(e){
16817 if(!this.disabled){
16818 var delta = e.getWheelDelta();
16820 this.showPrevMonth();
16821 } else if(delta < 0){
16822 this.showNextMonth();
16828 handleDateClick : function(e, t){
16830 if(!this.disabled && t.dateValue && !Ext.fly(t.parentNode).hasClass('x-date-disabled')){
16831 this.cancelFocus = this.focusOnSelect === false;
16832 this.setValue(new Date(t.dateValue));
16833 delete this.cancelFocus;
16834 this.fireEvent('select', this, this.value);
16839 selectToday : function(){
16840 if(this.todayBtn && !this.todayBtn.disabled){
16841 this.setValue(new Date().clearTime());
16842 this.fireEvent('select', this, this.value);
16847 update : function(date, forceRefresh){
16849 var vd = this.activeDate, vis = this.isVisible();
16850 this.activeDate = date;
16851 if(!forceRefresh && vd && this.el){
16852 var t = date.getTime();
16853 if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){
16854 this.cells.removeClass('x-date-selected');
16855 this.cells.each(function(c){
16856 if(c.dom.firstChild.dateValue == t){
16857 c.addClass('x-date-selected');
16858 if(vis && !this.cancelFocus){
16859 Ext.fly(c.dom.firstChild).focus(50);
16867 var days = date.getDaysInMonth(),
16868 firstOfMonth = date.getFirstDateOfMonth(),
16869 startingPos = firstOfMonth.getDay()-this.startDay;
16871 if(startingPos < 0){
16874 days += startingPos;
16876 var pm = date.add('mo', -1),
16877 prevStart = pm.getDaysInMonth()-startingPos,
16878 cells = this.cells.elements,
16879 textEls = this.textNodes,
16881 d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart, this.initHour)),
16882 today = new Date().clearTime().getTime(),
16883 sel = date.clearTime(true).getTime(),
16884 min = this.minDate ? this.minDate.clearTime(true) : Number.NEGATIVE_INFINITY,
16885 max = this.maxDate ? this.maxDate.clearTime(true) : Number.POSITIVE_INFINITY,
16886 ddMatch = this.disabledDatesRE,
16887 ddText = this.disabledDatesText,
16888 ddays = this.disabledDays ? this.disabledDays.join('') : false,
16889 ddaysText = this.disabledDaysText,
16890 format = this.format;
16892 if(this.showToday){
16893 var td = new Date().clearTime(),
16894 disable = (td < min || td > max ||
16895 (ddMatch && format && ddMatch.test(td.dateFormat(format))) ||
16896 (ddays && ddays.indexOf(td.getDay()) != -1));
16898 if(!this.disabled){
16899 this.todayBtn.setDisabled(disable);
16900 this.todayKeyListener[disable ? 'disable' : 'enable']();
16904 var setCellClass = function(cal, cell){
16906 var t = d.clearTime(true).getTime();
16907 cell.firstChild.dateValue = t;
16909 cell.className += ' x-date-today';
16910 cell.title = cal.todayText;
16913 cell.className += ' x-date-selected';
16915 Ext.fly(cell.firstChild).focus(50);
16920 cell.className = ' x-date-disabled';
16921 cell.title = cal.minText;
16925 cell.className = ' x-date-disabled';
16926 cell.title = cal.maxText;
16930 if(ddays.indexOf(d.getDay()) != -1){
16931 cell.title = ddaysText;
16932 cell.className = ' x-date-disabled';
16935 if(ddMatch && format){
16936 var fvalue = d.dateFormat(format);
16937 if(ddMatch.test(fvalue)){
16938 cell.title = ddText.replace('%0', fvalue);
16939 cell.className = ' x-date-disabled';
16945 for(; i < startingPos; i++) {
16946 textEls[i].innerHTML = (++prevStart);
16947 d.setDate(d.getDate()+1);
16948 cells[i].className = 'x-date-prevday';
16949 setCellClass(this, cells[i]);
16951 for(; i < days; i++){
16952 var intDay = i - startingPos + 1;
16953 textEls[i].innerHTML = (intDay);
16954 d.setDate(d.getDate()+1);
16955 cells[i].className = 'x-date-active';
16956 setCellClass(this, cells[i]);
16959 for(; i < 42; i++) {
16960 textEls[i].innerHTML = (++extraDays);
16961 d.setDate(d.getDate()+1);
16962 cells[i].className = 'x-date-nextday';
16963 setCellClass(this, cells[i]);
16966 this.mbtn.setText(this.monthNames[date.getMonth()] + ' ' + date.getFullYear());
16968 if(!this.internalRender){
16969 var main = this.el.dom.firstChild,
16970 w = main.offsetWidth;
16971 this.el.setWidth(w + this.el.getBorderWidth('lr'));
16972 Ext.fly(main).setWidth(w);
16973 this.internalRender = true;
16977 if(Ext.isOpera && !this.secondPass){
16978 main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + 'px';
16979 this.secondPass = true;
16980 this.update.defer(10, this, [date]);
16987 beforeDestroy : function() {
16999 delete this.textNodes;
17000 delete this.cells.elements;
17007 Ext.reg('datepicker', Ext.DatePicker);
17009 Ext.LoadMask = function(el, config){
17010 this.el = Ext.get(el);
17011 Ext.apply(this, config);
17015 beforeload: this.onBeforeLoad,
17017 exception: this.onLoad
17019 this.removeMask = Ext.value(this.removeMask, false);
17021 var um = this.el.getUpdater();
17022 um.showLoadIndicator = false;
17025 beforeupdate: this.onBeforeLoad,
17026 update: this.onLoad,
17027 failure: this.onLoad
17029 this.removeMask = Ext.value(this.removeMask, true);
17033 Ext.LoadMask.prototype = {
17037 msg : 'Loading...',
17039 msgCls : 'x-mask-loading',
17045 disable : function(){
17046 this.disabled = true;
17050 enable : function(){
17051 this.disabled = false;
17055 onLoad : function(){
17056 this.el.unmask(this.removeMask);
17060 onBeforeLoad : function(){
17061 if(!this.disabled){
17062 this.el.mask(this.msg, this.msgCls);
17068 this.onBeforeLoad();
17077 destroy : function(){
17079 this.store.un('beforeload', this.onBeforeLoad, this);
17080 this.store.un('load', this.onLoad, this);
17081 this.store.un('exception', this.onLoad, this);
17083 var um = this.el.getUpdater();
17084 um.un('beforeupdate', this.onBeforeLoad, this);
17085 um.un('update', this.onLoad, this);
17086 um.un('failure', this.onLoad, this);
17089 };Ext.ns('Ext.slider');
17092 Ext.slider.Thumb = Ext.extend(Object, {
17095 constructor: function(config) {
17097 Ext.apply(this, config || {}, {
17098 cls: 'x-slider-thumb',
17104 Ext.slider.Thumb.superclass.constructor.call(this, config);
17106 if (this.slider.vertical) {
17107 Ext.apply(this, Ext.slider.Thumb.Vertical);
17112 render: function() {
17113 this.el = this.slider.innerEl.insertFirst({cls: this.cls});
17119 enable: function() {
17120 this.disabled = false;
17121 this.el.removeClass(this.slider.disabledClass);
17125 disable: function() {
17126 this.disabled = true;
17127 this.el.addClass(this.slider.disabledClass);
17131 initEvents: function() {
17134 el.addClassOnOver('x-slider-thumb-over');
17136 this.tracker = new Ext.dd.DragTracker({
17137 onBeforeStart: this.onBeforeDragStart.createDelegate(this),
17138 onStart : this.onDragStart.createDelegate(this),
17139 onDrag : this.onDrag.createDelegate(this),
17140 onEnd : this.onDragEnd.createDelegate(this),
17145 this.tracker.initEl(el);
17149 onBeforeDragStart : function(e) {
17150 if (this.disabled) {
17153 this.slider.promoteThumb(this);
17159 onDragStart: function(e){
17160 this.el.addClass('x-slider-thumb-drag');
17161 this.dragging = true;
17162 this.dragStartValue = this.value;
17164 this.slider.fireEvent('dragstart', this.slider, e, this);
17168 onDrag: function(e) {
17169 var slider = this.slider,
17170 index = this.index,
17171 newValue = this.getNewValue();
17173 if (this.constrain) {
17174 var above = slider.thumbs[index + 1],
17175 below = slider.thumbs[index - 1];
17177 if (below != undefined && newValue <= below.value) newValue = below.value;
17178 if (above != undefined && newValue >= above.value) newValue = above.value;
17181 slider.setValue(index, newValue, false);
17182 slider.fireEvent('drag', slider, e, this);
17185 getNewValue: function() {
17186 var slider = this.slider,
17187 pos = slider.innerEl.translatePoints(this.tracker.getXY());
17189 return Ext.util.Format.round(slider.reverseValue(pos.left), slider.decimalPrecision);
17193 onDragEnd: function(e) {
17194 var slider = this.slider,
17195 value = this.value;
17197 this.el.removeClass('x-slider-thumb-drag');
17199 this.dragging = false;
17200 slider.fireEvent('dragend', slider, e);
17202 if (this.dragStartValue != value) {
17203 slider.fireEvent('changecomplete', slider, value, this);
17209 Ext.slider.MultiSlider = Ext.extend(Ext.BoxComponent, {
17218 decimalPrecision: 0,
17225 clickRange: [5,15],
17228 clickToChange : true,
17236 constrainThumbs: true,
17239 topThumbZIndex: 10000,
17242 initComponent : function(){
17243 if(!Ext.isDefined(this.value)){
17244 this.value = this.minValue;
17250 Ext.slider.MultiSlider.superclass.initComponent.call(this);
17252 this.keyIncrement = Math.max(this.increment, this.keyIncrement);
17274 if (this.values == undefined || Ext.isEmpty(this.values)) this.values = [0];
17276 var values = this.values;
17278 for (var i=0; i < values.length; i++) {
17279 this.addThumb(values[i]);
17283 Ext.apply(this, Ext.slider.Vertical);
17288 addThumb: function(value) {
17289 var thumb = new Ext.slider.Thumb({
17292 index : this.thumbs.length,
17293 constrain: this.constrainThumbs
17295 this.thumbs.push(thumb);
17298 if (this.rendered) thumb.render();
17302 promoteThumb: function(topThumb) {
17303 var thumbs = this.thumbs,
17306 for (var i = 0, j = thumbs.length; i < j; i++) {
17309 if (thumb == topThumb) {
17310 zIndex = this.topThumbZIndex;
17315 thumb.el.setStyle('zIndex', zIndex);
17320 onRender : function() {
17322 cls: 'x-slider ' + (this.vertical ? 'x-slider-vert' : 'x-slider-horz'),
17324 cls: 'x-slider-end',
17326 cls:'x-slider-inner',
17327 cn : [{tag:'a', cls:'x-slider-focus', href:"#", tabIndex: '-1', hidefocus:'on'}]
17332 Ext.slider.MultiSlider.superclass.onRender.apply(this, arguments);
17334 this.endEl = this.el.first();
17335 this.innerEl = this.endEl.first();
17336 this.focusEl = this.innerEl.child('.x-slider-focus');
17339 for (var i=0; i < this.thumbs.length; i++) {
17340 this.thumbs[i].render();
17344 var thumb = this.innerEl.child('.x-slider-thumb');
17345 this.halfThumb = (this.vertical ? thumb.getHeight() : thumb.getWidth()) / 2;
17351 initEvents : function(){
17352 this.mon(this.el, {
17354 mousedown: this.onMouseDown,
17355 keydown : this.onKeyDown
17358 this.focusEl.swallowEvent("click", true);
17362 onMouseDown : function(e){
17368 var thumbClicked = false;
17369 for (var i=0; i < this.thumbs.length; i++) {
17370 thumbClicked = thumbClicked || e.target == this.thumbs[i].el.dom;
17373 if (this.clickToChange && !thumbClicked) {
17374 var local = this.innerEl.translatePoints(e.getXY());
17375 this.onClickChange(local);
17381 onClickChange : function(local) {
17382 if (local.top > this.clickRange[0] && local.top < this.clickRange[1]) {
17384 var thumb = this.getNearest(local, 'left'),
17385 index = thumb.index;
17387 this.setValue(index, Ext.util.Format.round(this.reverseValue(local.left), this.decimalPrecision), undefined, true);
17392 getNearest: function(local, prop) {
17393 var localValue = prop == 'top' ? this.innerEl.getHeight() - local[prop] : local[prop],
17394 clickValue = this.reverseValue(localValue),
17395 nearestDistance = (this.maxValue - this.minValue) + 5,
17399 for (var i=0; i < this.thumbs.length; i++) {
17400 var thumb = this.thumbs[i],
17401 value = thumb.value,
17402 dist = Math.abs(value - clickValue);
17404 if (Math.abs(dist <= nearestDistance)) {
17407 nearestDistance = dist;
17414 onKeyDown : function(e){
17416 if(this.disabled || this.thumbs.length !== 1){
17417 e.preventDefault();
17420 var k = e.getKey(),
17426 val = e.ctrlKey ? this.maxValue : this.getValue(0) + this.keyIncrement;
17427 this.setValue(0, val, undefined, true);
17432 val = e.ctrlKey ? this.minValue : this.getValue(0) - this.keyIncrement;
17433 this.setValue(0, val, undefined, true);
17436 e.preventDefault();
17441 doSnap : function(value){
17442 if (!(this.increment && value)) {
17445 var newValue = value,
17446 inc = this.increment,
17450 if (m * 2 >= inc) {
17452 } else if (m * 2 < -inc) {
17456 return newValue.constrain(this.minValue, this.maxValue);
17460 afterRender : function(){
17461 Ext.slider.MultiSlider.superclass.afterRender.apply(this, arguments);
17463 for (var i=0; i < this.thumbs.length; i++) {
17464 var thumb = this.thumbs[i];
17466 if (thumb.value !== undefined) {
17467 var v = this.normalizeValue(thumb.value);
17469 if (v !== thumb.value) {
17471 this.setValue(i, v, false);
17473 this.moveThumb(i, this.translateValue(v), false);
17480 getRatio : function(){
17481 var w = this.innerEl.getWidth(),
17482 v = this.maxValue - this.minValue;
17483 return v == 0 ? w : (w/v);
17487 normalizeValue : function(v){
17488 v = this.doSnap(v);
17489 v = Ext.util.Format.round(v, this.decimalPrecision);
17490 v = v.constrain(this.minValue, this.maxValue);
17495 setMinValue : function(val){
17496 this.minValue = val;
17498 thumbs = this.thumbs,
17499 len = thumbs.length,
17502 for(; i < len; ++i){
17504 t.value = t.value < val ? val : t.value;
17510 setMaxValue : function(val){
17511 this.maxValue = val;
17513 thumbs = this.thumbs,
17514 len = thumbs.length,
17517 for(; i < len; ++i){
17519 t.value = t.value > val ? val : t.value;
17525 setValue : function(index, v, animate, changeComplete) {
17526 var thumb = this.thumbs[index],
17529 v = this.normalizeValue(v);
17531 if (v !== thumb.value && this.fireEvent('beforechange', this, v, thumb.value, thumb) !== false) {
17534 this.moveThumb(index, this.translateValue(v), animate !== false);
17535 this.fireEvent('change', this, v, thumb);
17536 if(changeComplete){
17537 this.fireEvent('changecomplete', this, v, thumb);
17544 translateValue : function(v) {
17545 var ratio = this.getRatio();
17546 return (v * ratio) - (this.minValue * ratio) - this.halfThumb;
17550 reverseValue : function(pos){
17551 var ratio = this.getRatio();
17552 return (pos + (this.minValue * ratio)) / ratio;
17556 moveThumb: function(index, v, animate){
17557 var thumb = this.thumbs[index].el;
17559 if(!animate || this.animate === false){
17562 thumb.shift({left: v, stopFx: true, duration:.35});
17567 focus : function(){
17568 this.focusEl.focus(10);
17572 onResize : function(w, h){
17573 var thumbs = this.thumbs,
17574 len = thumbs.length,
17578 for(; i < len; ++i){
17579 thumbs[i].el.stopFx();
17581 this.innerEl.setWidth(w - (this.el.getPadding('l') + this.endEl.getPadding('r')));
17583 Ext.slider.MultiSlider.superclass.onResize.apply(this, arguments);
17587 onDisable: function(){
17588 Ext.slider.MultiSlider.superclass.onDisable.call(this);
17590 for (var i=0; i < this.thumbs.length; i++) {
17591 var thumb = this.thumbs[i],
17599 var xy = el.getXY();
17602 this.innerEl.addClass(this.disabledClass).dom.disabled = true;
17604 if (!this.thumbHolder) {
17605 this.thumbHolder = this.endEl.createChild({cls: 'x-slider-thumb ' + this.disabledClass});
17608 this.thumbHolder.show().setXY(xy);
17614 onEnable: function(){
17615 Ext.slider.MultiSlider.superclass.onEnable.call(this);
17617 for (var i=0; i < this.thumbs.length; i++) {
17618 var thumb = this.thumbs[i],
17624 this.innerEl.removeClass(this.disabledClass).dom.disabled = false;
17626 if (this.thumbHolder) this.thumbHolder.hide();
17635 syncThumb : function() {
17636 if (this.rendered) {
17637 for (var i=0; i < this.thumbs.length; i++) {
17638 this.moveThumb(i, this.translateValue(this.thumbs[i].value));
17644 getValue : function(index) {
17645 return this.thumbs[index].value;
17649 getValues: function() {
17652 for (var i=0; i < this.thumbs.length; i++) {
17653 values.push(this.thumbs[i].value);
17660 beforeDestroy : function(){
17661 Ext.destroyMembers(this, 'endEl', 'innerEl', 'thumb', 'halfThumb', 'focusEl', 'tracker', 'thumbHolder');
17662 Ext.slider.MultiSlider.superclass.beforeDestroy.call(this);
17666 Ext.reg('multislider', Ext.slider.MultiSlider);
17669 Ext.slider.SingleSlider = Ext.extend(Ext.slider.MultiSlider, {
17670 constructor: function(config) {
17671 config = config || {};
17673 Ext.applyIf(config, {
17674 values: [config.value || 0]
17677 Ext.slider.SingleSlider.superclass.constructor.call(this, config);
17681 getValue: function() {
17683 return Ext.slider.SingleSlider.superclass.getValue.call(this, 0);
17687 setValue: function(value, animate) {
17688 var args = Ext.toArray(arguments),
17694 if (len == 1 || (len <= 3 && typeof arguments[1] != 'number')) {
17698 return Ext.slider.SingleSlider.superclass.setValue.apply(this, args);
17702 syncThumb : function() {
17703 return Ext.slider.SingleSlider.superclass.syncThumb.apply(this, [0].concat(arguments));
17707 getNearest : function(){
17709 return this.thumbs[0];
17714 Ext.Slider = Ext.slider.SingleSlider;
17716 Ext.reg('slider', Ext.slider.SingleSlider);
17719 Ext.slider.Vertical = {
17720 onResize : function(w, h){
17721 this.innerEl.setHeight(h - (this.el.getPadding('t') + this.endEl.getPadding('b')));
17725 getRatio : function(){
17726 var h = this.innerEl.getHeight(),
17727 v = this.maxValue - this.minValue;
17731 moveThumb: function(index, v, animate) {
17732 var thumb = this.thumbs[index],
17735 if (!animate || this.animate === false) {
17738 el.shift({bottom: v, stopFx: true, duration:.35});
17742 onClickChange : function(local) {
17743 if (local.left > this.clickRange[0] && local.left < this.clickRange[1]) {
17744 var thumb = this.getNearest(local, 'top'),
17745 index = thumb.index,
17746 value = this.minValue + this.reverseValue(this.innerEl.getHeight() - local.top);
17748 this.setValue(index, Ext.util.Format.round(value, this.decimalPrecision), undefined, true);
17754 Ext.slider.Thumb.Vertical = {
17755 getNewValue: function() {
17756 var slider = this.slider,
17757 innerEl = slider.innerEl,
17758 pos = innerEl.translatePoints(this.tracker.getXY()),
17759 bottom = innerEl.getHeight() - pos.top;
17761 return slider.minValue + Ext.util.Format.round(bottom / slider.getRatio(), slider.decimalPrecision);
17765 Ext.ProgressBar = Ext.extend(Ext.BoxComponent, {
17767 baseCls : 'x-progress',
17776 initComponent : function(){
17777 Ext.ProgressBar.superclass.initComponent.call(this);
17785 onRender : function(ct, position){
17786 var tpl = new Ext.Template(
17787 '<div class="{cls}-wrap">',
17788 '<div class="{cls}-inner">',
17789 '<div class="{cls}-bar">',
17790 '<div class="{cls}-text">',
17791 '<div> </div>',
17794 '<div class="{cls}-text {cls}-text-back">',
17795 '<div> </div>',
17801 this.el = position ? tpl.insertBefore(position, {cls: this.baseCls}, true)
17802 : tpl.append(ct, {cls: this.baseCls}, true);
17805 this.el.dom.id = this.id;
17807 var inner = this.el.dom.firstChild;
17808 this.progressBar = Ext.get(inner.firstChild);
17812 this.textEl = Ext.get(this.textEl);
17813 delete this.textTopEl;
17816 this.textTopEl = Ext.get(this.progressBar.dom.firstChild);
17817 var textBackEl = Ext.get(inner.childNodes[1]);
17818 this.textTopEl.setStyle("z-index", 99).addClass('x-hidden');
17819 this.textEl = new Ext.CompositeElement([this.textTopEl.dom.firstChild, textBackEl.dom.firstChild]);
17820 this.textEl.setWidth(inner.offsetWidth);
17822 this.progressBar.setHeight(inner.offsetHeight);
17826 afterRender : function(){
17827 Ext.ProgressBar.superclass.afterRender.call(this);
17829 this.updateProgress(this.value, this.text);
17831 this.updateText(this.text);
17836 updateProgress : function(value, text, animate){
17837 this.value = value || 0;
17839 this.updateText(text);
17841 if(this.rendered && !this.isDestroyed){
17842 var w = Math.floor(value*this.el.dom.firstChild.offsetWidth);
17843 this.progressBar.setWidth(w, animate === true || (animate !== false && this.animate));
17844 if(this.textTopEl){
17846 this.textTopEl.removeClass('x-hidden').setWidth(w);
17849 this.fireEvent('update', this, value, text);
17854 wait : function(o){
17855 if(!this.waitTimer){
17858 this.updateText(o.text);
17859 this.waitTimer = Ext.TaskMgr.start({
17861 var inc = o.increment || 10;
17863 this.updateProgress(((((i+inc)%inc)+1)*(100/inc))*0.01, null, o.animate);
17865 interval: o.interval || 1000,
17866 duration: o.duration,
17867 onStop: function(){
17869 o.fn.apply(o.scope || this);
17880 isWaiting : function(){
17881 return this.waitTimer !== null;
17885 updateText : function(text){
17886 this.text = text || ' ';
17888 this.textEl.update(this.text);
17894 syncProgressBar : function(){
17896 this.updateProgress(this.value, this.text);
17902 setSize : function(w, h){
17903 Ext.ProgressBar.superclass.setSize.call(this, w, h);
17904 if(this.textTopEl){
17905 var inner = this.el.dom.firstChild;
17906 this.textEl.setSize(inner.offsetWidth, inner.offsetHeight);
17908 this.syncProgressBar();
17913 reset : function(hide){
17914 this.updateProgress(0);
17915 if(this.textTopEl){
17916 this.textTopEl.addClass('x-hidden');
17926 clearTimer : function(){
17927 if(this.waitTimer){
17928 this.waitTimer.onStop = null;
17929 Ext.TaskMgr.stop(this.waitTimer);
17930 this.waitTimer = null;
17934 onDestroy: function(){
17937 if(this.textEl.isComposite){
17938 this.textEl.clear();
17940 Ext.destroyMembers(this, 'textEl', 'progressBar', 'textTopEl');
17942 Ext.ProgressBar.superclass.onDestroy.call(this);
17945 Ext.reg('progress', Ext.ProgressBar);
17949 var Event=Ext.EventManager;
17950 var Dom=Ext.lib.Dom;
17953 Ext.dd.DragDrop = function(id, sGroup, config) {
17955 this.init(id, sGroup, config);
17959 Ext.dd.DragDrop.prototype = {
17976 invalidHandleTypes: null,
17979 invalidHandleIds: null,
17982 invalidHandleClasses: null,
17998 this.locked = true;
18005 unlock: function() {
18006 this.locked = false;
18019 __ygDragDrop: true,
18040 maintainOffset: false,
18049 primaryButtonOnly: true,
18055 hasOuterHandles: false,
18058 b4StartDrag: function(x, y) { },
18061 startDrag: function(x, y) { },
18064 b4Drag: function(e) { },
18067 onDrag: function(e) { },
18070 onDragEnter: function(e, id) { },
18073 b4DragOver: function(e) { },
18076 onDragOver: function(e, id) { },
18079 b4DragOut: function(e) { },
18082 onDragOut: function(e, id) { },
18085 b4DragDrop: function(e) { },
18088 onDragDrop: function(e, id) { },
18091 onInvalidDrop: function(e) { },
18094 b4EndDrag: function(e) { },
18097 endDrag: function(e) { },
18100 b4MouseDown: function(e) { },
18103 onMouseDown: function(e) { },
18106 onMouseUp: function(e) { },
18109 onAvailable: function () {
18113 defaultPadding : {left:0, right:0, top:0, bottom:0},
18116 constrainTo : function(constrainTo, pad, inContent){
18117 if(Ext.isNumber(pad)){
18118 pad = {left: pad, right:pad, top:pad, bottom:pad};
18120 pad = pad || this.defaultPadding;
18121 var b = Ext.get(this.getEl()).getBox(),
18122 ce = Ext.get(constrainTo),
18123 s = ce.getScroll(),
18126 if(cd == document.body){
18127 c = { x: s.left, y: s.top, width: Ext.lib.Dom.getViewWidth(), height: Ext.lib.Dom.getViewHeight()};
18129 var xy = ce.getXY();
18130 c = {x : xy[0], y: xy[1], width: cd.clientWidth, height: cd.clientHeight};
18134 var topSpace = b.y - c.y,
18135 leftSpace = b.x - c.x;
18137 this.resetConstraints();
18138 this.setXConstraint(leftSpace - (pad.left||0),
18139 c.width - leftSpace - b.width - (pad.right||0),
18142 this.setYConstraint(topSpace - (pad.top||0),
18143 c.height - topSpace - b.height - (pad.bottom||0),
18149 getEl: function() {
18150 if (!this._domRef) {
18151 this._domRef = Ext.getDom(this.id);
18154 return this._domRef;
18158 getDragEl: function() {
18159 return Ext.getDom(this.dragElId);
18163 init: function(id, sGroup, config) {
18164 this.initTarget(id, sGroup, config);
18165 Event.on(this.id, "mousedown", this.handleMouseDown, this);
18170 initTarget: function(id, sGroup, config) {
18173 this.config = config || {};
18176 this.DDM = Ext.dd.DDM;
18182 if (typeof id !== "string") {
18190 this.addToGroup((sGroup) ? sGroup : "default");
18194 this.handleElId = id;
18197 this.setDragElId(id);
18200 this.invalidHandleTypes = { A: "A" };
18201 this.invalidHandleIds = {};
18202 this.invalidHandleClasses = [];
18204 this.applyConfig();
18206 this.handleOnAvailable();
18210 applyConfig: function() {
18214 this.padding = this.config.padding || [0, 0, 0, 0];
18215 this.isTarget = (this.config.isTarget !== false);
18216 this.maintainOffset = (this.config.maintainOffset);
18217 this.primaryButtonOnly = (this.config.primaryButtonOnly !== false);
18222 handleOnAvailable: function() {
18223 this.available = true;
18224 this.resetConstraints();
18225 this.onAvailable();
18229 setPadding: function(iTop, iRight, iBot, iLeft) {
18231 if (!iRight && 0 !== iRight) {
18232 this.padding = [iTop, iTop, iTop, iTop];
18233 } else if (!iBot && 0 !== iBot) {
18234 this.padding = [iTop, iRight, iTop, iRight];
18236 this.padding = [iTop, iRight, iBot, iLeft];
18241 setInitPosition: function(diffX, diffY) {
18242 var el = this.getEl();
18244 if (!this.DDM.verifyEl(el)) {
18248 var dx = diffX || 0;
18249 var dy = diffY || 0;
18251 var p = Dom.getXY( el );
18253 this.initPageX = p[0] - dx;
18254 this.initPageY = p[1] - dy;
18256 this.lastPageX = p[0];
18257 this.lastPageY = p[1];
18259 this.setStartPosition(p);
18263 setStartPosition: function(pos) {
18264 var p = pos || Dom.getXY( this.getEl() );
18265 this.deltaSetXY = null;
18267 this.startPageX = p[0];
18268 this.startPageY = p[1];
18272 addToGroup: function(sGroup) {
18273 this.groups[sGroup] = true;
18274 this.DDM.regDragDrop(this, sGroup);
18278 removeFromGroup: function(sGroup) {
18279 if (this.groups[sGroup]) {
18280 delete this.groups[sGroup];
18283 this.DDM.removeDDFromGroup(this, sGroup);
18287 setDragElId: function(id) {
18288 this.dragElId = id;
18292 setHandleElId: function(id) {
18293 if (typeof id !== "string") {
18296 this.handleElId = id;
18297 this.DDM.regHandle(this.id, id);
18301 setOuterHandleElId: function(id) {
18302 if (typeof id !== "string") {
18305 Event.on(id, "mousedown",
18306 this.handleMouseDown, this);
18307 this.setHandleElId(id);
18309 this.hasOuterHandles = true;
18313 unreg: function() {
18314 Event.un(this.id, "mousedown",
18315 this.handleMouseDown);
18316 this._domRef = null;
18317 this.DDM._remove(this);
18320 destroy : function(){
18325 isLocked: function() {
18326 return (this.DDM.isLocked() || this.locked);
18330 handleMouseDown: function(e, oDD){
18331 if (this.primaryButtonOnly && e.button != 0) {
18335 if (this.isLocked()) {
18339 this.DDM.refreshCache(this.groups);
18341 var pt = new Ext.lib.Point(Ext.lib.Event.getPageX(e), Ext.lib.Event.getPageY(e));
18342 if (!this.hasOuterHandles && !this.DDM.isOverTarget(pt, this) ) {
18344 if (this.clickValidator(e)) {
18347 this.setStartPosition();
18349 this.b4MouseDown(e);
18350 this.onMouseDown(e);
18352 this.DDM.handleMouseDown(e, this);
18354 this.DDM.stopEvent(e);
18362 clickValidator: function(e) {
18363 var target = e.getTarget();
18364 return ( this.isValidHandleChild(target) &&
18365 (this.id == this.handleElId ||
18366 this.DDM.handleWasClicked(target, this.id)) );
18370 addInvalidHandleType: function(tagName) {
18371 var type = tagName.toUpperCase();
18372 this.invalidHandleTypes[type] = type;
18376 addInvalidHandleId: function(id) {
18377 if (typeof id !== "string") {
18380 this.invalidHandleIds[id] = id;
18384 addInvalidHandleClass: function(cssClass) {
18385 this.invalidHandleClasses.push(cssClass);
18389 removeInvalidHandleType: function(tagName) {
18390 var type = tagName.toUpperCase();
18392 delete this.invalidHandleTypes[type];
18396 removeInvalidHandleId: function(id) {
18397 if (typeof id !== "string") {
18400 delete this.invalidHandleIds[id];
18404 removeInvalidHandleClass: function(cssClass) {
18405 for (var i=0, len=this.invalidHandleClasses.length; i<len; ++i) {
18406 if (this.invalidHandleClasses[i] == cssClass) {
18407 delete this.invalidHandleClasses[i];
18413 isValidHandleChild: function(node) {
18419 nodeName = node.nodeName.toUpperCase();
18421 nodeName = node.nodeName;
18423 valid = valid && !this.invalidHandleTypes[nodeName];
18424 valid = valid && !this.invalidHandleIds[node.id];
18426 for (var i=0, len=this.invalidHandleClasses.length; valid && i<len; ++i) {
18427 valid = !Ext.fly(node).hasClass(this.invalidHandleClasses[i]);
18436 setXTicks: function(iStartX, iTickSize) {
18438 this.xTickSize = iTickSize;
18442 for (var i = this.initPageX; i >= this.minX; i = i - iTickSize) {
18444 this.xTicks[this.xTicks.length] = i;
18449 for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) {
18451 this.xTicks[this.xTicks.length] = i;
18456 this.xTicks.sort(this.DDM.numericSort) ;
18460 setYTicks: function(iStartY, iTickSize) {
18462 this.yTickSize = iTickSize;
18466 for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) {
18468 this.yTicks[this.yTicks.length] = i;
18473 for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) {
18475 this.yTicks[this.yTicks.length] = i;
18480 this.yTicks.sort(this.DDM.numericSort) ;
18484 setXConstraint: function(iLeft, iRight, iTickSize) {
18485 this.leftConstraint = iLeft;
18486 this.rightConstraint = iRight;
18488 this.minX = this.initPageX - iLeft;
18489 this.maxX = this.initPageX + iRight;
18490 if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); }
18492 this.constrainX = true;
18496 clearConstraints: function() {
18497 this.constrainX = false;
18498 this.constrainY = false;
18503 clearTicks: function() {
18504 this.xTicks = null;
18505 this.yTicks = null;
18506 this.xTickSize = 0;
18507 this.yTickSize = 0;
18511 setYConstraint: function(iUp, iDown, iTickSize) {
18512 this.topConstraint = iUp;
18513 this.bottomConstraint = iDown;
18515 this.minY = this.initPageY - iUp;
18516 this.maxY = this.initPageY + iDown;
18517 if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); }
18519 this.constrainY = true;
18524 resetConstraints: function() {
18526 if (this.initPageX || this.initPageX === 0) {
18528 var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0;
18529 var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0;
18531 this.setInitPosition(dx, dy);
18535 this.setInitPosition();
18538 if (this.constrainX) {
18539 this.setXConstraint( this.leftConstraint,
18540 this.rightConstraint,
18544 if (this.constrainY) {
18545 this.setYConstraint( this.topConstraint,
18546 this.bottomConstraint,
18552 getTick: function(val, tickArray) {
18557 } else if (tickArray[0] >= val) {
18560 return tickArray[0];
18562 for (var i=0, len=tickArray.length; i<len; ++i) {
18564 if (tickArray[next] && tickArray[next] >= val) {
18565 var diff1 = val - tickArray[i];
18566 var diff2 = tickArray[next] - val;
18567 return (diff2 > diff1) ? tickArray[i] : tickArray[next];
18573 return tickArray[tickArray.length - 1];
18578 toString: function() {
18579 return ("DragDrop " + this.id);
18589 if (!Ext.dd.DragDropMgr) {
18592 Ext.dd.DragDropMgr = function() {
18594 var Event = Ext.EventManager;
18617 preventDefault: true,
18620 stopPropagation: true,
18623 initialized: false,
18630 this.initialized = true;
18643 _execOnAll: function(sMethod, args) {
18644 for (var i in this.ids) {
18645 for (var j in this.ids[i]) {
18646 var oDD = this.ids[i][j];
18647 if (! this.isTypeOfDD(oDD)) {
18650 oDD[sMethod].apply(oDD, args);
18656 _onLoad: function() {
18661 Event.on(document, "mouseup", this.handleMouseUp, this, true);
18662 Event.on(document, "mousemove", this.handleMouseMove, this, true);
18663 Event.on(window, "unload", this._onUnload, this, true);
18664 Event.on(window, "resize", this._onResize, this, true);
18670 _onResize: function(e) {
18671 this._execOnAll("resetConstraints", []);
18675 lock: function() { this.locked = true; },
18678 unlock: function() { this.locked = false; },
18681 isLocked: function() { return this.locked; },
18690 clickPixelThresh: 3,
18693 clickTimeThresh: 350,
18696 dragThreshMet: false,
18699 clickTimeout: null,
18708 regDragDrop: function(oDD, sGroup) {
18709 if (!this.initialized) { this.init(); }
18711 if (!this.ids[sGroup]) {
18712 this.ids[sGroup] = {};
18714 this.ids[sGroup][oDD.id] = oDD;
18718 removeDDFromGroup: function(oDD, sGroup) {
18719 if (!this.ids[sGroup]) {
18720 this.ids[sGroup] = {};
18723 var obj = this.ids[sGroup];
18724 if (obj && obj[oDD.id]) {
18725 delete obj[oDD.id];
18730 _remove: function(oDD) {
18731 for (var g in oDD.groups) {
18732 if (g && this.ids[g] && this.ids[g][oDD.id]) {
18733 delete this.ids[g][oDD.id];
18736 delete this.handleIds[oDD.id];
18740 regHandle: function(sDDId, sHandleId) {
18741 if (!this.handleIds[sDDId]) {
18742 this.handleIds[sDDId] = {};
18744 this.handleIds[sDDId][sHandleId] = sHandleId;
18748 isDragDrop: function(id) {
18749 return ( this.getDDById(id) ) ? true : false;
18753 getRelated: function(p_oDD, bTargetsOnly) {
18755 for (var i in p_oDD.groups) {
18756 for (var j in this.ids[i]) {
18757 var dd = this.ids[i][j];
18758 if (! this.isTypeOfDD(dd)) {
18761 if (!bTargetsOnly || dd.isTarget) {
18762 oDDs[oDDs.length] = dd;
18771 isLegalTarget: function (oDD, oTargetDD) {
18772 var targets = this.getRelated(oDD, true);
18773 for (var i=0, len=targets.length;i<len;++i) {
18774 if (targets[i].id == oTargetDD.id) {
18783 isTypeOfDD: function (oDD) {
18784 return (oDD && oDD.__ygDragDrop);
18788 isHandle: function(sDDId, sHandleId) {
18789 return ( this.handleIds[sDDId] &&
18790 this.handleIds[sDDId][sHandleId] );
18794 getDDById: function(id) {
18795 for (var i in this.ids) {
18796 if (this.ids[i][id]) {
18797 return this.ids[i][id];
18804 handleMouseDown: function(e, oDD) {
18806 Ext.QuickTips.disable();
18808 if(this.dragCurrent){
18811 this.handleMouseUp(e);
18814 this.currentTarget = e.getTarget();
18815 this.dragCurrent = oDD;
18817 var el = oDD.getEl();
18820 this.startX = e.getPageX();
18821 this.startY = e.getPageY();
18823 this.deltaX = this.startX - el.offsetLeft;
18824 this.deltaY = this.startY - el.offsetTop;
18826 this.dragThreshMet = false;
18828 this.clickTimeout = setTimeout(
18830 var DDM = Ext.dd.DDM;
18831 DDM.startDrag(DDM.startX, DDM.startY);
18833 this.clickTimeThresh );
18837 startDrag: function(x, y) {
18838 clearTimeout(this.clickTimeout);
18839 if (this.dragCurrent) {
18840 this.dragCurrent.b4StartDrag(x, y);
18841 this.dragCurrent.startDrag(x, y);
18843 this.dragThreshMet = true;
18847 handleMouseUp: function(e) {
18850 Ext.QuickTips.enable();
18852 if (! this.dragCurrent) {
18856 clearTimeout(this.clickTimeout);
18858 if (this.dragThreshMet) {
18859 this.fireEvents(e, true);
18869 stopEvent: function(e){
18870 if(this.stopPropagation) {
18871 e.stopPropagation();
18874 if (this.preventDefault) {
18875 e.preventDefault();
18880 stopDrag: function(e) {
18882 if (this.dragCurrent) {
18883 if (this.dragThreshMet) {
18884 this.dragCurrent.b4EndDrag(e);
18885 this.dragCurrent.endDrag(e);
18888 this.dragCurrent.onMouseUp(e);
18891 this.dragCurrent = null;
18892 this.dragOvers = {};
18896 handleMouseMove: function(e) {
18897 if (! this.dragCurrent) {
18903 if (Ext.isIE && (e.button !== 0 && e.button !== 1 && e.button !== 2)) {
18905 return this.handleMouseUp(e);
18908 if (!this.dragThreshMet) {
18909 var diffX = Math.abs(this.startX - e.getPageX());
18910 var diffY = Math.abs(this.startY - e.getPageY());
18911 if (diffX > this.clickPixelThresh ||
18912 diffY > this.clickPixelThresh) {
18913 this.startDrag(this.startX, this.startY);
18917 if (this.dragThreshMet) {
18918 this.dragCurrent.b4Drag(e);
18919 this.dragCurrent.onDrag(e);
18920 if(!this.dragCurrent.moveOnly){
18921 this.fireEvents(e, false);
18931 fireEvents: function(e, isDrop) {
18932 var dc = this.dragCurrent;
18936 if (!dc || dc.isLocked()) {
18940 var pt = e.getPoint();
18948 var enterEvts = [];
18952 for (var i in this.dragOvers) {
18954 var ddo = this.dragOvers[i];
18956 if (! this.isTypeOfDD(ddo)) {
18960 if (! this.isOverTarget(pt, ddo, this.mode)) {
18961 outEvts.push( ddo );
18964 oldOvers[i] = true;
18965 delete this.dragOvers[i];
18968 for (var sGroup in dc.groups) {
18970 if ("string" != typeof sGroup) {
18974 for (i in this.ids[sGroup]) {
18975 var oDD = this.ids[sGroup][i];
18976 if (! this.isTypeOfDD(oDD)) {
18980 if (oDD.isTarget && !oDD.isLocked() && ((oDD != dc) || (dc.ignoreSelf === false))) {
18981 if (this.isOverTarget(pt, oDD, this.mode)) {
18984 dropEvts.push( oDD );
18989 if (!oldOvers[oDD.id]) {
18990 enterEvts.push( oDD );
18993 overEvts.push( oDD );
18996 this.dragOvers[oDD.id] = oDD;
19004 if (outEvts.length) {
19005 dc.b4DragOut(e, outEvts);
19006 dc.onDragOut(e, outEvts);
19009 if (enterEvts.length) {
19010 dc.onDragEnter(e, enterEvts);
19013 if (overEvts.length) {
19014 dc.b4DragOver(e, overEvts);
19015 dc.onDragOver(e, overEvts);
19018 if (dropEvts.length) {
19019 dc.b4DragDrop(e, dropEvts);
19020 dc.onDragDrop(e, dropEvts);
19026 for (i=0, len=outEvts.length; i<len; ++i) {
19027 dc.b4DragOut(e, outEvts[i].id);
19028 dc.onDragOut(e, outEvts[i].id);
19032 for (i=0,len=enterEvts.length; i<len; ++i) {
19034 dc.onDragEnter(e, enterEvts[i].id);
19038 for (i=0,len=overEvts.length; i<len; ++i) {
19039 dc.b4DragOver(e, overEvts[i].id);
19040 dc.onDragOver(e, overEvts[i].id);
19044 for (i=0, len=dropEvts.length; i<len; ++i) {
19045 dc.b4DragDrop(e, dropEvts[i].id);
19046 dc.onDragDrop(e, dropEvts[i].id);
19052 if (isDrop && !dropEvts.length) {
19053 dc.onInvalidDrop(e);
19059 getBestMatch: function(dds) {
19067 var len = dds.length;
19073 for (var i=0; i<len; ++i) {
19078 if (dd.cursorIsOver) {
19084 winner.overlap.getArea() < dd.overlap.getArea()) {
19095 refreshCache: function(groups) {
19096 for (var sGroup in groups) {
19097 if ("string" != typeof sGroup) {
19100 for (var i in this.ids[sGroup]) {
19101 var oDD = this.ids[sGroup][i];
19103 if (this.isTypeOfDD(oDD)) {
19105 var loc = this.getLocation(oDD);
19107 this.locationCache[oDD.id] = loc;
19109 delete this.locationCache[oDD.id];
19120 verifyEl: function(el) {
19125 parent = el.offsetParent;
19128 parent = el.offsetParent;
19139 getLocation: function(oDD) {
19140 if (! this.isTypeOfDD(oDD)) {
19144 var el = oDD.getEl(), pos, x1, x2, y1, y2, t, r, b, l;
19147 pos= Ext.lib.Dom.getXY(el);
19155 x2 = x1 + el.offsetWidth;
19157 y2 = y1 + el.offsetHeight;
19159 t = y1 - oDD.padding[0];
19160 r = x2 + oDD.padding[1];
19161 b = y2 + oDD.padding[2];
19162 l = x1 - oDD.padding[3];
19164 return new Ext.lib.Region( t, r, b, l );
19168 isOverTarget: function(pt, oTarget, intersect) {
19170 var loc = this.locationCache[oTarget.id];
19171 if (!loc || !this.useCache) {
19172 loc = this.getLocation(oTarget);
19173 this.locationCache[oTarget.id] = loc;
19181 oTarget.cursorIsOver = loc.contains( pt );
19188 var dc = this.dragCurrent;
19189 if (!dc || !dc.getTargetCoord ||
19190 (!intersect && !dc.constrainX && !dc.constrainY)) {
19191 return oTarget.cursorIsOver;
19194 oTarget.overlap = null;
19200 var pos = dc.getTargetCoord(pt.x, pt.y);
19202 var el = dc.getDragEl();
19203 var curRegion = new Ext.lib.Region( pos.y,
19204 pos.x + el.offsetWidth,
19205 pos.y + el.offsetHeight,
19208 var overlap = curRegion.intersect(loc);
19211 oTarget.overlap = overlap;
19212 return (intersect) ? true : oTarget.cursorIsOver;
19219 _onUnload: function(e, me) {
19220 Ext.dd.DragDropMgr.unregAll();
19224 unregAll: function() {
19226 if (this.dragCurrent) {
19228 this.dragCurrent = null;
19231 this._execOnAll("unreg", []);
19233 for (var i in this.elementCache) {
19234 delete this.elementCache[i];
19237 this.elementCache = {};
19245 getElWrapper: function(id) {
19246 var oWrapper = this.elementCache[id];
19247 if (!oWrapper || !oWrapper.el) {
19248 oWrapper = this.elementCache[id] =
19249 new this.ElementWrapper(Ext.getDom(id));
19255 getElement: function(id) {
19256 return Ext.getDom(id);
19260 getCss: function(id) {
19261 var el = Ext.getDom(id);
19262 return (el) ? el.style : null;
19266 ElementWrapper: function(el) {
19268 this.el = el || null;
19270 this.id = this.el && el.id;
19272 this.css = this.el && el.style;
19276 getPosX: function(el) {
19277 return Ext.lib.Dom.getX(el);
19281 getPosY: function(el) {
19282 return Ext.lib.Dom.getY(el);
19286 swapNode: function(n1, n2) {
19290 var p = n2.parentNode;
19291 var s = n2.nextSibling;
19294 p.insertBefore(n1, n2);
19295 } else if (n2 == n1.nextSibling) {
19296 p.insertBefore(n2, n1);
19298 n1.parentNode.replaceChild(n2, n1);
19299 p.insertBefore(n1, s);
19305 getScroll: function () {
19306 var t, l, dde=document.documentElement, db=document.body;
19307 if (dde && (dde.scrollTop || dde.scrollLeft)) {
19309 l = dde.scrollLeft;
19316 return { top: t, left: l };
19320 getStyle: function(el, styleProp) {
19321 return Ext.fly(el).getStyle(styleProp);
19325 getScrollTop: function () {
19326 return this.getScroll().top;
19330 getScrollLeft: function () {
19331 return this.getScroll().left;
19335 moveToEl: function (moveEl, targetEl) {
19336 var aCoord = Ext.lib.Dom.getXY(targetEl);
19337 Ext.lib.Dom.setXY(moveEl, aCoord);
19341 numericSort: function(a, b) {
19349 _addListeners: function() {
19350 var DDM = Ext.dd.DDM;
19351 if ( Ext.lib.Event && document ) {
19354 if (DDM._timeoutCount > 2000) {
19356 setTimeout(DDM._addListeners, 10);
19357 if (document && document.body) {
19358 DDM._timeoutCount += 1;
19365 handleWasClicked: function(node, id) {
19366 if (this.isHandle(id, node.id)) {
19370 var p = node.parentNode;
19373 if (this.isHandle(id, p.id)) {
19389 Ext.dd.DDM = Ext.dd.DragDropMgr;
19390 Ext.dd.DDM._addListeners();
19395 Ext.dd.DD = function(id, sGroup, config) {
19397 this.init(id, sGroup, config);
19401 Ext.extend(Ext.dd.DD, Ext.dd.DragDrop, {
19407 autoOffset: function(iPageX, iPageY) {
19408 var x = iPageX - this.startPageX;
19409 var y = iPageY - this.startPageY;
19410 this.setDelta(x, y);
19414 setDelta: function(iDeltaX, iDeltaY) {
19415 this.deltaX = iDeltaX;
19416 this.deltaY = iDeltaY;
19420 setDragElPos: function(iPageX, iPageY) {
19424 var el = this.getDragEl();
19425 this.alignElWithMouse(el, iPageX, iPageY);
19429 alignElWithMouse: function(el, iPageX, iPageY) {
19430 var oCoord = this.getTargetCoord(iPageX, iPageY);
19431 var fly = el.dom ? el : Ext.fly(el, '_dd');
19432 if (!this.deltaSetXY) {
19433 var aCoord = [oCoord.x, oCoord.y];
19435 var newLeft = fly.getLeft(true);
19436 var newTop = fly.getTop(true);
19437 this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ];
19439 fly.setLeftTop(oCoord.x + this.deltaSetXY[0], oCoord.y + this.deltaSetXY[1]);
19442 this.cachePosition(oCoord.x, oCoord.y);
19443 this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
19448 cachePosition: function(iPageX, iPageY) {
19450 this.lastPageX = iPageX;
19451 this.lastPageY = iPageY;
19453 var aCoord = Ext.lib.Dom.getXY(this.getEl());
19454 this.lastPageX = aCoord[0];
19455 this.lastPageY = aCoord[1];
19460 autoScroll: function(x, y, h, w) {
19464 var clientH = Ext.lib.Dom.getViewHeight();
19467 var clientW = Ext.lib.Dom.getViewWidth();
19470 var st = this.DDM.getScrollTop();
19473 var sl = this.DDM.getScrollLeft();
19484 var toBot = (clientH + st - y - this.deltaY);
19487 var toRight = (clientW + sl - x - this.deltaX);
19497 var scrAmt = (document.all) ? 80 : 30;
19501 if ( bot > clientH && toBot < thresh ) {
19502 window.scrollTo(sl, st + scrAmt);
19507 if ( y < st && st > 0 && y - st < thresh ) {
19508 window.scrollTo(sl, st - scrAmt);
19513 if ( right > clientW && toRight < thresh ) {
19514 window.scrollTo(sl + scrAmt, st);
19519 if ( x < sl && sl > 0 && x - sl < thresh ) {
19520 window.scrollTo(sl - scrAmt, st);
19526 getTargetCoord: function(iPageX, iPageY) {
19527 var x = iPageX - this.deltaX;
19528 var y = iPageY - this.deltaY;
19530 if (this.constrainX) {
19531 if (x < this.minX) { x = this.minX; }
19532 if (x > this.maxX) { x = this.maxX; }
19535 if (this.constrainY) {
19536 if (y < this.minY) { y = this.minY; }
19537 if (y > this.maxY) { y = this.maxY; }
19540 x = this.getTick(x, this.xTicks);
19541 y = this.getTick(y, this.yTicks);
19548 applyConfig: function() {
19549 Ext.dd.DD.superclass.applyConfig.call(this);
19550 this.scroll = (this.config.scroll !== false);
19554 b4MouseDown: function(e) {
19556 this.autoOffset(e.getPageX(),
19561 b4Drag: function(e) {
19562 this.setDragElPos(e.getPageX(),
19566 toString: function() {
19567 return ("DD " + this.id);
19577 Ext.dd.DDProxy = function(id, sGroup, config) {
19579 this.init(id, sGroup, config);
19585 Ext.dd.DDProxy.dragElId = "ygddfdiv";
19587 Ext.extend(Ext.dd.DDProxy, Ext.dd.DD, {
19593 centerFrame: false,
19596 createFrame: function() {
19598 var body = document.body;
19600 if (!body || !body.firstChild) {
19601 setTimeout( function() { self.createFrame(); }, 50 );
19605 var div = this.getDragEl();
19608 div = document.createElement("div");
19609 div.id = this.dragElId;
19612 s.position = "absolute";
19613 s.visibility = "hidden";
19615 s.border = "2px solid #aaa";
19621 body.insertBefore(div, body.firstChild);
19626 initFrame: function() {
19627 this.createFrame();
19630 applyConfig: function() {
19631 Ext.dd.DDProxy.superclass.applyConfig.call(this);
19633 this.resizeFrame = (this.config.resizeFrame !== false);
19634 this.centerFrame = (this.config.centerFrame);
19635 this.setDragElId(this.config.dragElId || Ext.dd.DDProxy.dragElId);
19639 showFrame: function(iPageX, iPageY) {
19640 var el = this.getEl();
19641 var dragEl = this.getDragEl();
19642 var s = dragEl.style;
19644 this._resizeProxy();
19646 if (this.centerFrame) {
19647 this.setDelta( Math.round(parseInt(s.width, 10)/2),
19648 Math.round(parseInt(s.height, 10)/2) );
19651 this.setDragElPos(iPageX, iPageY);
19653 Ext.fly(dragEl).show();
19657 _resizeProxy: function() {
19658 if (this.resizeFrame) {
19659 var el = this.getEl();
19660 Ext.fly(this.getDragEl()).setSize(el.offsetWidth, el.offsetHeight);
19665 b4MouseDown: function(e) {
19666 var x = e.getPageX();
19667 var y = e.getPageY();
19668 this.autoOffset(x, y);
19669 this.setDragElPos(x, y);
19673 b4StartDrag: function(x, y) {
19675 this.showFrame(x, y);
19679 b4EndDrag: function(e) {
19680 Ext.fly(this.getDragEl()).hide();
19686 endDrag: function(e) {
19688 var lel = this.getEl();
19689 var del = this.getDragEl();
19692 del.style.visibility = "";
19697 lel.style.visibility = "hidden";
19698 Ext.dd.DDM.moveToEl(lel, del);
19699 del.style.visibility = "hidden";
19700 lel.style.visibility = "";
19705 beforeMove : function(){
19709 afterDrag : function(){
19713 toString: function() {
19714 return ("DDProxy " + this.id);
19719 Ext.dd.DDTarget = function(id, sGroup, config) {
19721 this.initTarget(id, sGroup, config);
19726 Ext.extend(Ext.dd.DDTarget, Ext.dd.DragDrop, {
19728 getDragEl: Ext.emptyFn,
19730 isValidHandleChild: Ext.emptyFn,
19732 startDrag: Ext.emptyFn,
19734 endDrag: Ext.emptyFn,
19736 onDrag: Ext.emptyFn,
19738 onDragDrop: Ext.emptyFn,
19740 onDragEnter: Ext.emptyFn,
19742 onDragOut: Ext.emptyFn,
19744 onDragOver: Ext.emptyFn,
19746 onInvalidDrop: Ext.emptyFn,
19748 onMouseDown: Ext.emptyFn,
19750 onMouseUp: Ext.emptyFn,
19752 setXConstraint: Ext.emptyFn,
19754 setYConstraint: Ext.emptyFn,
19756 resetConstraints: Ext.emptyFn,
19758 clearConstraints: Ext.emptyFn,
19760 clearTicks: Ext.emptyFn,
19762 setInitPosition: Ext.emptyFn,
19764 setDragElId: Ext.emptyFn,
19766 setHandleElId: Ext.emptyFn,
19768 setOuterHandleElId: Ext.emptyFn,
19770 addInvalidHandleClass: Ext.emptyFn,
19772 addInvalidHandleId: Ext.emptyFn,
19774 addInvalidHandleType: Ext.emptyFn,
19776 removeInvalidHandleClass: Ext.emptyFn,
19778 removeInvalidHandleId: Ext.emptyFn,
19780 removeInvalidHandleType: Ext.emptyFn,
19782 toString: function() {
19783 return ("DDTarget " + this.id);
19786 Ext.dd.DragTracker = Ext.extend(Ext.util.Observable, {
19794 constructor : function(config){
19795 Ext.apply(this, config);
19811 this.dragRegion = new Ext.lib.Region(0,0,0,0);
19814 this.initEl(this.el);
19816 Ext.dd.DragTracker.superclass.constructor.call(this, config);
19819 initEl: function(el){
19820 this.el = Ext.get(el);
19821 el.on('mousedown', this.onMouseDown, this,
19822 this.delegate ? {delegate: this.delegate} : undefined);
19825 destroy : function(){
19826 this.el.un('mousedown', this.onMouseDown, this);
19829 onMouseDown: function(e, target){
19830 if(this.fireEvent('mousedown', this, e) !== false && this.onBeforeStart(e) !== false){
19831 this.startXY = this.lastXY = e.getXY();
19832 this.dragTarget = this.delegate ? target : this.el.dom;
19833 if(this.preventDefault !== false){
19834 e.preventDefault();
19836 var doc = Ext.getDoc();
19837 doc.on('mouseup', this.onMouseUp, this);
19838 doc.on('mousemove', this.onMouseMove, this);
19839 doc.on('selectstart', this.stopSelect, this);
19840 if(this.autoStart){
19841 this.timer = this.triggerStart.defer(this.autoStart === true ? 1000 : this.autoStart, this);
19846 onMouseMove: function(e, target){
19848 if(this.active && Ext.isIE && !e.browserEvent.button){
19849 e.preventDefault();
19854 e.preventDefault();
19855 var xy = e.getXY(), s = this.startXY;
19858 if(Math.abs(s[0]-xy[0]) > this.tolerance || Math.abs(s[1]-xy[1]) > this.tolerance){
19859 this.triggerStart();
19864 this.fireEvent('mousemove', this, e);
19866 this.fireEvent('drag', this, e);
19869 onMouseUp: function(e) {
19870 var doc = Ext.getDoc();
19871 doc.un('mousemove', this.onMouseMove, this);
19872 doc.un('mouseup', this.onMouseUp, this);
19873 doc.un('selectstart', this.stopSelect, this);
19874 e.preventDefault();
19876 var wasActive = this.active;
19877 this.active = false;
19878 delete this.elRegion;
19879 this.fireEvent('mouseup', this, e);
19882 this.fireEvent('dragend', this, e);
19886 triggerStart: function(isTimer) {
19888 this.active = true;
19889 this.onStart(this.startXY);
19890 this.fireEvent('dragstart', this, this.startXY);
19893 clearStart : function() {
19895 clearTimeout(this.timer);
19900 stopSelect : function(e) {
19906 onBeforeStart : function(e) {
19911 onStart : function(xy) {
19916 onDrag : function(e) {
19921 onEnd : function(e) {
19926 getDragTarget : function(){
19927 return this.dragTarget;
19930 getDragCt : function(){
19934 getXY : function(constrain){
19936 this.constrainModes[constrain].call(this, this.lastXY) : this.lastXY;
19939 getOffset : function(constrain){
19940 var xy = this.getXY(constrain);
19941 var s = this.startXY;
19942 return [s[0]-xy[0], s[1]-xy[1]];
19946 'point' : function(xy){
19948 if(!this.elRegion){
19949 this.elRegion = this.getDragCt().getRegion();
19952 var dr = this.dragRegion;
19959 dr.constrainTo(this.elRegion);
19961 return [dr.left, dr.top];
19965 Ext.dd.ScrollManager = function(){
19966 var ddm = Ext.dd.DragDropMgr;
19971 var onStop = function(e){
19976 var triggerRefresh = function(){
19977 if(ddm.dragCurrent){
19978 ddm.refreshCache(ddm.dragCurrent.groups);
19982 var doScroll = function(){
19983 if(ddm.dragCurrent){
19984 var dds = Ext.dd.ScrollManager;
19985 var inc = proc.el.ddScrollConfig ?
19986 proc.el.ddScrollConfig.increment : dds.increment;
19988 if(proc.el.scroll(proc.dir, inc)){
19992 proc.el.scroll(proc.dir, inc, true, dds.animDuration, triggerRefresh);
19997 var clearProc = function(){
19999 clearInterval(proc.id);
20006 var startProc = function(el, dir){
20010 var freq = (el.ddScrollConfig && el.ddScrollConfig.frequency) ?
20011 el.ddScrollConfig.frequency : Ext.dd.ScrollManager.frequency;
20012 proc.id = setInterval(doScroll, freq);
20015 var onFire = function(e, isDrop){
20016 if(isDrop || !ddm.dragCurrent){ return; }
20017 var dds = Ext.dd.ScrollManager;
20018 if(!dragEl || dragEl != ddm.dragCurrent){
20019 dragEl = ddm.dragCurrent;
20021 dds.refreshCache();
20024 var xy = Ext.lib.Event.getXY(e);
20025 var pt = new Ext.lib.Point(xy[0], xy[1]);
20026 for(var id in els){
20027 var el = els[id], r = el._region;
20028 var c = el.ddScrollConfig ? el.ddScrollConfig : dds;
20029 if(r && r.contains(pt) && el.isScrollable()){
20030 if(r.bottom - pt.y <= c.vthresh){
20032 startProc(el, "down");
20035 }else if(r.right - pt.x <= c.hthresh){
20037 startProc(el, "left");
20040 }else if(pt.y - r.top <= c.vthresh){
20042 startProc(el, "up");
20045 }else if(pt.x - r.left <= c.hthresh){
20047 startProc(el, "right");
20056 ddm.fireEvents = ddm.fireEvents.createSequence(onFire, ddm);
20057 ddm.stopDrag = ddm.stopDrag.createSequence(onStop, ddm);
20061 register : function(el){
20062 if(Ext.isArray(el)){
20063 for(var i = 0, len = el.length; i < len; i++) {
20064 this.register(el[i]);
20073 unregister : function(el){
20074 if(Ext.isArray(el)){
20075 for(var i = 0, len = el.length; i < len; i++) {
20076 this.unregister(el[i]);
20102 refreshCache : function(){
20103 for(var id in els){
20104 if(typeof els[id] == 'object'){
20105 els[id]._region = els[id].getRegion();
20111 Ext.dd.Registry = function(){
20114 var autoIdSeed = 0;
20116 var getId = function(el, autogen){
20117 if(typeof el == "string"){
20121 if(!id && autogen !== false){
20122 id = "extdd-" + (++autoIdSeed);
20130 register : function(el, data){
20132 if(typeof el == "string"){
20133 el = document.getElementById(el);
20136 elements[getId(el)] = data;
20137 if(data.isHandle !== false){
20138 handles[data.ddel.id] = data;
20141 var hs = data.handles;
20142 for(var i = 0, len = hs.length; i < len; i++){
20143 handles[getId(hs[i])] = data;
20149 unregister : function(el){
20150 var id = getId(el, false);
20151 var data = elements[id];
20153 delete elements[id];
20155 var hs = data.handles;
20156 for(var i = 0, len = hs.length; i < len; i++){
20157 delete handles[getId(hs[i], false)];
20164 getHandle : function(id){
20165 if(typeof id != "string"){
20168 return handles[id];
20172 getHandleFromEvent : function(e){
20173 var t = Ext.lib.Event.getTarget(e);
20174 return t ? handles[t.id] : null;
20178 getTarget : function(id){
20179 if(typeof id != "string"){
20182 return elements[id];
20186 getTargetFromEvent : function(e){
20187 var t = Ext.lib.Event.getTarget(e);
20188 return t ? elements[t.id] || handles[t.id] : null;
20192 Ext.dd.StatusProxy = function(config){
20193 Ext.apply(this, config);
20194 this.id = this.id || Ext.id();
20195 this.el = new Ext.Layer({
20197 id: this.id, tag: "div", cls: "x-dd-drag-proxy "+this.dropNotAllowed, children: [
20198 {tag: "div", cls: "x-dd-drop-icon"},
20199 {tag: "div", cls: "x-dd-drag-ghost"}
20202 shadow: !config || config.shadow !== false
20204 this.ghost = Ext.get(this.el.dom.childNodes[1]);
20205 this.dropStatus = this.dropNotAllowed;
20208 Ext.dd.StatusProxy.prototype = {
20210 dropAllowed : "x-dd-drop-ok",
20212 dropNotAllowed : "x-dd-drop-nodrop",
20215 setStatus : function(cssClass){
20216 cssClass = cssClass || this.dropNotAllowed;
20217 if(this.dropStatus != cssClass){
20218 this.el.replaceClass(this.dropStatus, cssClass);
20219 this.dropStatus = cssClass;
20224 reset : function(clearGhost){
20225 this.el.dom.className = "x-dd-drag-proxy " + this.dropNotAllowed;
20226 this.dropStatus = this.dropNotAllowed;
20228 this.ghost.update("");
20233 update : function(html){
20234 if(typeof html == "string"){
20235 this.ghost.update(html);
20237 this.ghost.update("");
20238 html.style.margin = "0";
20239 this.ghost.dom.appendChild(html);
20241 var el = this.ghost.dom.firstChild;
20243 Ext.fly(el).setStyle('float', 'none');
20248 getEl : function(){
20253 getGhost : function(){
20258 hide : function(clear){
20267 if(this.anim && this.anim.isAnimated && this.anim.isAnimated()){
20283 repair : function(xy, callback, scope){
20284 this.callback = callback;
20285 this.scope = scope;
20286 if(xy && this.animRepair !== false){
20287 this.el.addClass("x-dd-drag-repair");
20288 this.el.hideUnders(true);
20289 this.anim = this.el.shift({
20290 duration: this.repairDuration || .5,
20294 callback: this.afterRepair,
20298 this.afterRepair();
20303 afterRepair : function(){
20305 if(typeof this.callback == "function"){
20306 this.callback.call(this.scope || this);
20308 this.callback = null;
20312 destroy: function(){
20313 Ext.destroy(this.ghost, this.el);
20316 Ext.dd.DragSource = function(el, config){
20317 this.el = Ext.get(el);
20318 if(!this.dragData){
20319 this.dragData = {};
20322 Ext.apply(this, config);
20325 this.proxy = new Ext.dd.StatusProxy();
20327 Ext.dd.DragSource.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group,
20328 {dragElId : this.proxy.id, resizeFrame: false, isTarget: false, scroll: this.scroll === true});
20330 this.dragging = false;
20333 Ext.extend(Ext.dd.DragSource, Ext.dd.DDProxy, {
20336 dropAllowed : "x-dd-drop-ok",
20338 dropNotAllowed : "x-dd-drop-nodrop",
20341 getDragData : function(e){
20342 return this.dragData;
20346 onDragEnter : function(e, id){
20347 var target = Ext.dd.DragDropMgr.getDDById(id);
20348 this.cachedTarget = target;
20349 if(this.beforeDragEnter(target, e, id) !== false){
20350 if(target.isNotifyTarget){
20351 var status = target.notifyEnter(this, e, this.dragData);
20352 this.proxy.setStatus(status);
20354 this.proxy.setStatus(this.dropAllowed);
20357 if(this.afterDragEnter){
20359 this.afterDragEnter(target, e, id);
20365 beforeDragEnter : function(target, e, id){
20370 alignElWithMouse: function() {
20371 Ext.dd.DragSource.superclass.alignElWithMouse.apply(this, arguments);
20376 onDragOver : function(e, id){
20377 var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
20378 if(this.beforeDragOver(target, e, id) !== false){
20379 if(target.isNotifyTarget){
20380 var status = target.notifyOver(this, e, this.dragData);
20381 this.proxy.setStatus(status);
20384 if(this.afterDragOver){
20386 this.afterDragOver(target, e, id);
20392 beforeDragOver : function(target, e, id){
20397 onDragOut : function(e, id){
20398 var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
20399 if(this.beforeDragOut(target, e, id) !== false){
20400 if(target.isNotifyTarget){
20401 target.notifyOut(this, e, this.dragData);
20403 this.proxy.reset();
20404 if(this.afterDragOut){
20406 this.afterDragOut(target, e, id);
20409 this.cachedTarget = null;
20413 beforeDragOut : function(target, e, id){
20418 onDragDrop : function(e, id){
20419 var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
20420 if(this.beforeDragDrop(target, e, id) !== false){
20421 if(target.isNotifyTarget){
20422 if(target.notifyDrop(this, e, this.dragData)){
20423 this.onValidDrop(target, e, id);
20425 this.onInvalidDrop(target, e, id);
20428 this.onValidDrop(target, e, id);
20431 if(this.afterDragDrop){
20433 this.afterDragDrop(target, e, id);
20436 delete this.cachedTarget;
20440 beforeDragDrop : function(target, e, id){
20445 onValidDrop : function(target, e, id){
20447 if(this.afterValidDrop){
20449 this.afterValidDrop(target, e, id);
20454 getRepairXY : function(e, data){
20455 return this.el.getXY();
20459 onInvalidDrop : function(target, e, id){
20460 this.beforeInvalidDrop(target, e, id);
20461 if(this.cachedTarget){
20462 if(this.cachedTarget.isNotifyTarget){
20463 this.cachedTarget.notifyOut(this, e, this.dragData);
20465 this.cacheTarget = null;
20467 this.proxy.repair(this.getRepairXY(e, this.dragData), this.afterRepair, this);
20469 if(this.afterInvalidDrop){
20471 this.afterInvalidDrop(e, id);
20476 afterRepair : function(){
20478 this.el.highlight(this.hlColor || "c3daf9");
20480 this.dragging = false;
20484 beforeInvalidDrop : function(target, e, id){
20489 handleMouseDown : function(e){
20490 if(this.dragging) {
20493 var data = this.getDragData(e);
20494 if(data && this.onBeforeDrag(data, e) !== false){
20495 this.dragData = data;
20497 Ext.dd.DragSource.superclass.handleMouseDown.apply(this, arguments);
20502 onBeforeDrag : function(data, e){
20507 onStartDrag : Ext.emptyFn,
20510 startDrag : function(x, y){
20511 this.proxy.reset();
20512 this.dragging = true;
20513 this.proxy.update("");
20514 this.onInitDrag(x, y);
20519 onInitDrag : function(x, y){
20520 var clone = this.el.dom.cloneNode(true);
20521 clone.id = Ext.id();
20522 this.proxy.update(clone);
20523 this.onStartDrag(x, y);
20528 getProxy : function(){
20533 hideProxy : function(){
20535 this.proxy.reset(true);
20536 this.dragging = false;
20540 triggerCacheRefresh : function(){
20541 Ext.dd.DDM.refreshCache(this.groups);
20545 b4EndDrag: function(e) {
20549 endDrag : function(e){
20550 this.onEndDrag(this.dragData, e);
20554 onEndDrag : function(data, e){
20558 autoOffset : function(x, y) {
20559 this.setDelta(-12, -20);
20562 destroy: function(){
20563 Ext.dd.DragSource.superclass.destroy.call(this);
20564 Ext.destroy(this.proxy);
20567 Ext.dd.DropTarget = function(el, config){
20568 this.el = Ext.get(el);
20570 Ext.apply(this, config);
20572 if(this.containerScroll){
20573 Ext.dd.ScrollManager.register(this.el);
20576 Ext.dd.DropTarget.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group,
20581 Ext.extend(Ext.dd.DropTarget, Ext.dd.DDTarget, {
20585 dropAllowed : "x-dd-drop-ok",
20587 dropNotAllowed : "x-dd-drop-nodrop",
20593 isNotifyTarget : true,
20596 notifyEnter : function(dd, e, data){
20597 if(this.overClass){
20598 this.el.addClass(this.overClass);
20600 return this.dropAllowed;
20604 notifyOver : function(dd, e, data){
20605 return this.dropAllowed;
20609 notifyOut : function(dd, e, data){
20610 if(this.overClass){
20611 this.el.removeClass(this.overClass);
20616 notifyDrop : function(dd, e, data){
20620 Ext.dd.DragZone = function(el, config){
20621 Ext.dd.DragZone.superclass.constructor.call(this, el, config);
20622 if(this.containerScroll){
20623 Ext.dd.ScrollManager.register(this.el);
20627 Ext.extend(Ext.dd.DragZone, Ext.dd.DragSource, {
20633 getDragData : function(e){
20634 return Ext.dd.Registry.getHandleFromEvent(e);
20638 onInitDrag : function(x, y){
20639 this.proxy.update(this.dragData.ddel.cloneNode(true));
20640 this.onStartDrag(x, y);
20645 afterRepair : function(){
20647 Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9");
20649 this.dragging = false;
20653 getRepairXY : function(e){
20654 return Ext.Element.fly(this.dragData.ddel).getXY();
20657 Ext.dd.DropZone = function(el, config){
20658 Ext.dd.DropZone.superclass.constructor.call(this, el, config);
20661 Ext.extend(Ext.dd.DropZone, Ext.dd.DropTarget, {
20663 getTargetFromEvent : function(e){
20664 return Ext.dd.Registry.getTargetFromEvent(e);
20668 onNodeEnter : function(n, dd, e, data){
20673 onNodeOver : function(n, dd, e, data){
20674 return this.dropAllowed;
20678 onNodeOut : function(n, dd, e, data){
20683 onNodeDrop : function(n, dd, e, data){
20688 onContainerOver : function(dd, e, data){
20689 return this.dropNotAllowed;
20693 onContainerDrop : function(dd, e, data){
20698 notifyEnter : function(dd, e, data){
20699 return this.dropNotAllowed;
20703 notifyOver : function(dd, e, data){
20704 var n = this.getTargetFromEvent(e);
20706 if(this.lastOverNode){
20707 this.onNodeOut(this.lastOverNode, dd, e, data);
20708 this.lastOverNode = null;
20710 return this.onContainerOver(dd, e, data);
20712 if(this.lastOverNode != n){
20713 if(this.lastOverNode){
20714 this.onNodeOut(this.lastOverNode, dd, e, data);
20716 this.onNodeEnter(n, dd, e, data);
20717 this.lastOverNode = n;
20719 return this.onNodeOver(n, dd, e, data);
20723 notifyOut : function(dd, e, data){
20724 if(this.lastOverNode){
20725 this.onNodeOut(this.lastOverNode, dd, e, data);
20726 this.lastOverNode = null;
20731 notifyDrop : function(dd, e, data){
20732 if(this.lastOverNode){
20733 this.onNodeOut(this.lastOverNode, dd, e, data);
20734 this.lastOverNode = null;
20736 var n = this.getTargetFromEvent(e);
20738 this.onNodeDrop(n, dd, e, data) :
20739 this.onContainerDrop(dd, e, data);
20743 triggerCacheRefresh : function(){
20744 Ext.dd.DDM.refreshCache(this.groups);
20747 Ext.Element.addMethods({
20749 initDD : function(group, config, overrides){
20750 var dd = new Ext.dd.DD(Ext.id(this.dom), group, config);
20751 return Ext.apply(dd, overrides);
20755 initDDProxy : function(group, config, overrides){
20756 var dd = new Ext.dd.DDProxy(Ext.id(this.dom), group, config);
20757 return Ext.apply(dd, overrides);
20761 initDDTarget : function(group, config, overrides){
20762 var dd = new Ext.dd.DDTarget(Ext.id(this.dom), group, config);
20763 return Ext.apply(dd, overrides);
20767 Ext.data.Api = (function() {
20773 var validActions = {};
20781 destroy : 'destroy'
20793 isAction : function(action) {
20794 return (Ext.data.Api.actions[action]) ? true : false;
20798 getVerb : function(name) {
20799 if (validActions[name]) {
20800 return validActions[name];
20802 for (var verb in this.actions) {
20803 if (this.actions[verb] === name) {
20804 validActions[name] = verb;
20808 return (validActions[name] !== undefined) ? validActions[name] : null;
20812 isValid : function(api){
20814 var crud = this.actions;
20815 for (var action in api) {
20816 if (!(action in crud)) {
20817 invalid.push(action);
20820 return (!invalid.length) ? true : invalid;
20824 hasUniqueUrl : function(proxy, verb) {
20825 var url = (proxy.api[verb]) ? proxy.api[verb].url : null;
20827 for (var action in proxy.api) {
20828 if ((unique = (action === verb) ? true : (proxy.api[action].url != url) ? true : false) === false) {
20836 prepare : function(proxy) {
20840 for (var verb in this.actions) {
20841 var action = this.actions[verb];
20842 proxy.api[action] = proxy.api[action] || proxy.url || proxy.directFn;
20843 if (typeof(proxy.api[action]) == 'string') {
20844 proxy.api[action] = {
20845 url: proxy.api[action],
20846 method: (proxy.restful === true) ? Ext.data.Api.restActions[action] : undefined
20853 restify : function(proxy) {
20854 proxy.restful = true;
20855 for (var verb in this.restActions) {
20856 proxy.api[this.actions[verb]].method ||
20857 (proxy.api[this.actions[verb]].method = this.restActions[verb]);
20861 proxy.onWrite = proxy.onWrite.createInterceptor(function(action, o, response, rs) {
20862 var reader = o.reader;
20863 var res = new Ext.data.Response({
20868 switch (response.status) {
20873 if (Ext.isEmpty(res.raw.responseText)) {
20874 res.success = true;
20881 res.success = true;
20888 if (res.success === true) {
20889 this.fireEvent("write", this, action, res.data, res, rs, o.request.arg);
20891 this.fireEvent('exception', this, 'remote', action, o, res, rs);
20893 o.request.callback.call(o.request.scope, res.data, res, res.success);
20902 Ext.data.Response = function(params, response) {
20903 Ext.apply(this, params, {
20907 Ext.data.Response.prototype = {
20914 getMessage : function() {
20915 return this.message;
20917 getSuccess : function() {
20918 return this.success;
20920 getStatus : function() {
20921 return this.status;
20923 getRoot : function() {
20926 getRawResponse : function() {
20932 Ext.data.Api.Error = Ext.extend(Ext.Error, {
20933 constructor : function(message, arg) {
20935 Ext.Error.call(this, message);
20937 name: 'Ext.data.Api'
20939 Ext.apply(Ext.data.Api.Error.prototype, {
20941 'action-url-undefined': 'No fallback url defined for this action. When defining a DataProxy api, please be sure to define an url for each CRUD action in Ext.data.Api.actions or define a default url in addition to your api-configuration.',
20942 'invalid': 'received an invalid API-configuration. Please ensure your proxy API-configuration contains only the actions defined in Ext.data.Api.actions',
20943 'invalid-url': 'Invalid url. Please review your proxy configuration.',
20944 'execute': 'Attempted to execute an unknown action. Valid API actions are defined in Ext.data.Api.actions"'
20951 Ext.data.SortTypes = {
20953 none : function(s){
20958 stripTagsRE : /<\/?[^>]+>/gi,
20961 asText : function(s){
20962 return String(s).replace(this.stripTagsRE, "");
20966 asUCText : function(s){
20967 return String(s).toUpperCase().replace(this.stripTagsRE, "");
20971 asUCString : function(s) {
20972 return String(s).toUpperCase();
20976 asDate : function(s) {
20981 return s.getTime();
20983 return Date.parse(String(s));
20987 asFloat : function(s) {
20988 var val = parseFloat(String(s).replace(/,/g, ""));
20989 return isNaN(val) ? 0 : val;
20993 asInt : function(s) {
20994 var val = parseInt(String(s).replace(/,/g, ""), 10);
20995 return isNaN(val) ? 0 : val;
20998 Ext.data.Record = function(data, id){
21000 this.id = (id || id === 0) ? id : Ext.data.Record.id(this);
21001 this.data = data || {};
21005 Ext.data.Record.create = function(o){
21006 var f = Ext.extend(Ext.data.Record, {});
21007 var p = f.prototype;
21008 p.fields = new Ext.util.MixedCollection(false, function(field){
21011 for(var i = 0, len = o.length; i < len; i++){
21012 p.fields.add(new Ext.data.Field(o[i]));
21014 f.getField = function(name){
21015 return p.fields.get(name);
21020 Ext.data.Record.PREFIX = 'ext-record';
21021 Ext.data.Record.AUTO_ID = 1;
21022 Ext.data.Record.EDIT = 'edit';
21023 Ext.data.Record.REJECT = 'reject';
21024 Ext.data.Record.COMMIT = 'commit';
21028 Ext.data.Record.id = function(rec) {
21029 rec.phantom = true;
21030 return [Ext.data.Record.PREFIX, '-', Ext.data.Record.AUTO_ID++].join('');
21033 Ext.data.Record.prototype = {
21049 join : function(store){
21051 this.store = store;
21055 set : function(name, value){
21056 var encode = Ext.isPrimitive(value) ? String : Ext.encode;
21057 if(encode(this.data[name]) == encode(value)) {
21061 if(!this.modified){
21062 this.modified = {};
21064 if(this.modified[name] === undefined){
21065 this.modified[name] = this.data[name];
21067 this.data[name] = value;
21074 afterEdit : function(){
21075 if (this.store != undefined && typeof this.store.afterEdit == "function") {
21076 this.store.afterEdit(this);
21081 afterReject : function(){
21083 this.store.afterReject(this);
21088 afterCommit : function(){
21090 this.store.afterCommit(this);
21095 get : function(name){
21096 return this.data[name];
21100 beginEdit : function(){
21101 this.editing = true;
21102 this.modified = this.modified || {};
21106 cancelEdit : function(){
21107 this.editing = false;
21108 delete this.modified;
21112 endEdit : function(){
21113 this.editing = false;
21120 reject : function(silent){
21121 var m = this.modified;
21123 if(typeof m[n] != "function"){
21124 this.data[n] = m[n];
21127 this.dirty = false;
21128 delete this.modified;
21129 this.editing = false;
21130 if(silent !== true){
21131 this.afterReject();
21136 commit : function(silent){
21137 this.dirty = false;
21138 delete this.modified;
21139 this.editing = false;
21140 if(silent !== true){
21141 this.afterCommit();
21146 getChanges : function(){
21147 var m = this.modified, cs = {};
21149 if(m.hasOwnProperty(n)){
21150 cs[n] = this.data[n];
21157 hasError : function(){
21158 return this.error !== null;
21162 clearError : function(){
21167 copy : function(newId) {
21168 return new this.constructor(Ext.apply({}, this.data), newId || this.id);
21172 isModified : function(fieldName){
21173 return !!(this.modified && this.modified.hasOwnProperty(fieldName));
21177 isValid : function() {
21178 return this.fields.find(function(f) {
21179 return (f.allowBlank === false && Ext.isEmpty(this.data[f.name])) ? true : false;
21180 },this) ? false : true;
21184 markDirty : function(){
21186 if(!this.modified){
21187 this.modified = {};
21189 this.fields.each(function(f) {
21190 this.modified[f.name] = this.data[f.name];
21195 Ext.StoreMgr = Ext.apply(new Ext.util.MixedCollection(), {
21199 register : function(){
21200 for(var i = 0, s; (s = arguments[i]); i++){
21206 unregister : function(){
21207 for(var i = 0, s; (s = arguments[i]); i++){
21208 this.remove(this.lookup(s));
21213 lookup : function(id){
21214 if(Ext.isArray(id)){
21215 var fields = ['field1'], expand = !Ext.isArray(id[0]);
21217 for(var i = 2, len = id[0].length; i <= len; ++i){
21218 fields.push('field' + i);
21221 return new Ext.data.ArrayStore({
21224 expandData: expand,
21230 return Ext.isObject(id) ? (id.events ? id : Ext.create(id, 'store')) : this.get(id);
21234 getKey : function(o){
21238 Ext.data.Store = Ext.extend(Ext.util.Observable, {
21246 writer : undefined,
21250 remoteSort : false,
21253 autoDestroy : false,
21256 pruneModifiedRecords : false,
21259 lastOptions : null,
21271 paramNames : undefined,
21274 defaultParamNames : {
21282 isDestroyed: false,
21285 hasMultiSort: false,
21288 batchKey : '_ext_batch_',
21290 constructor : function(config){
21291 this.data = new Ext.util.MixedCollection(false);
21292 this.data.getKey = function(o){
21300 if(config && config.data){
21301 this.inlineData = config.data;
21302 delete config.data;
21305 Ext.apply(this, config);
21308 this.baseParams = Ext.isObject(this.baseParams) ? this.baseParams : {};
21310 this.paramNames = Ext.applyIf(this.paramNames || {}, this.defaultParamNames);
21312 if((this.url || this.api) && !this.proxy){
21313 this.proxy = new Ext.data.HttpProxy({url: this.url, api: this.api});
21316 if (this.restful === true && this.proxy) {
21319 this.batch = false;
21320 Ext.data.Api.restify(this.proxy);
21324 if(!this.recordType){
21325 this.recordType = this.reader.recordType;
21327 if(this.reader.onMetaChange){
21328 this.reader.onMetaChange = this.reader.onMetaChange.createSequence(this.onMetaChange, this);
21331 if (this.writer instanceof(Ext.data.DataWriter) === false) {
21332 this.writer = this.buildWriter(this.writer);
21334 this.writer.meta = this.reader.meta;
21335 this.pruneModifiedRecords = true;
21341 if(this.recordType){
21343 this.fields = this.recordType.prototype.fields;
21345 this.modified = [];
21381 this.relayEvents(this.proxy, ['loadexception', 'exception']);
21387 add: this.createRecords,
21388 remove: this.destroyRecord,
21389 update: this.updateRecord,
21390 clear: this.onClear
21394 this.sortToggle = {};
21395 if(this.sortField){
21396 this.setDefaultSort(this.sortField, this.sortDir);
21397 }else if(this.sortInfo){
21398 this.setDefaultSort(this.sortInfo.field, this.sortInfo.direction);
21401 Ext.data.Store.superclass.constructor.call(this);
21404 this.storeId = this.id;
21408 Ext.StoreMgr.register(this);
21410 if(this.inlineData){
21411 this.loadData(this.inlineData);
21412 delete this.inlineData;
21413 }else if(this.autoLoad){
21414 this.load.defer(10, this, [
21415 typeof this.autoLoad == 'object' ?
21416 this.autoLoad : undefined]);
21419 this.batchCounter = 0;
21424 buildWriter : function(config) {
21425 var klass = undefined,
21426 type = (config.format || 'json').toLowerCase();
21429 klass = Ext.data.JsonWriter;
21432 klass = Ext.data.XmlWriter;
21435 klass = Ext.data.JsonWriter;
21437 return new klass(config);
21441 destroy : function(){
21442 if(!this.isDestroyed){
21444 Ext.StoreMgr.unregister(this);
21448 Ext.destroy(this.proxy);
21449 this.reader = this.writer = null;
21450 this.purgeListeners();
21451 this.isDestroyed = true;
21456 add : function(records){
21457 records = [].concat(records);
21458 if(records.length < 1){
21461 for(var i = 0, len = records.length; i < len; i++){
21462 records[i].join(this);
21464 var index = this.data.length;
21465 this.data.addAll(records);
21467 this.snapshot.addAll(records);
21469 this.fireEvent('add', this, records, index);
21473 addSorted : function(record){
21474 var index = this.findInsertIndex(record);
21475 this.insert(index, record);
21479 remove : function(record){
21480 if(Ext.isArray(record)){
21481 Ext.each(record, function(r){
21486 var index = this.data.indexOf(record);
21489 this.data.removeAt(index);
21491 if(this.pruneModifiedRecords){
21492 this.modified.remove(record);
21495 this.snapshot.remove(record);
21498 this.fireEvent('remove', this, record, index);
21503 removeAt : function(index){
21504 this.remove(this.getAt(index));
21508 removeAll : function(silent){
21510 this.each(function(rec){
21515 this.snapshot.clear();
21517 if(this.pruneModifiedRecords){
21518 this.modified = [];
21520 if (silent !== true) {
21521 this.fireEvent('clear', this, items);
21526 onClear: function(store, records){
21527 Ext.each(records, function(rec, index){
21528 this.destroyRecord(this, rec, index);
21533 insert : function(index, records){
21534 records = [].concat(records);
21535 for(var i = 0, len = records.length; i < len; i++){
21536 this.data.insert(index, records[i]);
21537 records[i].join(this);
21540 this.snapshot.addAll(records);
21542 this.fireEvent('add', this, records, index);
21546 indexOf : function(record){
21547 return this.data.indexOf(record);
21551 indexOfId : function(id){
21552 return this.data.indexOfKey(id);
21556 getById : function(id){
21557 return (this.snapshot || this.data).key(id);
21561 getAt : function(index){
21562 return this.data.itemAt(index);
21566 getRange : function(start, end){
21567 return this.data.getRange(start, end);
21571 storeOptions : function(o){
21572 o = Ext.apply({}, o);
21575 this.lastOptions = o;
21579 clearData: function(){
21580 this.data.each(function(rec) {
21587 load : function(options) {
21588 options = Ext.apply({}, options);
21589 this.storeOptions(options);
21590 if(this.sortInfo && this.remoteSort){
21591 var pn = this.paramNames;
21592 options.params = Ext.apply({}, options.params);
21593 options.params[pn.sort] = this.sortInfo.field;
21594 options.params[pn.dir] = this.sortInfo.direction;
21597 return this.execute('read', null, options);
21599 this.handleException(e);
21605 updateRecord : function(store, record, action) {
21606 if (action == Ext.data.Record.EDIT && this.autoSave === true && (!record.phantom || (record.phantom && record.isValid()))) {
21612 createRecords : function(store, rs, index) {
21613 for (var i = 0, len = rs.length; i < len; i++) {
21614 if (rs[i].phantom && rs[i].isValid()) {
21616 this.modified.push(rs[i]);
21619 if (this.autoSave === true) {
21625 destroyRecord : function(store, record, index) {
21626 if (this.modified.indexOf(record) != -1) {
21627 this.modified.remove(record);
21629 if (!record.phantom) {
21630 this.removed.push(record);
21635 record.lastIndex = index;
21637 if (this.autoSave === true) {
21644 execute : function(action, rs, options, batch) {
21646 if (!Ext.data.Api.isAction(action)) {
21647 throw new Ext.data.Api.Error('execute', action);
21650 options = Ext.applyIf(options||{}, {
21653 if(batch !== undefined){
21654 this.addToBatch(batch);
21658 var doRequest = true;
21660 if (action === 'read') {
21661 doRequest = this.fireEvent('beforeload', this, options);
21662 Ext.applyIf(options.params, this.baseParams);
21667 if (this.writer.listful === true && this.restful !== true) {
21668 rs = (Ext.isArray(rs)) ? rs : [rs];
21671 else if (Ext.isArray(rs) && rs.length == 1) {
21675 if ((doRequest = this.fireEvent('beforewrite', this, action, rs, options)) !== false) {
21676 this.writer.apply(options.params, this.baseParams, action, rs);
21679 if (doRequest !== false) {
21681 if (this.writer && this.proxy.url && !this.proxy.restful && !Ext.data.Api.hasUniqueUrl(this.proxy, action)) {
21682 options.params.xaction = action;
21689 this.proxy.request(Ext.data.Api.actions[action], rs, options.params, this.reader, this.createCallback(action, rs, batch), this, options);
21695 save : function() {
21696 if (!this.writer) {
21697 throw new Ext.data.Store.Error('writer-undefined');
21706 if(this.removed.length){
21707 queue.push(['destroy', this.removed]);
21711 var rs = [].concat(this.getModifiedRecords());
21715 for(var i = rs.length-1; i >= 0; i--){
21716 if(rs[i].phantom === true){
21717 var rec = rs.splice(i, 1).shift();
21719 phantoms.push(rec);
21721 }else if(!rs[i].isValid()){
21726 if(phantoms.length){
21727 queue.push(['create', phantoms]);
21732 queue.push(['update', rs]);
21735 len = queue.length;
21737 batch = ++this.batchCounter;
21738 for(var i = 0; i < len; ++i){
21740 data[trans[0]] = trans[1];
21742 if(this.fireEvent('beforesave', this, data) !== false){
21743 for(var i = 0; i < len; ++i){
21745 this.doTransaction(trans[0], trans[1], batch);
21754 doTransaction : function(action, rs, batch) {
21755 function transaction(records) {
21757 this.execute(action, records, undefined, batch);
21759 this.handleException(e);
21762 if(this.batch === false){
21763 for(var i = 0, len = rs.length; i < len; i++){
21764 transaction.call(this, rs[i]);
21767 transaction.call(this, rs);
21772 addToBatch : function(batch){
21773 var b = this.batches,
21774 key = this.batchKey + batch,
21787 removeFromBatch : function(batch, action, data){
21788 var b = this.batches,
21789 key = this.batchKey + batch,
21796 arr = o.data[action] || [];
21797 o.data[action] = arr.concat(data);
21801 this.fireEvent('save', this, batch, data);
21810 createCallback : function(action, rs, batch) {
21811 var actions = Ext.data.Api.actions;
21812 return (action == 'read') ? this.loadRecords : function(data, response, success) {
21814 this['on' + Ext.util.Format.capitalize(action) + 'Records'](success, rs, [].concat(data));
21816 if (success === true) {
21817 this.fireEvent('write', this, action, data, response, rs);
21819 this.removeFromBatch(batch, action, data);
21826 clearModified : function(rs) {
21827 if (Ext.isArray(rs)) {
21828 for (var n=rs.length-1;n>=0;n--) {
21829 this.modified.splice(this.modified.indexOf(rs[n]), 1);
21832 this.modified.splice(this.modified.indexOf(rs), 1);
21837 reMap : function(record) {
21838 if (Ext.isArray(record)) {
21839 for (var i = 0, len = record.length; i < len; i++) {
21840 this.reMap(record[i]);
21843 delete this.data.map[record._phid];
21844 this.data.map[record.id] = record;
21845 var index = this.data.keys.indexOf(record._phid);
21846 this.data.keys.splice(index, 1, record.id);
21847 delete record._phid;
21852 onCreateRecords : function(success, rs, data) {
21853 if (success === true) {
21855 this.reader.realize(rs, data);
21859 this.handleException(e);
21860 if (Ext.isArray(rs)) {
21862 this.onCreateRecords(success, rs, data);
21869 onUpdateRecords : function(success, rs, data) {
21870 if (success === true) {
21872 this.reader.update(rs, data);
21874 this.handleException(e);
21875 if (Ext.isArray(rs)) {
21877 this.onUpdateRecords(success, rs, data);
21884 onDestroyRecords : function(success, rs, data) {
21886 rs = (rs instanceof Ext.data.Record) ? [rs] : [].concat(rs);
21887 for (var i=0,len=rs.length;i<len;i++) {
21888 this.removed.splice(this.removed.indexOf(rs[i]), 1);
21890 if (success === false) {
21893 for (i=rs.length-1;i>=0;i--) {
21894 this.insert(rs[i].lastIndex, rs[i]);
21900 handleException : function(e) {
21902 Ext.handleError(e);
21906 reload : function(options){
21907 this.load(Ext.applyIf(options||{}, this.lastOptions));
21912 loadRecords : function(o, options, success){
21913 if (this.isDestroyed === true) {
21916 if(!o || success === false){
21917 if(success !== false){
21918 this.fireEvent('load', this, [], options);
21920 if(options.callback){
21921 options.callback.call(options.scope || this, [], options, false, o);
21925 var r = o.records, t = o.totalRecords || r.length;
21926 if(!options || options.add !== true){
21927 if(this.pruneModifiedRecords){
21928 this.modified = [];
21930 for(var i = 0, len = r.length; i < len; i++){
21934 this.data = this.snapshot;
21935 delete this.snapshot;
21938 this.data.addAll(r);
21939 this.totalLength = t;
21941 this.fireEvent('datachanged', this);
21943 this.totalLength = Math.max(t, this.data.length+r.length);
21946 this.fireEvent('load', this, r, options);
21947 if(options.callback){
21948 options.callback.call(options.scope || this, r, options, true);
21953 loadData : function(o, append){
21954 var r = this.reader.readRecords(o);
21955 this.loadRecords(r, {add: append}, true);
21959 getCount : function(){
21960 return this.data.length || 0;
21964 getTotalCount : function(){
21965 return this.totalLength || 0;
21969 getSortState : function(){
21970 return this.sortInfo;
21974 applySort : function(){
21975 if ((this.sortInfo || this.multiSortInfo) && !this.remoteSort) {
21981 sortData : function() {
21982 var sortInfo = this.hasMultiSort ? this.multiSortInfo : this.sortInfo,
21983 direction = sortInfo.direction || "ASC",
21984 sorters = sortInfo.sorters,
21988 if (!this.hasMultiSort) {
21989 sorters = [{direction: direction, field: sortInfo.field}];
21993 for (var i=0, j = sorters.length; i < j; i++) {
21994 sortFns.push(this.createSortFunction(sorters[i].field, sorters[i].direction));
21997 if (sortFns.length == 0) {
22003 var directionModifier = direction.toUpperCase() == "DESC" ? -1 : 1;
22006 var fn = function(r1, r2) {
22007 var result = sortFns[0].call(this, r1, r2);
22010 if (sortFns.length > 1) {
22011 for (var i=1, j = sortFns.length; i < j; i++) {
22012 result = result || sortFns[i].call(this, r1, r2);
22016 return directionModifier * result;
22020 this.data.sort(direction, fn);
22021 if (this.snapshot && this.snapshot != this.data) {
22022 this.snapshot.sort(direction, fn);
22027 createSortFunction: function(field, direction) {
22028 direction = direction || "ASC";
22029 var directionModifier = direction.toUpperCase() == "DESC" ? -1 : 1;
22031 var sortType = this.fields.get(field).sortType;
22035 return function(r1, r2) {
22036 var v1 = sortType(r1.data[field]),
22037 v2 = sortType(r2.data[field]);
22039 return directionModifier * (v1 > v2 ? 1 : (v1 < v2 ? -1 : 0));
22044 setDefaultSort : function(field, dir) {
22045 dir = dir ? dir.toUpperCase() : 'ASC';
22046 this.sortInfo = {field: field, direction: dir};
22047 this.sortToggle[field] = dir;
22051 sort : function(fieldName, dir) {
22052 if (Ext.isArray(arguments[0])) {
22053 return this.multiSort.call(this, fieldName, dir);
22055 return this.singleSort(fieldName, dir);
22060 singleSort: function(fieldName, dir) {
22061 var field = this.fields.get(fieldName);
22062 if (!field) return false;
22064 var name = field.name,
22065 sortInfo = this.sortInfo || null,
22066 sortToggle = this.sortToggle ? this.sortToggle[name] : null;
22069 if (sortInfo && sortInfo.field == name) {
22070 dir = (this.sortToggle[name] || 'ASC').toggle('ASC', 'DESC');
22072 dir = field.sortDir;
22076 this.sortToggle[name] = dir;
22077 this.sortInfo = {field: name, direction: dir};
22078 this.hasMultiSort = false;
22080 if (this.remoteSort) {
22081 if (!this.load(this.lastOptions)) {
22083 this.sortToggle[name] = sortToggle;
22086 this.sortInfo = sortInfo;
22091 this.fireEvent('datachanged', this);
22096 multiSort: function(sorters, direction) {
22097 this.hasMultiSort = true;
22098 direction = direction || "ASC";
22101 if (this.multiSortInfo && direction == this.multiSortInfo.direction) {
22102 direction = direction.toggle("ASC", "DESC");
22106 this.multiSortInfo = {
22108 direction: direction
22111 if (this.remoteSort) {
22112 this.singleSort(sorters[0].field, sorters[0].direction);
22116 this.fireEvent('datachanged', this);
22121 each : function(fn, scope){
22122 this.data.each(fn, scope);
22126 getModifiedRecords : function(){
22127 return this.modified;
22131 sum : function(property, start, end){
22132 var rs = this.data.items, v = 0;
22133 start = start || 0;
22134 end = (end || end === 0) ? end : rs.length-1;
22136 for(var i = start; i <= end; i++){
22137 v += (rs[i].data[property] || 0);
22143 createFilterFn : function(property, value, anyMatch, caseSensitive, exactMatch){
22144 if(Ext.isEmpty(value, false)){
22147 value = this.data.createValueMatcher(value, anyMatch, caseSensitive, exactMatch);
22148 return function(r) {
22149 return value.test(r.data[property]);
22154 createMultipleFilterFn: function(filters) {
22155 return function(record) {
22156 var isMatch = true;
22158 for (var i=0, j = filters.length; i < j; i++) {
22159 var filter = filters[i],
22161 scope = filter.scope;
22163 isMatch = isMatch && fn.call(scope, record);
22171 filter : function(property, value, anyMatch, caseSensitive, exactMatch){
22173 if (Ext.isObject(property)) {
22174 property = [property];
22177 if (Ext.isArray(property)) {
22181 for (var i=0, j = property.length; i < j; i++) {
22182 var filter = property[i],
22184 scope = filter.scope || this;
22187 if (!Ext.isFunction(func)) {
22188 func = this.createFilterFn(filter.property, filter.value, filter.anyMatch, filter.caseSensitive, filter.exactMatch);
22191 filters.push({fn: func, scope: scope});
22194 var fn = this.createMultipleFilterFn(filters);
22197 var fn = this.createFilterFn(property, value, anyMatch, caseSensitive, exactMatch);
22200 return fn ? this.filterBy(fn) : this.clearFilter();
22204 filterBy : function(fn, scope){
22205 this.snapshot = this.snapshot || this.data;
22206 this.data = this.queryBy(fn, scope||this);
22207 this.fireEvent('datachanged', this);
22211 clearFilter : function(suppressEvent){
22212 if(this.isFiltered()){
22213 this.data = this.snapshot;
22214 delete this.snapshot;
22215 if(suppressEvent !== true){
22216 this.fireEvent('datachanged', this);
22222 isFiltered : function(){
22223 return !!this.snapshot && this.snapshot != this.data;
22227 query : function(property, value, anyMatch, caseSensitive){
22228 var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
22229 return fn ? this.queryBy(fn) : this.data.clone();
22233 queryBy : function(fn, scope){
22234 var data = this.snapshot || this.data;
22235 return data.filterBy(fn, scope||this);
22239 find : function(property, value, start, anyMatch, caseSensitive){
22240 var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
22241 return fn ? this.data.findIndexBy(fn, null, start) : -1;
22245 findExact: function(property, value, start){
22246 return this.data.findIndexBy(function(rec){
22247 return rec.get(property) === value;
22252 findBy : function(fn, scope, start){
22253 return this.data.findIndexBy(fn, scope, start);
22257 collect : function(dataIndex, allowNull, bypassFilter){
22258 var d = (bypassFilter === true && this.snapshot) ?
22259 this.snapshot.items : this.data.items;
22260 var v, sv, r = [], l = {};
22261 for(var i = 0, len = d.length; i < len; i++){
22262 v = d[i].data[dataIndex];
22264 if((allowNull || !Ext.isEmpty(v)) && !l[sv]){
22273 afterEdit : function(record){
22274 if(this.modified.indexOf(record) == -1){
22275 this.modified.push(record);
22277 this.fireEvent('update', this, record, Ext.data.Record.EDIT);
22281 afterReject : function(record){
22282 this.modified.remove(record);
22283 this.fireEvent('update', this, record, Ext.data.Record.REJECT);
22287 afterCommit : function(record){
22288 this.modified.remove(record);
22289 this.fireEvent('update', this, record, Ext.data.Record.COMMIT);
22293 commitChanges : function(){
22294 var m = this.modified.slice(0);
22295 this.modified = [];
22296 for(var i = 0, len = m.length; i < len; i++){
22302 rejectChanges : function(){
22303 var m = this.modified.slice(0);
22304 this.modified = [];
22305 for(var i = 0, len = m.length; i < len; i++){
22308 var m = this.removed.slice(0).reverse();
22310 for(var i = 0, len = m.length; i < len; i++){
22311 this.insert(m[i].lastIndex||0, m[i]);
22317 onMetaChange : function(meta){
22318 this.recordType = this.reader.recordType;
22319 this.fields = this.recordType.prototype.fields;
22320 delete this.snapshot;
22321 if(this.reader.meta.sortInfo){
22322 this.sortInfo = this.reader.meta.sortInfo;
22323 }else if(this.sortInfo && !this.fields.get(this.sortInfo.field)){
22324 delete this.sortInfo;
22327 this.writer.meta = this.reader.meta;
22329 this.modified = [];
22330 this.fireEvent('metachange', this, this.reader.meta);
22334 findInsertIndex : function(record){
22335 this.suspendEvents();
22336 var data = this.data.clone();
22337 this.data.add(record);
22339 var index = this.data.indexOf(record);
22341 this.resumeEvents();
22346 setBaseParam : function (name, value){
22347 this.baseParams = this.baseParams || {};
22348 this.baseParams[name] = value;
22352 Ext.reg('store', Ext.data.Store);
22355 Ext.data.Store.Error = Ext.extend(Ext.Error, {
22356 name: 'Ext.data.Store'
22358 Ext.apply(Ext.data.Store.Error.prototype, {
22360 'writer-undefined' : 'Attempted to execute a write-action without a DataWriter installed.'
22364 Ext.data.Field = Ext.extend(Object, {
22366 constructor : function(config){
22367 if(Ext.isString(config)){
22368 config = {name: config};
22370 Ext.apply(this, config);
22372 var types = Ext.data.Types,
22373 st = this.sortType,
22377 if(Ext.isString(this.type)){
22378 this.type = Ext.data.Types[this.type.toUpperCase()] || types.AUTO;
22381 this.type = types.AUTO;
22385 if(Ext.isString(st)){
22386 this.sortType = Ext.data.SortTypes[st];
22387 }else if(Ext.isEmpty(st)){
22388 this.sortType = this.type.sortType;
22392 this.convert = this.type.convert;
22413 Ext.data.DataReader = function(meta, recordType){
22417 this.recordType = Ext.isArray(recordType) ?
22418 Ext.data.Record.create(recordType) : recordType;
22421 if (this.recordType){
22422 this.buildExtractors();
22426 Ext.data.DataReader.prototype = {
22429 getTotal: Ext.emptyFn,
22431 getRoot: Ext.emptyFn,
22433 getMessage: Ext.emptyFn,
22435 getSuccess: Ext.emptyFn,
22437 getId: Ext.emptyFn,
22439 buildExtractors : Ext.emptyFn,
22441 extractValues : Ext.emptyFn,
22444 realize: function(rs, data){
22445 if (Ext.isArray(rs)) {
22446 for (var i = rs.length - 1; i >= 0; i--) {
22448 if (Ext.isArray(data)) {
22449 this.realize(rs.splice(i,1).shift(), data.splice(i,1).shift());
22454 this.realize(rs.splice(i,1).shift(), data);
22460 if (Ext.isArray(data) && data.length == 1) {
22461 data = data.shift();
22463 if (!this.isData(data)) {
22466 throw new Ext.data.DataReader.Error('realize', rs);
22468 rs.phantom = false;
22470 rs.id = this.getId(data);
22478 update : function(rs, data) {
22479 if (Ext.isArray(rs)) {
22480 for (var i=rs.length-1; i >= 0; i--) {
22481 if (Ext.isArray(data)) {
22482 this.update(rs.splice(i,1).shift(), data.splice(i,1).shift());
22487 this.update(rs.splice(i,1).shift(), data);
22493 if (Ext.isArray(data) && data.length == 1) {
22494 data = data.shift();
22496 if (this.isData(data)) {
22497 rs.data = Ext.apply(rs.data, data);
22504 extractData : function(root, returnRecords) {
22506 var rawName = (this instanceof Ext.data.JsonReader) ? 'json' : 'node';
22512 if (this.isData(root) && !(this instanceof Ext.data.XmlReader)) {
22515 var f = this.recordType.prototype.fields,
22519 if (returnRecords === true) {
22520 var Record = this.recordType;
22521 for (var i = 0; i < root.length; i++) {
22523 var record = new Record(this.extractValues(n, fi, fl), this.getId(n));
22524 record[rawName] = n;
22529 for (var i = 0; i < root.length; i++) {
22530 var data = this.extractValues(root[i], fi, fl);
22531 data[this.meta.idProperty] = this.getId(root[i]);
22539 isData : function(data) {
22540 return (data && Ext.isObject(data) && !Ext.isEmpty(this.getId(data))) ? true : false;
22544 onMetaChange : function(meta){
22547 this.recordType = Ext.data.Record.create(meta.fields);
22548 this.buildExtractors();
22553 Ext.data.DataReader.Error = Ext.extend(Ext.Error, {
22554 constructor : function(message, arg) {
22556 Ext.Error.call(this, message);
22558 name: 'Ext.data.DataReader'
22560 Ext.apply(Ext.data.DataReader.Error.prototype, {
22562 'update': "#update received invalid data from server. Please see docs for DataReader#update and review your DataReader configuration.",
22563 'realize': "#realize was called with invalid remote-data. Please see the docs for DataReader#realize and review your DataReader configuration.",
22564 'invalid-response': "#readResponse received an invalid response from the server."
22568 Ext.data.DataWriter = function(config){
22569 Ext.apply(this, config);
22571 Ext.data.DataWriter.prototype = {
22574 writeAllFields : false,
22579 apply : function(params, baseParams, action, rs) {
22581 renderer = action + 'Record';
22583 if (Ext.isArray(rs)) {
22584 Ext.each(rs, function(rec){
22585 data.push(this[renderer](rec));
22588 else if (rs instanceof Ext.data.Record) {
22589 data = this[renderer](rs);
22591 this.render(params, baseParams, data);
22595 render : Ext.emptyFn,
22598 updateRecord : Ext.emptyFn,
22601 createRecord : Ext.emptyFn,
22604 destroyRecord : Ext.emptyFn,
22607 toHash : function(rec, config) {
22608 var map = rec.fields.map,
22610 raw = (this.writeAllFields === false && rec.phantom === false) ? rec.getChanges() : rec.data,
22612 Ext.iterate(raw, function(prop, value){
22613 if((m = map[prop])){
22614 data[m.mapping ? m.mapping : m.name] = value;
22621 if (rec.fields.containsKey(this.meta.idProperty) && Ext.isEmpty(rec.data[this.meta.idProperty])) {
22622 delete data[this.meta.idProperty];
22625 data[this.meta.idProperty] = rec.id
22631 toArray : function(data) {
22633 Ext.iterate(data, function(k, v) {fields.push({name: k, value: v});},this);
22637 Ext.data.DataProxy = function(conn){
22646 this.api = conn.api;
22647 this.url = conn.url;
22648 this.restful = conn.restful;
22649 this.listeners = conn.listeners;
22652 this.prettyUrls = conn.prettyUrls;
22670 Ext.data.DataProxy.superclass.constructor.call(this);
22674 Ext.data.Api.prepare(this);
22676 if (e instanceof Ext.data.Api.Error) {
22681 Ext.data.DataProxy.relayEvents(this, ['beforewrite', 'write', 'exception']);
22684 Ext.extend(Ext.data.DataProxy, Ext.util.Observable, {
22689 setApi : function() {
22690 if (arguments.length == 1) {
22691 var valid = Ext.data.Api.isValid(arguments[0]);
22692 if (valid === true) {
22693 this.api = arguments[0];
22696 throw new Ext.data.Api.Error('invalid', valid);
22699 else if (arguments.length == 2) {
22700 if (!Ext.data.Api.isAction(arguments[0])) {
22701 throw new Ext.data.Api.Error('invalid', arguments[0]);
22703 this.api[arguments[0]] = arguments[1];
22705 Ext.data.Api.prepare(this);
22709 isApiAction : function(action) {
22710 return (this.api[action]) ? true : false;
22714 request : function(action, rs, params, reader, callback, scope, options) {
22715 if (!this.api[action] && !this.load) {
22716 throw new Ext.data.DataProxy.Error('action-undefined', action);
22718 params = params || {};
22719 if ((action === Ext.data.Api.actions.read) ? this.fireEvent("beforeload", this, params) : this.fireEvent("beforewrite", this, action, rs, params) !== false) {
22720 this.doRequest.apply(this, arguments);
22723 callback.call(scope || this, null, options, false);
22732 doRequest : function(action, rs, params, reader, callback, scope, options) {
22736 this.load(params, reader, callback, scope, options);
22740 onRead : Ext.emptyFn,
22742 onWrite : Ext.emptyFn,
22744 buildUrl : function(action, record) {
22745 record = record || null;
22750 var url = (this.conn && this.conn.url) ? this.conn.url : (this.api[action]) ? this.api[action].url : this.url;
22752 throw new Ext.data.Api.Error('invalid-url', action);
22761 var provides = null;
22762 var m = url.match(/(.*)(\.json|\.xml|\.html)$/);
22768 if ((this.restful === true || this.prettyUrls === true) && record instanceof Ext.data.Record && !record.phantom) {
22769 url += '/' + record.id;
22771 return (provides === null) ? url : url + provides;
22775 destroy: function(){
22776 this.purgeListeners();
22782 Ext.apply(Ext.data.DataProxy, Ext.util.Observable.prototype);
22783 Ext.util.Observable.call(Ext.data.DataProxy);
22786 Ext.data.DataProxy.Error = Ext.extend(Ext.Error, {
22787 constructor : function(message, arg) {
22789 Ext.Error.call(this, message);
22791 name: 'Ext.data.DataProxy'
22793 Ext.apply(Ext.data.DataProxy.Error.prototype, {
22795 'action-undefined': "DataProxy attempted to execute an API-action but found an undefined url / function. Please review your Proxy url/api-configuration.",
22796 'api-invalid': 'Recieved an invalid API-configuration. Please ensure your proxy API-configuration contains only the actions from Ext.data.Api.actions.'
22802 Ext.data.Request = function(params) {
22803 Ext.apply(this, params);
22805 Ext.data.Request.prototype = {
22807 action : undefined,
22813 callback : Ext.emptyFn,
22820 Ext.data.Response = function(params) {
22821 Ext.apply(this, params);
22823 Ext.data.Response.prototype = {
22827 success : undefined,
22829 message : undefined,
22838 Ext.data.ScriptTagProxy = function(config){
22839 Ext.apply(this, config);
22841 Ext.data.ScriptTagProxy.superclass.constructor.call(this, config);
22843 this.head = document.getElementsByTagName("head")[0];
22848 Ext.data.ScriptTagProxy.TRANS_ID = 1000;
22850 Ext.extend(Ext.data.ScriptTagProxy, Ext.data.DataProxy, {
22855 callbackParam : "callback",
22860 doRequest : function(action, rs, params, reader, callback, scope, arg) {
22861 var p = Ext.urlEncode(Ext.apply(params, this.extraParams));
22863 var url = this.buildUrl(action, rs);
22865 throw new Ext.data.Api.Error('invalid-url', url);
22867 url = Ext.urlAppend(url, p);
22870 url = Ext.urlAppend(url, '_dc=' + (new Date().getTime()));
22872 var transId = ++Ext.data.ScriptTagProxy.TRANS_ID;
22876 cb : "stcCallback"+transId,
22877 scriptId : "stcScript"+transId,
22881 callback : callback,
22885 window[trans.cb] = this.createCallback(action, rs, trans);
22886 url += String.format("&{0}={1}", this.callbackParam, trans.cb);
22887 if(this.autoAbort !== false){
22891 trans.timeoutId = this.handleFailure.defer(this.timeout, this, [trans]);
22893 var script = document.createElement("script");
22894 script.setAttribute("src", url);
22895 script.setAttribute("type", "text/javascript");
22896 script.setAttribute("id", trans.scriptId);
22897 this.head.appendChild(script);
22899 this.trans = trans;
22903 createCallback : function(action, rs, trans) {
22905 return function(res) {
22906 self.trans = false;
22907 self.destroyTrans(trans, true);
22908 if (action === Ext.data.Api.actions.read) {
22909 self.onRead.call(self, action, trans, res);
22911 self.onWrite.call(self, action, trans, res, rs);
22916 onRead : function(action, trans, res) {
22919 result = trans.reader.readRecords(res);
22922 this.fireEvent("loadexception", this, trans, res, e);
22924 this.fireEvent('exception', this, 'response', action, trans, res, e);
22925 trans.callback.call(trans.scope||window, null, trans.arg, false);
22928 if (result.success === false) {
22930 this.fireEvent('loadexception', this, trans, res);
22932 this.fireEvent('exception', this, 'remote', action, trans, res, null);
22934 this.fireEvent("load", this, res, trans.arg);
22936 trans.callback.call(trans.scope||window, result, trans.arg, result.success);
22939 onWrite : function(action, trans, response, rs) {
22940 var reader = trans.reader;
22943 var res = reader.readResponse(action, response);
22945 this.fireEvent('exception', this, 'response', action, trans, res, e);
22946 trans.callback.call(trans.scope||window, null, res, false);
22949 if(!res.success === true){
22950 this.fireEvent('exception', this, 'remote', action, trans, res, rs);
22951 trans.callback.call(trans.scope||window, null, res, false);
22954 this.fireEvent("write", this, action, res.data, res, rs, trans.arg );
22955 trans.callback.call(trans.scope||window, res.data, res, true);
22959 isLoading : function(){
22960 return this.trans ? true : false;
22964 abort : function(){
22965 if(this.isLoading()){
22966 this.destroyTrans(this.trans);
22971 destroyTrans : function(trans, isLoaded){
22972 this.head.removeChild(document.getElementById(trans.scriptId));
22973 clearTimeout(trans.timeoutId);
22975 window[trans.cb] = undefined;
22977 delete window[trans.cb];
22981 window[trans.cb] = function(){
22982 window[trans.cb] = undefined;
22984 delete window[trans.cb];
22991 handleFailure : function(trans){
22992 this.trans = false;
22993 this.destroyTrans(trans, false);
22994 if (trans.action === Ext.data.Api.actions.read) {
22996 this.fireEvent("loadexception", this, null, trans.arg);
22999 this.fireEvent('exception', this, 'response', trans.action, {
23003 trans.callback.call(trans.scope||window, null, trans.arg, false);
23007 destroy: function(){
23009 Ext.data.ScriptTagProxy.superclass.destroy.call(this);
23012 Ext.data.HttpProxy = function(conn){
23013 Ext.data.HttpProxy.superclass.constructor.call(this, conn);
23022 this.conn.url = null;
23024 this.useAjax = !conn || !conn.events;
23027 var actions = Ext.data.Api.actions;
23028 this.activeRequest = {};
23029 for (var verb in actions) {
23030 this.activeRequest[actions[verb]] = undefined;
23034 Ext.extend(Ext.data.HttpProxy, Ext.data.DataProxy, {
23036 getConnection : function() {
23037 return this.useAjax ? Ext.Ajax : this.conn;
23041 setUrl : function(url, makePermanent) {
23042 this.conn.url = url;
23043 if (makePermanent === true) {
23046 Ext.data.Api.prepare(this);
23051 doRequest : function(action, rs, params, reader, cb, scope, arg) {
23053 method: (this.api[action]) ? this.api[action]['method'] : undefined,
23060 callback : this.createCallback(action, rs),
23066 if (params.jsonData) {
23067 o.jsonData = params.jsonData;
23068 } else if (params.xmlData) {
23069 o.xmlData = params.xmlData;
23071 o.params = params || {};
23076 this.conn.url = this.buildUrl(action, rs);
23080 Ext.applyIf(o, this.conn);
23083 if (this.activeRequest[action]) {
23090 this.activeRequest[action] = Ext.Ajax.request(o);
23092 this.conn.request(o);
23095 this.conn.url = null;
23099 createCallback : function(action, rs) {
23100 return function(o, success, response) {
23101 this.activeRequest[action] = undefined;
23103 if (action === Ext.data.Api.actions.read) {
23106 this.fireEvent('loadexception', this, o, response);
23108 this.fireEvent('exception', this, 'response', action, o, response);
23109 o.request.callback.call(o.request.scope, null, o.request.arg, false);
23112 if (action === Ext.data.Api.actions.read) {
23113 this.onRead(action, o, response);
23115 this.onWrite(action, o, response, rs);
23121 onRead : function(action, o, response) {
23124 result = o.reader.read(response);
23128 this.fireEvent('loadexception', this, o, response, e);
23130 this.fireEvent('exception', this, 'response', action, o, response, e);
23131 o.request.callback.call(o.request.scope, null, o.request.arg, false);
23134 if (result.success === false) {
23137 this.fireEvent('loadexception', this, o, response);
23140 var res = o.reader.readResponse(action, response);
23141 this.fireEvent('exception', this, 'remote', action, o, res, null);
23144 this.fireEvent('load', this, o, o.request.arg);
23149 o.request.callback.call(o.request.scope, result, o.request.arg, result.success);
23152 onWrite : function(action, o, response, rs) {
23153 var reader = o.reader;
23156 res = reader.readResponse(action, response);
23158 this.fireEvent('exception', this, 'response', action, o, response, e);
23159 o.request.callback.call(o.request.scope, null, o.request.arg, false);
23162 if (res.success === true) {
23163 this.fireEvent('write', this, action, res.data, res, rs, o.request.arg);
23165 this.fireEvent('exception', this, 'remote', action, o, res, rs);
23170 o.request.callback.call(o.request.scope, res.data, res, res.success);
23174 destroy: function(){
23177 }else if(this.activeRequest){
23178 var actions = Ext.data.Api.actions;
23179 for (var verb in actions) {
23180 if(this.activeRequest[actions[verb]]){
23181 Ext.Ajax.abort(this.activeRequest[actions[verb]]);
23185 Ext.data.HttpProxy.superclass.destroy.call(this);
23188 Ext.data.MemoryProxy = function(data){
23191 api[Ext.data.Api.actions.read] = true;
23192 Ext.data.MemoryProxy.superclass.constructor.call(this, {
23198 Ext.extend(Ext.data.MemoryProxy, Ext.data.DataProxy, {
23202 doRequest : function(action, rs, params, reader, callback, scope, arg) {
23204 params = params || {};
23207 result = reader.readRecords(this.data);
23210 this.fireEvent("loadexception", this, null, arg, e);
23212 this.fireEvent('exception', this, 'response', action, arg, null, e);
23213 callback.call(scope, null, arg, false);
23216 callback.call(scope, result, arg, true);
23219 Ext.data.Types = new function(){
23220 var st = Ext.data.SortTypes;
23223 stripRe: /[\$,%]/g,
23227 convert: function(v){ return v; },
23234 convert: function(v){ return (v === undefined || v === null) ? '' : String(v); },
23235 sortType: st.asUCString,
23241 convert: function(v){
23242 return v !== undefined && v !== null && v !== '' ?
23243 parseInt(String(v).replace(Ext.data.Types.stripRe, ''), 10) : 0;
23251 convert: function(v){
23252 return v !== undefined && v !== null && v !== '' ?
23253 parseFloat(String(v).replace(Ext.data.Types.stripRe, ''), 10) : 0;
23261 convert: function(v){ return v === true || v === 'true' || v == 1; },
23268 convert: function(v){
23269 var df = this.dateFormat;
23277 if(df == 'timestamp'){
23278 return new Date(v*1000);
23281 return new Date(parseInt(v, 10));
23283 return Date.parseDate(v, df);
23285 var parsed = Date.parse(v);
23286 return parsed ? new Date(parsed) : null;
23288 sortType: st.asDate,
23295 BOOLEAN: this.BOOL,
23302 Ext.data.JsonWriter = Ext.extend(Ext.data.DataWriter, {
23306 encodeDelete: false,
23308 constructor : function(config){
23309 Ext.data.JsonWriter.superclass.constructor.call(this, config);
23313 render : function(params, baseParams, data) {
23314 if (this.encode === true) {
23316 Ext.apply(params, baseParams);
23317 params[this.meta.root] = Ext.encode(data);
23320 var jdata = Ext.apply({}, baseParams);
23321 jdata[this.meta.root] = data;
23322 params.jsonData = jdata;
23326 createRecord : function(rec) {
23327 return this.toHash(rec);
23330 updateRecord : function(rec) {
23331 return this.toHash(rec);
23335 destroyRecord : function(rec){
23336 if(this.encodeDelete){
23338 data[this.meta.idProperty] = rec.id;
23345 Ext.data.JsonReader = function(meta, recordType){
23351 Ext.applyIf(meta, {
23353 successProperty: 'success',
23354 totalProperty: 'total'
23357 Ext.data.JsonReader.superclass.constructor.call(this, meta, recordType || meta.fields);
23359 Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
23362 read : function(response){
23363 var json = response.responseText;
23364 var o = Ext.decode(json);
23366 throw {message: 'JsonReader.read: Json object not found'};
23368 return this.readRecords(o);
23373 readResponse : function(action, response) {
23374 var o = (response.responseText !== undefined) ? Ext.decode(response.responseText) : response;
23376 throw new Ext.data.JsonReader.Error('response');
23379 var root = this.getRoot(o);
23380 if (action === Ext.data.Api.actions.create) {
23381 var def = Ext.isDefined(root);
23382 if (def && Ext.isEmpty(root)) {
23383 throw new Ext.data.JsonReader.Error('root-empty', this.meta.root);
23386 throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root);
23391 var res = new Ext.data.Response({
23393 success: this.getSuccess(o),
23394 data: (root) ? this.extractData(root, false) : [],
23395 message: this.getMessage(o),
23400 if (Ext.isEmpty(res.success)) {
23401 throw new Ext.data.JsonReader.Error('successProperty-response', this.meta.successProperty);
23407 readRecords : function(o){
23411 this.onMetaChange(o.metaData);
23413 var s = this.meta, Record = this.recordType,
23414 f = Record.prototype.fields, fi = f.items, fl = f.length, v;
23416 var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;
23417 if(s.totalProperty){
23418 v = parseInt(this.getTotal(o), 10);
23423 if(s.successProperty){
23424 v = this.getSuccess(o);
23425 if(v === false || v === 'false'){
23433 records : this.extractData(root, true),
23434 totalRecords : totalRecords
23439 buildExtractors : function() {
23443 var s = this.meta, Record = this.recordType,
23444 f = Record.prototype.fields, fi = f.items, fl = f.length;
23446 if(s.totalProperty) {
23447 this.getTotal = this.createAccessor(s.totalProperty);
23449 if(s.successProperty) {
23450 this.getSuccess = this.createAccessor(s.successProperty);
23452 if (s.messageProperty) {
23453 this.getMessage = this.createAccessor(s.messageProperty);
23455 this.getRoot = s.root ? this.createAccessor(s.root) : function(p){return p;};
23456 if (s.id || s.idProperty) {
23457 var g = this.createAccessor(s.id || s.idProperty);
23458 this.getId = function(rec) {
23460 return (r === undefined || r === '') ? null : r;
23463 this.getId = function(){return null;};
23466 for(var i = 0; i < fl; i++){
23468 var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
23469 ef.push(this.createAccessor(map));
23475 simpleAccess : function(obj, subsc) {
23480 createAccessor : function(){
23482 return function(expr) {
23483 if(Ext.isEmpty(expr)){
23484 return Ext.emptyFn;
23486 if(Ext.isFunction(expr)){
23489 var i = String(expr).search(re);
23491 return new Function('obj', 'return obj' + (i > 0 ? '.' : '') + expr);
23493 return function(obj){
23501 extractValues : function(data, items, len) {
23502 var f, values = {};
23503 for(var j = 0; j < len; j++){
23505 var v = this.ef[j](data);
23506 values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
23513 Ext.data.JsonReader.Error = Ext.extend(Ext.Error, {
23514 constructor : function(message, arg) {
23516 Ext.Error.call(this, message);
23518 name : 'Ext.data.JsonReader'
23520 Ext.apply(Ext.data.JsonReader.Error.prototype, {
23522 'response': 'An error occurred while json-decoding your server response',
23523 'successProperty-response': 'Could not locate your "successProperty" in your server response. Please review your JsonReader config to ensure the config-property "successProperty" matches the property in your server-response. See the JsonReader docs.',
23524 'root-undefined-config': 'Your JsonReader was configured without a "root" property. Please review your JsonReader config and make sure to define the root property. See the JsonReader docs.',
23525 'idProperty-undefined' : 'Your JsonReader was configured without an "idProperty" Please review your JsonReader configuration and ensure the "idProperty" is set (e.g.: "id"). See the JsonReader docs.',
23526 'root-empty': 'Data was expected to be returned by the server in the "root" property of the response. Please review your JsonReader configuration to ensure the "root" property matches that returned in the server-response. See JsonReader docs.'
23530 Ext.data.ArrayReader = Ext.extend(Ext.data.JsonReader, {
23535 readRecords : function(o){
23536 this.arrayData = o;
23538 sid = s ? Ext.num(s.idIndex, s.id) : null,
23539 recordType = this.recordType,
23540 fields = recordType.prototype.fields,
23545 var root = this.getRoot(o);
23547 for(var i = 0, len = root.length; i < len; i++) {
23550 id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);
23551 for(var j = 0, jlen = fields.length; j < jlen; j++) {
23552 var f = fields.items[j],
23553 k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;
23554 v = n[k] !== undefined ? n[k] : f.defaultValue;
23555 v = f.convert(v, n);
23556 values[f.name] = v;
23558 var record = new recordType(values, id);
23560 records[records.length] = record;
23563 var totalRecords = records.length;
23565 if(s.totalProperty) {
23566 v = parseInt(this.getTotal(o), 10);
23571 if(s.successProperty){
23572 v = this.getSuccess(o);
23573 if(v === false || v === 'false'){
23581 totalRecords : totalRecords
23585 Ext.data.ArrayStore = Ext.extend(Ext.data.Store, {
23587 constructor: function(config){
23588 Ext.data.ArrayStore.superclass.constructor.call(this, Ext.apply(config, {
23589 reader: new Ext.data.ArrayReader(config)
23593 loadData : function(data, append){
23594 if(this.expandData === true){
23596 for(var i = 0, len = data.length; i < len; i++){
23597 r[r.length] = [data[i]];
23601 Ext.data.ArrayStore.superclass.loadData.call(this, data, append);
23604 Ext.reg('arraystore', Ext.data.ArrayStore);
23607 Ext.data.SimpleStore = Ext.data.ArrayStore;
23608 Ext.reg('simplestore', Ext.data.SimpleStore);
23609 Ext.data.JsonStore = Ext.extend(Ext.data.Store, {
23611 constructor: function(config){
23612 Ext.data.JsonStore.superclass.constructor.call(this, Ext.apply(config, {
23613 reader: new Ext.data.JsonReader(config)
23617 Ext.reg('jsonstore', Ext.data.JsonStore);
23618 Ext.data.XmlWriter = function(params) {
23619 Ext.data.XmlWriter.superclass.constructor.apply(this, arguments);
23621 this.tpl = (typeof(this.tpl) === 'string') ? new Ext.XTemplate(this.tpl).compile() : this.tpl.compile();
23623 Ext.extend(Ext.data.XmlWriter, Ext.data.DataWriter, {
23625 documentRoot: 'xrequest',
23627 forceDocumentRoot: false,
23631 xmlVersion : '1.0',
23633 xmlEncoding: 'ISO-8859-15',
23636 tpl: '<tpl for="."><\u003fxml version="{version}" encoding="{encoding}"\u003f><tpl if="documentRoot"><{documentRoot}><tpl for="baseParams"><tpl for="."><{name}>{value}</{name}</tpl></tpl></tpl><tpl if="records.length>1"><{root}></tpl><tpl for="records"><{parent.record}><tpl for="."><{name}>{value}</{name}></tpl></{parent.record}></tpl><tpl if="records.length>1"></{root}></tpl><tpl if="documentRoot"></{documentRoot}></tpl></tpl>',
23640 render : function(params, baseParams, data) {
23641 baseParams = this.toArray(baseParams);
23642 params.xmlData = this.tpl.applyTemplate({
23643 version: this.xmlVersion,
23644 encoding: this.xmlEncoding,
23645 documentRoot: (baseParams.length > 0 || this.forceDocumentRoot === true) ? this.documentRoot : false,
23646 record: this.meta.record,
23648 baseParams: baseParams,
23649 records: (Ext.isArray(data[0])) ? data : [data]
23654 createRecord : function(rec) {
23655 return this.toArray(this.toHash(rec));
23659 updateRecord : function(rec) {
23660 return this.toArray(this.toHash(rec));
23664 destroyRecord : function(rec) {
23666 data[this.meta.idProperty] = rec.id;
23667 return this.toArray(data);
23671 Ext.data.XmlReader = function(meta, recordType){
23675 Ext.applyIf(meta, {
23676 idProperty: meta.idProperty || meta.idPath || meta.id,
23677 successProperty: meta.successProperty || meta.success
23680 Ext.data.XmlReader.superclass.constructor.call(this, meta, recordType || meta.fields);
23682 Ext.extend(Ext.data.XmlReader, Ext.data.DataReader, {
23684 read : function(response){
23685 var doc = response.responseXML;
23687 throw {message: "XmlReader.read: XML Document not available"};
23689 return this.readRecords(doc);
23693 readRecords : function(doc){
23695 this.xmlData = doc;
23697 var root = doc.documentElement || doc,
23702 if(this.meta.totalProperty){
23703 totalRecords = this.getTotal(root, 0);
23705 if(this.meta.successProperty){
23706 success = this.getSuccess(root);
23709 var records = this.extractData(q.select(this.meta.record, root), true);
23715 totalRecords : totalRecords || records.length
23720 readResponse : function(action, response) {
23721 var q = Ext.DomQuery,
23722 doc = response.responseXML;
23725 var res = new Ext.data.Response({
23727 success : this.getSuccess(doc),
23728 message: this.getMessage(doc),
23729 data: this.extractData(q.select(this.meta.record, doc) || q.select(this.meta.root, doc), false),
23733 if (Ext.isEmpty(res.success)) {
23734 throw new Ext.data.DataReader.Error('successProperty-response', this.meta.successProperty);
23738 if (action === Ext.data.Api.actions.create) {
23739 var def = Ext.isDefined(res.data);
23740 if (def && Ext.isEmpty(res.data)) {
23741 throw new Ext.data.JsonReader.Error('root-empty', this.meta.root);
23744 throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root);
23750 getSuccess : function() {
23755 buildExtractors : function() {
23760 Record = this.recordType,
23761 f = Record.prototype.fields,
23765 if(s.totalProperty) {
23766 this.getTotal = this.createAccessor(s.totalProperty);
23768 if(s.successProperty) {
23769 this.getSuccess = this.createAccessor(s.successProperty);
23771 if (s.messageProperty) {
23772 this.getMessage = this.createAccessor(s.messageProperty);
23774 this.getRoot = function(res) {
23775 return (!Ext.isEmpty(res[this.meta.record])) ? res[this.meta.record] : res[this.meta.root];
23777 if (s.idPath || s.idProperty) {
23778 var g = this.createAccessor(s.idPath || s.idProperty);
23779 this.getId = function(rec) {
23780 var id = g(rec) || rec.id;
23781 return (id === undefined || id === '') ? null : id;
23784 this.getId = function(){return null;};
23787 for(var i = 0; i < fl; i++){
23789 var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
23790 ef.push(this.createAccessor(map));
23796 createAccessor : function(){
23797 var q = Ext.DomQuery;
23798 return function(key) {
23800 case this.meta.totalProperty:
23801 return function(root, def){
23802 return q.selectNumber(key, root, def);
23805 case this.meta.successProperty:
23806 return function(root, def) {
23807 var sv = q.selectValue(key, root, true);
23808 var success = sv !== false && sv !== 'false';
23813 return function(root, def) {
23814 return q.selectValue(key, root, def);
23822 extractValues : function(data, items, len) {
23823 var f, values = {};
23824 for(var j = 0; j < len; j++){
23826 var v = this.ef[j](data);
23827 values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
23832 Ext.data.XmlStore = Ext.extend(Ext.data.Store, {
23834 constructor: function(config){
23835 Ext.data.XmlStore.superclass.constructor.call(this, Ext.apply(config, {
23836 reader: new Ext.data.XmlReader(config)
23840 Ext.reg('xmlstore', Ext.data.XmlStore);
23841 Ext.data.GroupingStore = Ext.extend(Ext.data.Store, {
23844 constructor: function(config) {
23845 config = config || {};
23851 this.hasMultiSort = true;
23852 this.multiSortInfo = this.multiSortInfo || {sorters: []};
23854 var sorters = this.multiSortInfo.sorters,
23855 groupField = config.groupField || this.groupField,
23856 sortInfo = config.sortInfo || this.sortInfo,
23857 groupDir = config.groupDir || this.groupDir;
23862 field : groupField,
23863 direction: groupDir
23869 sorters.push(sortInfo);
23872 Ext.data.GroupingStore.superclass.constructor.call(this, config);
23879 this.applyGroupField();
23884 remoteGroup : false,
23891 clearGrouping : function(){
23892 this.groupField = false;
23894 if(this.remoteGroup){
23895 if(this.baseParams){
23896 delete this.baseParams.groupBy;
23897 delete this.baseParams.groupDir;
23899 var lo = this.lastOptions;
23900 if(lo && lo.params){
23901 delete lo.params.groupBy;
23902 delete lo.params.groupDir;
23908 this.fireEvent('datachanged', this);
23913 groupBy : function(field, forceRegroup, direction) {
23914 direction = direction ? (String(direction).toUpperCase() == 'DESC' ? 'DESC' : 'ASC') : this.groupDir;
23916 if (this.groupField == field && this.groupDir == direction && !forceRegroup) {
23922 sorters = this.multiSortInfo.sorters;
23923 if (sorters.length > 0 && sorters[0].field == this.groupField) {
23927 this.groupField = field;
23928 this.groupDir = direction;
23929 this.applyGroupField();
23931 var fireGroupEvent = function() {
23932 this.fireEvent('groupchange', this, this.getGroupState());
23935 if (this.groupOnSort) {
23936 this.sort(field, direction);
23937 fireGroupEvent.call(this);
23941 if (this.remoteGroup) {
23942 this.on('load', fireGroupEvent, this, {single: true});
23945 this.sort(sorters);
23946 fireGroupEvent.call(this);
23952 sort : function(fieldName, dir) {
23953 if (this.remoteSort) {
23954 return Ext.data.GroupingStore.superclass.sort.call(this, fieldName, dir);
23960 if (Ext.isArray(arguments[0])) {
23961 sorters = arguments[0];
23962 } else if (fieldName == undefined) {
23965 sorters = this.sortInfo ? [this.sortInfo] : [];
23969 var field = this.fields.get(fieldName);
23970 if (!field) return false;
23972 var name = field.name,
23973 sortInfo = this.sortInfo || null,
23974 sortToggle = this.sortToggle ? this.sortToggle[name] : null;
23977 if (sortInfo && sortInfo.field == name) {
23978 dir = (this.sortToggle[name] || 'ASC').toggle('ASC', 'DESC');
23980 dir = field.sortDir;
23984 this.sortToggle[name] = dir;
23985 this.sortInfo = {field: name, direction: dir};
23987 sorters = [this.sortInfo];
23991 if (this.groupField) {
23992 sorters.unshift({direction: this.groupDir, field: this.groupField});
23995 return this.multiSort.call(this, sorters, dir);
23999 applyGroupField: function(){
24000 if (this.remoteGroup) {
24001 if(!this.baseParams){
24002 this.baseParams = {};
24005 Ext.apply(this.baseParams, {
24006 groupBy : this.groupField,
24007 groupDir: this.groupDir
24010 var lo = this.lastOptions;
24011 if (lo && lo.params) {
24012 lo.params.groupDir = this.groupDir;
24015 delete lo.params.groupBy;
24021 applyGrouping : function(alwaysFireChange){
24022 if(this.groupField !== false){
24023 this.groupBy(this.groupField, true, this.groupDir);
24026 if(alwaysFireChange === true){
24027 this.fireEvent('datachanged', this);
24034 getGroupState : function(){
24035 return this.groupOnSort && this.groupField !== false ?
24036 (this.sortInfo ? this.sortInfo.field : undefined) : this.groupField;
24039 Ext.reg('groupingstore', Ext.data.GroupingStore);
24041 Ext.data.DirectProxy = function(config){
24042 Ext.apply(this, config);
24043 if(typeof this.paramOrder == 'string'){
24044 this.paramOrder = this.paramOrder.split(/[\s,|]/);
24046 Ext.data.DirectProxy.superclass.constructor.call(this, config);
24049 Ext.extend(Ext.data.DirectProxy, Ext.data.DataProxy, {
24051 paramOrder: undefined,
24054 paramsAsHash: true,
24057 directFn : undefined,
24060 doRequest : function(action, rs, params, reader, callback, scope, options) {
24062 directFn = this.api[action] || this.directFn;
24065 case Ext.data.Api.actions.create:
24066 args.push(params.jsonData);
24068 case Ext.data.Api.actions.read:
24070 if(directFn.directCfg.method.len > 0){
24071 if(this.paramOrder){
24072 for(var i = 0, len = this.paramOrder.length; i < len; i++){
24073 args.push(params[this.paramOrder[i]]);
24075 }else if(this.paramsAsHash){
24080 case Ext.data.Api.actions.update:
24081 args.push(params.jsonData);
24083 case Ext.data.Api.actions.destroy:
24084 args.push(params.jsonData);
24089 params : params || {},
24091 callback : callback,
24098 args.push(this.createCallback(action, rs, trans), this);
24099 directFn.apply(window, args);
24103 createCallback : function(action, rs, trans) {
24105 return function(result, res) {
24108 if (action === Ext.data.Api.actions.read) {
24109 me.fireEvent("loadexception", me, trans, res, null);
24111 me.fireEvent('exception', me, 'remote', action, trans, res, null);
24112 trans.request.callback.call(trans.request.scope, null, trans.request.arg, false);
24115 if (action === Ext.data.Api.actions.read) {
24116 me.onRead(action, trans, result, res);
24118 me.onWrite(action, trans, result, res, rs);
24124 onRead : function(action, trans, result, res) {
24127 records = trans.reader.readRecords(result);
24131 this.fireEvent("loadexception", this, trans, res, ex);
24133 this.fireEvent('exception', this, 'response', action, trans, res, ex);
24134 trans.request.callback.call(trans.request.scope, null, trans.request.arg, false);
24137 this.fireEvent("load", this, res, trans.request.arg);
24138 trans.request.callback.call(trans.request.scope, records, trans.request.arg, true);
24141 onWrite : function(action, trans, result, res, rs) {
24142 var data = trans.reader.extractData(trans.reader.getRoot(result), false);
24143 var success = trans.reader.getSuccess(result);
24144 success = (success !== false);
24146 this.fireEvent("write", this, action, data, res, rs, trans.request.arg);
24148 this.fireEvent('exception', this, 'remote', action, trans, result, rs);
24150 trans.request.callback.call(trans.request.scope, data, res, success);
24154 Ext.data.DirectStore = Ext.extend(Ext.data.Store, {
24155 constructor : function(config){
24157 var c = Ext.apply({}, {
24158 batchTransactions: false
24160 Ext.data.DirectStore.superclass.constructor.call(this, Ext.apply(c, {
24161 proxy: Ext.isDefined(c.proxy) ? c.proxy : new Ext.data.DirectProxy(Ext.copyTo({}, c, 'paramOrder,paramsAsHash,directFn,api')),
24162 reader: (!Ext.isDefined(c.reader) && c.fields) ? new Ext.data.JsonReader(Ext.copyTo({}, c, 'totalProperty,root,idProperty'), c.fields) : c.reader
24166 Ext.reg('directstore', Ext.data.DirectStore);
24168 Ext.Direct = Ext.extend(Ext.util.Observable, {
24176 SERVER: 'exception'
24180 constructor: function(){
24187 this.transactions = {};
24188 this.providers = {};
24192 addProvider : function(provider){
24195 for(var i = 0, len = a.length; i < len; i++){
24196 this.addProvider(a[i]);
24202 if(!provider.events){
24203 provider = new Ext.Direct.PROVIDERS[provider.type](provider);
24205 provider.id = provider.id || Ext.id();
24206 this.providers[provider.id] = provider;
24208 provider.on('data', this.onProviderData, this);
24209 provider.on('exception', this.onProviderException, this);
24212 if(!provider.isConnected()){
24213 provider.connect();
24220 getProvider : function(id){
24221 return this.providers[id];
24224 removeProvider : function(id){
24225 var provider = id.id ? id : this.providers[id];
24226 provider.un('data', this.onProviderData, this);
24227 provider.un('exception', this.onProviderException, this);
24228 delete this.providers[provider.id];
24232 addTransaction: function(t){
24233 this.transactions[t.tid] = t;
24237 removeTransaction: function(t){
24238 delete this.transactions[t.tid || t];
24242 getTransaction: function(tid){
24243 return this.transactions[tid.tid || tid];
24246 onProviderData : function(provider, e){
24247 if(Ext.isArray(e)){
24248 for(var i = 0, len = e.length; i < len; i++){
24249 this.onProviderData(provider, e[i]);
24253 if(e.name && e.name != 'event' && e.name != 'exception'){
24254 this.fireEvent(e.name, e);
24255 }else if(e.type == 'exception'){
24256 this.fireEvent('exception', e);
24258 this.fireEvent('event', e, provider);
24261 createEvent : function(response, extraProps){
24262 return new Ext.Direct.eventTypes[response.type](Ext.apply(response, extraProps));
24266 Ext.Direct = new Ext.Direct();
24268 Ext.Direct.TID = 1;
24269 Ext.Direct.PROVIDERS = {};
24270 Ext.Direct.Transaction = function(config){
24271 Ext.apply(this, config);
24272 this.tid = ++Ext.Direct.TID;
24273 this.retryCount = 0;
24275 Ext.Direct.Transaction.prototype = {
24277 this.provider.queueTransaction(this);
24285 getProvider: function(){
24286 return this.provider;
24288 };Ext.Direct.Event = function(config){
24289 Ext.apply(this, config);
24292 Ext.Direct.Event.prototype = {
24294 getData: function(){
24299 Ext.Direct.RemotingEvent = Ext.extend(Ext.Direct.Event, {
24301 getTransaction: function(){
24302 return this.transaction || Ext.Direct.getTransaction(this.tid);
24306 Ext.Direct.ExceptionEvent = Ext.extend(Ext.Direct.RemotingEvent, {
24311 Ext.Direct.eventTypes = {
24312 'rpc': Ext.Direct.RemotingEvent,
24313 'event': Ext.Direct.Event,
24314 'exception': Ext.Direct.ExceptionEvent
24317 Ext.direct.Provider = Ext.extend(Ext.util.Observable, {
24326 constructor : function(config){
24327 Ext.apply(this, config);
24338 Ext.direct.Provider.superclass.constructor.call(this, config);
24342 isConnected: function(){
24347 connect: Ext.emptyFn,
24350 disconnect: Ext.emptyFn
24353 Ext.direct.JsonProvider = Ext.extend(Ext.direct.Provider, {
24354 parseResponse: function(xhr){
24355 if(!Ext.isEmpty(xhr.responseText)){
24356 if(typeof xhr.responseText == 'object'){
24357 return xhr.responseText;
24359 return Ext.decode(xhr.responseText);
24364 getEvents: function(xhr){
24367 data = this.parseResponse(xhr);
24369 var event = new Ext.Direct.ExceptionEvent({
24372 code: Ext.Direct.exceptions.PARSE,
24373 message: 'Error parsing json response: \n\n ' + data
24378 if(Ext.isArray(data)){
24379 for(var i = 0, len = data.length; i < len; i++){
24380 events.push(Ext.Direct.createEvent(data[i]));
24383 events.push(Ext.Direct.createEvent(data));
24388 Ext.direct.PollingProvider = Ext.extend(Ext.direct.JsonProvider, {
24401 constructor : function(config){
24402 Ext.direct.PollingProvider.superclass.constructor.call(this, config);
24412 isConnected: function(){
24413 return !!this.pollTask;
24417 connect: function(){
24418 if(this.url && !this.pollTask){
24419 this.pollTask = Ext.TaskMgr.start({
24421 if(this.fireEvent('beforepoll', this) !== false){
24422 if(typeof this.url == 'function'){
24423 this.url(this.baseParams);
24427 callback: this.onData,
24429 params: this.baseParams
24434 interval: this.interval,
24437 this.fireEvent('connect', this);
24438 }else if(!this.url){
24439 throw 'Error initializing PollingProvider, no url configured.';
24444 disconnect: function(){
24446 Ext.TaskMgr.stop(this.pollTask);
24447 delete this.pollTask;
24448 this.fireEvent('disconnect', this);
24453 onData: function(opt, success, xhr){
24455 var events = this.getEvents(xhr);
24456 for(var i = 0, len = events.length; i < len; i++){
24458 this.fireEvent('data', this, e);
24461 var e = new Ext.Direct.ExceptionEvent({
24463 code: Ext.Direct.exceptions.TRANSPORT,
24464 message: 'Unable to connect to the server.',
24467 this.fireEvent('data', this, e);
24472 Ext.Direct.PROVIDERS['polling'] = Ext.direct.PollingProvider;
24473 Ext.direct.RemotingProvider = Ext.extend(Ext.direct.JsonProvider, {
24489 timeout: undefined,
24491 constructor : function(config){
24492 Ext.direct.RemotingProvider.superclass.constructor.call(this, config);
24499 this.namespace = (Ext.isString(this.namespace)) ? Ext.ns(this.namespace) : this.namespace || window;
24500 this.transactions = {};
24501 this.callBuffer = [];
24505 initAPI : function(){
24506 var o = this.actions;
24508 var cls = this.namespace[c] || (this.namespace[c] = {}),
24510 for(var i = 0, len = ms.length; i < len; i++){
24512 cls[m.name] = this.createMethod(c, m);
24518 isConnected: function(){
24519 return !!this.connected;
24522 connect: function(){
24525 this.connected = true;
24526 this.fireEvent('connect', this);
24527 }else if(!this.url){
24528 throw 'Error initializing RemotingProvider, no url configured.';
24532 disconnect: function(){
24533 if(this.connected){
24534 this.connected = false;
24535 this.fireEvent('disconnect', this);
24539 onData: function(opt, success, xhr){
24541 var events = this.getEvents(xhr);
24542 for(var i = 0, len = events.length; i < len; i++){
24544 t = this.getTransaction(e);
24545 this.fireEvent('data', this, e);
24547 this.doCallback(t, e, true);
24548 Ext.Direct.removeTransaction(t);
24552 var ts = [].concat(opt.ts);
24553 for(var i = 0, len = ts.length; i < len; i++){
24554 var t = this.getTransaction(ts[i]);
24555 if(t && t.retryCount < this.maxRetries){
24558 var e = new Ext.Direct.ExceptionEvent({
24561 code: Ext.Direct.exceptions.TRANSPORT,
24562 message: 'Unable to connect to the server.',
24565 this.fireEvent('data', this, e);
24567 this.doCallback(t, e, false);
24568 Ext.Direct.removeTransaction(t);
24575 getCallData: function(t){
24585 doSend : function(data){
24588 callback: this.onData,
24591 timeout: this.timeout
24594 if(Ext.isArray(data)){
24596 for(var i = 0, len = data.length; i < len; i++){
24597 callData.push(this.getCallData(data[i]));
24600 callData = this.getCallData(data);
24603 if(this.enableUrlEncode){
24605 params[Ext.isString(this.enableUrlEncode) ? this.enableUrlEncode : 'data'] = Ext.encode(callData);
24608 o.jsonData = callData;
24610 Ext.Ajax.request(o);
24613 combineAndSend : function(){
24614 var len = this.callBuffer.length;
24616 this.doSend(len == 1 ? this.callBuffer[0] : this.callBuffer);
24617 this.callBuffer = [];
24621 queueTransaction: function(t){
24623 this.processForm(t);
24626 this.callBuffer.push(t);
24627 if(this.enableBuffer){
24628 if(!this.callTask){
24629 this.callTask = new Ext.util.DelayedTask(this.combineAndSend, this);
24631 this.callTask.delay(Ext.isNumber(this.enableBuffer) ? this.enableBuffer : 10);
24633 this.combineAndSend();
24637 doCall : function(c, m, args){
24638 var data = null, hs = args[m.len], scope = args[m.len+1];
24641 data = args.slice(0, m.len);
24644 var t = new Ext.Direct.Transaction({
24650 cb: scope && Ext.isFunction(hs) ? hs.createDelegate(scope) : hs
24653 if(this.fireEvent('beforecall', this, t) !== false){
24654 Ext.Direct.addTransaction(t);
24655 this.queueTransaction(t);
24656 this.fireEvent('call', this, t);
24660 doForm : function(c, m, form, callback, scope){
24661 var t = new Ext.Direct.Transaction({
24665 args:[form, callback, scope],
24666 cb: scope && Ext.isFunction(callback) ? callback.createDelegate(scope) : callback,
24670 if(this.fireEvent('beforecall', this, t) !== false){
24671 Ext.Direct.addTransaction(t);
24672 var isUpload = String(form.getAttribute("enctype")).toLowerCase() == 'multipart/form-data',
24678 extUpload: String(isUpload)
24684 form: Ext.getDom(form),
24685 isUpload: isUpload,
24686 params: callback && Ext.isObject(callback.params) ? Ext.apply(params, callback.params) : params
24688 this.fireEvent('call', this, t);
24689 this.processForm(t);
24693 processForm: function(t){
24697 callback: this.onData,
24700 isUpload: t.isUpload,
24705 createMethod : function(c, m){
24707 if(!m.formHandler){
24709 this.doCall(c, m, Array.prototype.slice.call(arguments, 0));
24710 }.createDelegate(this);
24712 f = function(form, callback, scope){
24713 this.doForm(c, m, form, callback, scope);
24714 }.createDelegate(this);
24723 getTransaction: function(opt){
24724 return opt && opt.tid ? Ext.Direct.getTransaction(opt.tid) : null;
24727 doCallback: function(t, e){
24728 var fn = e.status ? 'success' : 'failure';
24731 result = Ext.isDefined(e.result) ? e.result : e.data;
24732 if(Ext.isFunction(hs)){
24735 Ext.callback(hs[fn], hs.scope, [result, e]);
24736 Ext.callback(hs.callback, hs.scope, [result, e]);
24741 Ext.Direct.PROVIDERS['remoting'] = Ext.direct.RemotingProvider;
24742 Ext.Resizable = Ext.extend(Ext.util.Observable, {
24744 constructor: function(el, config){
24745 this.el = Ext.get(el);
24746 if(config && config.wrap){
24747 config.resizeChild = this.el;
24748 this.el = this.el.wrap(typeof config.wrap == 'object' ? config.wrap : {cls:'xresizable-wrap'});
24749 this.el.id = this.el.dom.id = config.resizeChild.id + '-rzwrap';
24750 this.el.setStyle('overflow', 'hidden');
24751 this.el.setPositioning(config.resizeChild.getPositioning());
24752 config.resizeChild.clearPositioning();
24753 if(!config.width || !config.height){
24754 var csize = config.resizeChild.getSize();
24755 this.el.setSize(csize.width, csize.height);
24757 if(config.pinned && !config.adjustments){
24758 config.adjustments = 'auto';
24763 this.proxy = this.el.createProxy({tag: 'div', cls: 'x-resizable-proxy', id: this.el.id + '-rzproxy'}, Ext.getBody());
24764 this.proxy.unselectable();
24765 this.proxy.enableDisplayMode('block');
24767 Ext.apply(this, config);
24770 this.disableTrackOver = true;
24771 this.el.addClass('x-resizable-pinned');
24774 var position = this.el.getStyle('position');
24775 if(position != 'absolute' && position != 'fixed'){
24776 this.el.setStyle('position', 'relative');
24779 this.handles = 's,e,se';
24780 if(this.multiDirectional){
24781 this.handles += ',n,w';
24784 if(this.handles == 'all'){
24785 this.handles = 'n s e w ne nw se sw';
24787 var hs = this.handles.split(/\s*?[,;]\s*?| /);
24788 var ps = Ext.Resizable.positions;
24789 for(var i = 0, len = hs.length; i < len; i++){
24790 if(hs[i] && ps[hs[i]]){
24791 var pos = ps[hs[i]];
24792 this[pos] = new Ext.Resizable.Handle(this, pos, this.disableTrackOver, this.transparent, this.handleCls);
24796 this.corner = this.southeast;
24798 if(this.handles.indexOf('n') != -1 || this.handles.indexOf('w') != -1){
24799 this.updateBox = true;
24802 this.activeHandle = null;
24804 if(this.resizeChild){
24805 if(typeof this.resizeChild == 'boolean'){
24806 this.resizeChild = Ext.get(this.el.dom.firstChild, true);
24808 this.resizeChild = Ext.get(this.resizeChild, true);
24812 if(this.adjustments == 'auto'){
24813 var rc = this.resizeChild;
24814 var hw = this.west, he = this.east, hn = this.north, hs = this.south;
24815 if(rc && (hw || hn)){
24816 rc.position('relative');
24817 rc.setLeft(hw ? hw.el.getWidth() : 0);
24818 rc.setTop(hn ? hn.el.getHeight() : 0);
24820 this.adjustments = [
24821 (he ? -he.el.getWidth() : 0) + (hw ? -hw.el.getWidth() : 0),
24822 (hn ? -hn.el.getHeight() : 0) + (hs ? -hs.el.getHeight() : 0) -1
24826 if(this.draggable){
24827 this.dd = this.dynamic ?
24828 this.el.initDD(null) : this.el.initDDProxy(null, {dragElId: this.proxy.id});
24829 this.dd.setHandleElId(this.resizeChild ? this.resizeChild.id : this.el.id);
24830 if(this.constrainTo){
24831 this.dd.constrainTo(this.constrainTo);
24842 if(this.width !== null && this.height !== null){
24843 this.resizeTo(this.width, this.height);
24845 this.updateChildSize();
24848 this.el.dom.style.zoom = 1;
24850 Ext.Resizable.superclass.constructor.call(this);
24854 adjustments : [0, 0],
24859 disableTrackOver : false,
24867 easing : 'easeOutStrong',
24874 multiDirectional : false,
24880 heightIncrement : 0,
24882 widthIncrement : 0,
24898 preserveRatio : false,
24900 resizeChild : false,
24902 transparent: false,
24909 resizeTo : function(width, height){
24910 this.el.setSize(width, height);
24911 this.updateChildSize();
24912 this.fireEvent('resize', this, width, height, null);
24916 startSizing : function(e, handle){
24917 this.fireEvent('beforeresize', this, e);
24921 this.overlay = this.el.createProxy({tag: 'div', cls: 'x-resizable-overlay', html: ' '}, Ext.getBody());
24922 this.overlay.unselectable();
24923 this.overlay.enableDisplayMode('block');
24926 mousemove: this.onMouseMove,
24927 mouseup: this.onMouseUp
24930 this.overlay.setStyle('cursor', handle.el.getStyle('cursor'));
24932 this.resizing = true;
24933 this.startBox = this.el.getBox();
24934 this.startPoint = e.getXY();
24935 this.offsets = [(this.startBox.x + this.startBox.width) - this.startPoint[0],
24936 (this.startBox.y + this.startBox.height) - this.startPoint[1]];
24938 this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
24939 this.overlay.show();
24941 if(this.constrainTo) {
24942 var ct = Ext.get(this.constrainTo);
24943 this.resizeRegion = ct.getRegion().adjust(
24944 ct.getFrameWidth('t'),
24945 ct.getFrameWidth('l'),
24946 -ct.getFrameWidth('b'),
24947 -ct.getFrameWidth('r')
24951 this.proxy.setStyle('visibility', 'hidden');
24953 this.proxy.setBox(this.startBox);
24955 this.proxy.setStyle('visibility', 'visible');
24961 onMouseDown : function(handle, e){
24964 this.activeHandle = handle;
24965 this.startSizing(e, handle);
24970 onMouseUp : function(e){
24971 this.activeHandle = null;
24972 var size = this.resizeElement();
24973 this.resizing = false;
24975 this.overlay.hide();
24977 this.fireEvent('resize', this, size.width, size.height, e);
24981 updateChildSize : function(){
24982 if(this.resizeChild){
24984 var child = this.resizeChild;
24985 var adj = this.adjustments;
24986 if(el.dom.offsetWidth){
24987 var b = el.getSize(true);
24988 child.setSize(b.width+adj[0], b.height+adj[1]);
24995 setTimeout(function(){
24996 if(el.dom.offsetWidth){
24997 var b = el.getSize(true);
24998 child.setSize(b.width+adj[0], b.height+adj[1]);
25006 snap : function(value, inc, min){
25007 if(!inc || !value){
25010 var newValue = value;
25011 var m = value % inc;
25014 newValue = value + (inc-m);
25016 newValue = value - m;
25019 return Math.max(min, newValue);
25023 resizeElement : function(){
25024 var box = this.proxy.getBox();
25025 if(this.updateBox){
25026 this.el.setBox(box, false, this.animate, this.duration, null, this.easing);
25028 this.el.setSize(box.width, box.height, this.animate, this.duration, null, this.easing);
25030 this.updateChildSize();
25034 if(this.draggable && this.constrainTo){
25035 this.dd.resetConstraints();
25036 this.dd.constrainTo(this.constrainTo);
25042 constrain : function(v, diff, m, mx){
25045 }else if(v - diff > mx){
25052 onMouseMove : function(e){
25053 if(this.enabled && this.activeHandle){
25056 if(this.resizeRegion && !this.resizeRegion.contains(e.getPoint())) {
25061 var curSize = this.curSize || this.startBox,
25062 x = this.startBox.x, y = this.startBox.y,
25066 h = curSize.height,
25069 mw = this.minWidth,
25070 mh = this.minHeight,
25071 mxw = this.maxWidth,
25072 mxh = this.maxHeight,
25073 wi = this.widthIncrement,
25074 hi = this.heightIncrement,
25075 eventXY = e.getXY(),
25076 diffX = -(this.startPoint[0] - Math.max(this.minX, eventXY[0])),
25077 diffY = -(this.startPoint[1] - Math.max(this.minY, eventXY[1])),
25078 pos = this.activeHandle.position,
25085 w = Math.min(Math.max(mw, w), mxw);
25089 h = Math.min(Math.max(mh, h), mxh);
25094 w = Math.min(Math.max(mw, w), mxw);
25095 h = Math.min(Math.max(mh, h), mxh);
25098 diffY = this.constrain(h, diffY, mh, mxh);
25103 diffX = this.constrain(w, diffX, mw, mxw);
25109 w = Math.min(Math.max(mw, w), mxw);
25110 diffY = this.constrain(h, diffY, mh, mxh);
25115 diffX = this.constrain(w, diffX, mw, mxw);
25116 diffY = this.constrain(h, diffY, mh, mxh);
25123 diffX = this.constrain(w, diffX, mw, mxw);
25125 h = Math.min(Math.max(mh, h), mxh);
25131 var sw = this.snap(w, wi, mw);
25132 var sh = this.snap(h, hi, mh);
25133 if(sw != w || sh != h){
25156 if(this.preserveRatio){
25161 h = Math.min(Math.max(mh, h), mxh);
25166 w = Math.min(Math.max(mw, w), mxw);
25171 w = Math.min(Math.max(mw, w), mxw);
25177 w = Math.min(Math.max(mw, w), mxw);
25183 h = Math.min(Math.max(mh, h), mxh);
25191 h = Math.min(Math.max(mh, h), mxh);
25201 h = Math.min(Math.max(mh, h), mxh);
25209 this.proxy.setBounds(x, y, w, h);
25211 this.resizeElement();
25218 handleOver : function(){
25220 this.el.addClass('x-resizable-over');
25225 handleOut : function(){
25226 if(!this.resizing){
25227 this.el.removeClass('x-resizable-over');
25232 getEl : function(){
25237 getResizeChild : function(){
25238 return this.resizeChild;
25242 destroy : function(removeEl){
25243 Ext.destroy(this.dd, this.overlay, this.proxy);
25244 this.overlay = null;
25247 var ps = Ext.Resizable.positions;
25249 if(typeof ps[k] != 'function' && this[ps[k]]){
25250 this[ps[k]].destroy();
25254 this.el.update('');
25255 Ext.destroy(this.el);
25258 this.purgeListeners();
25261 syncHandleHeight : function(){
25262 var h = this.el.getHeight(true);
25264 this.west.el.setHeight(h);
25267 this.east.el.setHeight(h);
25274 Ext.Resizable.positions = {
25275 n: 'north', s: 'south', e: 'east', w: 'west', se: 'southeast', sw: 'southwest', nw: 'northwest', ne: 'northeast'
25278 Ext.Resizable.Handle = Ext.extend(Object, {
25279 constructor : function(rz, pos, disableTrackOver, transparent, cls){
25282 var tpl = Ext.DomHelper.createTemplate(
25283 {tag: 'div', cls: 'x-resizable-handle x-resizable-handle-{0}'}
25286 Ext.Resizable.Handle.prototype.tpl = tpl;
25288 this.position = pos;
25290 this.el = this.tpl.append(rz.el.dom, [this.position], true);
25291 this.el.unselectable();
25293 this.el.setOpacity(0);
25295 if(!Ext.isEmpty(cls)){
25296 this.el.addClass(cls);
25298 this.el.on('mousedown', this.onMouseDown, this);
25299 if(!disableTrackOver){
25302 mouseover: this.onMouseOver,
25303 mouseout: this.onMouseOut
25309 afterResize : function(rz){
25313 onMouseDown : function(e){
25314 this.rz.onMouseDown(this, e);
25317 onMouseOver : function(e){
25318 this.rz.handleOver(this, e);
25321 onMouseOut : function(e){
25322 this.rz.handleOut(this, e);
25325 destroy : function(){
25326 Ext.destroy(this.el);
25331 Ext.Window = Ext.extend(Ext.Panel, {
25344 baseCls : 'x-window',
25352 closeAction : 'close',
25356 constrainHeader : false,
25360 minimizable : false,
25362 maximizable : false,
25368 expandOnShow : true,
25371 collapsible : false,
25374 initHidden : undefined,
25384 elements : 'header,body',
25391 initComponent : function(){
25393 Ext.Window.superclass.initComponent.call(this);
25407 if(Ext.isDefined(this.initHidden)){
25408 this.hidden = this.initHidden;
25410 if(this.hidden === false){
25411 this.hidden = true;
25417 getState : function(){
25418 return Ext.apply(Ext.Window.superclass.getState.call(this) || {}, this.getBox(true));
25422 onRender : function(ct, position){
25423 Ext.Window.superclass.onRender.call(this, ct, position);
25426 this.el.addClass('x-window-plain');
25430 this.focusEl = this.el.createChild({
25431 tag: 'a', href:'#', cls:'x-dlg-focus',
25432 tabIndex:'-1', html: ' '});
25433 this.focusEl.swallowEvent('click', true);
25435 this.proxy = this.el.createProxy('x-window-proxy');
25436 this.proxy.enableDisplayMode('block');
25439 this.mask = this.container.createChild({cls:'ext-el-mask'}, this.el.dom);
25440 this.mask.enableDisplayMode('block');
25442 this.mon(this.mask, 'click', this.focus, this);
25444 if(this.maximizable){
25445 this.mon(this.header, 'dblclick', this.toggleMaximize, this);
25450 initEvents : function(){
25451 Ext.Window.superclass.initEvents.call(this);
25452 if(this.animateTarget){
25453 this.setAnimateTarget(this.animateTarget);
25456 if(this.resizable){
25457 this.resizer = new Ext.Resizable(this.el, {
25458 minWidth: this.minWidth,
25459 minHeight:this.minHeight,
25460 handles: this.resizeHandles || 'all',
25462 resizeElement : this.resizerAction,
25463 handleCls: 'x-window-handle'
25465 this.resizer.window = this;
25466 this.mon(this.resizer, 'beforeresize', this.beforeResize, this);
25469 if(this.draggable){
25470 this.header.addClass('x-window-draggable');
25472 this.mon(this.el, 'mousedown', this.toFront, this);
25473 this.manager = this.manager || Ext.WindowMgr;
25474 this.manager.register(this);
25475 if(this.maximized){
25476 this.maximized = false;
25480 var km = this.getKeyMap();
25481 km.on(27, this.onEsc, this);
25486 initDraggable : function(){
25488 this.dd = new Ext.Window.DD(this);
25492 onEsc : function(k, e){
25494 this[this.closeAction]();
25498 beforeDestroy : function(){
25501 this.clearAnchor();
25510 Ext.Window.superclass.beforeDestroy.call(this);
25514 onDestroy : function(){
25516 this.manager.unregister(this);
25518 Ext.Window.superclass.onDestroy.call(this);
25522 initTools : function(){
25523 if(this.minimizable){
25526 handler: this.minimize.createDelegate(this, [])
25529 if(this.maximizable){
25532 handler: this.maximize.createDelegate(this, [])
25536 handler: this.restore.createDelegate(this, []),
25543 handler: this[this.closeAction].createDelegate(this, [])
25549 resizerAction : function(){
25550 var box = this.proxy.getBox();
25552 this.window.handleResize(box);
25557 beforeResize : function(){
25558 this.resizer.minHeight = Math.max(this.minHeight, this.getFrameHeight() + 40);
25559 this.resizer.minWidth = Math.max(this.minWidth, this.getFrameWidth() + 40);
25560 this.resizeBox = this.el.getBox();
25564 updateHandles : function(){
25565 if(Ext.isIE && this.resizer){
25566 this.resizer.syncHandleHeight();
25572 handleResize : function(box){
25573 var rz = this.resizeBox;
25574 if(rz.x != box.x || rz.y != box.y){
25575 this.updateBox(box);
25578 if (Ext.isIE6 && Ext.isStrict) {
25583 this.updateHandles();
25588 focus : function(){
25589 var f = this.focusEl,
25590 db = this.defaultButton,
25594 if(Ext.isDefined(db)){
25595 if(Ext.isNumber(db) && this.fbar){
25596 f = this.fbar.items.get(db);
25597 }else if(Ext.isString(db)){
25598 f = Ext.getCmp(db);
25603 ct = Ext.getDom(this.container);
25605 if (!Ext.lib.Region.getRegion(ct).contains(Ext.lib.Region.getRegion(el.dom))){
25610 f = f || this.focusEl;
25611 f.focus.defer(10, f);
25615 setAnimateTarget : function(el){
25617 this.animateTarget = el;
25621 beforeShow : function(){
25622 delete this.el.lastXY;
25623 delete this.el.lastLT;
25624 if(this.x === undefined || this.y === undefined){
25625 var xy = this.el.getAlignToXY(this.container, 'c-c');
25626 var pos = this.el.translatePoints(xy[0], xy[1]);
25627 this.x = this.x === undefined? pos.left : this.x;
25628 this.y = this.y === undefined? pos.top : this.y;
25630 this.el.setLeftTop(this.x, this.y);
25632 if(this.expandOnShow){
25633 this.expand(false);
25637 Ext.getBody().addClass('x-body-masked');
25638 this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
25644 show : function(animateTarget, cb, scope){
25645 if(!this.rendered){
25646 this.render(Ext.getBody());
25648 if(this.hidden === false){
25652 if(this.fireEvent('beforeshow', this) === false){
25656 this.on('show', cb, scope, {single:true});
25658 this.hidden = false;
25659 if(Ext.isDefined(animateTarget)){
25660 this.setAnimateTarget(animateTarget);
25663 if(this.animateTarget){
25672 afterShow : function(isAnim){
25673 if (this.isDestroyed){
25677 this.el.setStyle('display', 'block');
25679 if(this.maximized){
25680 this.fitContainer();
25682 if(Ext.isMac && Ext.isGecko2){
25683 this.cascade(this.setAutoScroll);
25686 if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
25687 Ext.EventManager.onWindowResize(this.onWindowResize, this);
25689 this.doConstrain();
25692 this.keyMap.enable();
25695 this.updateHandles();
25696 if(isAnim && (Ext.isIE || Ext.isWebKit)){
25697 var sz = this.getSize();
25698 this.onResize(sz.width, sz.height);
25701 this.fireEvent('show', this);
25705 animShow : function(){
25707 this.proxy.setBox(this.animateTarget.getBox());
25708 this.proxy.setOpacity(0);
25709 var b = this.getBox();
25710 this.el.setStyle('display', 'none');
25711 this.proxy.shift(Ext.apply(b, {
25712 callback: this.afterShow.createDelegate(this, [true], false),
25714 easing: 'easeNone',
25721 hide : function(animateTarget, cb, scope){
25722 if(this.hidden || this.fireEvent('beforehide', this) === false){
25726 this.on('hide', cb, scope, {single:true});
25728 this.hidden = true;
25729 if(animateTarget !== undefined){
25730 this.setAnimateTarget(animateTarget);
25734 Ext.getBody().removeClass('x-body-masked');
25736 if(this.animateTarget){
25746 afterHide : function(){
25748 if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
25749 Ext.EventManager.removeResizeListener(this.onWindowResize, this);
25752 this.keyMap.disable();
25755 this.fireEvent('hide', this);
25759 animHide : function(){
25760 this.proxy.setOpacity(0.5);
25762 var tb = this.getBox(false);
25763 this.proxy.setBox(tb);
25765 this.proxy.shift(Ext.apply(this.animateTarget.getBox(), {
25766 callback: this.afterHide,
25769 easing: 'easeNone',
25775 onShow : Ext.emptyFn,
25778 onHide : Ext.emptyFn,
25781 onWindowResize : function(){
25782 if(this.maximized){
25783 this.fitContainer();
25786 this.mask.setSize('100%', '100%');
25787 var force = this.mask.dom.offsetHeight;
25788 this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
25790 this.doConstrain();
25794 doConstrain : function(){
25795 if(this.constrain || this.constrainHeader){
25797 if(this.constrain){
25799 right:this.el.shadowOffset,
25800 left:this.el.shadowOffset,
25801 bottom:this.el.shadowOffset
25804 var s = this.getSize();
25806 right:-(s.width - 100),
25807 bottom:-(s.height - 25)
25811 var xy = this.el.getConstrainToXY(this.container, true, offsets);
25813 this.setPosition(xy[0], xy[1]);
25819 ghost : function(cls){
25820 var ghost = this.createGhost(cls);
25821 var box = this.getBox(true);
25822 ghost.setLeftTop(box.x, box.y);
25823 ghost.setWidth(box.width);
25825 this.activeGhost = ghost;
25830 unghost : function(show, matchPosition){
25831 if(!this.activeGhost) {
25834 if(show !== false){
25836 this.focus.defer(10, this);
25837 if(Ext.isMac && Ext.isGecko2){
25838 this.cascade(this.setAutoScroll);
25841 if(matchPosition !== false){
25842 this.setPosition(this.activeGhost.getLeft(true), this.activeGhost.getTop(true));
25844 this.activeGhost.hide();
25845 this.activeGhost.remove();
25846 delete this.activeGhost;
25850 minimize : function(){
25851 this.fireEvent('minimize', this);
25856 close : function(){
25857 if(this.fireEvent('beforeclose', this) !== false){
25861 this.hide(null, this.doClose, this);
25867 doClose : function(){
25868 this.fireEvent('close', this);
25873 maximize : function(){
25874 if(!this.maximized){
25875 this.expand(false);
25876 this.restoreSize = this.getSize();
25877 this.restorePos = this.getPosition(true);
25878 if (this.maximizable){
25879 this.tools.maximize.hide();
25880 this.tools.restore.show();
25882 this.maximized = true;
25883 this.el.disableShadow();
25888 if(this.collapsible){
25889 this.tools.toggle.hide();
25891 this.el.addClass('x-window-maximized');
25892 this.container.addClass('x-window-maximized-ct');
25894 this.setPosition(0, 0);
25895 this.fitContainer();
25896 this.fireEvent('maximize', this);
25902 restore : function(){
25903 if(this.maximized){
25904 var t = this.tools;
25905 this.el.removeClass('x-window-maximized');
25912 this.setPosition(this.restorePos[0], this.restorePos[1]);
25913 this.setSize(this.restoreSize.width, this.restoreSize.height);
25914 delete this.restorePos;
25915 delete this.restoreSize;
25916 this.maximized = false;
25917 this.el.enableShadow(true);
25922 if(this.collapsible && t.toggle){
25925 this.container.removeClass('x-window-maximized-ct');
25927 this.doConstrain();
25928 this.fireEvent('restore', this);
25934 toggleMaximize : function(){
25935 return this[this.maximized ? 'restore' : 'maximize']();
25939 fitContainer : function(){
25940 var vs = this.container.getViewSize(false);
25941 this.setSize(vs.width, vs.height);
25946 setZIndex : function(index){
25948 this.mask.setStyle('z-index', index);
25950 this.el.setZIndex(++index);
25954 this.resizer.proxy.setStyle('z-index', ++index);
25957 this.lastZIndex = index;
25961 alignTo : function(element, position, offsets){
25962 var xy = this.el.getAlignToXY(element, position, offsets);
25963 this.setPagePosition(xy[0], xy[1]);
25968 anchorTo : function(el, alignment, offsets, monitorScroll){
25969 this.clearAnchor();
25970 this.anchorTarget = {
25972 alignment: alignment,
25976 Ext.EventManager.onWindowResize(this.doAnchor, this);
25977 var tm = typeof monitorScroll;
25978 if(tm != 'undefined'){
25979 Ext.EventManager.on(window, 'scroll', this.doAnchor, this,
25980 {buffer: tm == 'number' ? monitorScroll : 50});
25982 return this.doAnchor();
25986 doAnchor : function(){
25987 var o = this.anchorTarget;
25988 this.alignTo(o.el, o.alignment, o.offsets);
25993 clearAnchor : function(){
25994 if(this.anchorTarget){
25995 Ext.EventManager.removeResizeListener(this.doAnchor, this);
25996 Ext.EventManager.un(window, 'scroll', this.doAnchor, this);
25997 delete this.anchorTarget;
26003 toFront : function(e){
26004 if(this.manager.bringToFront(this)){
26005 if(!e || !e.getTarget().focus){
26013 setActive : function(active){
26015 if(!this.maximized){
26016 this.el.enableShadow(true);
26018 this.fireEvent('activate', this);
26020 this.el.disableShadow();
26021 this.fireEvent('deactivate', this);
26026 toBack : function(){
26027 this.manager.sendToBack(this);
26032 center : function(){
26033 var xy = this.el.getAlignToXY(this.container, 'c-c');
26034 this.setPagePosition(xy[0], xy[1]);
26040 Ext.reg('window', Ext.Window);
26043 Ext.Window.DD = function(win){
26045 Ext.Window.DD.superclass.constructor.call(this, win.el.id, 'WindowDD-'+win.id);
26046 this.setHandleElId(win.header.id);
26047 this.scroll = false;
26050 Ext.extend(Ext.Window.DD, Ext.dd.DD, {
26052 headerOffsets:[100, 25],
26053 startDrag : function(){
26055 this.proxy = w.ghost();
26056 if(w.constrain !== false){
26057 var so = w.el.shadowOffset;
26058 this.constrainTo(w.container, {right: so, left: so, bottom: so});
26059 }else if(w.constrainHeader !== false){
26060 var s = this.proxy.getSize();
26061 this.constrainTo(w.container, {right: -(s.width-this.headerOffsets[0]), bottom: -(s.height-this.headerOffsets[1])});
26064 b4Drag : Ext.emptyFn,
26066 onDrag : function(e){
26067 this.alignElWithMouse(this.proxy, e.getPageX(), e.getPageY());
26070 endDrag : function(e){
26071 this.win.unghost();
26072 this.win.saveState();
26076 Ext.WindowGroup = function(){
26078 var accessList = [];
26082 var sortWindows = function(d1, d2){
26083 return (!d1._lastAccess || d1._lastAccess < d2._lastAccess) ? -1 : 1;
26087 var orderWindows = function(){
26088 var a = accessList, len = a.length;
26090 a.sort(sortWindows);
26091 var seed = a[0].manager.zseed;
26092 for(var i = 0; i < len; i++){
26094 if(win && !win.hidden){
26095 win.setZIndex(seed + (i*10));
26103 var setActiveWin = function(win){
26106 front.setActive(false);
26110 win.setActive(true);
26116 var activateLast = function(){
26117 for(var i = accessList.length-1; i >=0; --i) {
26118 if(!accessList[i].hidden){
26119 setActiveWin(accessList[i]);
26124 setActiveWin(null);
26132 register : function(win){
26134 win.manager.unregister(win);
26136 win.manager = this;
26138 list[win.id] = win;
26139 accessList.push(win);
26140 win.on('hide', activateLast);
26144 unregister : function(win){
26145 delete win.manager;
26146 delete list[win.id];
26147 win.un('hide', activateLast);
26148 accessList.remove(win);
26152 get : function(id){
26153 return typeof id == "object" ? id : list[id];
26157 bringToFront : function(win){
26158 win = this.get(win);
26160 win._lastAccess = new Date().getTime();
26168 sendToBack : function(win){
26169 win = this.get(win);
26170 win._lastAccess = -(new Date().getTime());
26176 hideAll : function(){
26177 for(var id in list){
26178 if(list[id] && typeof list[id] != "function" && list[id].isVisible()){
26185 getActive : function(){
26190 getBy : function(fn, scope){
26192 for(var i = accessList.length-1; i >=0; --i) {
26193 var win = accessList[i];
26194 if(fn.call(scope||win, win) !== false){
26202 each : function(fn, scope){
26203 for(var id in list){
26204 if(list[id] && typeof list[id] != "function"){
26205 if(fn.call(scope || list[id], list[id]) === false){
26216 Ext.WindowMgr = new Ext.WindowGroup();
26217 Ext.MessageBox = function(){
26218 var dlg, opt, mask, waitTimer,
26219 bodyEl, msgEl, textboxEl, textareaEl, progressBar, pp, iconEl, spacerEl,
26220 buttons, activeTextEl, bwidth, bufferIcon = '', iconCls = '',
26221 buttonNames = ['ok', 'yes', 'no', 'cancel'];
26224 var handleButton = function(button){
26225 buttons[button].blur();
26226 if(dlg.isVisible()){
26229 Ext.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value, opt], 1);
26234 var handleHide = function(){
26235 if(opt && opt.cls){
26236 dlg.el.removeClass(opt.cls);
26238 progressBar.reset();
26242 var handleEsc = function(d, k, e){
26243 if(opt && opt.closable !== false){
26253 var updateButtons = function(b){
26257 Ext.each(buttonNames, function(name){
26258 buttons[name].hide();
26262 dlg.footer.dom.style.display = '';
26263 Ext.iterate(buttons, function(name, btn){
26267 btn.setText(Ext.isString(cfg) ? cfg : Ext.MessageBox.buttonText[name]);
26268 width += btn.getEl().getWidth() + 15;
26278 getDialog : function(titleText){
26283 Ext.each(buttonNames, function(name){
26284 btns.push(buttons[name] = new Ext.Button({
26285 text: this.buttonText[name],
26286 handler: handleButton.createCallback(name),
26287 hideMode: 'offsets'
26290 dlg = new Ext.Window({
26295 constrainHeader:true,
26296 minimizable : false,
26297 maximizable : false,
26301 buttonAlign:"center",
26308 close : function(){
26309 if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){
26310 handleButton("no");
26312 handleButton("cancel");
26315 fbar: new Ext.Toolbar({
26317 enableOverflow: false
26320 dlg.render(document.body);
26321 dlg.getEl().addClass('x-window-dlg');
26323 bodyEl = dlg.body.createChild({
26324 html:'<div class="ext-mb-icon"></div><div class="ext-mb-content"><span class="ext-mb-text"></span><br /><div class="ext-mb-fix-cursor"><input type="text" class="ext-mb-input" /><textarea class="ext-mb-textarea"></textarea></div></div>'
26326 iconEl = Ext.get(bodyEl.dom.firstChild);
26327 var contentEl = bodyEl.dom.childNodes[1];
26328 msgEl = Ext.get(contentEl.firstChild);
26329 textboxEl = Ext.get(contentEl.childNodes[2].firstChild);
26330 textboxEl.enableDisplayMode();
26331 textboxEl.addKeyListener([10,13], function(){
26332 if(dlg.isVisible() && opt && opt.buttons){
26333 if(opt.buttons.ok){
26334 handleButton("ok");
26335 }else if(opt.buttons.yes){
26336 handleButton("yes");
26340 textareaEl = Ext.get(contentEl.childNodes[2].childNodes[1]);
26341 textareaEl.enableDisplayMode();
26342 progressBar = new Ext.ProgressBar({
26345 bodyEl.createChild({cls:'x-clear'});
26351 updateText : function(text){
26352 if(!dlg.isVisible() && !opt.width){
26353 dlg.setSize(this.maxWidth, 100);
26355 msgEl.update(text || ' ');
26357 var iw = iconCls != '' ? (iconEl.getWidth() + iconEl.getMargins('lr')) : 0,
26358 mw = msgEl.getWidth() + msgEl.getMargins('lr'),
26359 fw = dlg.getFrameWidth('lr'),
26360 bw = dlg.body.getFrameWidth('lr'),
26363 if (Ext.isIE && iw > 0){
26368 w = Math.max(Math.min(opt.width || iw+mw+fw+bw, opt.maxWidth || this.maxWidth),
26369 Math.max(opt.minWidth || this.minWidth, bwidth || 0));
26371 if(opt.prompt === true){
26372 activeTextEl.setWidth(w-iw-fw-bw);
26374 if(opt.progress === true || opt.wait === true){
26375 progressBar.setSize(w-iw-fw-bw);
26377 if(Ext.isIE && w == bwidth){
26380 dlg.setSize(w, 'auto').center();
26385 updateProgress : function(value, progressText, msg){
26386 progressBar.updateProgress(value, progressText);
26388 this.updateText(msg);
26394 isVisible : function(){
26395 return dlg && dlg.isVisible();
26400 var proxy = dlg ? dlg.activeGhost : null;
26401 if(this.isVisible() || proxy){
26407 dlg.unghost(false, false);
26414 show : function(options){
26415 if(this.isVisible()){
26419 var d = this.getDialog(opt.title || " ");
26421 d.setTitle(opt.title || " ");
26422 var allowClose = (opt.closable !== false && opt.progress !== true && opt.wait !== true);
26423 d.tools.close.setDisplayed(allowClose);
26424 activeTextEl = textboxEl;
26425 opt.prompt = opt.prompt || (opt.multiline ? true : false);
26430 textareaEl.setHeight(Ext.isNumber(opt.multiline) ? opt.multiline : this.defaultTextHeight);
26431 activeTextEl = textareaEl;
26440 activeTextEl.dom.value = opt.value || "";
26442 d.focusEl = activeTextEl;
26444 var bs = opt.buttons;
26447 db = buttons["ok"];
26448 }else if(bs && bs.yes){
26449 db = buttons["yes"];
26456 d.setIconClass(opt.iconCls);
26458 this.setIcon(Ext.isDefined(opt.icon) ? opt.icon : bufferIcon);
26459 bwidth = updateButtons(opt.buttons);
26460 progressBar.setVisible(opt.progress === true || opt.wait === true);
26461 this.updateProgress(0, opt.progressText);
26462 this.updateText(opt.msg);
26464 d.el.addClass(opt.cls);
26466 d.proxyDrag = opt.proxyDrag === true;
26467 d.modal = opt.modal !== false;
26468 d.mask = opt.modal !== false ? mask : false;
26469 if(!d.isVisible()){
26471 document.body.appendChild(dlg.el.dom);
26472 d.setAnimateTarget(opt.animEl);
26474 d.on('show', function(){
26475 if(allowClose === true){
26478 d.keyMap.disable();
26480 }, this, {single:true});
26481 d.show(opt.animEl);
26483 if(opt.wait === true){
26484 progressBar.wait(opt.waitConfig);
26490 setIcon : function(icon){
26495 bufferIcon = undefined;
26496 if(icon && icon != ''){
26497 iconEl.removeClass('x-hidden');
26498 iconEl.replaceClass(iconCls, icon);
26499 bodyEl.addClass('x-dlg-icon');
26502 iconEl.replaceClass(iconCls, 'x-hidden');
26503 bodyEl.removeClass('x-dlg-icon');
26510 progress : function(title, msg, progressText){
26517 minWidth: this.minProgressWidth,
26518 progressText: progressText
26524 wait : function(msg, title, config){
26532 minWidth: this.minProgressWidth,
26539 alert : function(title, msg, fn, scope){
26546 minWidth: this.minWidth
26552 confirm : function(title, msg, fn, scope){
26556 buttons: this.YESNO,
26559 icon: this.QUESTION,
26560 minWidth: this.minWidth
26566 prompt : function(title, msg, fn, scope, multiline, value){
26570 buttons: this.OKCANCEL,
26572 minWidth: this.minPromptWidth,
26575 multiline: multiline,
26584 CANCEL : {cancel:true},
26586 OKCANCEL : {ok:true, cancel:true},
26588 YESNO : {yes:true, no:true},
26590 YESNOCANCEL : {yes:true, no:true, cancel:true},
26592 INFO : 'ext-mb-info',
26594 WARNING : 'ext-mb-warning',
26596 QUESTION : 'ext-mb-question',
26598 ERROR : 'ext-mb-error',
26601 defaultTextHeight : 75,
26607 minProgressWidth : 250,
26609 minPromptWidth: 250,
26621 Ext.Msg = Ext.MessageBox;
26622 Ext.dd.PanelProxy = function(panel, config){
26623 this.panel = panel;
26624 this.id = this.panel.id +'-ddproxy';
26625 Ext.apply(this, config);
26628 Ext.dd.PanelProxy.prototype = {
26630 insertProxy : true,
26633 setStatus : Ext.emptyFn,
26634 reset : Ext.emptyFn,
26635 update : Ext.emptyFn,
26636 stop : Ext.emptyFn,
26640 getEl : function(){
26645 getGhost : function(){
26650 getProxy : function(){
26658 this.proxy.remove();
26661 this.panel.el.dom.style.display = '';
26662 this.ghost.remove();
26670 this.ghost = this.panel.createGhost(undefined, undefined, Ext.getBody());
26671 this.ghost.setXY(this.panel.el.getXY());
26672 if(this.insertProxy){
26673 this.proxy = this.panel.el.insertSibling({cls:'x-panel-dd-spacer'});
26674 this.proxy.setSize(this.panel.getSize());
26676 this.panel.el.dom.style.display = 'none';
26681 repair : function(xy, callback, scope){
26683 if(typeof callback == "function"){
26684 callback.call(scope || this);
26689 moveProxy : function(parentNode, before){
26691 parentNode.insertBefore(this.proxy.dom, before);
26697 Ext.Panel.DD = function(panel, cfg){
26698 this.panel = panel;
26699 this.dragData = {panel: panel};
26700 this.proxy = new Ext.dd.PanelProxy(panel, cfg);
26701 Ext.Panel.DD.superclass.constructor.call(this, panel.el, cfg);
26702 var h = panel.header;
26704 this.setHandleElId(h.id);
26706 (h ? h : this.panel.body).setStyle('cursor', 'move');
26707 this.scroll = false;
26710 Ext.extend(Ext.Panel.DD, Ext.dd.DragSource, {
26711 showFrame: Ext.emptyFn,
26712 startDrag: Ext.emptyFn,
26713 b4StartDrag: function(x, y) {
26716 b4MouseDown: function(e) {
26717 var x = e.getPageX();
26718 var y = e.getPageY();
26719 this.autoOffset(x, y);
26721 onInitDrag : function(x, y){
26722 this.onStartDrag(x, y);
26725 createFrame : Ext.emptyFn,
26726 getDragEl : function(e){
26727 return this.proxy.ghost.dom;
26729 endDrag : function(e){
26731 this.panel.saveState();
26734 autoOffset : function(x, y) {
26735 x -= this.startPageX;
26736 y -= this.startPageY;
26737 this.setDelta(x, y);
26740 Ext.state.Provider = function(){
26742 this.addEvents("statechange");
26744 Ext.state.Provider.superclass.constructor.call(this);
26746 Ext.extend(Ext.state.Provider, Ext.util.Observable, {
26748 get : function(name, defaultValue){
26749 return typeof this.state[name] == "undefined" ?
26750 defaultValue : this.state[name];
26754 clear : function(name){
26755 delete this.state[name];
26756 this.fireEvent("statechange", this, name, null);
26760 set : function(name, value){
26761 this.state[name] = value;
26762 this.fireEvent("statechange", this, name, value);
26766 decodeValue : function(cookie){
26767 var re = /^(a|n|d|b|s|o)\:(.*)$/;
26768 var matches = re.exec(unescape(cookie));
26769 if(!matches || !matches[1]) return;
26770 var type = matches[1];
26771 var v = matches[2];
26774 return parseFloat(v);
26776 return new Date(Date.parse(v));
26782 Ext.each(v.split('^'), function(val){
26783 all.push(this.decodeValue(val));
26790 Ext.each(v.split('^'), function(val){
26791 var kv = val.split('=');
26792 all[kv[0]] = this.decodeValue(kv[1]);
26802 encodeValue : function(v){
26804 if(typeof v == "number"){
26806 }else if(typeof v == "boolean"){
26807 enc = "b:" + (v ? "1" : "0");
26808 }else if(Ext.isDate(v)){
26809 enc = "d:" + v.toGMTString();
26810 }else if(Ext.isArray(v)){
26812 for(var i = 0, len = v.length; i < len; i++){
26813 flat += this.encodeValue(v[i]);
26814 if(i != len-1) flat += "^";
26817 }else if(typeof v == "object"){
26820 if(typeof v[key] != "function" && v[key] !== undefined){
26821 flat += key + "=" + this.encodeValue(v[key]) + "^";
26824 enc = "o:" + flat.substring(0, flat.length-1);
26828 return escape(enc);
26832 Ext.state.Manager = function(){
26833 var provider = new Ext.state.Provider();
26837 setProvider : function(stateProvider){
26838 provider = stateProvider;
26842 get : function(key, defaultValue){
26843 return provider.get(key, defaultValue);
26847 set : function(key, value){
26848 provider.set(key, value);
26852 clear : function(key){
26853 provider.clear(key);
26857 getProvider : function(){
26863 Ext.state.CookieProvider = function(config){
26864 Ext.state.CookieProvider.superclass.constructor.call(this);
26866 this.expires = new Date(new Date().getTime()+(1000*60*60*24*7));
26867 this.domain = null;
26868 this.secure = false;
26869 Ext.apply(this, config);
26870 this.state = this.readCookies();
26873 Ext.extend(Ext.state.CookieProvider, Ext.state.Provider, {
26875 set : function(name, value){
26876 if(typeof value == "undefined" || value === null){
26880 this.setCookie(name, value);
26881 Ext.state.CookieProvider.superclass.set.call(this, name, value);
26885 clear : function(name){
26886 this.clearCookie(name);
26887 Ext.state.CookieProvider.superclass.clear.call(this, name);
26891 readCookies : function(){
26893 var c = document.cookie + ";";
26894 var re = /\s?(.*?)=(.*?);/g;
26896 while((matches = re.exec(c)) != null){
26897 var name = matches[1];
26898 var value = matches[2];
26899 if(name && name.substring(0,3) == "ys-"){
26900 cookies[name.substr(3)] = this.decodeValue(value);
26907 setCookie : function(name, value){
26908 document.cookie = "ys-"+ name + "=" + this.encodeValue(value) +
26909 ((this.expires == null) ? "" : ("; expires=" + this.expires.toGMTString())) +
26910 ((this.path == null) ? "" : ("; path=" + this.path)) +
26911 ((this.domain == null) ? "" : ("; domain=" + this.domain)) +
26912 ((this.secure == true) ? "; secure" : "");
26916 clearCookie : function(name){
26917 document.cookie = "ys-" + name + "=null; expires=Thu, 01-Jan-70 00:00:01 GMT" +
26918 ((this.path == null) ? "" : ("; path=" + this.path)) +
26919 ((this.domain == null) ? "" : ("; domain=" + this.domain)) +
26920 ((this.secure == true) ? "; secure" : "");
26923 Ext.DataView = Ext.extend(Ext.BoxComponent, {
26933 selectedClass : "x-view-selected",
26938 deferEmptyText: true,
26943 blockRefresh: false,
26949 initComponent : function(){
26950 Ext.DataView.superclass.initComponent.call(this);
26951 if(Ext.isString(this.tpl) || Ext.isArray(this.tpl)){
26952 this.tpl = new Ext.XTemplate(this.tpl);
26971 "containercontextmenu",
26979 this.store = Ext.StoreMgr.lookup(this.store);
26980 this.all = new Ext.CompositeElementLite();
26981 this.selected = new Ext.CompositeElementLite();
26985 afterRender : function(){
26986 Ext.DataView.superclass.afterRender.call(this);
26988 this.mon(this.getTemplateTarget(), {
26989 "click": this.onClick,
26990 "dblclick": this.onDblClick,
26991 "contextmenu": this.onContextMenu,
26995 if(this.overClass || this.trackOver){
26996 this.mon(this.getTemplateTarget(), {
26997 "mouseover": this.onMouseOver,
26998 "mouseout": this.onMouseOut,
27004 this.bindStore(this.store, true);
27009 refresh : function() {
27010 this.clearSelections(false, true);
27011 var el = this.getTemplateTarget();
27013 var records = this.store.getRange();
27014 if(records.length < 1){
27015 if(!this.deferEmptyText || this.hasSkippedEmptyText){
27016 el.update(this.emptyText);
27020 this.tpl.overwrite(el, this.collectData(records, 0));
27021 this.all.fill(Ext.query(this.itemSelector, el.dom));
27022 this.updateIndexes(0);
27024 this.hasSkippedEmptyText = true;
27027 getTemplateTarget: function(){
27032 prepareData : function(data){
27037 collectData : function(records, startIndex){
27039 for(var i = 0, len = records.length; i < len; i++){
27040 r[r.length] = this.prepareData(records[i].data, startIndex+i, records[i]);
27046 bufferRender : function(records){
27047 var div = document.createElement('div');
27048 this.tpl.overwrite(div, this.collectData(records));
27049 return Ext.query(this.itemSelector, div);
27053 onUpdate : function(ds, record){
27054 var index = this.store.indexOf(record);
27056 var sel = this.isSelected(index);
27057 var original = this.all.elements[index];
27058 var node = this.bufferRender([record], index)[0];
27060 this.all.replaceElement(index, node, true);
27062 this.selected.replaceElement(original, node);
27063 this.all.item(index).addClass(this.selectedClass);
27065 this.updateIndexes(index, index);
27070 onAdd : function(ds, records, index){
27071 if(this.all.getCount() === 0){
27075 var nodes = this.bufferRender(records, index), n, a = this.all.elements;
27076 if(index < this.all.getCount()){
27077 n = this.all.item(index).insertSibling(nodes, 'before', true);
27078 a.splice.apply(a, [index, 0].concat(nodes));
27080 n = this.all.last().insertSibling(nodes, 'after', true);
27081 a.push.apply(a, nodes);
27083 this.updateIndexes(index);
27087 onRemove : function(ds, record, index){
27088 this.deselect(index);
27089 this.all.removeElement(index, true);
27090 this.updateIndexes(index);
27091 if (this.store.getCount() === 0){
27097 refreshNode : function(index){
27098 this.onUpdate(this.store, this.store.getAt(index));
27102 updateIndexes : function(startIndex, endIndex){
27103 var ns = this.all.elements;
27104 startIndex = startIndex || 0;
27105 endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length - 1));
27106 for(var i = startIndex; i <= endIndex; i++){
27107 ns[i].viewIndex = i;
27112 getStore : function(){
27117 bindStore : function(store, initial){
27118 if(!initial && this.store){
27119 if(store !== this.store && this.store.autoDestroy){
27120 this.store.destroy();
27122 this.store.un("beforeload", this.onBeforeLoad, this);
27123 this.store.un("datachanged", this.onDataChanged, this);
27124 this.store.un("add", this.onAdd, this);
27125 this.store.un("remove", this.onRemove, this);
27126 this.store.un("update", this.onUpdate, this);
27127 this.store.un("clear", this.refresh, this);
27134 store = Ext.StoreMgr.lookup(store);
27137 beforeload: this.onBeforeLoad,
27138 datachanged: this.onDataChanged,
27140 remove: this.onRemove,
27141 update: this.onUpdate,
27142 clear: this.refresh
27145 this.store = store;
27152 onDataChanged: function() {
27153 if (this.blockRefresh !== true) {
27154 this.refresh.apply(this, arguments);
27159 findItemFromChild : function(node){
27160 return Ext.fly(node).findParent(this.itemSelector, this.getTemplateTarget());
27164 onClick : function(e){
27165 var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
27167 var index = this.indexOf(item);
27168 if(this.onItemClick(item, index, e) !== false){
27169 this.fireEvent("click", this, index, item, e);
27172 if(this.fireEvent("containerclick", this, e) !== false){
27173 this.onContainerClick(e);
27178 onContainerClick : function(e){
27179 this.clearSelections();
27183 onContextMenu : function(e){
27184 var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
27186 this.fireEvent("contextmenu", this, this.indexOf(item), item, e);
27188 this.fireEvent("containercontextmenu", this, e);
27193 onDblClick : function(e){
27194 var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
27196 this.fireEvent("dblclick", this, this.indexOf(item), item, e);
27201 onMouseOver : function(e){
27202 var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
27203 if(item && item !== this.lastItem){
27204 this.lastItem = item;
27205 Ext.fly(item).addClass(this.overClass);
27206 this.fireEvent("mouseenter", this, this.indexOf(item), item, e);
27211 onMouseOut : function(e){
27213 if(!e.within(this.lastItem, true, true)){
27214 Ext.fly(this.lastItem).removeClass(this.overClass);
27215 this.fireEvent("mouseleave", this, this.indexOf(this.lastItem), this.lastItem, e);
27216 delete this.lastItem;
27222 onItemClick : function(item, index, e){
27223 if(this.fireEvent("beforeclick", this, index, item, e) === false){
27226 if(this.multiSelect){
27227 this.doMultiSelection(item, index, e);
27228 e.preventDefault();
27229 }else if(this.singleSelect){
27230 this.doSingleSelection(item, index, e);
27231 e.preventDefault();
27237 doSingleSelection : function(item, index, e){
27238 if(e.ctrlKey && this.isSelected(index)){
27239 this.deselect(index);
27241 this.select(index, false);
27246 doMultiSelection : function(item, index, e){
27247 if(e.shiftKey && this.last !== false){
27248 var last = this.last;
27249 this.selectRange(last, index, e.ctrlKey);
27252 if((e.ctrlKey||this.simpleSelect) && this.isSelected(index)){
27253 this.deselect(index);
27255 this.select(index, e.ctrlKey || e.shiftKey || this.simpleSelect);
27261 getSelectionCount : function(){
27262 return this.selected.getCount();
27266 getSelectedNodes : function(){
27267 return this.selected.elements;
27271 getSelectedIndexes : function(){
27272 var indexes = [], s = this.selected.elements;
27273 for(var i = 0, len = s.length; i < len; i++){
27274 indexes.push(s[i].viewIndex);
27280 getSelectedRecords : function(){
27281 var r = [], s = this.selected.elements;
27282 for(var i = 0, len = s.length; i < len; i++){
27283 r[r.length] = this.store.getAt(s[i].viewIndex);
27289 getRecords : function(nodes){
27290 var r = [], s = nodes;
27291 for(var i = 0, len = s.length; i < len; i++){
27292 r[r.length] = this.store.getAt(s[i].viewIndex);
27298 getRecord : function(node){
27299 return this.store.getAt(node.viewIndex);
27303 clearSelections : function(suppressEvent, skipUpdate){
27304 if((this.multiSelect || this.singleSelect) && this.selected.getCount() > 0){
27306 this.selected.removeClass(this.selectedClass);
27308 this.selected.clear();
27310 if(!suppressEvent){
27311 this.fireEvent("selectionchange", this, this.selected.elements);
27317 isSelected : function(node){
27318 return this.selected.contains(this.getNode(node));
27322 deselect : function(node){
27323 if(this.isSelected(node)){
27324 node = this.getNode(node);
27325 this.selected.removeElement(node);
27326 if(this.last == node.viewIndex){
27329 Ext.fly(node).removeClass(this.selectedClass);
27330 this.fireEvent("selectionchange", this, this.selected.elements);
27335 select : function(nodeInfo, keepExisting, suppressEvent){
27336 if(Ext.isArray(nodeInfo)){
27338 this.clearSelections(true);
27340 for(var i = 0, len = nodeInfo.length; i < len; i++){
27341 this.select(nodeInfo[i], true, true);
27343 if(!suppressEvent){
27344 this.fireEvent("selectionchange", this, this.selected.elements);
27347 var node = this.getNode(nodeInfo);
27349 this.clearSelections(true);
27351 if(node && !this.isSelected(node)){
27352 if(this.fireEvent("beforeselect", this, node, this.selected.elements) !== false){
27353 Ext.fly(node).addClass(this.selectedClass);
27354 this.selected.add(node);
27355 this.last = node.viewIndex;
27356 if(!suppressEvent){
27357 this.fireEvent("selectionchange", this, this.selected.elements);
27365 selectRange : function(start, end, keepExisting){
27367 this.clearSelections(true);
27369 this.select(this.getNodes(start, end), true);
27373 getNode : function(nodeInfo){
27374 if(Ext.isString(nodeInfo)){
27375 return document.getElementById(nodeInfo);
27376 }else if(Ext.isNumber(nodeInfo)){
27377 return this.all.elements[nodeInfo];
27378 }else if(nodeInfo instanceof Ext.data.Record){
27379 var idx = this.store.indexOf(nodeInfo);
27380 return this.all.elements[idx];
27386 getNodes : function(start, end){
27387 var ns = this.all.elements;
27388 start = start || 0;
27389 end = !Ext.isDefined(end) ? Math.max(ns.length - 1, 0) : end;
27392 for(i = start; i <= end && ns[i]; i++){
27396 for(i = start; i >= end && ns[i]; i--){
27404 indexOf : function(node){
27405 node = this.getNode(node);
27406 if(Ext.isNumber(node.viewIndex)){
27407 return node.viewIndex;
27409 return this.all.indexOf(node);
27413 onBeforeLoad : function(){
27414 if(this.loadingText){
27415 this.clearSelections(false, true);
27416 this.getTemplateTarget().update('<div class="loading-indicator">'+this.loadingText+'</div>');
27421 onDestroy : function(){
27423 this.selected.clear();
27424 Ext.DataView.superclass.onDestroy.call(this);
27425 this.bindStore(null);
27430 Ext.DataView.prototype.setStore = Ext.DataView.prototype.bindStore;
27432 Ext.reg('dataview', Ext.DataView);
27434 Ext.list.ListView = Ext.extend(Ext.DataView, {
27438 itemSelector: 'dl',
27440 selectedClass:'x-list-selected',
27442 overClass:'x-list-over',
27445 scrollOffset : undefined,
27447 columnResize: true,
27454 maxWidth: Ext.isIE ? 99 : 100,
27456 initComponent : function(){
27457 if(this.columnResize){
27458 this.colResizer = new Ext.list.ColumnResizer(this.colResizer);
27459 this.colResizer.init(this);
27461 if(this.columnSort){
27462 this.colSorter = new Ext.list.Sorter(this.columnSort);
27463 this.colSorter.init(this);
27465 if(!this.internalTpl){
27466 this.internalTpl = new Ext.XTemplate(
27467 '<div class="x-list-header"><div class="x-list-header-inner">',
27468 '<tpl for="columns">',
27469 '<div style="width:{[values.width*100]}%;text-align:{align};"><em unselectable="on" id="',this.id, '-xlhd-{#}">',
27473 '<div class="x-clear"></div>',
27475 '<div class="x-list-body"><div class="x-list-body-inner">',
27480 this.tpl = new Ext.XTemplate(
27481 '<tpl for="rows">',
27483 '<tpl for="parent.columns">',
27484 '<dt style="width:{[values.width*100]}%;text-align:{align};">',
27485 '<em unselectable="on"<tpl if="cls"> class="{cls}</tpl>">',
27486 '{[values.tpl.apply(parent)]}',
27489 '<div class="x-clear"></div>',
27495 var cs = this.columns,
27496 allocatedWidth = 0,
27501 for(var i = 0; i < len; i++){
27504 c.xtype = c.xtype ? (/^lv/.test(c.xtype) ? c.xtype : 'lv' + c.xtype) : 'lvcolumn';
27508 allocatedWidth += c.width*100;
27514 cs = this.columns = columns;
27517 if(colsWithWidth < len){
27518 var remaining = len - colsWithWidth;
27519 if(allocatedWidth < this.maxWidth){
27520 var perCol = ((this.maxWidth-allocatedWidth) / remaining)/100;
27521 for(var j = 0; j < len; j++){
27529 Ext.list.ListView.superclass.initComponent.call(this);
27532 onRender : function(){
27536 Ext.list.ListView.superclass.onRender.apply(this, arguments);
27538 this.internalTpl.overwrite(this.el, {columns: this.columns});
27540 this.innerBody = Ext.get(this.el.dom.childNodes[1].firstChild);
27541 this.innerHd = Ext.get(this.el.dom.firstChild.firstChild);
27543 if(this.hideHeaders){
27544 this.el.dom.firstChild.style.display = 'none';
27548 getTemplateTarget : function(){
27549 return this.innerBody;
27553 collectData : function(){
27554 var rs = Ext.list.ListView.superclass.collectData.apply(this, arguments);
27556 columns: this.columns,
27561 verifyInternalSize : function(){
27563 this.onResize(this.lastSize.width, this.lastSize.height);
27568 onResize : function(w, h){
27569 var bd = this.innerBody.dom;
27570 var hd = this.innerHd.dom;
27574 var bdp = bd.parentNode;
27575 if(Ext.isNumber(w)){
27576 var sw = w - Ext.num(this.scrollOffset, Ext.getScrollBarWidth());
27577 if(this.reserveScrollOffset || ((bdp.offsetWidth - bdp.clientWidth) > 10)){
27578 bd.style.width = sw + 'px';
27579 hd.style.width = sw + 'px';
27581 bd.style.width = w + 'px';
27582 hd.style.width = w + 'px';
27583 setTimeout(function(){
27584 if((bdp.offsetWidth - bdp.clientWidth) > 10){
27585 bd.style.width = sw + 'px';
27586 hd.style.width = sw + 'px';
27591 if(Ext.isNumber(h)){
27592 bdp.style.height = (h - hd.parentNode.offsetHeight) + 'px';
27596 updateIndexes : function(){
27597 Ext.list.ListView.superclass.updateIndexes.apply(this, arguments);
27598 this.verifyInternalSize();
27601 findHeaderIndex : function(hd){
27603 var pn = hd.parentNode, cs = pn.parentNode.childNodes;
27604 for(var i = 0, c; c = cs[i]; i++){
27612 setHdWidths : function(){
27613 var els = this.innerHd.dom.getElementsByTagName('div');
27614 for(var i = 0, cs = this.columns, len = cs.length; i < len; i++){
27615 els[i].style.width = (cs[i].width*100) + '%';
27620 Ext.reg('listview', Ext.list.ListView);
27623 Ext.ListView = Ext.list.ListView;
27624 Ext.list.Column = Ext.extend(Object, {
27643 constructor : function(c){
27645 c.tpl = new Ext.XTemplate('{' + c.dataIndex + '}');
27647 else if(Ext.isString(c.tpl)){
27648 c.tpl = new Ext.XTemplate(c.tpl);
27651 Ext.apply(this, c);
27655 Ext.reg('lvcolumn', Ext.list.Column);
27658 Ext.list.NumberColumn = Ext.extend(Ext.list.Column, {
27660 format: '0,000.00',
27662 constructor : function(c) {
27663 c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':number("' + (c.format || this.format) + '")}');
27664 Ext.list.NumberColumn.superclass.constructor.call(this, c);
27668 Ext.reg('lvnumbercolumn', Ext.list.NumberColumn);
27671 Ext.list.DateColumn = Ext.extend(Ext.list.Column, {
27673 constructor : function(c) {
27674 c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':date("' + (c.format || this.format) + '")}');
27675 Ext.list.DateColumn.superclass.constructor.call(this, c);
27678 Ext.reg('lvdatecolumn', Ext.list.DateColumn);
27681 Ext.list.BooleanColumn = Ext.extend(Ext.list.Column, {
27685 falseText: 'false',
27687 undefinedText: ' ',
27689 constructor : function(c) {
27690 c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':this.format}');
27692 var t = this.trueText, f = this.falseText, u = this.undefinedText;
27693 c.tpl.format = function(v){
27694 if(v === undefined){
27697 if(!v || v === 'false'){
27703 Ext.list.DateColumn.superclass.constructor.call(this, c);
27707 Ext.reg('lvbooleancolumn', Ext.list.BooleanColumn);
27708 Ext.list.ColumnResizer = Ext.extend(Ext.util.Observable, {
27712 constructor: function(config){
27713 Ext.apply(this, config);
27714 Ext.list.ColumnResizer.superclass.constructor.call(this);
27716 init : function(listView){
27717 this.view = listView;
27718 listView.on('render', this.initEvents, this);
27721 initEvents : function(view){
27722 view.mon(view.innerHd, 'mousemove', this.handleHdMove, this);
27723 this.tracker = new Ext.dd.DragTracker({
27724 onBeforeStart: this.onBeforeStart.createDelegate(this),
27725 onStart: this.onStart.createDelegate(this),
27726 onDrag: this.onDrag.createDelegate(this),
27727 onEnd: this.onEnd.createDelegate(this),
27731 this.tracker.initEl(view.innerHd);
27732 view.on('beforedestroy', this.tracker.destroy, this.tracker);
27735 handleHdMove : function(e, t){
27738 hd = e.getTarget('em', 3, true);
27740 var r = hd.getRegion(),
27742 pn = hd.dom.parentNode;
27744 if(x - r.left <= hw && pn != pn.parentNode.firstChild){
27745 this.activeHd = Ext.get(pn.previousSibling.firstChild);
27746 ss.cursor = Ext.isWebKit ? 'e-resize' : 'col-resize';
27747 } else if(r.right - x <= hw && pn != pn.parentNode.lastChild.previousSibling){
27748 this.activeHd = hd;
27749 ss.cursor = Ext.isWebKit ? 'w-resize' : 'col-resize';
27751 delete this.activeHd;
27757 onBeforeStart : function(e){
27758 this.dragHd = this.activeHd;
27759 return !!this.dragHd;
27762 onStart: function(e){
27763 this.view.disableHeaders = true;
27764 this.proxy = this.view.el.createChild({cls:'x-list-resizer'});
27765 this.proxy.setHeight(this.view.el.getHeight());
27767 var x = this.tracker.getXY()[0],
27768 w = this.view.innerHd.getWidth();
27770 this.hdX = this.dragHd.getX();
27771 this.hdIndex = this.view.findHeaderIndex(this.dragHd);
27773 this.proxy.setX(this.hdX);
27774 this.proxy.setWidth(x-this.hdX);
27776 this.minWidth = w*this.minPct;
27777 this.maxWidth = w - (this.minWidth*(this.view.columns.length-1-this.hdIndex));
27780 onDrag: function(e){
27781 var cursorX = this.tracker.getXY()[0];
27782 this.proxy.setWidth((cursorX-this.hdX).constrain(this.minWidth, this.maxWidth));
27785 onEnd: function(e){
27787 var nw = this.proxy.getWidth();
27788 this.proxy.remove();
27790 var index = this.hdIndex,
27794 w = this.view.innerHd.getWidth(),
27795 minPct = this.minPct * 100,
27796 pct = Math.ceil((nw * vw.maxWidth) / w),
27797 diff = (cs[index].width * 100) - pct,
27798 eachItem = Math.floor(diff / (len-1-index)),
27799 mod = diff - (eachItem * (len-1-index));
27801 for(var i = index+1; i < len; i++){
27802 var cw = (cs[i].width * 100) + eachItem,
27803 ncw = Math.max(minPct, cw);
27807 cs[i].width = ncw / 100;
27809 cs[index].width = pct / 100;
27810 cs[index+1].width += (mod / 100);
27811 delete this.dragHd;
27814 setTimeout(function(){
27815 vw.disableHeaders = false;
27821 Ext.ListView.ColumnResizer = Ext.list.ColumnResizer;
27822 Ext.list.Sorter = Ext.extend(Ext.util.Observable, {
27824 sortClasses : ["sort-asc", "sort-desc"],
27826 constructor: function(config){
27827 Ext.apply(this, config);
27828 Ext.list.Sorter.superclass.constructor.call(this);
27831 init : function(listView){
27832 this.view = listView;
27833 listView.on('render', this.initEvents, this);
27836 initEvents : function(view){
27837 view.mon(view.innerHd, 'click', this.onHdClick, this);
27838 view.innerHd.setStyle('cursor', 'pointer');
27839 view.mon(view.store, 'datachanged', this.updateSortState, this);
27840 this.updateSortState.defer(10, this, [view.store]);
27843 updateSortState : function(store){
27844 var state = store.getSortState();
27848 this.sortState = state;
27849 var cs = this.view.columns, sortColumn = -1;
27850 for(var i = 0, len = cs.length; i < len; i++){
27851 if(cs[i].dataIndex == state.field){
27856 if(sortColumn != -1){
27857 var sortDir = state.direction;
27858 this.updateSortIcon(sortColumn, sortDir);
27862 updateSortIcon : function(col, dir){
27863 var sc = this.sortClasses;
27864 var hds = this.view.innerHd.select('em').removeClass(sc);
27865 hds.item(col).addClass(sc[dir == "DESC" ? 1 : 0]);
27868 onHdClick : function(e){
27869 var hd = e.getTarget('em', 3);
27870 if(hd && !this.view.disableHeaders){
27871 var index = this.view.findHeaderIndex(hd);
27872 this.view.store.sort(this.view.columns[index].dataIndex);
27878 Ext.ListView.Sorter = Ext.list.Sorter;
27879 Ext.TabPanel = Ext.extend(Ext.Panel, {
27883 deferredRender : true,
27889 resizeTabs : false,
27891 enableTabScroll : false,
27893 scrollIncrement : 0,
27895 scrollRepeatInterval : 400,
27897 scrollDuration : 0.35,
27901 tabPosition : 'top',
27903 baseCls : 'x-tab-panel',
27907 autoTabSelector : 'div.x-tab',
27909 activeTab : undefined,
27915 wheelIncrement : 20,
27918 idDelimiter : '__',
27921 itemCls : 'x-tab-item',
27925 headerAsText : false,
27930 initComponent : function(){
27931 this.frame = false;
27932 Ext.TabPanel.superclass.initComponent.call(this);
27942 this.setLayout(new Ext.layout.CardLayout(Ext.apply({
27943 layoutOnCardChange: this.layoutOnTabChange,
27944 deferredRender: this.deferredRender
27945 }, this.layoutConfig)));
27947 if(this.tabPosition == 'top'){
27948 this.elements += ',header';
27949 this.stripTarget = 'header';
27951 this.elements += ',footer';
27952 this.stripTarget = 'footer';
27955 this.stack = Ext.TabPanel.AccessStack();
27961 onRender : function(ct, position){
27962 Ext.TabPanel.superclass.onRender.call(this, ct, position);
27965 var pos = this.tabPosition == 'top' ? 'header' : 'footer';
27966 this[pos].addClass('x-tab-panel-'+pos+'-plain');
27969 var st = this[this.stripTarget];
27971 this.stripWrap = st.createChild({cls:'x-tab-strip-wrap', cn:{
27972 tag:'ul', cls:'x-tab-strip x-tab-strip-'+this.tabPosition}});
27974 var beforeEl = (this.tabPosition=='bottom' ? this.stripWrap : null);
27975 st.createChild({cls:'x-tab-strip-spacer'}, beforeEl);
27976 this.strip = new Ext.Element(this.stripWrap.dom.firstChild);
27979 this.edge = this.strip.createChild({tag:'li', cls:'x-tab-edge', cn: [{tag: 'span', cls: 'x-tab-strip-text', cn: ' '}]});
27980 this.strip.createChild({cls:'x-clear'});
27982 this.body.addClass('x-tab-panel-body-'+this.tabPosition);
27986 var tt = new Ext.Template(
27987 '<li class="{cls}" id="{id}"><a class="x-tab-strip-close"></a>',
27988 '<a class="x-tab-right" href="#"><em class="x-tab-left">',
27989 '<span class="x-tab-strip-inner"><span class="x-tab-strip-text {iconCls}">{text}</span></span>',
27992 tt.disableFormats = true;
27994 Ext.TabPanel.prototype.itemTpl = tt;
27997 this.items.each(this.initTab, this);
28001 afterRender : function(){
28002 Ext.TabPanel.superclass.afterRender.call(this);
28004 this.readTabs(false);
28006 if(this.activeTab !== undefined){
28007 var item = Ext.isObject(this.activeTab) ? this.activeTab : this.items.get(this.activeTab);
28008 delete this.activeTab;
28009 this.setActiveTab(item);
28014 initEvents : function(){
28015 Ext.TabPanel.superclass.initEvents.call(this);
28016 this.mon(this.strip, {
28018 mousedown: this.onStripMouseDown,
28019 contextmenu: this.onStripContextMenu
28021 if(this.enableTabScroll){
28022 this.mon(this.strip, 'mousewheel', this.onWheel, this);
28027 findTargets : function(e){
28029 itemEl = e.getTarget('li:not(.x-tab-edge)', this.strip);
28032 item = this.getComponent(itemEl.id.split(this.idDelimiter)[1]);
28042 close : e.getTarget('.x-tab-strip-close', this.strip),
28049 onStripMouseDown : function(e){
28050 if(e.button !== 0){
28053 e.preventDefault();
28054 var t = this.findTargets(e);
28056 if (t.item.fireEvent('beforeclose', t.item) !== false) {
28057 t.item.fireEvent('close', t.item);
28058 this.remove(t.item);
28062 if(t.item && t.item != this.activeTab){
28063 this.setActiveTab(t.item);
28068 onStripContextMenu : function(e){
28069 e.preventDefault();
28070 var t = this.findTargets(e);
28072 this.fireEvent('contextmenu', this, t.item, e);
28077 readTabs : function(removeExisting){
28078 if(removeExisting === true){
28079 this.items.each(function(item){
28083 var tabs = this.el.query(this.autoTabSelector);
28084 for(var i = 0, len = tabs.length; i < len; i++){
28086 title = tab.getAttribute('title');
28087 tab.removeAttribute('title');
28096 initTab : function(item, index){
28097 var before = this.strip.dom.childNodes[index],
28098 p = this.getTemplateArgs(item),
28100 this.itemTpl.insertBefore(before, p) :
28101 this.itemTpl.append(this.strip, p),
28102 cls = 'x-tab-strip-over',
28103 tabEl = Ext.get(el);
28105 tabEl.hover(function(){
28106 if(!item.disabled){
28107 tabEl.addClass(cls);
28110 tabEl.removeClass(cls);
28114 tabEl.child('span.x-tab-strip-text', true).qtip = item.tabTip;
28119 tabEl.select('a').on('click', function(e){
28121 this.onStripMouseDown(e);
28123 }, this, {preventDefault: true});
28127 disable: this.onItemDisabled,
28128 enable: this.onItemEnabled,
28129 titlechange: this.onItemTitleChanged,
28130 iconchange: this.onItemIconChanged,
28131 beforeshow: this.onBeforeShowItem
28138 getTemplateArgs : function(item) {
28139 var cls = item.closable ? 'x-tab-strip-closable' : '';
28141 cls += ' x-item-disabled';
28144 cls += ' x-tab-with-icon';
28147 cls += ' ' + item.tabCls;
28151 id: this.id + this.idDelimiter + item.getItemId(),
28154 iconCls: item.iconCls || ''
28159 onAdd : function(c){
28160 Ext.TabPanel.superclass.onAdd.call(this, c);
28162 var items = this.items;
28163 this.initTab(c, items.indexOf(c));
28164 this.delegateUpdates();
28169 onBeforeAdd : function(item){
28170 var existing = item.events ? (this.items.containsKey(item.getItemId()) ? item : null) : this.items.get(item);
28172 this.setActiveTab(item);
28175 Ext.TabPanel.superclass.onBeforeAdd.apply(this, arguments);
28176 var es = item.elements;
28177 item.elements = es ? es.replace(',header', '') : es;
28178 item.border = (item.border === true);
28182 onRemove : function(c){
28183 var te = Ext.get(c.tabEl);
28186 te.select('a').removeAllListeners();
28189 Ext.TabPanel.superclass.onRemove.call(this, c);
28190 this.stack.remove(c);
28192 c.un('disable', this.onItemDisabled, this);
28193 c.un('enable', this.onItemEnabled, this);
28194 c.un('titlechange', this.onItemTitleChanged, this);
28195 c.un('iconchange', this.onItemIconChanged, this);
28196 c.un('beforeshow', this.onBeforeShowItem, this);
28197 if(c == this.activeTab){
28198 var next = this.stack.next();
28200 this.setActiveTab(next);
28201 }else if(this.items.getCount() > 0){
28202 this.setActiveTab(0);
28204 this.setActiveTab(null);
28207 if(!this.destroying){
28208 this.delegateUpdates();
28213 onBeforeShowItem : function(item){
28214 if(item != this.activeTab){
28215 this.setActiveTab(item);
28221 onItemDisabled : function(item){
28222 var el = this.getTabEl(item);
28224 Ext.fly(el).addClass('x-item-disabled');
28226 this.stack.remove(item);
28230 onItemEnabled : function(item){
28231 var el = this.getTabEl(item);
28233 Ext.fly(el).removeClass('x-item-disabled');
28238 onItemTitleChanged : function(item){
28239 var el = this.getTabEl(item);
28241 Ext.fly(el).child('span.x-tab-strip-text', true).innerHTML = item.title;
28246 onItemIconChanged : function(item, iconCls, oldCls){
28247 var el = this.getTabEl(item);
28250 el.child('span.x-tab-strip-text').replaceClass(oldCls, iconCls);
28251 el[Ext.isEmpty(iconCls) ? 'removeClass' : 'addClass']('x-tab-with-icon');
28256 getTabEl : function(item){
28257 var c = this.getComponent(item);
28258 return c ? c.tabEl : null;
28262 onResize : function(){
28263 Ext.TabPanel.superclass.onResize.apply(this, arguments);
28264 this.delegateUpdates();
28268 beginUpdate : function(){
28269 this.suspendUpdates = true;
28273 endUpdate : function(){
28274 this.suspendUpdates = false;
28275 this.delegateUpdates();
28279 hideTabStripItem : function(item){
28280 item = this.getComponent(item);
28281 var el = this.getTabEl(item);
28283 el.style.display = 'none';
28284 this.delegateUpdates();
28286 this.stack.remove(item);
28290 unhideTabStripItem : function(item){
28291 item = this.getComponent(item);
28292 var el = this.getTabEl(item);
28294 el.style.display = '';
28295 this.delegateUpdates();
28300 delegateUpdates : function(){
28301 if(this.suspendUpdates){
28304 if(this.resizeTabs && this.rendered){
28305 this.autoSizeTabs();
28307 if(this.enableTabScroll && this.rendered){
28308 this.autoScrollTabs();
28313 autoSizeTabs : function(){
28314 var count = this.items.length,
28315 ce = this.tabPosition != 'bottom' ? 'header' : 'footer',
28316 ow = this[ce].dom.offsetWidth,
28317 aw = this[ce].dom.clientWidth;
28319 if(!this.resizeTabs || count < 1 || !aw){
28323 var each = Math.max(Math.min(Math.floor((aw-4) / count) - this.tabMargin, this.tabWidth), this.minTabWidth);
28324 this.lastTabWidth = each;
28325 var lis = this.strip.query('li:not(.x-tab-edge)');
28326 for(var i = 0, len = lis.length; i < len; i++) {
28328 inner = Ext.fly(li).child('.x-tab-strip-inner', true),
28329 tw = li.offsetWidth,
28330 iw = inner.offsetWidth;
28331 inner.style.width = (each - (tw-iw)) + 'px';
28336 adjustBodyWidth : function(w){
28338 this.header.setWidth(w);
28341 this.footer.setWidth(w);
28347 setActiveTab : function(item){
28348 item = this.getComponent(item);
28349 if(this.fireEvent('beforetabchange', this, item, this.activeTab) === false){
28352 if(!this.rendered){
28353 this.activeTab = item;
28356 if(this.activeTab != item){
28357 if(this.activeTab){
28358 var oldEl = this.getTabEl(this.activeTab);
28360 Ext.fly(oldEl).removeClass('x-tab-strip-active');
28363 this.activeTab = item;
28365 var el = this.getTabEl(item);
28366 Ext.fly(el).addClass('x-tab-strip-active');
28367 this.stack.add(item);
28369 this.layout.setActiveItem(item);
28370 if(this.scrolling){
28371 this.scrollToTab(item, this.animScroll);
28374 this.fireEvent('tabchange', this, item);
28379 getActiveTab : function(){
28380 return this.activeTab || null;
28384 getItem : function(item){
28385 return this.getComponent(item);
28389 autoScrollTabs : function(){
28390 this.pos = this.tabPosition=='bottom' ? this.footer : this.header;
28391 var count = this.items.length,
28392 ow = this.pos.dom.offsetWidth,
28393 tw = this.pos.dom.clientWidth,
28394 wrap = this.stripWrap,
28396 cw = wd.offsetWidth,
28397 pos = this.getScrollPos(),
28398 l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos;
28400 if(!this.enableTabScroll || count < 1 || cw < 20){
28406 if(this.scrolling){
28407 this.scrolling = false;
28408 this.pos.removeClass('x-tab-scrolling');
28409 this.scrollLeft.hide();
28410 this.scrollRight.hide();
28412 if(Ext.isAir || Ext.isWebKit){
28413 wd.style.marginLeft = '';
28414 wd.style.marginRight = '';
28418 if(!this.scrolling){
28419 this.pos.addClass('x-tab-scrolling');
28421 if(Ext.isAir || Ext.isWebKit){
28422 wd.style.marginLeft = '18px';
28423 wd.style.marginRight = '18px';
28426 tw -= wrap.getMargins('lr');
28427 wrap.setWidth(tw > 20 ? tw : 20);
28428 if(!this.scrolling){
28429 if(!this.scrollLeft){
28430 this.createScrollers();
28432 this.scrollLeft.show();
28433 this.scrollRight.show();
28436 this.scrolling = true;
28438 wd.scrollLeft = l-tw;
28440 this.scrollToTab(this.activeTab, false);
28442 this.updateScrollButtons();
28447 createScrollers : function(){
28448 this.pos.addClass('x-tab-scrolling-' + this.tabPosition);
28449 var h = this.stripWrap.dom.offsetHeight;
28452 var sl = this.pos.insertFirst({
28453 cls:'x-tab-scroller-left'
28456 sl.addClassOnOver('x-tab-scroller-left-over');
28457 this.leftRepeater = new Ext.util.ClickRepeater(sl, {
28458 interval : this.scrollRepeatInterval,
28459 handler: this.onScrollLeft,
28462 this.scrollLeft = sl;
28465 var sr = this.pos.insertFirst({
28466 cls:'x-tab-scroller-right'
28469 sr.addClassOnOver('x-tab-scroller-right-over');
28470 this.rightRepeater = new Ext.util.ClickRepeater(sr, {
28471 interval : this.scrollRepeatInterval,
28472 handler: this.onScrollRight,
28475 this.scrollRight = sr;
28479 getScrollWidth : function(){
28480 return this.edge.getOffsetsTo(this.stripWrap)[0] + this.getScrollPos();
28484 getScrollPos : function(){
28485 return parseInt(this.stripWrap.dom.scrollLeft, 10) || 0;
28489 getScrollArea : function(){
28490 return parseInt(this.stripWrap.dom.clientWidth, 10) || 0;
28494 getScrollAnim : function(){
28495 return {duration:this.scrollDuration, callback: this.updateScrollButtons, scope: this};
28499 getScrollIncrement : function(){
28500 return this.scrollIncrement || (this.resizeTabs ? this.lastTabWidth+2 : 100);
28505 scrollToTab : function(item, animate){
28509 var el = this.getTabEl(item),
28510 pos = this.getScrollPos(),
28511 area = this.getScrollArea(),
28512 left = Ext.fly(el).getOffsetsTo(this.stripWrap)[0] + pos,
28513 right = left + el.offsetWidth;
28515 this.scrollTo(left, animate);
28516 }else if(right > (pos + area)){
28517 this.scrollTo(right - area, animate);
28522 scrollTo : function(pos, animate){
28523 this.stripWrap.scrollTo('left', pos, animate ? this.getScrollAnim() : false);
28525 this.updateScrollButtons();
28529 onWheel : function(e){
28530 var d = e.getWheelDelta()*this.wheelIncrement*-1;
28533 var pos = this.getScrollPos(),
28535 sw = this.getScrollWidth()-this.getScrollArea();
28537 var s = Math.max(0, Math.min(sw, newpos));
28539 this.scrollTo(s, false);
28544 onScrollRight : function(){
28545 var sw = this.getScrollWidth()-this.getScrollArea(),
28546 pos = this.getScrollPos(),
28547 s = Math.min(sw, pos + this.getScrollIncrement());
28549 this.scrollTo(s, this.animScroll);
28554 onScrollLeft : function(){
28555 var pos = this.getScrollPos(),
28556 s = Math.max(0, pos - this.getScrollIncrement());
28558 this.scrollTo(s, this.animScroll);
28563 updateScrollButtons : function(){
28564 var pos = this.getScrollPos();
28565 this.scrollLeft[pos === 0 ? 'addClass' : 'removeClass']('x-tab-scroller-left-disabled');
28566 this.scrollRight[pos >= (this.getScrollWidth()-this.getScrollArea()) ? 'addClass' : 'removeClass']('x-tab-scroller-right-disabled');
28570 beforeDestroy : function() {
28571 Ext.destroy(this.leftRepeater, this.rightRepeater);
28572 this.deleteMembers('strip', 'edge', 'scrollLeft', 'scrollRight', 'stripWrap');
28573 this.activeTab = null;
28574 Ext.TabPanel.superclass.beforeDestroy.apply(this);
28590 Ext.reg('tabpanel', Ext.TabPanel);
28593 Ext.TabPanel.prototype.activate = Ext.TabPanel.prototype.setActiveTab;
28596 Ext.TabPanel.AccessStack = function(){
28599 add : function(item){
28601 if(items.length > 10){
28606 remove : function(item){
28608 for(var i = 0, len = items.length; i < len; i++) {
28609 if(items[i] != item){
28617 return items.pop();
28622 Ext.Button = Ext.extend(Ext.BoxComponent, {
28635 enableToggle : false,
28639 menuAlign : 'tl-bl?',
28647 menuClassTarget : 'tr:nth(2)',
28650 clickEvent : 'click',
28653 handleMouseEvents : true,
28656 tooltipType : 'qtip',
28659 buttonSelector : 'button:first-child',
28667 iconAlign : 'left',
28670 arrowAlign : 'right',
28677 initComponent : function(){
28678 Ext.Button.superclass.initComponent.call(this);
28699 this.menu = Ext.menu.MenuMgr.get(this.menu);
28701 if(Ext.isString(this.toggleGroup)){
28702 this.enableToggle = true;
28707 getTemplateArgs : function(){
28708 return [this.type, 'x-btn-' + this.scale + ' x-btn-icon-' + this.scale + '-' + this.iconAlign, this.getMenuClass(), this.cls, this.id];
28712 setButtonClass : function(){
28713 if(this.useSetClass){
28714 if(!Ext.isEmpty(this.oldCls)){
28715 this.el.removeClass([this.oldCls, 'x-btn-pressed']);
28717 this.oldCls = (this.iconCls || this.icon) ? (this.text ? 'x-btn-text-icon' : 'x-btn-icon') : 'x-btn-noicon';
28718 this.el.addClass([this.oldCls, this.pressed ? 'x-btn-pressed' : null]);
28723 getMenuClass : function(){
28724 return this.menu ? (this.arrowAlign != 'bottom' ? 'x-btn-arrow' : 'x-btn-arrow-bottom') : '';
28728 onRender : function(ct, position){
28729 if(!this.template){
28730 if(!Ext.Button.buttonTemplate){
28732 Ext.Button.buttonTemplate = new Ext.Template(
28733 '<table id="{4}" cellspacing="0" class="x-btn {3}"><tbody class="{1}">',
28734 '<tr><td class="x-btn-tl"><i> </i></td><td class="x-btn-tc"></td><td class="x-btn-tr"><i> </i></td></tr>',
28735 '<tr><td class="x-btn-ml"><i> </i></td><td class="x-btn-mc"><em class="{2}" unselectable="on"><button type="{0}"></button></em></td><td class="x-btn-mr"><i> </i></td></tr>',
28736 '<tr><td class="x-btn-bl"><i> </i></td><td class="x-btn-bc"></td><td class="x-btn-br"><i> </i></td></tr>',
28737 '</tbody></table>');
28738 Ext.Button.buttonTemplate.compile();
28740 this.template = Ext.Button.buttonTemplate;
28743 var btn, targs = this.getTemplateArgs();
28746 btn = this.template.insertBefore(position, targs, true);
28748 btn = this.template.append(ct, targs, true);
28751 this.btnEl = btn.child(this.buttonSelector);
28752 this.mon(this.btnEl, {
28754 focus: this.onFocus,
28758 this.initButtonEl(btn, this.btnEl);
28760 Ext.ButtonToggleMgr.register(this);
28764 initButtonEl : function(btn, btnEl){
28766 this.setIcon(this.icon);
28767 this.setText(this.text);
28768 this.setIconClass(this.iconCls);
28769 if(Ext.isDefined(this.tabIndex)){
28770 btnEl.dom.tabIndex = this.tabIndex;
28773 this.setTooltip(this.tooltip, true);
28776 if(this.handleMouseEvents){
28779 mouseover: this.onMouseOver,
28780 mousedown: this.onMouseDown
28788 this.mon(this.menu, {
28790 show: this.onMenuShow,
28791 hide: this.onMenuHide
28796 var repeater = new Ext.util.ClickRepeater(btn, Ext.isObject(this.repeat) ? this.repeat : {});
28797 this.mon(repeater, 'click', this.onClick, this);
28799 this.mon(btn, this.clickEvent, this.onClick, this);
28803 afterRender : function(){
28804 Ext.Button.superclass.afterRender.call(this);
28805 this.useSetClass = true;
28806 this.setButtonClass();
28807 this.doc = Ext.getDoc();
28808 this.doAutoWidth();
28812 setIconClass : function(cls){
28813 this.iconCls = cls;
28815 this.btnEl.dom.className = '';
28816 this.btnEl.addClass(['x-btn-text', cls || '']);
28817 this.setButtonClass();
28823 setTooltip : function(tooltip, initial){
28828 if(Ext.isObject(tooltip)){
28829 Ext.QuickTips.register(Ext.apply({
28830 target: this.btnEl.id
28832 this.tooltip = tooltip;
28834 this.btnEl.dom[this.tooltipType] = tooltip;
28837 this.tooltip = tooltip;
28843 clearTip : function(){
28844 if(Ext.isObject(this.tooltip)){
28845 Ext.QuickTips.unregister(this.btnEl);
28850 beforeDestroy : function(){
28854 if(this.menu && this.destroyMenu !== false) {
28855 Ext.destroy(this.menu);
28857 Ext.destroy(this.repeater);
28861 onDestroy : function(){
28863 this.doc.un('mouseover', this.monitorMouseOver, this);
28864 this.doc.un('mouseup', this.onMouseUp, this);
28867 Ext.ButtonToggleMgr.unregister(this);
28869 Ext.Button.superclass.onDestroy.call(this);
28873 doAutoWidth : function(){
28874 if(this.autoWidth !== false && this.el && this.text && this.width === undefined){
28875 this.el.setWidth('auto');
28876 if(Ext.isIE7 && Ext.isStrict){
28877 var ib = this.btnEl;
28878 if(ib && ib.getWidth() > 20){
28880 ib.setWidth(Ext.util.TextMetrics.measure(ib, this.text).width+ib.getFrameWidth('lr'));
28884 if(this.el.getWidth() < this.minWidth){
28885 this.el.setWidth(this.minWidth);
28892 setHandler : function(handler, scope){
28893 this.handler = handler;
28894 this.scope = scope;
28899 setText : function(text){
28902 this.btnEl.update(text || ' ');
28903 this.setButtonClass();
28905 this.doAutoWidth();
28910 setIcon : function(icon){
28913 this.btnEl.setStyle('background-image', icon ? 'url(' + icon + ')' : '');
28914 this.setButtonClass();
28920 getText : function(){
28925 toggle : function(state, suppressEvent){
28926 state = state === undefined ? !this.pressed : !!state;
28927 if(state != this.pressed){
28929 this.el[state ? 'addClass' : 'removeClass']('x-btn-pressed');
28931 this.pressed = state;
28932 if(!suppressEvent){
28933 this.fireEvent('toggle', this, state);
28934 if(this.toggleHandler){
28935 this.toggleHandler.call(this.scope || this, this, state);
28943 onDisable : function(){
28944 this.onDisableChange(true);
28948 onEnable : function(){
28949 this.onDisableChange(false);
28952 onDisableChange : function(disabled){
28954 if(!Ext.isIE6 || !this.text){
28955 this.el[disabled ? 'addClass' : 'removeClass'](this.disabledClass);
28957 this.el.dom.disabled = disabled;
28959 this.disabled = disabled;
28963 showMenu : function(){
28964 if(this.rendered && this.menu){
28966 Ext.QuickTips.getQuickTip().cancelShow(this.btnEl);
28968 if(this.menu.isVisible()){
28971 this.menu.ownerCt = this;
28972 this.menu.show(this.el, this.menuAlign);
28978 hideMenu : function(){
28979 if(this.hasVisibleMenu()){
28986 hasVisibleMenu : function(){
28987 return this.menu && this.menu.ownerCt == this && this.menu.isVisible();
28991 onClick : function(e){
28993 e.preventDefault();
28995 if(e.button !== 0){
28998 if(!this.disabled){
28999 if(this.enableToggle && (this.allowDepress !== false || !this.pressed)){
29002 if(this.menu && !this.hasVisibleMenu() && !this.ignoreNextClick){
29005 this.fireEvent('click', this, e);
29008 this.handler.call(this.scope || this, this, e);
29014 isMenuTriggerOver : function(e, internal){
29015 return this.menu && !internal;
29019 isMenuTriggerOut : function(e, internal){
29020 return this.menu && !internal;
29024 onMouseOver : function(e){
29025 if(!this.disabled){
29026 var internal = e.within(this.el, true);
29028 this.el.addClass('x-btn-over');
29029 if(!this.monitoringMouseOver){
29030 this.doc.on('mouseover', this.monitorMouseOver, this);
29031 this.monitoringMouseOver = true;
29033 this.fireEvent('mouseover', this, e);
29035 if(this.isMenuTriggerOver(e, internal)){
29036 this.fireEvent('menutriggerover', this, this.menu, e);
29042 monitorMouseOver : function(e){
29043 if(e.target != this.el.dom && !e.within(this.el)){
29044 if(this.monitoringMouseOver){
29045 this.doc.un('mouseover', this.monitorMouseOver, this);
29046 this.monitoringMouseOver = false;
29048 this.onMouseOut(e);
29053 onMouseOut : function(e){
29054 var internal = e.within(this.el) && e.target != this.el.dom;
29055 this.el.removeClass('x-btn-over');
29056 this.fireEvent('mouseout', this, e);
29057 if(this.isMenuTriggerOut(e, internal)){
29058 this.fireEvent('menutriggerout', this, this.menu, e);
29062 focus : function() {
29063 this.btnEl.focus();
29066 blur : function() {
29071 onFocus : function(e){
29072 if(!this.disabled){
29073 this.el.addClass('x-btn-focus');
29077 onBlur : function(e){
29078 this.el.removeClass('x-btn-focus');
29082 getClickEl : function(e, isUp){
29087 onMouseDown : function(e){
29088 if(!this.disabled && e.button === 0){
29089 this.getClickEl(e).addClass('x-btn-click');
29090 this.doc.on('mouseup', this.onMouseUp, this);
29094 onMouseUp : function(e){
29095 if(e.button === 0){
29096 this.getClickEl(e, true).removeClass('x-btn-click');
29097 this.doc.un('mouseup', this.onMouseUp, this);
29101 onMenuShow : function(e){
29102 if(this.menu.ownerCt == this){
29103 this.menu.ownerCt = this;
29104 this.ignoreNextClick = 0;
29105 this.el.addClass('x-btn-menu-active');
29106 this.fireEvent('menushow', this, this.menu);
29110 onMenuHide : function(e){
29111 if(this.menu.ownerCt == this){
29112 this.el.removeClass('x-btn-menu-active');
29113 this.ignoreNextClick = this.restoreClick.defer(250, this);
29114 this.fireEvent('menuhide', this, this.menu);
29115 delete this.menu.ownerCt;
29120 restoreClick : function(){
29121 this.ignoreNextClick = 0;
29131 Ext.reg('button', Ext.Button);
29134 Ext.ButtonToggleMgr = function(){
29137 function toggleGroup(btn, state){
29139 var g = groups[btn.toggleGroup];
29140 for(var i = 0, l = g.length; i < l; i++){
29142 g[i].toggle(false);
29149 register : function(btn){
29150 if(!btn.toggleGroup){
29153 var g = groups[btn.toggleGroup];
29155 g = groups[btn.toggleGroup] = [];
29158 btn.on('toggle', toggleGroup);
29161 unregister : function(btn){
29162 if(!btn.toggleGroup){
29165 var g = groups[btn.toggleGroup];
29168 btn.un('toggle', toggleGroup);
29173 getPressed : function(group){
29174 var g = groups[group];
29176 for(var i = 0, len = g.length; i < len; i++){
29177 if(g[i].pressed === true){
29187 Ext.SplitButton = Ext.extend(Ext.Button, {
29189 arrowSelector : 'em',
29193 initComponent : function(){
29194 Ext.SplitButton.superclass.initComponent.call(this);
29196 this.addEvents("arrowclick");
29200 onRender : function(){
29201 Ext.SplitButton.superclass.onRender.apply(this, arguments);
29202 if(this.arrowTooltip){
29203 this.el.child(this.arrowSelector).dom[this.tooltipType] = this.arrowTooltip;
29208 setArrowHandler : function(handler, scope){
29209 this.arrowHandler = handler;
29210 this.scope = scope;
29213 getMenuClass : function(){
29214 return 'x-btn-split' + (this.arrowAlign == 'bottom' ? '-bottom' : '');
29217 isClickOnArrow : function(e){
29218 if (this.arrowAlign != 'bottom') {
29219 var visBtn = this.el.child('em.x-btn-split');
29220 var right = visBtn.getRegion().right - visBtn.getPadding('r');
29221 return e.getPageX() > right;
29223 return e.getPageY() > this.btnEl.getRegion().bottom;
29228 onClick : function(e, t){
29229 e.preventDefault();
29230 if(!this.disabled){
29231 if(this.isClickOnArrow(e)){
29232 if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
29235 this.fireEvent("arrowclick", this, e);
29236 if(this.arrowHandler){
29237 this.arrowHandler.call(this.scope || this, this, e);
29240 if(this.enableToggle){
29243 this.fireEvent("click", this, e);
29245 this.handler.call(this.scope || this, this, e);
29252 isMenuTriggerOver : function(e){
29253 return this.menu && e.target.tagName == this.arrowSelector;
29257 isMenuTriggerOut : function(e, internal){
29258 return this.menu && e.target.tagName != this.arrowSelector;
29262 Ext.reg('splitbutton', Ext.SplitButton);
29263 Ext.CycleButton = Ext.extend(Ext.SplitButton, {
29272 getItemText : function(item){
29273 if(item && this.showText === true){
29275 if(this.prependText){
29276 text += this.prependText;
29285 setActiveItem : function(item, suppressEvent){
29286 if(!Ext.isObject(item)){
29287 item = this.menu.getComponent(item);
29290 if(!this.rendered){
29291 this.text = this.getItemText(item);
29292 this.iconCls = item.iconCls;
29294 var t = this.getItemText(item);
29298 this.setIconClass(item.iconCls);
29300 this.activeItem = item;
29302 item.setChecked(true, false);
29304 if(this.forceIcon){
29305 this.setIconClass(this.forceIcon);
29307 if(!suppressEvent){
29308 this.fireEvent('change', this, item);
29314 getActiveItem : function(){
29315 return this.activeItem;
29319 initComponent : function(){
29325 if(this.changeHandler){
29326 this.on('change', this.changeHandler, this.scope||this);
29327 delete this.changeHandler;
29330 this.itemCount = this.items.length;
29332 this.menu = {cls:'x-cycle-menu', items:[]};
29334 Ext.each(this.items, function(item, i){
29336 group: item.group || this.id,
29338 checkHandler: this.checkHandler,
29340 checked: item.checked || false
29342 this.menu.items.push(item);
29347 Ext.CycleButton.superclass.initComponent.call(this);
29348 this.on('click', this.toggleSelected, this);
29349 this.setActiveItem(checked, true);
29353 checkHandler : function(item, pressed){
29355 this.setActiveItem(item);
29360 toggleSelected : function(){
29368 var nextIdx, checkItem;
29369 for (var i = 1; i < this.itemCount; i++) {
29370 nextIdx = (this.activeItem.itemIndex + i) % this.itemCount;
29372 checkItem = m.items.itemAt(nextIdx);
29374 if (!checkItem.disabled) {
29375 checkItem.setChecked(true);
29381 Ext.reg('cycle', Ext.CycleButton);
29382 Ext.Toolbar = function(config){
29383 if(Ext.isArray(config)){
29384 config = {items: config, layout: 'toolbar'};
29386 config = Ext.apply({
29389 if(config.buttons) {
29390 config.items = config.buttons;
29393 Ext.Toolbar.superclass.constructor.call(this, config);
29398 var T = Ext.Toolbar;
29400 Ext.extend(T, Ext.Container, {
29402 defaultType: 'button',
29406 enableOverflow : false,
29412 internalDefaults: {removeMode: 'container', hideParent: true},
29413 toolbarCls: 'x-toolbar',
29415 initComponent : function(){
29416 T.superclass.initComponent.call(this);
29419 this.addEvents('overflowchange');
29423 onRender : function(ct, position){
29425 if(!this.autoCreate){
29426 this.autoCreate = {
29427 cls: this.toolbarCls + ' x-small-editor'
29430 this.el = ct.createChild(Ext.apply({ id: this.id },this.autoCreate), position);
29431 Ext.Toolbar.superclass.onRender.apply(this, arguments);
29438 lookupComponent : function(c){
29439 if(Ext.isString(c)){
29441 c = new T.Separator();
29442 }else if(c == ' '){
29443 c = new T.Spacer();
29444 }else if(c == '->'){
29447 c = new T.TextItem(c);
29449 this.applyDefaults(c);
29451 if(c.isFormField || c.render){
29452 c = this.createComponent(c);
29454 c = new T.Item({autoEl: c});
29455 }else if(c.tagName){
29456 c = new T.Item({el:c});
29457 }else if(Ext.isObject(c)){
29458 c = c.xtype ? this.createComponent(c) : this.constructButton(c);
29465 applyDefaults : function(c){
29466 if(!Ext.isString(c)){
29467 c = Ext.Toolbar.superclass.applyDefaults.call(this, c);
29468 var d = this.internalDefaults;
29470 Ext.applyIf(c.initialConfig, d);
29480 addSeparator : function(){
29481 return this.add(new T.Separator());
29485 addSpacer : function(){
29486 return this.add(new T.Spacer());
29490 addFill : function(){
29491 this.add(new T.Fill());
29495 addElement : function(el){
29496 return this.addItem(new T.Item({el:el}));
29500 addItem : function(item){
29501 return this.add.apply(this, arguments);
29505 addButton : function(config){
29506 if(Ext.isArray(config)){
29508 for(var i = 0, len = config.length; i < len; i++) {
29509 buttons.push(this.addButton(config[i]));
29513 return this.add(this.constructButton(config));
29517 addText : function(text){
29518 return this.addItem(new T.TextItem(text));
29522 addDom : function(config){
29523 return this.add(new T.Item({autoEl: config}));
29527 addField : function(field){
29528 return this.add(field);
29532 insertButton : function(index, item){
29533 if(Ext.isArray(item)){
29535 for(var i = 0, len = item.length; i < len; i++) {
29536 buttons.push(this.insertButton(index + i, item[i]));
29540 return Ext.Toolbar.superclass.insert.call(this, index, item);
29544 trackMenu : function(item, remove){
29545 if(this.trackMenus && item.menu){
29546 var method = remove ? 'mun' : 'mon';
29547 this[method](item, 'menutriggerover', this.onButtonTriggerOver, this);
29548 this[method](item, 'menushow', this.onButtonMenuShow, this);
29549 this[method](item, 'menuhide', this.onButtonMenuHide, this);
29554 constructButton : function(item){
29555 var b = item.events ? item : this.createComponent(item, item.split ? 'splitbutton' : this.defaultType);
29560 onAdd : function(c){
29561 Ext.Toolbar.superclass.onAdd.call(this);
29569 onRemove : function(c){
29570 Ext.Toolbar.superclass.onRemove.call(this);
29571 this.trackMenu(c, true);
29575 onDisable : function(){
29576 this.items.each(function(item){
29584 onEnable : function(){
29585 this.items.each(function(item){
29593 onButtonTriggerOver : function(btn){
29594 if(this.activeMenuBtn && this.activeMenuBtn != btn){
29595 this.activeMenuBtn.hideMenu();
29597 this.activeMenuBtn = btn;
29602 onButtonMenuShow : function(btn){
29603 this.activeMenuBtn = btn;
29607 onButtonMenuHide : function(btn){
29608 delete this.activeMenuBtn;
29611 Ext.reg('toolbar', Ext.Toolbar);
29614 T.Item = Ext.extend(Ext.BoxComponent, {
29616 enable:Ext.emptyFn,
29617 disable:Ext.emptyFn,
29621 Ext.reg('tbitem', T.Item);
29624 T.Separator = Ext.extend(T.Item, {
29625 onRender : function(ct, position){
29626 this.el = ct.createChild({tag:'span', cls:'xtb-sep'}, position);
29629 Ext.reg('tbseparator', T.Separator);
29632 T.Spacer = Ext.extend(T.Item, {
29635 onRender : function(ct, position){
29636 this.el = ct.createChild({tag:'div', cls:'xtb-spacer', style: this.width?'width:'+this.width+'px':''}, position);
29639 Ext.reg('tbspacer', T.Spacer);
29642 T.Fill = Ext.extend(T.Item, {
29644 render : Ext.emptyFn,
29647 Ext.reg('tbfill', T.Fill);
29650 T.TextItem = Ext.extend(T.Item, {
29653 constructor: function(config){
29654 T.TextItem.superclass.constructor.call(this, Ext.isString(config) ? {text: config} : config);
29658 onRender : function(ct, position) {
29659 this.autoEl = {cls: 'xtb-text', html: this.text || ''};
29660 T.TextItem.superclass.onRender.call(this, ct, position);
29664 setText : function(t) {
29672 Ext.reg('tbtext', T.TextItem);
29675 T.Button = Ext.extend(Ext.Button, {});
29676 T.SplitButton = Ext.extend(Ext.SplitButton, {});
29677 Ext.reg('tbbutton', T.Button);
29678 Ext.reg('tbsplit', T.SplitButton);
29682 Ext.ButtonGroup = Ext.extend(Ext.Panel, {
29685 baseCls: 'x-btn-group',
29688 defaultType: 'button',
29691 internalDefaults: {removeMode: 'container', hideParent: true},
29693 initComponent : function(){
29694 this.layoutConfig = this.layoutConfig || {};
29695 Ext.applyIf(this.layoutConfig, {
29696 columns : this.columns
29699 this.addClass('x-btn-group-notitle');
29701 this.on('afterlayout', this.onAfterLayout, this);
29702 Ext.ButtonGroup.superclass.initComponent.call(this);
29705 applyDefaults : function(c){
29706 c = Ext.ButtonGroup.superclass.applyDefaults.call(this, c);
29707 var d = this.internalDefaults;
29709 Ext.applyIf(c.initialConfig, d);
29717 onAfterLayout : function(){
29718 var bodyWidth = this.body.getFrameWidth('lr') + this.body.dom.firstChild.offsetWidth;
29719 this.body.setWidth(bodyWidth);
29720 this.el.setWidth(bodyWidth + this.getFrameWidth());
29725 Ext.reg('buttongroup', Ext.ButtonGroup);
29729 var T = Ext.Toolbar;
29731 Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {
29738 displayMsg : 'Displaying {0} - {1} of {2}',
29740 emptyMsg : 'No data to display',
29742 beforePageText : 'Page',
29744 afterPageText : 'of {0}',
29746 firstText : 'First Page',
29748 prevText : 'Previous Page',
29750 nextText : 'Next Page',
29752 lastText : 'Last Page',
29754 refreshText : 'Refresh',
29762 initComponent : function(){
29763 var pagingItems = [this.first = new T.Button({
29764 tooltip: this.firstText,
29765 overflowText: this.firstText,
29766 iconCls: 'x-tbar-page-first',
29768 handler: this.moveFirst,
29770 }), this.prev = new T.Button({
29771 tooltip: this.prevText,
29772 overflowText: this.prevText,
29773 iconCls: 'x-tbar-page-prev',
29775 handler: this.movePrevious,
29777 }), '-', this.beforePageText,
29778 this.inputItem = new Ext.form.NumberField({
29779 cls: 'x-tbar-page-number',
29780 allowDecimals: false,
29781 allowNegative: false,
29782 enableKeyEvents: true,
29783 selectOnFocus: true,
29784 submitValue: false,
29787 keydown: this.onPagingKeyDown,
29788 blur: this.onPagingBlur
29790 }), this.afterTextItem = new T.TextItem({
29791 text: String.format(this.afterPageText, 1)
29792 }), '-', this.next = new T.Button({
29793 tooltip: this.nextText,
29794 overflowText: this.nextText,
29795 iconCls: 'x-tbar-page-next',
29797 handler: this.moveNext,
29799 }), this.last = new T.Button({
29800 tooltip: this.lastText,
29801 overflowText: this.lastText,
29802 iconCls: 'x-tbar-page-last',
29804 handler: this.moveLast,
29806 }), '-', this.refresh = new T.Button({
29807 tooltip: this.refreshText,
29808 overflowText: this.refreshText,
29809 iconCls: 'x-tbar-loading',
29810 handler: this.doRefresh,
29815 var userItems = this.items || this.buttons || [];
29816 if (this.prependButtons) {
29817 this.items = userItems.concat(pagingItems);
29819 this.items = pagingItems.concat(userItems);
29821 delete this.buttons;
29822 if(this.displayInfo){
29823 this.items.push('->');
29824 this.items.push(this.displayItem = new T.TextItem({}));
29826 Ext.PagingToolbar.superclass.initComponent.call(this);
29833 this.on('afterlayout', this.onFirstLayout, this, {single: true});
29835 this.bindStore(this.store, true);
29839 onFirstLayout : function(){
29841 this.onLoad.apply(this, this.dsLoaded);
29846 updateInfo : function(){
29847 if(this.displayItem){
29848 var count = this.store.getCount();
29849 var msg = count == 0 ?
29853 this.cursor+1, this.cursor+count, this.store.getTotalCount()
29855 this.displayItem.setText(msg);
29860 onLoad : function(store, r, o){
29861 if(!this.rendered){
29862 this.dsLoaded = [store, r, o];
29865 var p = this.getParams();
29866 this.cursor = (o.params && o.params[p.start]) ? o.params[p.start] : 0;
29867 var d = this.getPageData(), ap = d.activePage, ps = d.pages;
29869 this.afterTextItem.setText(String.format(this.afterPageText, d.pages));
29870 this.inputItem.setValue(ap);
29871 this.first.setDisabled(ap == 1);
29872 this.prev.setDisabled(ap == 1);
29873 this.next.setDisabled(ap == ps);
29874 this.last.setDisabled(ap == ps);
29875 this.refresh.enable();
29877 this.fireEvent('change', this, d);
29881 getPageData : function(){
29882 var total = this.store.getTotalCount();
29885 activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize),
29886 pages : total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)
29891 changePage : function(page){
29892 this.doLoad(((page-1) * this.pageSize).constrain(0, this.store.getTotalCount()));
29896 onLoadError : function(){
29897 if(!this.rendered){
29900 this.refresh.enable();
29904 readPage : function(d){
29905 var v = this.inputItem.getValue(), pageNum;
29906 if (!v || isNaN(pageNum = parseInt(v, 10))) {
29907 this.inputItem.setValue(d.activePage);
29913 onPagingFocus : function(){
29914 this.inputItem.select();
29918 onPagingBlur : function(e){
29919 this.inputItem.setValue(this.getPageData().activePage);
29923 onPagingKeyDown : function(field, e){
29924 var k = e.getKey(), d = this.getPageData(), pageNum;
29925 if (k == e.RETURN) {
29927 pageNum = this.readPage(d);
29928 if(pageNum !== false){
29929 pageNum = Math.min(Math.max(1, pageNum), d.pages) - 1;
29930 this.doLoad(pageNum * this.pageSize);
29932 }else if (k == e.HOME || k == e.END){
29934 pageNum = k == e.HOME ? 1 : d.pages;
29935 field.setValue(pageNum);
29936 }else if (k == e.UP || k == e.PAGEUP || k == e.DOWN || k == e.PAGEDOWN){
29938 if((pageNum = this.readPage(d))){
29939 var increment = e.shiftKey ? 10 : 1;
29940 if(k == e.DOWN || k == e.PAGEDOWN){
29943 pageNum += increment;
29944 if(pageNum >= 1 & pageNum <= d.pages){
29945 field.setValue(pageNum);
29952 getParams : function(){
29954 return this.paramNames || this.store.paramNames;
29958 beforeLoad : function(){
29959 if(this.rendered && this.refresh){
29960 this.refresh.disable();
29965 doLoad : function(start){
29966 var o = {}, pn = this.getParams();
29967 o[pn.start] = start;
29968 o[pn.limit] = this.pageSize;
29969 if(this.fireEvent('beforechange', this, o) !== false){
29970 this.store.load({params:o});
29975 moveFirst : function(){
29980 movePrevious : function(){
29981 this.doLoad(Math.max(0, this.cursor-this.pageSize));
29985 moveNext : function(){
29986 this.doLoad(this.cursor+this.pageSize);
29990 moveLast : function(){
29991 var total = this.store.getTotalCount(),
29992 extra = total % this.pageSize;
29994 this.doLoad(extra ? (total - extra) : total - this.pageSize);
29998 doRefresh : function(){
29999 this.doLoad(this.cursor);
30003 bindStore : function(store, initial){
30005 if(!initial && this.store){
30006 if(store !== this.store && this.store.autoDestroy){
30007 this.store.destroy();
30009 this.store.un('beforeload', this.beforeLoad, this);
30010 this.store.un('load', this.onLoad, this);
30011 this.store.un('exception', this.onLoadError, this);
30018 store = Ext.StoreMgr.lookup(store);
30021 beforeload: this.beforeLoad,
30023 exception: this.onLoadError
30027 this.store = store;
30029 this.onLoad(store, null, {});
30034 unbind : function(store){
30035 this.bindStore(null);
30039 bind : function(store){
30040 this.bindStore(store);
30044 onDestroy : function(){
30045 this.bindStore(null);
30046 Ext.PagingToolbar.superclass.onDestroy.call(this);
30051 Ext.reg('paging', Ext.PagingToolbar);
30052 Ext.History = (function () {
30053 var iframe, hiddenField;
30057 function getHash() {
30058 var href = top.location.href, i = href.indexOf("#");
30059 return i >= 0 ? href.substr(i + 1) : null;
30062 function doSave() {
30063 hiddenField.value = currentToken;
30066 function handleStateChange(token) {
30067 currentToken = token;
30068 Ext.History.fireEvent('change', token);
30071 function updateIFrame (token) {
30072 var html = ['<html><body><div id="state">',Ext.util.Format.htmlEncode(token),'</div></body></html>'].join('');
30074 var doc = iframe.contentWindow.document;
30084 function checkIFrame() {
30085 if (!iframe.contentWindow || !iframe.contentWindow.document) {
30086 setTimeout(checkIFrame, 10);
30090 var doc = iframe.contentWindow.document;
30091 var elem = doc.getElementById("state");
30092 var token = elem ? elem.innerText : null;
30094 var hash = getHash();
30096 setInterval(function () {
30098 doc = iframe.contentWindow.document;
30099 elem = doc.getElementById("state");
30101 var newtoken = elem ? elem.innerText : null;
30103 var newHash = getHash();
30105 if (newtoken !== token) {
30107 handleStateChange(token);
30108 top.location.hash = token;
30111 } else if (newHash !== hash) {
30113 updateIFrame(newHash);
30120 Ext.History.fireEvent('ready', Ext.History);
30123 function startUp() {
30124 currentToken = hiddenField.value ? hiddenField.value : getHash();
30129 var hash = getHash();
30130 setInterval(function () {
30131 var newHash = getHash();
30132 if (newHash !== hash) {
30134 handleStateChange(hash);
30139 Ext.History.fireEvent('ready', Ext.History);
30145 fieldId: 'x-history-field',
30147 iframeId: 'x-history-frame',
30152 init: function (onReady, scope) {
30154 Ext.callback(onReady, scope, [this]);
30158 Ext.onReady(function(){
30159 Ext.History.init(onReady, scope);
30163 hiddenField = Ext.getDom(Ext.History.fieldId);
30165 iframe = Ext.getDom(Ext.History.iframeId);
30174 this.on('ready', onReady, scope, {single:true});
30180 add: function (token, preventDup) {
30181 if(preventDup !== false){
30182 if(this.getToken() == token){
30187 return updateIFrame(token);
30189 top.location.hash = token;
30200 forward: function(){
30205 getToken: function() {
30206 return ready ? currentToken : getHash();
30210 Ext.apply(Ext.History, new Ext.util.Observable());
30211 Ext.Tip = Ext.extend(Ext.Panel, {
30221 defaultAlign : "tl-bl?",
30223 quickShowInterval : 250,
30229 floating:{shadow:true,shim:true,useDisplay:true,constrain:false},
30232 closeAction: 'hide',
30235 initComponent : function(){
30236 Ext.Tip.superclass.initComponent.call(this);
30237 if(this.closable && !this.title){
30238 this.elements += ',header';
30243 afterRender : function(){
30244 Ext.Tip.superclass.afterRender.call(this);
30248 handler: this[this.closeAction],
30255 showAt : function(xy){
30256 Ext.Tip.superclass.show.call(this);
30257 if(this.measureWidth !== false && (!this.initialConfig || typeof this.initialConfig.width != 'number')){
30258 this.doAutoWidth();
30260 if(this.constrainPosition){
30261 xy = this.el.adjustForConstraints(xy);
30263 this.setPagePosition(xy[0], xy[1]);
30267 doAutoWidth : function(adjust){
30268 adjust = adjust || 0;
30269 var bw = this.body.getTextWidth();
30271 bw = Math.max(bw, this.header.child('span').getTextWidth(this.title));
30273 bw += this.getFrameWidth() + (this.closable ? 20 : 0) + this.body.getPadding("lr") + adjust;
30274 this.setWidth(bw.constrain(this.minWidth, this.maxWidth));
30277 if(Ext.isIE7 && !this.repainted){
30279 this.repainted = true;
30284 showBy : function(el, pos){
30285 if(!this.rendered){
30286 this.render(Ext.getBody());
30288 this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign));
30291 initDraggable : function(){
30292 this.dd = new Ext.Tip.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);
30293 this.header.addClass('x-tip-draggable');
30297 Ext.reg('tip', Ext.Tip);
30300 Ext.Tip.DD = function(tip, config){
30301 Ext.apply(this, config);
30303 Ext.Tip.DD.superclass.constructor.call(this, tip.el.id, 'WindowDD-'+tip.id);
30304 this.setHandleElId(tip.header.id);
30305 this.scroll = false;
30308 Ext.extend(Ext.Tip.DD, Ext.dd.DD, {
30311 headerOffsets:[100, 25],
30312 startDrag : function(){
30313 this.tip.el.disableShadow();
30315 endDrag : function(e){
30316 this.tip.el.enableShadow(true);
30319 Ext.ToolTip = Ext.extend(Ext.Tip, {
30328 dismissDelay : 5000,
30331 trackMouse : false,
30333 anchorToTarget : true,
30341 constrainPosition : false,
30344 initComponent : function(){
30345 Ext.ToolTip.superclass.initComponent.call(this);
30346 this.lastActive = new Date();
30347 this.initTarget(this.target);
30348 this.origAnchor = this.anchor;
30352 onRender : function(ct, position){
30353 Ext.ToolTip.superclass.onRender.call(this, ct, position);
30354 this.anchorCls = 'x-tip-anchor-' + this.getAnchorPosition();
30355 this.anchorEl = this.el.createChild({
30356 cls: 'x-tip-anchor ' + this.anchorCls
30361 afterRender : function(){
30362 Ext.ToolTip.superclass.afterRender.call(this);
30363 this.anchorEl.setStyle('z-index', this.el.getZIndex() + 1);
30367 initTarget : function(target){
30369 if((t = Ext.get(target))){
30371 var tg = Ext.get(this.target);
30372 this.mun(tg, 'mouseover', this.onTargetOver, this);
30373 this.mun(tg, 'mouseout', this.onTargetOut, this);
30374 this.mun(tg, 'mousemove', this.onMouseMove, this);
30377 mouseover: this.onTargetOver,
30378 mouseout: this.onTargetOut,
30379 mousemove: this.onMouseMove,
30385 this.anchorTarget = this.target;
30390 onMouseMove : function(e){
30391 var t = this.delegate ? e.getTarget(this.delegate) : this.triggerElement = true;
30393 this.targetXY = e.getXY();
30394 if (t === this.triggerElement) {
30395 if(!this.hidden && this.trackMouse){
30396 this.setPagePosition(this.getTargetXY());
30400 this.lastActive = new Date(0);
30401 this.onTargetOver(e);
30403 } else if (!this.closable && this.isVisible()) {
30409 getTargetXY : function(){
30411 this.anchorTarget = this.triggerElement;
30414 this.targetCounter++;
30415 var offsets = this.getOffsets(),
30416 xy = (this.anchorToTarget && !this.trackMouse) ? this.el.getAlignToXY(this.anchorTarget, this.getAnchorAlign()) : this.targetXY,
30417 dw = Ext.lib.Dom.getViewWidth() - 5,
30418 dh = Ext.lib.Dom.getViewHeight() - 5,
30419 de = document.documentElement,
30420 bd = document.body,
30421 scrollX = (de.scrollLeft || bd.scrollLeft || 0) + 5,
30422 scrollY = (de.scrollTop || bd.scrollTop || 0) + 5,
30423 axy = [xy[0] + offsets[0], xy[1] + offsets[1]],
30424 sz = this.getSize();
30426 this.anchorEl.removeClass(this.anchorCls);
30428 if(this.targetCounter < 2){
30429 if(axy[0] < scrollX){
30430 if(this.anchorToTarget){
30431 this.defaultAlign = 'l-r';
30432 if(this.mouseOffset){this.mouseOffset[0] *= -1;}
30434 this.anchor = 'left';
30435 return this.getTargetXY();
30437 if(axy[0]+sz.width > dw){
30438 if(this.anchorToTarget){
30439 this.defaultAlign = 'r-l';
30440 if(this.mouseOffset){this.mouseOffset[0] *= -1;}
30442 this.anchor = 'right';
30443 return this.getTargetXY();
30445 if(axy[1] < scrollY){
30446 if(this.anchorToTarget){
30447 this.defaultAlign = 't-b';
30448 if(this.mouseOffset){this.mouseOffset[1] *= -1;}
30450 this.anchor = 'top';
30451 return this.getTargetXY();
30453 if(axy[1]+sz.height > dh){
30454 if(this.anchorToTarget){
30455 this.defaultAlign = 'b-t';
30456 if(this.mouseOffset){this.mouseOffset[1] *= -1;}
30458 this.anchor = 'bottom';
30459 return this.getTargetXY();
30463 this.anchorCls = 'x-tip-anchor-'+this.getAnchorPosition();
30464 this.anchorEl.addClass(this.anchorCls);
30465 this.targetCounter = 0;
30468 var mouseOffset = this.getMouseOffset();
30469 return [this.targetXY[0]+mouseOffset[0], this.targetXY[1]+mouseOffset[1]];
30473 getMouseOffset : function(){
30474 var offset = this.anchor ? [0,0] : [15,18];
30475 if(this.mouseOffset){
30476 offset[0] += this.mouseOffset[0];
30477 offset[1] += this.mouseOffset[1];
30483 getAnchorPosition : function(){
30485 this.tipAnchor = this.anchor.charAt(0);
30487 var m = this.defaultAlign.match(/^([a-z]+)-([a-z]+)(\?)?$/);
30489 throw 'AnchorTip.defaultAlign is invalid';
30491 this.tipAnchor = m[1].charAt(0);
30494 switch(this.tipAnchor){
30495 case 't': return 'top';
30496 case 'b': return 'bottom';
30497 case 'r': return 'right';
30503 getAnchorAlign : function(){
30504 switch(this.anchor){
30505 case 'top' : return 'tl-bl';
30506 case 'left' : return 'tl-tr';
30507 case 'right': return 'tr-tl';
30508 default : return 'bl-tl';
30513 getOffsets : function(){
30515 ap = this.getAnchorPosition().charAt(0);
30516 if(this.anchorToTarget && !this.trackMouse){
30522 offsets = [0, -13];
30525 offsets = [-13, 0];
30534 offsets = [-15-this.anchorOffset, 30];
30537 offsets = [-19-this.anchorOffset, -13-this.el.dom.offsetHeight];
30540 offsets = [-15-this.el.dom.offsetWidth, -13-this.anchorOffset];
30543 offsets = [25, -13-this.anchorOffset];
30547 var mouseOffset = this.getMouseOffset();
30548 offsets[0] += mouseOffset[0];
30549 offsets[1] += mouseOffset[1];
30555 onTargetOver : function(e){
30556 if(this.disabled || e.within(this.target.dom, true)){
30559 var t = e.getTarget(this.delegate);
30561 this.triggerElement = t;
30562 this.clearTimer('hide');
30563 this.targetXY = e.getXY();
30569 delayShow : function(){
30570 if(this.hidden && !this.showTimer){
30571 if(this.lastActive.getElapsed() < this.quickShowInterval){
30574 this.showTimer = this.show.defer(this.showDelay, this);
30576 }else if(!this.hidden && this.autoHide !== false){
30582 onTargetOut : function(e){
30583 if(this.disabled || e.within(this.target.dom, true)){
30586 this.clearTimer('show');
30587 if(this.autoHide !== false){
30593 delayHide : function(){
30594 if(!this.hidden && !this.hideTimer){
30595 this.hideTimer = this.hide.defer(this.hideDelay, this);
30601 this.clearTimer('dismiss');
30602 this.lastActive = new Date();
30604 this.anchorEl.hide();
30606 Ext.ToolTip.superclass.hide.call(this);
30607 delete this.triggerElement;
30615 this.showAt([-1000,-1000]);
30616 this.origConstrainPosition = this.constrainPosition;
30617 this.constrainPosition = false;
30618 this.anchor = this.origAnchor;
30620 this.showAt(this.getTargetXY());
30624 this.anchorEl.show();
30625 this.constrainPosition = this.origConstrainPosition;
30627 this.anchorEl.hide();
30632 showAt : function(xy){
30633 this.lastActive = new Date();
30634 this.clearTimers();
30635 Ext.ToolTip.superclass.showAt.call(this, xy);
30636 if(this.dismissDelay && this.autoHide !== false){
30637 this.dismissTimer = this.hide.defer(this.dismissDelay, this);
30639 if(this.anchor && !this.anchorEl.isVisible()){
30641 this.anchorEl.show();
30646 syncAnchor : function(){
30647 var anchorPos, targetPos, offset;
30648 switch(this.tipAnchor.charAt(0)){
30652 offset = [20+this.anchorOffset, 2];
30657 offset = [-2, 11+this.anchorOffset];
30662 offset = [20+this.anchorOffset, -2];
30667 offset = [2, 11+this.anchorOffset];
30670 this.anchorEl.alignTo(this.el, anchorPos+'-'+targetPos, offset);
30674 setPagePosition : function(x, y){
30675 Ext.ToolTip.superclass.setPagePosition.call(this, x, y);
30682 clearTimer : function(name){
30683 name = name + 'Timer';
30684 clearTimeout(this[name]);
30689 clearTimers : function(){
30690 this.clearTimer('show');
30691 this.clearTimer('dismiss');
30692 this.clearTimer('hide');
30696 onShow : function(){
30697 Ext.ToolTip.superclass.onShow.call(this);
30698 Ext.getDoc().on('mousedown', this.onDocMouseDown, this);
30702 onHide : function(){
30703 Ext.ToolTip.superclass.onHide.call(this);
30704 Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
30708 onDocMouseDown : function(e){
30709 if(this.autoHide !== true && !this.closable && !e.within(this.el.dom)){
30711 this.doEnable.defer(100, this);
30716 doEnable : function(){
30717 if(!this.isDestroyed){
30723 onDisable : function(){
30724 this.clearTimers();
30729 adjustPosition : function(x, y){
30730 if(this.contstrainPosition){
30731 var ay = this.targetXY[1], h = this.getSize().height;
30732 if(y <= ay && (y+h) >= ay){
30736 return {x : x, y: y};
30739 beforeDestroy : function(){
30740 this.clearTimers();
30741 Ext.destroy(this.anchorEl);
30742 delete this.anchorEl;
30743 delete this.target;
30744 delete this.anchorTarget;
30745 delete this.triggerElement;
30746 Ext.ToolTip.superclass.beforeDestroy.call(this);
30750 onDestroy : function(){
30751 Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
30752 Ext.ToolTip.superclass.onDestroy.call(this);
30756 Ext.reg('tooltip', Ext.ToolTip);
30757 Ext.QuickTip = Ext.extend(Ext.ToolTip, {
30760 interceptTitles : false,
30765 attribute : "qtip",
30776 initComponent : function(){
30777 this.target = this.target || Ext.getDoc();
30778 this.targets = this.targets || {};
30779 Ext.QuickTip.superclass.initComponent.call(this);
30783 register : function(config){
30784 var cs = Ext.isArray(config) ? config : arguments;
30785 for(var i = 0, len = cs.length; i < len; i++){
30787 var target = c.target;
30789 if(Ext.isArray(target)){
30790 for(var j = 0, jlen = target.length; j < jlen; j++){
30791 this.targets[Ext.id(target[j])] = c;
30794 this.targets[Ext.id(target)] = c;
30801 unregister : function(el){
30802 delete this.targets[Ext.id(el)];
30806 cancelShow: function(el){
30807 var at = this.activeTarget;
30808 el = Ext.get(el).dom;
30809 if(this.isVisible()){
30810 if(at && at.el == el){
30813 }else if(at && at.el == el){
30814 this.clearTimer('show');
30818 getTipCfg: function(e) {
30819 var t = e.getTarget(),
30822 if(this.interceptTitles && t.title && Ext.isString(t.title)){
30825 t.removeAttribute("title");
30826 e.preventDefault();
30828 cfg = this.tagConfig;
30829 ttp = t.qtip || Ext.fly(t).getAttribute(cfg.attribute, cfg.namespace);
30835 onTargetOver : function(e){
30839 this.targetXY = e.getXY();
30840 var t = e.getTarget();
30841 if(!t || t.nodeType !== 1 || t == document || t == document.body){
30844 if(this.activeTarget && ((t == this.activeTarget.el) || Ext.fly(this.activeTarget.el).contains(t))){
30845 this.clearTimer('hide');
30849 if(t && this.targets[t.id]){
30850 this.activeTarget = this.targets[t.id];
30851 this.activeTarget.el = t;
30852 this.anchor = this.activeTarget.anchor;
30854 this.anchorTarget = t;
30859 var ttp, et = Ext.fly(t), cfg = this.tagConfig, ns = cfg.namespace;
30860 if(ttp = this.getTipCfg(e)){
30861 var autoHide = et.getAttribute(cfg.hide, ns);
30862 this.activeTarget = {
30865 width: et.getAttribute(cfg.width, ns),
30866 autoHide: autoHide != "user" && autoHide !== 'false',
30867 title: et.getAttribute(cfg.title, ns),
30868 cls: et.getAttribute(cfg.cls, ns),
30869 align: et.getAttribute(cfg.align, ns)
30872 this.anchor = et.getAttribute(cfg.anchor, ns);
30874 this.anchorTarget = t;
30881 onTargetOut : function(e){
30884 if (this.activeTarget && e.within(this.activeTarget.el) && !this.getTipCfg(e)) {
30888 this.clearTimer('show');
30889 if(this.autoHide !== false){
30895 showAt : function(xy){
30896 var t = this.activeTarget;
30898 if(!this.rendered){
30899 this.render(Ext.getBody());
30900 this.activeTarget = t;
30903 this.setWidth(t.width);
30904 this.body.setWidth(this.adjustBodyWidth(t.width - this.getFrameWidth()));
30905 this.measureWidth = false;
30907 this.measureWidth = true;
30909 this.setTitle(t.title || '');
30910 this.body.update(t.text);
30911 this.autoHide = t.autoHide;
30912 this.dismissDelay = t.dismissDelay || this.dismissDelay;
30914 this.el.removeClass(this.lastCls);
30915 delete this.lastCls;
30918 this.el.addClass(t.cls);
30919 this.lastCls = t.cls;
30922 this.constrainPosition = false;
30924 xy = this.el.getAlignToXY(t.el, t.align);
30925 this.constrainPosition = false;
30927 this.constrainPosition = true;
30930 Ext.QuickTip.superclass.showAt.call(this, xy);
30935 delete this.activeTarget;
30936 Ext.QuickTip.superclass.hide.call(this);
30939 Ext.reg('quicktip', Ext.QuickTip);
30940 Ext.QuickTips = function(){
30941 var tip, locks = [];
30944 init : function(autoRender){
30947 Ext.onReady(function(){
30948 Ext.QuickTips.init(autoRender);
30952 tip = new Ext.QuickTip({elements:'header,body'});
30953 if(autoRender !== false){
30954 tip.render(Ext.getBody());
30960 enable : function(){
30963 if(locks.length < 1){
30970 disable : function(){
30978 isEnabled : function(){
30979 return tip !== undefined && !tip.disabled;
30983 getQuickTip : function(){
30988 register : function(){
30989 tip.register.apply(tip, arguments);
30993 unregister : function(){
30994 tip.unregister.apply(tip, arguments);
30999 tip.register.apply(tip, arguments);
31003 Ext.slider.Tip = Ext.extend(Ext.Tip, {
31005 offsets : [0, -10],
31007 init: function(slider) {
31010 dragstart: this.onSlide,
31011 drag : this.onSlide,
31012 dragend : this.hide,
31013 destroy : this.destroy
31018 onSlide : function(slider, e, thumb) {
31020 this.body.update(this.getText(thumb));
31021 this.doAutoWidth();
31022 this.el.alignTo(thumb.el, 'b-t?', this.offsets);
31026 getText : function(thumb) {
31027 return String(thumb.value);
31032 Ext.ux.SliderTip = Ext.slider.Tip;
31033 Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
31034 rootVisible : true,
31035 animate : Ext.enableFx,
31038 hlDrop : Ext.enableFx,
31039 pathSeparator : '/',
31044 initComponent : function(){
31045 Ext.tree.TreePanel.superclass.initComponent.call(this);
31047 if(!this.eventModel){
31048 this.eventModel = new Ext.tree.TreeEventModel(this);
31052 var l = this.loader;
31054 l = new Ext.tree.TreeLoader({
31055 dataUrl: this.dataUrl,
31056 requestMethod: this.requestMethod
31058 }else if(Ext.isObject(l) && !l.load){
31059 l = new Ext.tree.TreeLoader(l);
31063 this.nodeHash = {};
31069 this.setRootNode(r);
31099 'beforeexpandnode',
31101 'beforecollapsenode',
31121 'containerdblclick',
31125 'containercontextmenu',
31127 'beforechildrenrendered',
31141 if(this.singleExpand){
31142 this.on('beforeexpandnode', this.restrictExpand, this);
31147 proxyNodeEvent : function(ename, a1, a2, a3, a4, a5, a6){
31148 if(ename == 'collapse' || ename == 'expand' || ename == 'beforecollapse' || ename == 'beforeexpand' || ename == 'move' || ename == 'beforemove'){
31149 ename = ename+'node';
31152 return this.fireEvent(ename, a1, a2, a3, a4, a5, a6);
31157 getRootNode : function(){
31162 setRootNode : function(node){
31163 this.destroyRoot();
31165 node = this.loader.createNode(node);
31168 node.ownerTree = this;
31169 node.isRoot = true;
31170 this.registerNode(node);
31171 if(!this.rootVisible){
31172 var uiP = node.attributes.uiProvider;
31173 node.ui = uiP ? new uiP(node) : new Ext.tree.RootTreeNodeUI(node);
31176 this.clearInnerCt();
31182 clearInnerCt : function(){
31183 this.innerCt.update('');
31187 renderRoot : function(){
31188 this.root.render();
31189 if(!this.rootVisible){
31190 this.root.renderChildren();
31195 getNodeById : function(id){
31196 return this.nodeHash[id];
31200 registerNode : function(node){
31201 this.nodeHash[node.id] = node;
31205 unregisterNode : function(node){
31206 delete this.nodeHash[node.id];
31210 toString : function(){
31211 return '[Tree'+(this.id?' '+this.id:'')+']';
31215 restrictExpand : function(node){
31216 var p = node.parentNode;
31218 if(p.expandedChild && p.expandedChild.parentNode == p){
31219 p.expandedChild.collapse();
31221 p.expandedChild = node;
31226 getChecked : function(a, startNode){
31227 startNode = startNode || this.root;
31229 var f = function(){
31230 if(this.attributes.checked){
31231 r.push(!a ? this : (a == 'id' ? this.id : this.attributes[a]));
31234 startNode.cascade(f);
31239 getLoader : function(){
31240 return this.loader;
31244 expandAll : function(){
31245 this.root.expand(true);
31249 collapseAll : function(){
31250 this.root.collapse(true);
31254 getSelectionModel : function(){
31255 if(!this.selModel){
31256 this.selModel = new Ext.tree.DefaultSelectionModel();
31258 return this.selModel;
31262 expandPath : function(path, attr, callback){
31263 attr = attr || 'id';
31264 var keys = path.split(this.pathSeparator);
31265 var curNode = this.root;
31266 if(curNode.attributes[attr] != keys[1]){
31268 callback(false, null);
31273 var f = function(){
31274 if(++index == keys.length){
31276 callback(true, curNode);
31280 var c = curNode.findChild(attr, keys[index]);
31283 callback(false, curNode);
31288 c.expand(false, false, f);
31290 curNode.expand(false, false, f);
31294 selectPath : function(path, attr, callback){
31295 attr = attr || 'id';
31296 var keys = path.split(this.pathSeparator),
31298 if(keys.length > 1){
31299 var f = function(success, node){
31300 if(success && node){
31301 var n = node.findChild(attr, v);
31307 }else if(callback){
31308 callback(false, n);
31312 callback(false, n);
31316 this.expandPath(keys.join(this.pathSeparator), attr, f);
31318 this.root.select();
31320 callback(true, this.root);
31326 getTreeEl : function(){
31331 onRender : function(ct, position){
31332 Ext.tree.TreePanel.superclass.onRender.call(this, ct, position);
31333 this.el.addClass('x-tree');
31334 this.innerCt = this.body.createChild({tag:'ul',
31335 cls:'x-tree-root-ct ' +
31336 (this.useArrows ? 'x-tree-arrows' : this.lines ? 'x-tree-lines' : 'x-tree-no-lines')});
31340 initEvents : function(){
31341 Ext.tree.TreePanel.superclass.initEvents.call(this);
31343 if(this.containerScroll){
31344 Ext.dd.ScrollManager.register(this.body);
31346 if((this.enableDD || this.enableDrop) && !this.dropZone){
31348 this.dropZone = new Ext.tree.TreeDropZone(this, this.dropConfig || {
31349 ddGroup: this.ddGroup || 'TreeDD', appendOnly: this.ddAppendOnly === true
31352 if((this.enableDD || this.enableDrag) && !this.dragZone){
31354 this.dragZone = new Ext.tree.TreeDragZone(this, this.dragConfig || {
31355 ddGroup: this.ddGroup || 'TreeDD',
31356 scroll: this.ddScroll
31359 this.getSelectionModel().init(this);
31363 afterRender : function(){
31364 Ext.tree.TreePanel.superclass.afterRender.call(this);
31368 beforeDestroy : function(){
31370 Ext.dd.ScrollManager.unregister(this.body);
31371 Ext.destroy(this.dropZone, this.dragZone);
31373 this.destroyRoot();
31374 Ext.destroy(this.loader);
31375 this.nodeHash = this.root = this.loader = null;
31376 Ext.tree.TreePanel.superclass.beforeDestroy.call(this);
31380 destroyRoot : function(){
31381 if(this.root && this.root.destroy){
31382 this.root.destroy(true);
31438 Ext.tree.TreePanel.nodeTypes = {};
31440 Ext.reg('treepanel', Ext.tree.TreePanel);Ext.tree.TreeEventModel = function(tree){
31442 this.tree.on('render', this.initEvents, this);
31445 Ext.tree.TreeEventModel.prototype = {
31446 initEvents : function(){
31449 if(t.trackMouseOver !== false){
31452 mouseover: this.delegateOver,
31453 mouseout: this.delegateOut
31456 t.mon(t.getTreeEl(), {
31458 click: this.delegateClick,
31459 dblclick: this.delegateDblClick,
31460 contextmenu: this.delegateContextMenu
31464 getNode : function(e){
31466 if(t = e.getTarget('.x-tree-node-el', 10)){
31467 var id = Ext.fly(t, '_treeEvents').getAttribute('tree-node-id', 'ext');
31469 return this.tree.getNodeById(id);
31475 getNodeTarget : function(e){
31476 var t = e.getTarget('.x-tree-node-icon', 1);
31478 t = e.getTarget('.x-tree-node-el', 6);
31483 delegateOut : function(e, t){
31484 if(!this.beforeEvent(e)){
31487 if(e.getTarget('.x-tree-ec-icon', 1)){
31488 var n = this.getNode(e);
31489 this.onIconOut(e, n);
31490 if(n == this.lastEcOver){
31491 delete this.lastEcOver;
31494 if((t = this.getNodeTarget(e)) && !e.within(t, true)){
31495 this.onNodeOut(e, this.getNode(e));
31499 delegateOver : function(e, t){
31500 if(!this.beforeEvent(e)){
31503 if(Ext.isGecko && !this.trackingDoc){
31504 Ext.getBody().on('mouseover', this.trackExit, this);
31505 this.trackingDoc = true;
31507 if(this.lastEcOver){
31508 this.onIconOut(e, this.lastEcOver);
31509 delete this.lastEcOver;
31511 if(e.getTarget('.x-tree-ec-icon', 1)){
31512 this.lastEcOver = this.getNode(e);
31513 this.onIconOver(e, this.lastEcOver);
31515 if(t = this.getNodeTarget(e)){
31516 this.onNodeOver(e, this.getNode(e));
31520 trackExit : function(e){
31521 if(this.lastOverNode){
31522 if(this.lastOverNode.ui && !e.within(this.lastOverNode.ui.getEl())){
31523 this.onNodeOut(e, this.lastOverNode);
31525 delete this.lastOverNode;
31526 Ext.getBody().un('mouseover', this.trackExit, this);
31527 this.trackingDoc = false;
31532 delegateClick : function(e, t){
31533 if(this.beforeEvent(e)){
31534 if(e.getTarget('input[type=checkbox]', 1)){
31535 this.onCheckboxClick(e, this.getNode(e));
31536 }else if(e.getTarget('.x-tree-ec-icon', 1)){
31537 this.onIconClick(e, this.getNode(e));
31538 }else if(this.getNodeTarget(e)){
31539 this.onNodeClick(e, this.getNode(e));
31542 this.checkContainerEvent(e, 'click');
31546 delegateDblClick : function(e, t){
31547 if(this.beforeEvent(e)){
31548 if(this.getNodeTarget(e)){
31549 this.onNodeDblClick(e, this.getNode(e));
31552 this.checkContainerEvent(e, 'dblclick');
31556 delegateContextMenu : function(e, t){
31557 if(this.beforeEvent(e)){
31558 if(this.getNodeTarget(e)){
31559 this.onNodeContextMenu(e, this.getNode(e));
31562 this.checkContainerEvent(e, 'contextmenu');
31566 checkContainerEvent: function(e, type){
31571 this.onContainerEvent(e, type);
31574 onContainerEvent: function(e, type){
31575 this.tree.fireEvent('container' + type, this.tree, e);
31578 onNodeClick : function(e, node){
31579 node.ui.onClick(e);
31582 onNodeOver : function(e, node){
31583 this.lastOverNode = node;
31587 onNodeOut : function(e, node){
31591 onIconOver : function(e, node){
31592 node.ui.addClass('x-tree-ec-over');
31595 onIconOut : function(e, node){
31596 node.ui.removeClass('x-tree-ec-over');
31599 onIconClick : function(e, node){
31600 node.ui.ecClick(e);
31603 onCheckboxClick : function(e, node){
31604 node.ui.onCheckChange(e);
31607 onNodeDblClick : function(e, node){
31608 node.ui.onDblClick(e);
31611 onNodeContextMenu : function(e, node){
31612 node.ui.onContextMenu(e);
31615 beforeEvent : function(e){
31616 var node = this.getNode(e);
31617 if(this.disabled || !node || !node.ui){
31624 disable: function(){
31625 this.disabled = true;
31628 enable: function(){
31629 this.disabled = false;
31632 Ext.tree.DefaultSelectionModel = Ext.extend(Ext.util.Observable, {
31634 constructor : function(config){
31635 this.selNode = null;
31645 Ext.apply(this, config);
31646 Ext.tree.DefaultSelectionModel.superclass.constructor.call(this);
31649 init : function(tree){
31651 tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);
31652 tree.on('click', this.onNodeClick, this);
31655 onNodeClick : function(node, e){
31660 select : function(node, selectNextNode){
31662 if (!Ext.fly(node.ui.wrap).isVisible() && selectNextNode) {
31663 return selectNextNode.call(this, node);
31665 var last = this.selNode;
31667 node.ui.onSelectedChange(true);
31668 }else if(this.fireEvent('beforeselect', this, node, last) !== false){
31669 if(last && last.ui){
31670 last.ui.onSelectedChange(false);
31672 this.selNode = node;
31673 node.ui.onSelectedChange(true);
31674 this.fireEvent('selectionchange', this, node, last);
31680 unselect : function(node, silent){
31681 if(this.selNode == node){
31682 this.clearSelections(silent);
31687 clearSelections : function(silent){
31688 var n = this.selNode;
31690 n.ui.onSelectedChange(false);
31691 this.selNode = null;
31692 if(silent !== true){
31693 this.fireEvent('selectionchange', this, null);
31700 getSelectedNode : function(){
31701 return this.selNode;
31705 isSelected : function(node){
31706 return this.selNode == node;
31710 selectPrevious : function( s){
31711 if(!(s = s || this.selNode || this.lastSelNode)){
31715 var ps = s.previousSibling;
31717 if(!ps.isExpanded() || ps.childNodes.length < 1){
31718 return this.select(ps, this.selectPrevious);
31720 var lc = ps.lastChild;
31721 while(lc && lc.isExpanded() && Ext.fly(lc.ui.wrap).isVisible() && lc.childNodes.length > 0){
31724 return this.select(lc, this.selectPrevious);
31726 } else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){
31727 return this.select(s.parentNode, this.selectPrevious);
31733 selectNext : function( s){
31734 if(!(s = s || this.selNode || this.lastSelNode)){
31738 if(s.firstChild && s.isExpanded() && Ext.fly(s.ui.wrap).isVisible()){
31739 return this.select(s.firstChild, this.selectNext);
31740 }else if(s.nextSibling){
31741 return this.select(s.nextSibling, this.selectNext);
31742 }else if(s.parentNode){
31744 s.parentNode.bubble(function(){
31745 if(this.nextSibling){
31746 newS = this.getOwnerTree().selModel.select(this.nextSibling, this.selectNext);
31755 onKeyDown : function(e){
31756 var s = this.selNode || this.lastSelNode;
31762 var k = e.getKey();
31770 this.selectPrevious();
31773 e.preventDefault();
31774 if(s.hasChildNodes()){
31775 if(!s.isExpanded()){
31777 }else if(s.firstChild){
31778 this.select(s.firstChild, e);
31783 e.preventDefault();
31784 if(s.hasChildNodes() && s.isExpanded()){
31786 }else if(s.parentNode && (this.tree.rootVisible || s.parentNode != this.tree.getRootNode())){
31787 this.select(s.parentNode, e);
31795 Ext.tree.MultiSelectionModel = Ext.extend(Ext.util.Observable, {
31797 constructor : function(config){
31798 this.selNodes = [];
31804 Ext.apply(this, config);
31805 Ext.tree.MultiSelectionModel.superclass.constructor.call(this);
31808 init : function(tree){
31810 tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);
31811 tree.on('click', this.onNodeClick, this);
31814 onNodeClick : function(node, e){
31815 if(e.ctrlKey && this.isSelected(node)){
31816 this.unselect(node);
31818 this.select(node, e, e.ctrlKey);
31823 select : function(node, e, keepExisting){
31824 if(keepExisting !== true){
31825 this.clearSelections(true);
31827 if(this.isSelected(node)){
31828 this.lastSelNode = node;
31831 this.selNodes.push(node);
31832 this.selMap[node.id] = node;
31833 this.lastSelNode = node;
31834 node.ui.onSelectedChange(true);
31835 this.fireEvent('selectionchange', this, this.selNodes);
31840 unselect : function(node){
31841 if(this.selMap[node.id]){
31842 node.ui.onSelectedChange(false);
31843 var sn = this.selNodes;
31844 var index = sn.indexOf(node);
31846 this.selNodes.splice(index, 1);
31848 delete this.selMap[node.id];
31849 this.fireEvent('selectionchange', this, this.selNodes);
31854 clearSelections : function(suppressEvent){
31855 var sn = this.selNodes;
31857 for(var i = 0, len = sn.length; i < len; i++){
31858 sn[i].ui.onSelectedChange(false);
31860 this.selNodes = [];
31862 if(suppressEvent !== true){
31863 this.fireEvent('selectionchange', this, this.selNodes);
31869 isSelected : function(node){
31870 return this.selMap[node.id] ? true : false;
31874 getSelectedNodes : function(){
31875 return this.selNodes.concat([]);
31878 onKeyDown : Ext.tree.DefaultSelectionModel.prototype.onKeyDown,
31880 selectNext : Ext.tree.DefaultSelectionModel.prototype.selectNext,
31882 selectPrevious : Ext.tree.DefaultSelectionModel.prototype.selectPrevious
31884 Ext.data.Tree = function(root){
31885 this.nodeHash = {};
31889 this.setRootNode(root);
31910 Ext.data.Tree.superclass.constructor.call(this);
31913 Ext.extend(Ext.data.Tree, Ext.util.Observable, {
31915 pathSeparator: "/",
31918 proxyNodeEvent : function(){
31919 return this.fireEvent.apply(this, arguments);
31923 getRootNode : function(){
31928 setRootNode : function(node){
31930 node.ownerTree = this;
31931 node.isRoot = true;
31932 this.registerNode(node);
31937 getNodeById : function(id){
31938 return this.nodeHash[id];
31942 registerNode : function(node){
31943 this.nodeHash[node.id] = node;
31947 unregisterNode : function(node){
31948 delete this.nodeHash[node.id];
31951 toString : function(){
31952 return "[Tree"+(this.id?" "+this.id:"")+"]";
31957 Ext.data.Node = function(attributes){
31959 this.attributes = attributes || {};
31960 this.leaf = this.attributes.leaf;
31962 this.id = this.attributes.id;
31964 this.id = Ext.id(null, "xnode-");
31965 this.attributes.id = this.id;
31968 this.childNodes = [];
31969 if(!this.childNodes.indexOf){
31970 this.childNodes.indexOf = function(o){
31971 for(var i = 0, len = this.length; i < len; i++){
31980 this.parentNode = null;
31982 this.firstChild = null;
31984 this.lastChild = null;
31986 this.previousSibling = null;
31988 this.nextSibling = null;
32000 "beforeappend" : true,
32002 "beforeremove" : true,
32004 "beforemove" : true,
32006 "beforeinsert" : true
32008 this.listeners = this.attributes.listeners;
32009 Ext.data.Node.superclass.constructor.call(this);
32012 Ext.extend(Ext.data.Node, Ext.util.Observable, {
32014 fireEvent : function(evtName){
32016 if(Ext.data.Node.superclass.fireEvent.apply(this, arguments) === false){
32020 var ot = this.getOwnerTree();
32022 if(ot.proxyNodeEvent.apply(ot, arguments) === false){
32030 isLeaf : function(){
32031 return this.leaf === true;
32035 setFirstChild : function(node){
32036 this.firstChild = node;
32040 setLastChild : function(node){
32041 this.lastChild = node;
32046 isLast : function(){
32047 return (!this.parentNode ? true : this.parentNode.lastChild == this);
32051 isFirst : function(){
32052 return (!this.parentNode ? true : this.parentNode.firstChild == this);
32056 hasChildNodes : function(){
32057 return !this.isLeaf() && this.childNodes.length > 0;
32061 isExpandable : function(){
32062 return this.attributes.expandable || this.hasChildNodes();
32066 appendChild : function(node){
32068 if(Ext.isArray(node)){
32070 }else if(arguments.length > 1){
32075 for(var i = 0, len = multi.length; i < len; i++) {
32076 this.appendChild(multi[i]);
32079 if(this.fireEvent("beforeappend", this.ownerTree, this, node) === false){
32082 var index = this.childNodes.length;
32083 var oldParent = node.parentNode;
32086 if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index) === false){
32089 oldParent.removeChild(node);
32091 index = this.childNodes.length;
32093 this.setFirstChild(node);
32095 this.childNodes.push(node);
32096 node.parentNode = this;
32097 var ps = this.childNodes[index-1];
32099 node.previousSibling = ps;
32100 ps.nextSibling = node;
32102 node.previousSibling = null;
32104 node.nextSibling = null;
32105 this.setLastChild(node);
32106 node.setOwnerTree(this.getOwnerTree());
32107 this.fireEvent("append", this.ownerTree, this, node, index);
32109 node.fireEvent("move", this.ownerTree, node, oldParent, this, index);
32116 removeChild : function(node, destroy){
32117 var index = this.childNodes.indexOf(node);
32121 if(this.fireEvent("beforeremove", this.ownerTree, this, node) === false){
32126 this.childNodes.splice(index, 1);
32129 if(node.previousSibling){
32130 node.previousSibling.nextSibling = node.nextSibling;
32132 if(node.nextSibling){
32133 node.nextSibling.previousSibling = node.previousSibling;
32137 if(this.firstChild == node){
32138 this.setFirstChild(node.nextSibling);
32140 if(this.lastChild == node){
32141 this.setLastChild(node.previousSibling);
32144 this.fireEvent("remove", this.ownerTree, this, node);
32146 node.destroy(true);
32154 clear : function(destroy){
32156 this.setOwnerTree(null, destroy);
32157 this.parentNode = this.previousSibling = this.nextSibling = null;
32159 this.firstChild = this.lastChild = null;
32164 destroy : function( silent){
32166 if(silent === true){
32167 this.purgeListeners();
32169 Ext.each(this.childNodes, function(n){
32172 this.childNodes = null;
32179 insertBefore : function(node, refNode){
32181 return this.appendChild(node);
32184 if(node == refNode){
32188 if(this.fireEvent("beforeinsert", this.ownerTree, this, node, refNode) === false){
32191 var index = this.childNodes.indexOf(refNode);
32192 var oldParent = node.parentNode;
32193 var refIndex = index;
32196 if(oldParent == this && this.childNodes.indexOf(node) < index){
32202 if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index, refNode) === false){
32205 oldParent.removeChild(node);
32207 if(refIndex === 0){
32208 this.setFirstChild(node);
32210 this.childNodes.splice(refIndex, 0, node);
32211 node.parentNode = this;
32212 var ps = this.childNodes[refIndex-1];
32214 node.previousSibling = ps;
32215 ps.nextSibling = node;
32217 node.previousSibling = null;
32219 node.nextSibling = refNode;
32220 refNode.previousSibling = node;
32221 node.setOwnerTree(this.getOwnerTree());
32222 this.fireEvent("insert", this.ownerTree, this, node, refNode);
32224 node.fireEvent("move", this.ownerTree, node, oldParent, this, refIndex, refNode);
32230 remove : function(destroy){
32231 if (this.parentNode) {
32232 this.parentNode.removeChild(this, destroy);
32238 removeAll : function(destroy){
32239 var cn = this.childNodes,
32241 while((n = cn[0])){
32242 this.removeChild(n, destroy);
32248 item : function(index){
32249 return this.childNodes[index];
32253 replaceChild : function(newChild, oldChild){
32254 var s = oldChild ? oldChild.nextSibling : null;
32255 this.removeChild(oldChild);
32256 this.insertBefore(newChild, s);
32261 indexOf : function(child){
32262 return this.childNodes.indexOf(child);
32266 getOwnerTree : function(){
32268 if(!this.ownerTree){
32272 this.ownerTree = p.ownerTree;
32278 return this.ownerTree;
32282 getDepth : function(){
32285 while(p.parentNode){
32293 setOwnerTree : function(tree, destroy){
32295 if(tree != this.ownerTree){
32296 if(this.ownerTree){
32297 this.ownerTree.unregisterNode(this);
32299 this.ownerTree = tree;
32301 if(destroy !== true){
32302 Ext.each(this.childNodes, function(n){
32303 n.setOwnerTree(tree);
32307 tree.registerNode(this);
32313 setId: function(id){
32314 if(id !== this.id){
32315 var t = this.ownerTree;
32317 t.unregisterNode(this);
32319 this.id = this.attributes.id = id;
32321 t.registerNode(this);
32323 this.onIdChange(id);
32328 onIdChange: Ext.emptyFn,
32331 getPath : function(attr){
32332 attr = attr || "id";
32333 var p = this.parentNode;
32334 var b = [this.attributes[attr]];
32336 b.unshift(p.attributes[attr]);
32339 var sep = this.getOwnerTree().pathSeparator;
32340 return sep + b.join(sep);
32344 bubble : function(fn, scope, args){
32347 if(fn.apply(scope || p, args || [p]) === false){
32355 cascade : function(fn, scope, args){
32356 if(fn.apply(scope || this, args || [this]) !== false){
32357 var cs = this.childNodes;
32358 for(var i = 0, len = cs.length; i < len; i++) {
32359 cs[i].cascade(fn, scope, args);
32365 eachChild : function(fn, scope, args){
32366 var cs = this.childNodes;
32367 for(var i = 0, len = cs.length; i < len; i++) {
32368 if(fn.apply(scope || this, args || [cs[i]]) === false){
32375 findChild : function(attribute, value, deep){
32376 return this.findChildBy(function(){
32377 return this.attributes[attribute] == value;
32382 findChildBy : function(fn, scope, deep){
32383 var cs = this.childNodes,
32388 for(; i < len; i++){
32390 if(fn.call(scope || n, n) === true){
32393 res = n.findChildBy(fn, scope, deep);
32404 sort : function(fn, scope){
32405 var cs = this.childNodes;
32406 var len = cs.length;
32408 var sortFn = scope ? function(){fn.apply(scope, arguments);} : fn;
32410 for(var i = 0; i < len; i++){
32412 n.previousSibling = cs[i-1];
32413 n.nextSibling = cs[i+1];
32415 this.setFirstChild(n);
32418 this.setLastChild(n);
32425 contains : function(node){
32426 return node.isAncestor(this);
32430 isAncestor : function(node){
32431 var p = this.parentNode;
32441 toString : function(){
32442 return "[Node"+(this.id?" "+this.id:"")+"]";
32445 Ext.tree.TreeNode = function(attributes){
32446 attributes = attributes || {};
32447 if(Ext.isString(attributes)){
32448 attributes = {text: attributes};
32450 this.childrenRendered = false;
32451 this.rendered = false;
32452 Ext.tree.TreeNode.superclass.constructor.call(this, attributes);
32453 this.expanded = attributes.expanded === true;
32454 this.isTarget = attributes.isTarget !== false;
32455 this.draggable = attributes.draggable !== false && attributes.allowDrag !== false;
32456 this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false;
32459 this.text = attributes.text;
32461 this.disabled = attributes.disabled === true;
32463 this.hidden = attributes.hidden === true;
32491 'beforechildrenrendered'
32494 var uiClass = this.attributes.uiProvider || this.defaultUI || Ext.tree.TreeNodeUI;
32497 this.ui = new uiClass(this);
32499 Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
32500 preventHScroll : true,
32502 isExpanded : function(){
32503 return this.expanded;
32507 getUI : function(){
32511 getLoader : function(){
32513 return this.loader || ((owner = this.getOwnerTree()) && owner.loader ? owner.loader : (this.loader = new Ext.tree.TreeLoader()));
32517 setFirstChild : function(node){
32518 var of = this.firstChild;
32519 Ext.tree.TreeNode.superclass.setFirstChild.call(this, node);
32520 if(this.childrenRendered && of && node != of){
32521 of.renderIndent(true, true);
32524 this.renderIndent(true, true);
32529 setLastChild : function(node){
32530 var ol = this.lastChild;
32531 Ext.tree.TreeNode.superclass.setLastChild.call(this, node);
32532 if(this.childrenRendered && ol && node != ol){
32533 ol.renderIndent(true, true);
32536 this.renderIndent(true, true);
32542 appendChild : function(n){
32543 if(!n.render && !Ext.isArray(n)){
32544 n = this.getLoader().createNode(n);
32546 var node = Ext.tree.TreeNode.superclass.appendChild.call(this, n);
32547 if(node && this.childrenRendered){
32550 this.ui.updateExpandIcon();
32555 removeChild : function(node, destroy){
32556 this.ownerTree.getSelectionModel().unselect(node);
32557 Ext.tree.TreeNode.superclass.removeChild.apply(this, arguments);
32561 if(node.ui.rendered){
32564 if(this.childNodes.length < 1){
32565 this.collapse(false, false);
32567 this.ui.updateExpandIcon();
32569 if(!this.firstChild && !this.isHiddenRoot()){
32570 this.childrenRendered = false;
32577 insertBefore : function(node, refNode){
32579 node = this.getLoader().createNode(node);
32581 var newNode = Ext.tree.TreeNode.superclass.insertBefore.call(this, node, refNode);
32582 if(newNode && refNode && this.childrenRendered){
32585 this.ui.updateExpandIcon();
32590 setText : function(text){
32591 var oldText = this.text;
32592 this.text = this.attributes.text = text;
32594 this.ui.onTextChange(this, text, oldText);
32596 this.fireEvent('textchange', this, text, oldText);
32600 select : function(){
32601 var t = this.getOwnerTree();
32603 t.getSelectionModel().select(this);
32608 unselect : function(silent){
32609 var t = this.getOwnerTree();
32611 t.getSelectionModel().unselect(this, silent);
32616 isSelected : function(){
32617 var t = this.getOwnerTree();
32618 return t ? t.getSelectionModel().isSelected(this) : false;
32622 expand : function(deep, anim, callback, scope){
32623 if(!this.expanded){
32624 if(this.fireEvent('beforeexpand', this, deep, anim) === false){
32627 if(!this.childrenRendered){
32628 this.renderChildren();
32630 this.expanded = true;
32631 if(!this.isHiddenRoot() && (this.getOwnerTree().animate && anim !== false) || anim){
32632 this.ui.animExpand(function(){
32633 this.fireEvent('expand', this);
32634 this.runCallback(callback, scope || this, [this]);
32636 this.expandChildNodes(true);
32638 }.createDelegate(this));
32642 this.fireEvent('expand', this);
32643 this.runCallback(callback, scope || this, [this]);
32646 this.runCallback(callback, scope || this, [this]);
32649 this.expandChildNodes(true);
32653 runCallback : function(cb, scope, args){
32654 if(Ext.isFunction(cb)){
32655 cb.apply(scope, args);
32659 isHiddenRoot : function(){
32660 return this.isRoot && !this.getOwnerTree().rootVisible;
32664 collapse : function(deep, anim, callback, scope){
32665 if(this.expanded && !this.isHiddenRoot()){
32666 if(this.fireEvent('beforecollapse', this, deep, anim) === false){
32669 this.expanded = false;
32670 if((this.getOwnerTree().animate && anim !== false) || anim){
32671 this.ui.animCollapse(function(){
32672 this.fireEvent('collapse', this);
32673 this.runCallback(callback, scope || this, [this]);
32675 this.collapseChildNodes(true);
32677 }.createDelegate(this));
32680 this.ui.collapse();
32681 this.fireEvent('collapse', this);
32682 this.runCallback(callback, scope || this, [this]);
32684 }else if(!this.expanded){
32685 this.runCallback(callback, scope || this, [this]);
32688 var cs = this.childNodes;
32689 for(var i = 0, len = cs.length; i < len; i++) {
32690 cs[i].collapse(true, false);
32696 delayedExpand : function(delay){
32697 if(!this.expandProcId){
32698 this.expandProcId = this.expand.defer(delay, this);
32703 cancelExpand : function(){
32704 if(this.expandProcId){
32705 clearTimeout(this.expandProcId);
32707 this.expandProcId = false;
32711 toggle : function(){
32720 ensureVisible : function(callback, scope){
32721 var tree = this.getOwnerTree();
32722 tree.expandPath(this.parentNode ? this.parentNode.getPath() : this.getPath(), false, function(){
32723 var node = tree.getNodeById(this.id);
32724 tree.getTreeEl().scrollChildIntoView(node.ui.anchor);
32725 this.runCallback(callback, scope || this, [this]);
32726 }.createDelegate(this));
32730 expandChildNodes : function(deep){
32731 var cs = this.childNodes;
32732 for(var i = 0, len = cs.length; i < len; i++) {
32733 cs[i].expand(deep);
32738 collapseChildNodes : function(deep){
32739 var cs = this.childNodes;
32740 for(var i = 0, len = cs.length; i < len; i++) {
32741 cs[i].collapse(deep);
32746 disable : function(){
32747 this.disabled = true;
32749 if(this.rendered && this.ui.onDisableChange){
32750 this.ui.onDisableChange(this, true);
32752 this.fireEvent('disabledchange', this, true);
32756 enable : function(){
32757 this.disabled = false;
32758 if(this.rendered && this.ui.onDisableChange){
32759 this.ui.onDisableChange(this, false);
32761 this.fireEvent('disabledchange', this, false);
32765 renderChildren : function(suppressEvent){
32766 if(suppressEvent !== false){
32767 this.fireEvent('beforechildrenrendered', this);
32769 var cs = this.childNodes;
32770 for(var i = 0, len = cs.length; i < len; i++){
32771 cs[i].render(true);
32773 this.childrenRendered = true;
32777 sort : function(fn, scope){
32778 Ext.tree.TreeNode.superclass.sort.apply(this, arguments);
32779 if(this.childrenRendered){
32780 var cs = this.childNodes;
32781 for(var i = 0, len = cs.length; i < len; i++){
32782 cs[i].render(true);
32788 render : function(bulkRender){
32789 this.ui.render(bulkRender);
32790 if(!this.rendered){
32792 this.getOwnerTree().registerNode(this);
32793 this.rendered = true;
32795 this.expanded = false;
32796 this.expand(false, false);
32802 renderIndent : function(deep, refresh){
32804 this.ui.childIndent = null;
32806 this.ui.renderIndent();
32807 if(deep === true && this.childrenRendered){
32808 var cs = this.childNodes;
32809 for(var i = 0, len = cs.length; i < len; i++){
32810 cs[i].renderIndent(true, refresh);
32815 beginUpdate : function(){
32816 this.childrenRendered = false;
32819 endUpdate : function(){
32820 if(this.expanded && this.rendered){
32821 this.renderChildren();
32826 destroy : function(silent){
32827 if(silent === true){
32828 this.unselect(true);
32830 Ext.tree.TreeNode.superclass.destroy.call(this, silent);
32831 Ext.destroy(this.ui, this.loader);
32832 this.ui = this.loader = null;
32836 onIdChange : function(id){
32837 this.ui.onIdChange(id);
32841 Ext.tree.TreePanel.nodeTypes.node = Ext.tree.TreeNode;
32842 Ext.tree.AsyncTreeNode = function(config){
32843 this.loaded = config && config.loaded === true;
32844 this.loading = false;
32845 Ext.tree.AsyncTreeNode.superclass.constructor.apply(this, arguments);
32847 this.addEvents('beforeload', 'load');
32851 Ext.extend(Ext.tree.AsyncTreeNode, Ext.tree.TreeNode, {
32852 expand : function(deep, anim, callback, scope){
32855 var f = function(){
32857 clearInterval(timer);
32858 this.expand(deep, anim, callback, scope);
32860 }.createDelegate(this);
32861 timer = setInterval(f, 200);
32865 if(this.fireEvent("beforeload", this) === false){
32868 this.loading = true;
32869 this.ui.beforeLoad(this);
32870 var loader = this.loader || this.attributes.loader || this.getOwnerTree().getLoader();
32872 loader.load(this, this.loadComplete.createDelegate(this, [deep, anim, callback, scope]), this);
32876 Ext.tree.AsyncTreeNode.superclass.expand.call(this, deep, anim, callback, scope);
32880 isLoading : function(){
32881 return this.loading;
32884 loadComplete : function(deep, anim, callback, scope){
32885 this.loading = false;
32886 this.loaded = true;
32887 this.ui.afterLoad(this);
32888 this.fireEvent("load", this);
32889 this.expand(deep, anim, callback, scope);
32893 isLoaded : function(){
32894 return this.loaded;
32897 hasChildNodes : function(){
32898 if(!this.isLeaf() && !this.loaded){
32901 return Ext.tree.AsyncTreeNode.superclass.hasChildNodes.call(this);
32906 reload : function(callback, scope){
32907 this.collapse(false, false);
32908 while(this.firstChild){
32909 this.removeChild(this.firstChild).destroy();
32911 this.childrenRendered = false;
32912 this.loaded = false;
32913 if(this.isHiddenRoot()){
32914 this.expanded = false;
32916 this.expand(false, false, callback, scope);
32920 Ext.tree.TreePanel.nodeTypes.async = Ext.tree.AsyncTreeNode;
32921 Ext.tree.TreeNodeUI = function(node){
32923 this.rendered = false;
32924 this.animating = false;
32925 this.wasLeaf = true;
32926 this.ecc = 'x-tree-ec-icon x-tree-elbow';
32927 this.emptyIcon = Ext.BLANK_IMAGE_URL;
32930 Ext.tree.TreeNodeUI.prototype = {
32932 removeChild : function(node){
32934 this.ctNode.removeChild(node.ui.getEl());
32939 beforeLoad : function(){
32940 this.addClass("x-tree-node-loading");
32944 afterLoad : function(){
32945 this.removeClass("x-tree-node-loading");
32949 onTextChange : function(node, text, oldText){
32951 this.textNode.innerHTML = text;
32956 onDisableChange : function(node, state){
32957 this.disabled = state;
32958 if (this.checkbox) {
32959 this.checkbox.disabled = state;
32962 this.addClass("x-tree-node-disabled");
32964 this.removeClass("x-tree-node-disabled");
32969 onSelectedChange : function(state){
32972 this.addClass("x-tree-selected");
32975 this.removeClass("x-tree-selected");
32980 onMove : function(tree, node, oldParent, newParent, index, refNode){
32981 this.childIndent = null;
32983 var targetNode = newParent.ui.getContainer();
32985 this.holder = document.createElement("div");
32986 this.holder.appendChild(this.wrap);
32989 var insertBefore = refNode ? refNode.ui.getEl() : null;
32991 targetNode.insertBefore(this.wrap, insertBefore);
32993 targetNode.appendChild(this.wrap);
32995 this.node.renderIndent(true, oldParent != newParent);
33000 addClass : function(cls){
33002 Ext.fly(this.elNode).addClass(cls);
33007 removeClass : function(cls){
33009 Ext.fly(this.elNode).removeClass(cls);
33014 remove : function(){
33016 this.holder = document.createElement("div");
33017 this.holder.appendChild(this.wrap);
33022 fireEvent : function(){
33023 return this.node.fireEvent.apply(this.node, arguments);
33027 initEvents : function(){
33028 this.node.on("move", this.onMove, this);
33030 if(this.node.disabled){
33031 this.onDisableChange(this.node, true);
33033 if(this.node.hidden){
33036 var ot = this.node.getOwnerTree();
33037 var dd = ot.enableDD || ot.enableDrag || ot.enableDrop;
33038 if(dd && (!this.node.isRoot || ot.rootVisible)){
33039 Ext.dd.Registry.register(this.elNode, {
33041 handles: this.getDDHandles(),
33048 getDDHandles : function(){
33049 return [this.iconNode, this.textNode, this.elNode];
33054 this.node.hidden = true;
33056 this.wrap.style.display = "none";
33062 this.node.hidden = false;
33064 this.wrap.style.display = "";
33069 onContextMenu : function(e){
33070 if (this.node.hasListener("contextmenu") || this.node.getOwnerTree().hasListener("contextmenu")) {
33071 e.preventDefault();
33073 this.fireEvent("contextmenu", this.node, e);
33078 onClick : function(e){
33083 if(this.fireEvent("beforeclick", this.node, e) !== false){
33084 var a = e.getTarget('a');
33085 if(!this.disabled && this.node.attributes.href && a){
33086 this.fireEvent("click", this.node, e);
33088 }else if(a && e.ctrlKey){
33091 e.preventDefault();
33096 if(this.node.attributes.singleClickExpand && !this.animating && this.node.isExpandable()){
33097 this.node.toggle();
33100 this.fireEvent("click", this.node, e);
33107 onDblClick : function(e){
33108 e.preventDefault();
33112 if(this.fireEvent("beforedblclick", this.node, e) !== false){
33114 this.toggleCheck();
33116 if(!this.animating && this.node.isExpandable()){
33117 this.node.toggle();
33119 this.fireEvent("dblclick", this.node, e);
33123 onOver : function(e){
33124 this.addClass('x-tree-node-over');
33127 onOut : function(e){
33128 this.removeClass('x-tree-node-over');
33132 onCheckChange : function(){
33133 var checked = this.checkbox.checked;
33135 this.checkbox.defaultChecked = checked;
33136 this.node.attributes.checked = checked;
33137 this.fireEvent('checkchange', this.node, checked);
33141 ecClick : function(e){
33142 if(!this.animating && this.node.isExpandable()){
33143 this.node.toggle();
33148 startDrop : function(){
33149 this.dropping = true;
33153 endDrop : function(){
33154 setTimeout(function(){
33155 this.dropping = false;
33156 }.createDelegate(this), 50);
33160 expand : function(){
33161 this.updateExpandIcon();
33162 this.ctNode.style.display = "";
33166 focus : function(){
33167 if(!this.node.preventHScroll){
33168 try{this.anchor.focus();
33172 var noscroll = this.node.getOwnerTree().getTreeEl().dom;
33173 var l = noscroll.scrollLeft;
33174 this.anchor.focus();
33175 noscroll.scrollLeft = l;
33181 toggleCheck : function(value){
33182 var cb = this.checkbox;
33184 cb.checked = (value === undefined ? !cb.checked : value);
33185 this.onCheckChange();
33192 this.anchor.blur();
33197 animExpand : function(callback){
33198 var ct = Ext.get(this.ctNode);
33200 if(!this.node.isExpandable()){
33201 this.updateExpandIcon();
33202 this.ctNode.style.display = "";
33203 Ext.callback(callback);
33206 this.animating = true;
33207 this.updateExpandIcon();
33210 callback : function(){
33211 this.animating = false;
33212 Ext.callback(callback);
33215 duration: this.node.ownerTree.duration || .25
33220 highlight : function(){
33221 var tree = this.node.getOwnerTree();
33222 Ext.fly(this.wrap).highlight(
33223 tree.hlColor || "C3DAF9",
33224 {endColor: tree.hlBaseColor}
33229 collapse : function(){
33230 this.updateExpandIcon();
33231 this.ctNode.style.display = "none";
33235 animCollapse : function(callback){
33236 var ct = Ext.get(this.ctNode);
33237 ct.enableDisplayMode('block');
33240 this.animating = true;
33241 this.updateExpandIcon();
33244 callback : function(){
33245 this.animating = false;
33246 Ext.callback(callback);
33249 duration: this.node.ownerTree.duration || .25
33254 getContainer : function(){
33255 return this.ctNode;
33259 getEl : function(){
33264 appendDDGhost : function(ghostNode){
33265 ghostNode.appendChild(this.elNode.cloneNode(true));
33269 getDDRepairXY : function(){
33270 return Ext.lib.Dom.getXY(this.iconNode);
33274 onRender : function(){
33279 render : function(bulkRender){
33280 var n = this.node, a = n.attributes;
33281 var targetNode = n.parentNode ?
33282 n.parentNode.ui.getContainer() : n.ownerTree.innerCt.dom;
33284 if(!this.rendered){
33285 this.rendered = true;
33287 this.renderElements(n, a, targetNode, bulkRender);
33290 if(this.textNode.setAttributeNS){
33291 this.textNode.setAttributeNS("ext", "qtip", a.qtip);
33293 this.textNode.setAttributeNS("ext", "qtitle", a.qtipTitle);
33296 this.textNode.setAttribute("ext:qtip", a.qtip);
33298 this.textNode.setAttribute("ext:qtitle", a.qtipTitle);
33301 }else if(a.qtipCfg){
33302 a.qtipCfg.target = Ext.id(this.textNode);
33303 Ext.QuickTips.register(a.qtipCfg);
33306 if(!this.node.expanded){
33307 this.updateExpandIcon(true);
33310 if(bulkRender === true) {
33311 targetNode.appendChild(this.wrap);
33317 renderElements : function(n, a, targetNode, bulkRender){
33319 this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
33321 var cb = Ext.isBoolean(a.checked),
33323 href = a.href ? a.href : Ext.isGecko ? "" : "#",
33324 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">',
33325 '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
33326 '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
33327 '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />',
33328 cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
33329 '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
33330 a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span unselectable="on">',n.text,"</span></a></div>",
33331 '<ul class="x-tree-node-ct" style="display:none;"></ul>',
33334 if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){
33335 this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
33337 this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
33340 this.elNode = this.wrap.childNodes[0];
33341 this.ctNode = this.wrap.childNodes[1];
33342 var cs = this.elNode.childNodes;
33343 this.indentNode = cs[0];
33344 this.ecNode = cs[1];
33345 this.iconNode = cs[2];
33348 this.checkbox = cs[3];
33350 this.checkbox.defaultChecked = this.checkbox.checked;
33353 this.anchor = cs[index];
33354 this.textNode = cs[index].firstChild;
33358 getAnchor : function(){
33359 return this.anchor;
33363 getTextEl : function(){
33364 return this.textNode;
33368 getIconEl : function(){
33369 return this.iconNode;
33373 isChecked : function(){
33374 return this.checkbox ? this.checkbox.checked : false;
33378 updateExpandIcon : function(){
33383 cls = n.isLast() ? "x-tree-elbow-end" : "x-tree-elbow",
33384 hasChild = n.hasChildNodes();
33385 if(hasChild || n.attributes.expandable){
33388 c1 = "x-tree-node-collapsed";
33389 c2 = "x-tree-node-expanded";
33392 c1 = "x-tree-node-expanded";
33393 c2 = "x-tree-node-collapsed";
33396 this.removeClass("x-tree-node-leaf");
33397 this.wasLeaf = false;
33399 if(this.c1 != c1 || this.c2 != c2){
33400 Ext.fly(this.elNode).replaceClass(c1, c2);
33401 this.c1 = c1; this.c2 = c2;
33405 Ext.fly(this.elNode).replaceClass("x-tree-node-expanded", "x-tree-node-collapsed");
33408 this.wasLeaf = true;
33411 var ecc = "x-tree-ec-icon "+cls;
33412 if(this.ecc != ecc){
33413 this.ecNode.className = ecc;
33420 onIdChange: function(id){
33422 this.elNode.setAttribute('ext:tree-node-id', id);
33427 getChildIndent : function(){
33428 if(!this.childIndent){
33432 if(!p.isRoot || (p.isRoot && p.ownerTree.rootVisible)){
33434 buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-elbow-line" />');
33436 buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-icon" />');
33441 this.childIndent = buf.join("");
33443 return this.childIndent;
33447 renderIndent : function(){
33450 p = this.node.parentNode;
33452 indent = p.ui.getChildIndent();
33454 if(this.indentMarkup != indent){
33455 this.indentNode.innerHTML = indent;
33456 this.indentMarkup = indent;
33458 this.updateExpandIcon();
33462 destroy : function(){
33464 Ext.dd.Registry.unregister(this.elNode.id);
33467 Ext.each(['textnode', 'anchor', 'checkbox', 'indentNode', 'ecNode', 'iconNode', 'elNode', 'ctNode', 'wrap', 'holder'], function(el){
33469 Ext.fly(this[el]).remove();
33478 Ext.tree.RootTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
33480 render : function(){
33481 if(!this.rendered){
33482 var targetNode = this.node.ownerTree.innerCt.dom;
33483 this.node.expanded = true;
33484 targetNode.innerHTML = '<div class="x-tree-root-node"></div>';
33485 this.wrap = this.ctNode = targetNode.firstChild;
33488 collapse : Ext.emptyFn,
33489 expand : Ext.emptyFn
33491 Ext.tree.TreeLoader = function(config){
33492 this.baseParams = {};
33493 Ext.apply(this, config);
33503 Ext.tree.TreeLoader.superclass.constructor.call(this);
33504 if(Ext.isString(this.paramOrder)){
33505 this.paramOrder = this.paramOrder.split(/[\s,|]/);
33509 Ext.extend(Ext.tree.TreeLoader, Ext.util.Observable, {
33520 clearOnLoad : true,
33523 paramOrder: undefined,
33526 paramsAsHash: false,
33529 nodeParameter: 'node',
33532 directFn : undefined,
33535 load : function(node, callback, scope){
33536 if(this.clearOnLoad){
33537 while(node.firstChild){
33538 node.removeChild(node.firstChild);
33541 if(this.doPreload(node)){
33542 this.runCallback(callback, scope || node, [node]);
33543 }else if(this.directFn || this.dataUrl || this.url){
33544 this.requestData(node, callback, scope || node);
33548 doPreload : function(node){
33549 if(node.attributes.children){
33550 if(node.childNodes.length < 1){
33551 var cs = node.attributes.children;
33552 node.beginUpdate();
33553 for(var i = 0, len = cs.length; i < len; i++){
33554 var cn = node.appendChild(this.createNode(cs[i]));
33555 if(this.preloadChildren){
33556 this.doPreload(cn);
33566 getParams: function(node){
33567 var bp = Ext.apply({}, this.baseParams),
33568 np = this.nodeParameter,
33569 po = this.paramOrder;
33571 np && (bp[ np ] = node.id);
33574 var buf = [node.id];
33577 if(np && po.indexOf(np) > -1){
33581 for(var i = 0, len = po.length; i < len; i++){
33582 buf.push(bp[ po[i] ]);
33584 }else if(this.paramsAsHash){
33593 requestData : function(node, callback, scope){
33594 if(this.fireEvent("beforeload", this, node, callback) !== false){
33596 var args = this.getParams(node);
33597 args.push(this.processDirectResponse.createDelegate(this, [{callback: callback, node: node, scope: scope}], true));
33598 this.directFn.apply(window, args);
33600 this.transId = Ext.Ajax.request({
33601 method:this.requestMethod,
33602 url: this.dataUrl||this.url,
33603 success: this.handleResponse,
33604 failure: this.handleFailure,
33606 argument: {callback: callback, node: node, scope: scope},
33607 params: this.getParams(node)
33613 this.runCallback(callback, scope || node, []);
33617 processDirectResponse: function(result, response, args){
33618 if(response.status){
33619 this.handleResponse({
33620 responseData: Ext.isArray(result) ? result : null,
33621 responseText: result,
33625 this.handleFailure({
33632 runCallback: function(cb, scope, args){
33633 if(Ext.isFunction(cb)){
33634 cb.apply(scope, args);
33638 isLoading : function(){
33639 return !!this.transId;
33642 abort : function(){
33643 if(this.isLoading()){
33644 Ext.Ajax.abort(this.transId);
33649 createNode : function(attr){
33651 if(this.baseAttrs){
33652 Ext.applyIf(attr, this.baseAttrs);
33654 if(this.applyLoader !== false && !attr.loader){
33655 attr.loader = this;
33657 if(Ext.isString(attr.uiProvider)){
33658 attr.uiProvider = this.uiProviders[attr.uiProvider] || eval(attr.uiProvider);
33661 return new Ext.tree.TreePanel.nodeTypes[attr.nodeType](attr);
33664 new Ext.tree.TreeNode(attr) :
33665 new Ext.tree.AsyncTreeNode(attr);
33669 processResponse : function(response, node, callback, scope){
33670 var json = response.responseText;
33672 var o = response.responseData || Ext.decode(json);
33673 node.beginUpdate();
33674 for(var i = 0, len = o.length; i < len; i++){
33675 var n = this.createNode(o[i]);
33677 node.appendChild(n);
33681 this.runCallback(callback, scope || node, [node]);
33683 this.handleFailure(response);
33687 handleResponse : function(response){
33688 this.transId = false;
33689 var a = response.argument;
33690 this.processResponse(response, a.node, a.callback, a.scope);
33691 this.fireEvent("load", this, a.node, response);
33694 handleFailure : function(response){
33695 this.transId = false;
33696 var a = response.argument;
33697 this.fireEvent("loadexception", this, a.node, response);
33698 this.runCallback(a.callback, a.scope || a.node, [a.node]);
33701 destroy : function(){
33703 this.purgeListeners();
33706 Ext.tree.TreeFilter = function(tree, config){
33708 this.filtered = {};
33709 Ext.apply(this, config);
33712 Ext.tree.TreeFilter.prototype = {
33719 filter : function(value, attr, startNode){
33720 attr = attr || "text";
33722 if(typeof value == "string"){
33723 var vlen = value.length;
33725 if(vlen == 0 && this.clearBlank){
33729 value = value.toLowerCase();
33731 return n.attributes[attr].substr(0, vlen).toLowerCase() == value;
33733 }else if(value.exec){
33735 return value.test(n.attributes[attr]);
33738 throw 'Illegal filter type, must be string or regex';
33740 this.filterBy(f, null, startNode);
33744 filterBy : function(fn, scope, startNode){
33745 startNode = startNode || this.tree.root;
33746 if(this.autoClear){
33749 var af = this.filtered, rv = this.reverse;
33750 var f = function(n){
33751 if(n == startNode){
33757 var m = fn.call(scope || n, n);
33765 startNode.cascade(f);
33768 if(typeof id != "function"){
33770 if(n && n.parentNode){
33771 n.parentNode.removeChild(n);
33779 clear : function(){
33781 var af = this.filtered;
33783 if(typeof id != "function"){
33790 this.filtered = {};
33794 Ext.tree.TreeSorter = function(tree, config){
33802 Ext.apply(this, config);
33803 tree.on("beforechildrenrendered", this.doSort, this);
33804 tree.on("append", this.updateSort, this);
33805 tree.on("insert", this.updateSort, this);
33806 tree.on("textchange", this.updateSortParent, this);
33808 var dsc = this.dir && this.dir.toLowerCase() == "desc";
33809 var p = this.property || "text";
33810 var sortType = this.sortType;
33811 var fs = this.folderSort;
33812 var cs = this.caseSensitive === true;
33813 var leafAttr = this.leafAttr || 'leaf';
33815 this.sortFn = function(n1, n2){
33817 if(n1.attributes[leafAttr] && !n2.attributes[leafAttr]){
33820 if(!n1.attributes[leafAttr] && n2.attributes[leafAttr]){
33824 var v1 = sortType ? sortType(n1) : (cs ? n1.attributes[p] : n1.attributes[p].toUpperCase());
33825 var v2 = sortType ? sortType(n2) : (cs ? n2.attributes[p] : n2.attributes[p].toUpperCase());
33827 return dsc ? +1 : -1;
33829 return dsc ? -1 : +1;
33836 Ext.tree.TreeSorter.prototype = {
33837 doSort : function(node){
33838 node.sort(this.sortFn);
33841 compareNodes : function(n1, n2){
33842 return (n1.text.toUpperCase() > n2.text.toUpperCase() ? 1 : -1);
33845 updateSort : function(tree, node){
33846 if(node.childrenRendered){
33847 this.doSort.defer(1, this, [node]);
33851 updateSortParent : function(node){
33852 var p = node.parentNode;
33853 if(p && p.childrenRendered){
33854 this.doSort.defer(1, this, [p]);
33858 if(Ext.dd.DropZone){
33860 Ext.tree.TreeDropZone = function(tree, config){
33862 this.allowParentInsert = config.allowParentInsert || false;
33864 this.allowContainerDrop = config.allowContainerDrop || false;
33866 this.appendOnly = config.appendOnly || false;
33868 Ext.tree.TreeDropZone.superclass.constructor.call(this, tree.getTreeEl(), config);
33872 this.dragOverData = {};
33874 this.lastInsertClass = "x-tree-no-status";
33877 Ext.extend(Ext.tree.TreeDropZone, Ext.dd.DropZone, {
33879 ddGroup : "TreeDD",
33882 expandDelay : 1000,
33885 expandNode : function(node){
33886 if(node.hasChildNodes() && !node.isExpanded()){
33887 node.expand(false, null, this.triggerCacheRefresh.createDelegate(this));
33892 queueExpand : function(node){
33893 this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]);
33897 cancelExpand : function(){
33898 if(this.expandProcId){
33899 clearTimeout(this.expandProcId);
33900 this.expandProcId = false;
33905 isValidDropPoint : function(n, pt, dd, e, data){
33906 if(!n || !data){ return false; }
33907 var targetNode = n.node;
33908 var dropNode = data.node;
33910 if(!(targetNode && targetNode.isTarget && pt)){
33913 if(pt == "append" && targetNode.allowChildren === false){
33916 if((pt == "above" || pt == "below") && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){
33919 if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){
33923 var overEvent = this.dragOverData;
33924 overEvent.tree = this.tree;
33925 overEvent.target = targetNode;
33926 overEvent.data = data;
33927 overEvent.point = pt;
33928 overEvent.source = dd;
33929 overEvent.rawEvent = e;
33930 overEvent.dropNode = dropNode;
33931 overEvent.cancel = false;
33932 var result = this.tree.fireEvent("nodedragover", overEvent);
33933 return overEvent.cancel === false && result !== false;
33937 getDropPoint : function(e, n, dd){
33940 return tn.allowChildren !== false ? "append" : false;
33942 var dragEl = n.ddel;
33943 var t = Ext.lib.Dom.getY(dragEl), b = t + dragEl.offsetHeight;
33944 var y = Ext.lib.Event.getPageY(e);
33945 var noAppend = tn.allowChildren === false || tn.isLeaf();
33946 if(this.appendOnly || tn.parentNode.allowChildren === false){
33947 return noAppend ? false : "append";
33949 var noBelow = false;
33950 if(!this.allowParentInsert){
33951 noBelow = tn.hasChildNodes() && tn.isExpanded();
33953 var q = (b - t) / (noAppend ? 2 : 3);
33954 if(y >= t && y < (t + q)){
33956 }else if(!noBelow && (noAppend || y >= b-q && y <= b)){
33964 onNodeEnter : function(n, dd, e, data){
33965 this.cancelExpand();
33968 onContainerOver : function(dd, e, data) {
33969 if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) {
33970 return this.dropAllowed;
33972 return this.dropNotAllowed;
33976 onNodeOver : function(n, dd, e, data){
33977 var pt = this.getDropPoint(e, n, dd);
33981 if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){
33982 this.queueExpand(node);
33983 }else if(pt != "append"){
33984 this.cancelExpand();
33988 var returnCls = this.dropNotAllowed;
33989 if(this.isValidDropPoint(n, pt, dd, e, data)){
33994 returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between";
33995 cls = "x-tree-drag-insert-above";
33996 }else if(pt == "below"){
33997 returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between";
33998 cls = "x-tree-drag-insert-below";
34000 returnCls = "x-tree-drop-ok-append";
34001 cls = "x-tree-drag-append";
34003 if(this.lastInsertClass != cls){
34004 Ext.fly(el).replaceClass(this.lastInsertClass, cls);
34005 this.lastInsertClass = cls;
34013 onNodeOut : function(n, dd, e, data){
34014 this.cancelExpand();
34015 this.removeDropIndicators(n);
34019 onNodeDrop : function(n, dd, e, data){
34020 var point = this.getDropPoint(e, n, dd);
34021 var targetNode = n.node;
34022 targetNode.ui.startDrop();
34023 if(!this.isValidDropPoint(n, point, dd, e, data)){
34024 targetNode.ui.endDrop();
34028 var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
34029 return this.processDrop(targetNode, data, point, dd, e, dropNode);
34032 onContainerDrop : function(dd, e, data){
34033 if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) {
34034 var targetNode = this.tree.getRootNode();
34035 targetNode.ui.startDrop();
34036 var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, 'append', e) : null);
34037 return this.processDrop(targetNode, data, 'append', dd, e, dropNode);
34043 processDrop: function(target, data, point, dd, e, dropNode){
34051 dropNode: dropNode,
34055 var retval = this.tree.fireEvent("beforenodedrop", dropEvent);
34056 if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
34057 target.ui.endDrop();
34058 return dropEvent.dropStatus;
34061 target = dropEvent.target;
34062 if(point == 'append' && !target.isExpanded()){
34063 target.expand(false, null, function(){
34064 this.completeDrop(dropEvent);
34065 }.createDelegate(this));
34067 this.completeDrop(dropEvent);
34073 completeDrop : function(de){
34074 var ns = de.dropNode, p = de.point, t = de.target;
34075 if(!Ext.isArray(ns)){
34079 for(var i = 0, len = ns.length; i < len; i++){
34082 t.parentNode.insertBefore(n, t);
34083 }else if(p == "below"){
34084 t.parentNode.insertBefore(n, t.nextSibling);
34090 if(Ext.enableFx && this.tree.hlDrop){
34094 this.tree.fireEvent("nodedrop", de);
34098 afterNodeMoved : function(dd, data, e, targetNode, dropNode){
34099 if(Ext.enableFx && this.tree.hlDrop){
34100 dropNode.ui.focus();
34101 dropNode.ui.highlight();
34103 this.tree.fireEvent("nodedrop", this.tree, targetNode, data, dd, e);
34107 getTree : function(){
34112 removeDropIndicators : function(n){
34115 Ext.fly(el).removeClass([
34116 "x-tree-drag-insert-above",
34117 "x-tree-drag-insert-below",
34118 "x-tree-drag-append"]);
34119 this.lastInsertClass = "_noclass";
34124 beforeDragDrop : function(target, e, id){
34125 this.cancelExpand();
34130 afterRepair : function(data){
34131 if(data && Ext.enableFx){
34132 data.node.ui.highlight();
34139 if(Ext.dd.DragZone){
34140 Ext.tree.TreeDragZone = function(tree, config){
34141 Ext.tree.TreeDragZone.superclass.constructor.call(this, tree.innerCt, config);
34146 Ext.extend(Ext.tree.TreeDragZone, Ext.dd.DragZone, {
34148 ddGroup : "TreeDD",
34151 onBeforeDrag : function(data, e){
34153 return n && n.draggable && !n.disabled;
34157 onInitDrag : function(e){
34158 var data = this.dragData;
34159 this.tree.getSelectionModel().select(data.node);
34160 this.tree.eventModel.disable();
34161 this.proxy.update("");
34162 data.node.ui.appendDDGhost(this.proxy.ghost.dom);
34163 this.tree.fireEvent("startdrag", this.tree, data.node, e);
34167 getRepairXY : function(e, data){
34168 return data.node.ui.getDDRepairXY();
34172 onEndDrag : function(data, e){
34173 this.tree.eventModel.enable.defer(100, this.tree.eventModel);
34174 this.tree.fireEvent("enddrag", this.tree, data.node, e);
34178 onValidDrop : function(dd, e, id){
34179 this.tree.fireEvent("dragdrop", this.tree, this.dragData.node, dd, e);
34184 beforeInvalidDrop : function(e, id){
34186 var sm = this.tree.getSelectionModel();
34187 sm.clearSelections();
34188 sm.select(this.dragData.node);
34192 afterRepair : function(){
34193 if (Ext.enableFx && this.tree.hlDrop) {
34194 Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9");
34196 this.dragging = false;
34200 Ext.tree.TreeEditor = function(tree, fc, config){
34202 var field = fc.events ? fc : new Ext.form.TextField(fc);
34204 Ext.tree.TreeEditor.superclass.constructor.call(this, field, config);
34208 if(!tree.rendered){
34209 tree.on('render', this.initEditor, this);
34211 this.initEditor(tree);
34215 Ext.extend(Ext.tree.TreeEditor, Ext.Editor, {
34223 cls: "x-small-editor x-tree-editor",
34233 initEditor : function(tree){
34236 beforeclick: this.beforeNodeClick,
34237 dblclick : this.onNodeDblClick
34242 complete : this.updateNode,
34243 beforestartedit: this.fitToTree,
34244 specialkey : this.onSpecialKey
34247 this.on('startedit', this.bindScroll, this, {delay:10});
34251 fitToTree : function(ed, el){
34252 var td = this.tree.getTreeEl().dom, nd = el.dom;
34253 if(td.scrollLeft > nd.offsetLeft){
34254 td.scrollLeft = nd.offsetLeft;
34258 (td.clientWidth > 20 ? td.clientWidth : td.offsetWidth) - Math.max(0, nd.offsetLeft-td.scrollLeft) - 5);
34259 this.setSize(w, '');
34263 triggerEdit : function(node, defer){
34264 this.completeEdit();
34265 if(node.attributes.editable !== false){
34267 this.editNode = node;
34268 if(this.tree.autoScroll){
34269 Ext.fly(node.ui.getEl()).scrollIntoView(this.tree.body);
34271 var value = node.text || '';
34272 if (!Ext.isGecko && Ext.isEmpty(node.text)){
34273 node.setText(' ');
34275 this.autoEditTimer = this.startEdit.defer(this.editDelay, this, [node.ui.textNode, value]);
34281 bindScroll : function(){
34282 this.tree.getTreeEl().on('scroll', this.cancelEdit, this);
34286 beforeNodeClick : function(node, e){
34287 clearTimeout(this.autoEditTimer);
34288 if(this.tree.getSelectionModel().isSelected(node)){
34290 return this.triggerEdit(node);
34294 onNodeDblClick : function(node, e){
34295 clearTimeout(this.autoEditTimer);
34299 updateNode : function(ed, value){
34300 this.tree.getTreeEl().un('scroll', this.cancelEdit, this);
34301 this.editNode.setText(value);
34305 onHide : function(){
34306 Ext.tree.TreeEditor.superclass.onHide.call(this);
34308 this.editNode.ui.focus.defer(50, this.editNode.ui);
34313 onSpecialKey : function(field, e){
34314 var k = e.getKey();
34318 }else if(k == e.ENTER && !e.hasModifier()){
34320 this.completeEdit();
34324 onDestroy : function(){
34325 clearTimeout(this.autoEditTimer);
34326 Ext.tree.TreeEditor.superclass.onDestroy.call(this);
34327 var tree = this.tree;
34328 tree.un('beforeclick', this.beforeNodeClick, this);
34329 tree.un('dblclick', this.onNodeDblClick, this);
34333 var swfobject = function() {
34335 var UNDEF = "undefined",
34337 SHOCKWAVE_FLASH = "Shockwave Flash",
34338 SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash",
34339 FLASH_MIME_TYPE = "application/x-shockwave-flash",
34340 EXPRESS_INSTALL_ID = "SWFObjectExprInst",
34341 ON_READY_STATE_CHANGE = "onreadystatechange",
34348 domLoadFnArr = [main],
34353 storedAltContentId,
34356 isDomLoaded = false,
34357 isExpressInstallActive = false,
34359 dynamicStylesheetMedia,
34360 autoHideShow = true,
34364 var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF,
34365 u = nav.userAgent.toLowerCase(),
34366 p = nav.platform.toLowerCase(),
34367 windows = p ? /win/.test(p) : /win/.test(u),
34368 mac = p ? /mac/.test(p) : /mac/.test(u),
34369 webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false,
34371 playerVersion = [0,0,0],
34373 if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) {
34374 d = nav.plugins[SHOCKWAVE_FLASH].description;
34375 if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) {
34378 d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
34379 playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10);
34380 playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10);
34381 playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0;
34384 else if (typeof win.ActiveXObject != UNDEF) {
34386 var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);
34388 d = a.GetVariable("$version");
34391 d = d.split(" ")[1].split(",");
34392 playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
34398 return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac };
34402 onDomLoad = function() {
34403 if (!ua.w3) { return; }
34404 if ((typeof doc.readyState != UNDEF && doc.readyState == "complete") || (typeof doc.readyState == UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) {
34405 callDomLoadFunctions();
34407 if (!isDomLoaded) {
34408 if (typeof doc.addEventListener != UNDEF) {
34409 doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false);
34411 if (ua.ie && ua.win) {
34412 doc.attachEvent(ON_READY_STATE_CHANGE, function() {
34413 if (doc.readyState == "complete") {
34414 doc.detachEvent(ON_READY_STATE_CHANGE, arguments.callee);
34415 callDomLoadFunctions();
34420 if (isDomLoaded) { return; }
34422 doc.documentElement.doScroll("left");
34425 setTimeout(arguments.callee, 0);
34428 callDomLoadFunctions();
34434 if (isDomLoaded) { return; }
34435 if (!/loaded|complete/.test(doc.readyState)) {
34436 setTimeout(arguments.callee, 0);
34439 callDomLoadFunctions();
34442 addLoadEvent(callDomLoadFunctions);
34446 function callDomLoadFunctions() {
34447 if (isDomLoaded) { return; }
34449 var t = doc.getElementsByTagName("body")[0].appendChild(createElement("span"));
34450 t.parentNode.removeChild(t);
34452 catch (e) { return; }
34453 isDomLoaded = true;
34454 var dl = domLoadFnArr.length;
34455 for (var i = 0; i < dl; i++) {
34460 function addDomLoadEvent(fn) {
34465 domLoadFnArr[domLoadFnArr.length] = fn;
34470 function addLoadEvent(fn) {
34471 if (typeof win.addEventListener != UNDEF) {
34472 win.addEventListener("load", fn, false);
34474 else if (typeof doc.addEventListener != UNDEF) {
34475 doc.addEventListener("load", fn, false);
34477 else if (typeof win.attachEvent != UNDEF) {
34478 addListener(win, "onload", fn);
34480 else if (typeof win.onload == "function") {
34481 var fnOld = win.onload;
34482 win.onload = function() {
34495 testPlayerVersion();
34503 function testPlayerVersion() {
34504 var b = doc.getElementsByTagName("body")[0];
34505 var o = createElement(OBJECT);
34506 o.setAttribute("type", FLASH_MIME_TYPE);
34507 var t = b.appendChild(o);
34511 if (typeof t.GetVariable != UNDEF) {
34512 var d = t.GetVariable("$version");
34514 d = d.split(" ")[1].split(",");
34515 ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
34518 else if (counter < 10) {
34520 setTimeout(arguments.callee, 10);
34534 function matchVersions() {
34535 var rl = regObjArr.length;
34537 for (var i = 0; i < rl; i++) {
34538 var id = regObjArr[i].id;
34539 var cb = regObjArr[i].callbackFn;
34540 var cbObj = {success:false, id:id};
34541 if (ua.pv[0] > 0) {
34542 var obj = getElementById(id);
34544 if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) {
34545 setVisibility(id, true);
34547 cbObj.success = true;
34548 cbObj.ref = getObjectById(id);
34552 else if (regObjArr[i].expressInstall && canExpressInstall()) {
34554 att.data = regObjArr[i].expressInstall;
34555 att.width = obj.getAttribute("width") || "0";
34556 att.height = obj.getAttribute("height") || "0";
34557 if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); }
34558 if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); }
34561 var p = obj.getElementsByTagName("param");
34563 for (var j = 0; j < pl; j++) {
34564 if (p[j].getAttribute("name").toLowerCase() != "movie") {
34565 par[p[j].getAttribute("name")] = p[j].getAttribute("value");
34568 showExpressInstall(att, par, id, cb);
34571 displayAltContent(obj);
34572 if (cb) { cb(cbObj); }
34577 setVisibility(id, true);
34579 var o = getObjectById(id);
34580 if (o && typeof o.SetVariable != UNDEF) {
34581 cbObj.success = true;
34591 function getObjectById(objectIdStr) {
34593 var o = getElementById(objectIdStr);
34594 if (o && o.nodeName == "OBJECT") {
34595 if (typeof o.SetVariable != UNDEF) {
34599 var n = o.getElementsByTagName(OBJECT)[0];
34609 function canExpressInstall() {
34610 return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312);
34614 function showExpressInstall(att, par, replaceElemIdStr, callbackFn) {
34615 isExpressInstallActive = true;
34616 storedCallbackFn = callbackFn || null;
34617 storedCallbackObj = {success:false, id:replaceElemIdStr};
34618 var obj = getElementById(replaceElemIdStr);
34620 if (obj.nodeName == "OBJECT") {
34621 storedAltContent = abstractAltContent(obj);
34622 storedAltContentId = null;
34625 storedAltContent = obj;
34626 storedAltContentId = replaceElemIdStr;
34628 att.id = EXPRESS_INSTALL_ID;
34629 if (typeof att.width == UNDEF || (!/%$/.test(att.width) && parseInt(att.width, 10) < 310)) { att.width = "310"; }
34630 if (typeof att.height == UNDEF || (!/%$/.test(att.height) && parseInt(att.height, 10) < 137)) { att.height = "137"; }
34631 doc.title = doc.title.slice(0, 47) + " - Flash Player Installation";
34632 var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn",
34633 fv = "MMredirectURL=" + win.location.toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title;
34634 if (typeof par.flashvars != UNDEF) {
34635 par.flashvars += "&" + fv;
34638 par.flashvars = fv;
34642 if (ua.ie && ua.win && obj.readyState != 4) {
34643 var newObj = createElement("div");
34644 replaceElemIdStr += "SWFObjectNew";
34645 newObj.setAttribute("id", replaceElemIdStr);
34646 obj.parentNode.insertBefore(newObj, obj);
34647 obj.style.display = "none";
34649 if (obj.readyState == 4) {
34650 obj.parentNode.removeChild(obj);
34653 setTimeout(arguments.callee, 10);
34657 createSWF(att, par, replaceElemIdStr);
34662 function displayAltContent(obj) {
34663 if (ua.ie && ua.win && obj.readyState != 4) {
34666 var el = createElement("div");
34667 obj.parentNode.insertBefore(el, obj);
34668 el.parentNode.replaceChild(abstractAltContent(obj), el);
34669 obj.style.display = "none";
34671 if (obj.readyState == 4) {
34672 obj.parentNode.removeChild(obj);
34675 setTimeout(arguments.callee, 10);
34680 obj.parentNode.replaceChild(abstractAltContent(obj), obj);
34684 function abstractAltContent(obj) {
34685 var ac = createElement("div");
34686 if (ua.win && ua.ie) {
34687 ac.innerHTML = obj.innerHTML;
34690 var nestedObj = obj.getElementsByTagName(OBJECT)[0];
34692 var c = nestedObj.childNodes;
34695 for (var i = 0; i < cl; i++) {
34696 if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) {
34697 ac.appendChild(c[i].cloneNode(true));
34707 function createSWF(attObj, parObj, id) {
34708 var r, el = getElementById(id);
34709 if (ua.wk && ua.wk < 312) { return r; }
34711 if (typeof attObj.id == UNDEF) {
34714 if (ua.ie && ua.win) {
34716 for (var i in attObj) {
34717 if (attObj[i] != Object.prototype[i]) {
34718 if (i.toLowerCase() == "data") {
34719 parObj.movie = attObj[i];
34721 else if (i.toLowerCase() == "styleclass") {
34722 att += ' class="' + attObj[i] + '"';
34724 else if (i.toLowerCase() != "classid") {
34725 att += ' ' + i + '="' + attObj[i] + '"';
34730 for (var j in parObj) {
34731 if (parObj[j] != Object.prototype[j]) {
34732 par += '<param name="' + j + '" value="' + parObj[j] + '" />';
34735 el.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + '>' + par + '</object>';
34736 objIdArr[objIdArr.length] = attObj.id;
34737 r = getElementById(attObj.id);
34740 var o = createElement(OBJECT);
34741 o.setAttribute("type", FLASH_MIME_TYPE);
34742 for (var m in attObj) {
34743 if (attObj[m] != Object.prototype[m]) {
34744 if (m.toLowerCase() == "styleclass") {
34745 o.setAttribute("class", attObj[m]);
34747 else if (m.toLowerCase() != "classid") {
34748 o.setAttribute(m, attObj[m]);
34752 for (var n in parObj) {
34753 if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") {
34754 createObjParam(o, n, parObj[n]);
34757 el.parentNode.replaceChild(o, el);
34764 function createObjParam(el, pName, pValue) {
34765 var p = createElement("param");
34766 p.setAttribute("name", pName);
34767 p.setAttribute("value", pValue);
34772 function removeSWF(id) {
34773 var obj = getElementById(id);
34774 if (obj && obj.nodeName == "OBJECT") {
34775 if (ua.ie && ua.win) {
34776 obj.style.display = "none";
34778 if (obj.readyState == 4) {
34779 removeObjectInIE(id);
34782 setTimeout(arguments.callee, 10);
34787 obj.parentNode.removeChild(obj);
34792 function removeObjectInIE(id) {
34793 var obj = getElementById(id);
34795 for (var i in obj) {
34796 if (typeof obj[i] == "function") {
34800 obj.parentNode.removeChild(obj);
34805 function getElementById(id) {
34808 el = doc.getElementById(id);
34814 function createElement(el) {
34815 return doc.createElement(el);
34819 function addListener(target, eventType, fn) {
34820 target.attachEvent(eventType, fn);
34821 listenersArr[listenersArr.length] = [target, eventType, fn];
34825 function hasPlayerVersion(rv) {
34826 var pv = ua.pv, v = rv.split(".");
34827 v[0] = parseInt(v[0], 10);
34828 v[1] = parseInt(v[1], 10) || 0;
34829 v[2] = parseInt(v[2], 10) || 0;
34830 return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false;
34834 function createCSS(sel, decl, media, newStyle) {
34835 if (ua.ie && ua.mac) { return; }
34836 var h = doc.getElementsByTagName("head")[0];
34837 if (!h) { return; }
34838 var m = (media && typeof media == "string") ? media : "screen";
34840 dynamicStylesheet = null;
34841 dynamicStylesheetMedia = null;
34843 if (!dynamicStylesheet || dynamicStylesheetMedia != m) {
34845 var s = createElement("style");
34846 s.setAttribute("type", "text/css");
34847 s.setAttribute("media", m);
34848 dynamicStylesheet = h.appendChild(s);
34849 if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) {
34850 dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];
34852 dynamicStylesheetMedia = m;
34855 if (ua.ie && ua.win) {
34856 if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) {
34857 dynamicStylesheet.addRule(sel, decl);
34861 if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) {
34862 dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}"));
34867 function setVisibility(id, isVisible) {
34868 if (!autoHideShow) { return; }
34869 var v = isVisible ? "visible" : "hidden";
34870 if (isDomLoaded && getElementById(id)) {
34871 getElementById(id).style.visibility = v;
34874 createCSS("#" + id, "visibility:" + v);
34879 function urlEncodeIfNecessary(s) {
34880 var regex = /[\\\"<>\.;]/;
34881 var hasBadChars = regex.exec(s) != null;
34882 return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s;
34886 var cleanup = function() {
34887 if (ua.ie && ua.win) {
34888 window.attachEvent("onunload", function() {
34890 var ll = listenersArr.length;
34891 for (var i = 0; i < ll; i++) {
34892 listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);
34895 var il = objIdArr.length;
34896 for (var j = 0; j < il; j++) {
34897 removeSWF(objIdArr[j]);
34900 for (var k in ua) {
34904 for (var l in swfobject) {
34905 swfobject[l] = null;
34914 registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) {
34915 if (ua.w3 && objectIdStr && swfVersionStr) {
34917 regObj.id = objectIdStr;
34918 regObj.swfVersion = swfVersionStr;
34919 regObj.expressInstall = xiSwfUrlStr;
34920 regObj.callbackFn = callbackFn;
34921 regObjArr[regObjArr.length] = regObj;
34922 setVisibility(objectIdStr, false);
34924 else if (callbackFn) {
34925 callbackFn({success:false, id:objectIdStr});
34929 getObjectById: function(objectIdStr) {
34931 return getObjectById(objectIdStr);
34935 embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {
34936 var callbackObj = {success:false, id:replaceElemIdStr};
34937 if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) {
34938 setVisibility(replaceElemIdStr, false);
34939 addDomLoadEvent(function() {
34943 if (attObj && typeof attObj === OBJECT) {
34944 for (var i in attObj) {
34945 att[i] = attObj[i];
34948 att.data = swfUrlStr;
34949 att.width = widthStr;
34950 att.height = heightStr;
34952 if (parObj && typeof parObj === OBJECT) {
34953 for (var j in parObj) {
34954 par[j] = parObj[j];
34957 if (flashvarsObj && typeof flashvarsObj === OBJECT) {
34958 for (var k in flashvarsObj) {
34959 if (typeof par.flashvars != UNDEF) {
34960 par.flashvars += "&" + k + "=" + flashvarsObj[k];
34963 par.flashvars = k + "=" + flashvarsObj[k];
34967 if (hasPlayerVersion(swfVersionStr)) {
34968 var obj = createSWF(att, par, replaceElemIdStr);
34969 if (att.id == replaceElemIdStr) {
34970 setVisibility(replaceElemIdStr, true);
34972 callbackObj.success = true;
34973 callbackObj.ref = obj;
34975 else if (xiSwfUrlStr && canExpressInstall()) {
34976 att.data = xiSwfUrlStr;
34977 showExpressInstall(att, par, replaceElemIdStr, callbackFn);
34981 setVisibility(replaceElemIdStr, true);
34983 if (callbackFn) { callbackFn(callbackObj); }
34986 else if (callbackFn) { callbackFn(callbackObj); }
34989 switchOffAutoHideShow: function() {
34990 autoHideShow = false;
34995 getFlashPlayerVersion: function() {
34996 return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] };
34999 hasFlashPlayerVersion: hasPlayerVersion,
35001 createSWF: function(attObj, parObj, replaceElemIdStr) {
35003 return createSWF(attObj, parObj, replaceElemIdStr);
35010 showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) {
35011 if (ua.w3 && canExpressInstall()) {
35012 showExpressInstall(att, par, replaceElemIdStr, callbackFn);
35016 removeSWF: function(objElemIdStr) {
35018 removeSWF(objElemIdStr);
35022 createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) {
35024 createCSS(selStr, declStr, mediaStr, newStyleBoolean);
35028 addDomLoadEvent: addDomLoadEvent,
35030 addLoadEvent: addLoadEvent,
35032 getQueryParamValue: function(param) {
35033 var q = doc.location.search || doc.location.hash;
35035 if (/\?/.test(q)) { q = q.split("?")[1]; }
35036 if (param == null) {
35037 return urlEncodeIfNecessary(q);
35039 var pairs = q.split("&");
35040 for (var i = 0; i < pairs.length; i++) {
35041 if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
35042 return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1)));
35050 expressInstallCallback: function() {
35051 if (isExpressInstallActive) {
35052 var obj = getElementById(EXPRESS_INSTALL_ID);
35053 if (obj && storedAltContent) {
35054 obj.parentNode.replaceChild(storedAltContent, obj);
35055 if (storedAltContentId) {
35056 setVisibility(storedAltContentId, true);
35057 if (ua.ie && ua.win) { storedAltContent.style.display = "block"; }
35059 if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); }
35061 isExpressInstallActive = false;
35067 Ext.FlashComponent = Ext.extend(Ext.BoxComponent, {
35069 flashVersion : '9.0.115',
35072 backgroundColor: '#ffffff',
35078 flashVars: undefined,
35081 flashParams: undefined,
35090 expressInstall: false,
35092 initComponent : function(){
35093 Ext.FlashComponent.superclass.initComponent.call(this);
35101 onRender : function(){
35102 Ext.FlashComponent.superclass.onRender.apply(this, arguments);
35104 var params = Ext.apply({
35105 allowScriptAccess: 'always',
35106 bgcolor: this.backgroundColor,
35108 }, this.flashParams), vars = Ext.apply({
35109 allowedDomain: document.location.hostname,
35110 YUISwfId: this.getId(),
35111 YUIBridgeCallback: 'Ext.FlashEventProxy.onEvent'
35112 }, this.flashVars);
35114 new swfobject.embedSWF(this.url, this.id, this.swfWidth, this.swfHeight, this.flashVersion,
35115 this.expressInstall ? Ext.FlashComponent.EXPRESS_INSTALL_URL : undefined, vars, params);
35117 this.swf = Ext.getDom(this.id);
35118 this.el = Ext.get(this.swf);
35121 getSwfId : function(){
35122 return this.swfId || (this.swfId = "extswf" + (++Ext.Component.AUTO_ID));
35125 getId : function(){
35126 return this.id || (this.id = "extflashcmp" + (++Ext.Component.AUTO_ID));
35129 onFlashEvent : function(e){
35137 e.component = this;
35138 this.fireEvent(e.type.toLowerCase().replace(/event$/, ''), e);
35141 initSwf : function(){
35142 this.onSwfReady(!!this.isInitialized);
35143 this.isInitialized = true;
35144 this.fireEvent('initialize', this);
35147 beforeDestroy: function(){
35149 swfobject.removeSWF(this.swf.id);
35151 Ext.FlashComponent.superclass.beforeDestroy.call(this);
35154 onSwfReady : Ext.emptyFn
35158 Ext.FlashComponent.EXPRESS_INSTALL_URL = 'http:/' + '/swfobject.googlecode.com/svn/trunk/swfobject/expressInstall.swf';
35160 Ext.reg('flash', Ext.FlashComponent);
35161 Ext.FlashEventProxy = {
35162 onEvent : function(id, e){
35163 var fp = Ext.getCmp(id);
35165 fp.onFlashEvent(e);
35167 arguments.callee.defer(10, this, [id, e]);
35172 Ext.chart.Chart = Ext.extend(Ext.FlashComponent, {
35173 refreshBuffer: 100,
35180 animationEnabled: true,
35211 seriesStyles: null,
35214 disableCaching: Ext.isIE || Ext.isOpera,
35215 disableCacheParam: '_dc',
35217 initComponent : function(){
35218 Ext.chart.Chart.superclass.initComponent.call(this);
35220 this.url = Ext.chart.Chart.CHART_URL;
35222 if(this.disableCaching){
35223 this.url = Ext.urlAppend(this.url, String.format('{0}={1}', this.disableCacheParam, new Date().getTime()));
35238 this.store = Ext.StoreMgr.lookup(this.store);
35242 setStyle: function(name, value){
35243 this.swf.setStyle(name, Ext.encode(value));
35247 setStyles: function(styles){
35248 this.swf.setStyles(Ext.encode(styles));
35252 setSeriesStyles: function(styles){
35253 this.seriesStyles = styles;
35255 Ext.each(styles, function(style){
35256 s.push(Ext.encode(style));
35258 this.swf.setSeriesStyles(s);
35261 setCategoryNames : function(names){
35262 this.swf.setCategoryNames(names);
35265 setLegendRenderer : function(fn, scope){
35267 scope = scope || chart;
35268 chart.removeFnProxy(chart.legendFnName);
35269 chart.legendFnName = chart.createFnProxy(function(name){
35270 return fn.call(scope, name);
35272 chart.swf.setLegendLabelFunction(chart.legendFnName);
35275 setTipRenderer : function(fn, scope){
35277 scope = scope || chart;
35278 chart.removeFnProxy(chart.tipFnName);
35279 chart.tipFnName = chart.createFnProxy(function(item, index, series){
35280 var record = chart.store.getAt(index);
35281 return fn.call(scope, chart, record, index, series);
35283 chart.swf.setDataTipFunction(chart.tipFnName);
35286 setSeries : function(series){
35287 this.series = series;
35292 bindStore : function(store, initial){
35293 if(!initial && this.store){
35294 if(store !== this.store && this.store.autoDestroy){
35295 this.store.destroy();
35297 this.store.un("datachanged", this.refresh, this);
35298 this.store.un("add", this.delayRefresh, this);
35299 this.store.un("remove", this.delayRefresh, this);
35300 this.store.un("update", this.delayRefresh, this);
35301 this.store.un("clear", this.refresh, this);
35305 store = Ext.StoreMgr.lookup(store);
35308 datachanged: this.refresh,
35309 add: this.delayRefresh,
35310 remove: this.delayRefresh,
35311 update: this.delayRefresh,
35312 clear: this.refresh
35315 this.store = store;
35316 if(store && !initial){
35321 onSwfReady : function(isReset){
35322 Ext.chart.Chart.superclass.onSwfReady.call(this, isReset);
35324 this.swf.setType(this.type);
35326 if(this.chartStyle){
35327 this.setStyles(Ext.apply({}, this.extraStyle, this.chartStyle));
35330 if(this.categoryNames){
35331 this.setCategoryNames(this.categoryNames);
35334 if(this.tipRenderer){
35335 ref = this.getFunctionRef(this.tipRenderer);
35336 this.setTipRenderer(ref.fn, ref.scope);
35338 if(this.legendRenderer){
35339 ref = this.getFunctionRef(this.legendRenderer);
35340 this.setLegendRenderer(ref.fn, ref.scope);
35343 this.bindStore(this.store, true);
35345 this.refresh.defer(10, this);
35348 delayRefresh : function(){
35349 if(!this.refreshTask){
35350 this.refreshTask = new Ext.util.DelayedTask(this.refresh, this);
35352 this.refreshTask.delay(this.refreshBuffer);
35355 refresh : function(){
35356 if(this.fireEvent('beforerefresh', this) !== false){
35357 var styleChanged = false;
35359 var data = [], rs = this.store.data.items;
35360 for(var j = 0, len = rs.length; j < len; j++){
35361 data[j] = rs[j].data;
35365 var dataProvider = [];
35366 var seriesCount = 0;
35367 var currentSeries = null;
35370 seriesCount = this.series.length;
35371 for(i = 0; i < seriesCount; i++){
35372 currentSeries = this.series[i];
35373 var clonedSeries = {};
35374 for(var prop in currentSeries){
35375 if(prop == "style" && currentSeries.style !== null){
35376 clonedSeries.style = Ext.encode(currentSeries.style);
35377 styleChanged = true;
35383 clonedSeries[prop] = currentSeries[prop];
35386 dataProvider.push(clonedSeries);
35390 if(seriesCount > 0){
35391 for(i = 0; i < seriesCount; i++){
35392 currentSeries = dataProvider[i];
35393 if(!currentSeries.type){
35394 currentSeries.type = this.type;
35396 currentSeries.dataProvider = data;
35399 dataProvider.push({type: this.type, dataProvider: data});
35401 this.swf.setDataProvider(dataProvider);
35402 if(this.seriesStyles){
35403 this.setSeriesStyles(this.seriesStyles);
35405 this.fireEvent('refresh', this);
35410 createFnProxy : function(fn){
35411 var fnName = 'extFnProxy' + (++Ext.chart.Chart.PROXY_FN_ID);
35412 Ext.chart.Chart.proxyFunction[fnName] = fn;
35413 return 'Ext.chart.Chart.proxyFunction.' + fnName;
35417 removeFnProxy : function(fn){
35418 if(!Ext.isEmpty(fn)){
35419 fn = fn.replace('Ext.chart.Chart.proxyFunction.', '');
35420 delete Ext.chart.Chart.proxyFunction[fn];
35425 getFunctionRef : function(val){
35426 if(Ext.isFunction(val)){
35434 scope: val.scope || this
35440 onDestroy: function(){
35441 if (this.refreshTask && this.refreshTask.cancel){
35442 this.refreshTask.cancel();
35444 Ext.chart.Chart.superclass.onDestroy.call(this);
35445 this.bindStore(null);
35446 this.removeFnProxy(this.tipFnName);
35447 this.removeFnProxy(this.legendFnName);
35450 Ext.reg('chart', Ext.chart.Chart);
35451 Ext.chart.Chart.PROXY_FN_ID = 0;
35452 Ext.chart.Chart.proxyFunction = {};
35455 Ext.chart.Chart.CHART_URL = 'http:/' + '/yui.yahooapis.com/2.8.0/build/charts/assets/charts.swf';
35458 Ext.chart.PieChart = Ext.extend(Ext.chart.Chart, {
35461 onSwfReady : function(isReset){
35462 Ext.chart.PieChart.superclass.onSwfReady.call(this, isReset);
35464 this.setDataField(this.dataField);
35465 this.setCategoryField(this.categoryField);
35468 setDataField : function(field){
35469 this.dataField = field;
35470 this.swf.setDataField(field);
35473 setCategoryField : function(field){
35474 this.categoryField = field;
35475 this.swf.setCategoryField(field);
35478 Ext.reg('piechart', Ext.chart.PieChart);
35481 Ext.chart.CartesianChart = Ext.extend(Ext.chart.Chart, {
35482 onSwfReady : function(isReset){
35483 Ext.chart.CartesianChart.superclass.onSwfReady.call(this, isReset);
35486 this.setXField(this.xField);
35489 this.setYField(this.yField);
35492 this.setXAxis(this.xAxis);
35495 this.setXAxes(this.xAxes);
35498 this.setYAxis(this.yAxis);
35501 this.setYAxes(this.yAxes);
35503 if(Ext.isDefined(this.constrainViewport)){
35504 this.swf.setConstrainViewport(this.constrainViewport);
35508 setXField : function(value){
35509 this.xField = value;
35510 this.swf.setHorizontalField(value);
35513 setYField : function(value){
35514 this.yField = value;
35515 this.swf.setVerticalField(value);
35518 setXAxis : function(value){
35519 this.xAxis = this.createAxis('xAxis', value);
35520 this.swf.setHorizontalAxis(this.xAxis);
35523 setXAxes : function(value){
35525 for(var i = 0; i < value.length; i++) {
35526 axis = this.createAxis('xAxis' + i, value[i]);
35527 this.swf.setHorizontalAxis(axis);
35531 setYAxis : function(value){
35532 this.yAxis = this.createAxis('yAxis', value);
35533 this.swf.setVerticalAxis(this.yAxis);
35536 setYAxes : function(value){
35538 for(var i = 0; i < value.length; i++) {
35539 axis = this.createAxis('yAxis' + i, value[i]);
35540 this.swf.setVerticalAxis(axis);
35544 createAxis : function(axis, value){
35545 var o = Ext.apply({}, value),
35550 old = this[axis].labelFunction;
35551 this.removeFnProxy(old);
35552 this.labelFn.remove(old);
35554 if(o.labelRenderer){
35555 ref = this.getFunctionRef(o.labelRenderer);
35556 o.labelFunction = this.createFnProxy(function(v){
35557 return ref.fn.call(ref.scope, v);
35559 delete o.labelRenderer;
35560 this.labelFn.push(o.labelFunction);
35562 if(axis.indexOf('xAxis') > -1 && o.position == 'left'){
35563 o.position = 'bottom';
35568 onDestroy : function(){
35569 Ext.chart.CartesianChart.superclass.onDestroy.call(this);
35570 Ext.each(this.labelFn, function(fn){
35571 this.removeFnProxy(fn);
35575 Ext.reg('cartesianchart', Ext.chart.CartesianChart);
35578 Ext.chart.LineChart = Ext.extend(Ext.chart.CartesianChart, {
35581 Ext.reg('linechart', Ext.chart.LineChart);
35584 Ext.chart.ColumnChart = Ext.extend(Ext.chart.CartesianChart, {
35587 Ext.reg('columnchart', Ext.chart.ColumnChart);
35590 Ext.chart.StackedColumnChart = Ext.extend(Ext.chart.CartesianChart, {
35591 type: 'stackcolumn'
35593 Ext.reg('stackedcolumnchart', Ext.chart.StackedColumnChart);
35596 Ext.chart.BarChart = Ext.extend(Ext.chart.CartesianChart, {
35599 Ext.reg('barchart', Ext.chart.BarChart);
35602 Ext.chart.StackedBarChart = Ext.extend(Ext.chart.CartesianChart, {
35605 Ext.reg('stackedbarchart', Ext.chart.StackedBarChart);
35610 Ext.chart.Axis = function(config){
35611 Ext.apply(this, config);
35614 Ext.chart.Axis.prototype =
35620 orientation: "horizontal",
35626 labelFunction: null,
35629 hideOverlappingLabels: true,
35636 Ext.chart.NumericAxis = Ext.extend(Ext.chart.Axis, {
35655 alwaysShowZero: true,
35661 roundMajorUnit: true,
35664 calculateByLabelSize: true,
35670 adjustMaximumByMajorUnit: true,
35673 adjustMinimumByMajorUnit: true
35678 Ext.chart.TimeAxis = Ext.extend(Ext.chart.Axis, {
35691 majorTimeUnit: null,
35697 minorTimeUnit: null,
35703 stackingEnabled: false,
35706 calculateByLabelSize: true
35711 Ext.chart.CategoryAxis = Ext.extend(Ext.chart.Axis, {
35715 categoryNames: null,
35718 calculateCategoryCount: false
35723 Ext.chart.Series = function(config) { Ext.apply(this, config); };
35725 Ext.chart.Series.prototype =
35735 Ext.chart.CartesianSeries = Ext.extend(Ext.chart.Series, {
35743 showInLegend: true,
35750 Ext.chart.ColumnSeries = Ext.extend(Ext.chart.CartesianSeries, {
35755 Ext.chart.LineSeries = Ext.extend(Ext.chart.CartesianSeries, {
35760 Ext.chart.BarSeries = Ext.extend(Ext.chart.CartesianSeries, {
35766 Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, {
35769 categoryField: null
35771 Ext.menu.Menu = Ext.extend(Ext.Container, {
35779 subMenuAlign : 'tl-tr?',
35781 defaultAlign : 'tl-bl?',
35783 allowOtherMenus : false,
35785 ignoreParentClicks : false,
35787 enableScrolling : true,
35791 scrollIncrement : 24,
35793 showSeparator : true,
35795 defaultOffsets : [0, 0],
35812 hideMode : 'offsets',
35813 scrollerHeight : 8,
35815 defaultType : 'menuitem',
35816 bufferResize : false,
35818 initComponent : function(){
35819 if(Ext.isArray(this.initialConfig)){
35820 Ext.apply(this, {items:this.initialConfig});
35832 Ext.menu.MenuMgr.register(this);
35834 Ext.EventManager.onWindowResize(this.hide, this);
35836 if(this.initialConfig.hidden !== false){
35837 this.hidden = false;
35839 this.internalDefaults = {hideOnClick: false};
35841 Ext.menu.Menu.superclass.initComponent.call(this);
35842 if(this.autoLayout){
35843 var fn = this.doLayout.createDelegate(this, []);
35852 getLayoutTarget : function() {
35857 onRender : function(ct, position){
35859 ct = Ext.getBody();
35864 cls: 'x-menu ' + ((this.floating) ? 'x-menu-floating x-layer ' : '') + (this.cls || '') + (this.plain ? ' x-menu-plain' : '') + (this.showSeparator ? '' : ' x-menu-nosep'),
35867 {tag: 'a', cls: 'x-menu-focus', href: '#', onclick: 'return false;', tabIndex: '-1'},
35868 {tag: 'ul', cls: 'x-menu-list'}
35872 this.el = new Ext.Layer({
35873 shadow: this.shadow,
35877 zindex: this.zIndex
35880 this.el = ct.createChild(dh);
35882 Ext.menu.Menu.superclass.onRender.call(this, ct, position);
35885 this.keyNav = new Ext.menu.MenuNav(this);
35888 this.focusEl = this.el.child('a.x-menu-focus');
35889 this.ul = this.el.child('ul.x-menu-list');
35890 this.mon(this.ul, {
35892 click: this.onClick,
35893 mouseover: this.onMouseOver,
35894 mouseout: this.onMouseOut
35896 if(this.enableScrolling){
35897 this.mon(this.el, {
35899 delegate: '.x-menu-scroller',
35900 click: this.onScroll,
35901 mouseover: this.deactivateActive
35907 findTargetItem : function(e){
35908 var t = e.getTarget('.x-menu-list-item', this.ul, true);
35909 if(t && t.menuItemId){
35910 return this.items.get(t.menuItemId);
35915 onClick : function(e){
35916 var t = this.findTargetItem(e);
35919 this.setActiveItem(t);
35920 }else if(t instanceof Ext.menu.BaseItem){
35921 if(t.menu && this.ignoreParentClicks){
35923 e.preventDefault();
35924 }else if(t.onClick){
35926 this.fireEvent('click', this, t, e);
35933 setActiveItem : function(item, autoExpand){
35934 if(item != this.activeItem){
35935 this.deactivateActive();
35936 if((this.activeItem = item).isFormField){
35939 item.activate(autoExpand);
35941 }else if(autoExpand){
35946 deactivateActive : function(){
35947 var a = this.activeItem;
35957 delete this.activeItem;
35962 tryActivate : function(start, step){
35963 var items = this.items;
35964 for(var i = start, len = items.length; i >= 0 && i < len; i+= step){
35965 var item = items.get(i);
35966 if(!item.disabled && (item.canActivate || item.isFormField)){
35967 this.setActiveItem(item, false);
35975 onMouseOver : function(e){
35976 var t = this.findTargetItem(e);
35978 if(t.canActivate && !t.disabled){
35979 this.setActiveItem(t, true);
35983 this.fireEvent('mouseover', this, e, t);
35987 onMouseOut : function(e){
35988 var t = this.findTargetItem(e);
35990 if(t == this.activeItem && t.shouldDeactivate && t.shouldDeactivate(e)){
35991 this.activeItem.deactivate();
35992 delete this.activeItem;
35996 this.fireEvent('mouseout', this, e, t);
36000 onScroll : function(e, t){
36004 var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top');
36005 ul.scrollTop += this.scrollIncrement * (top ? -1 : 1);
36006 if(top ? ul.scrollTop <= 0 : ul.scrollTop + this.activeMax >= ul.scrollHeight){
36007 this.onScrollerOut(null, t);
36012 onScrollerIn : function(e, t){
36013 var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top');
36014 if(top ? ul.scrollTop > 0 : ul.scrollTop + this.activeMax < ul.scrollHeight){
36015 Ext.fly(t).addClass(['x-menu-item-active', 'x-menu-scroller-active']);
36020 onScrollerOut : function(e, t){
36021 Ext.fly(t).removeClass(['x-menu-item-active', 'x-menu-scroller-active']);
36025 show : function(el, pos, parentMenu){
36027 this.parentMenu = parentMenu;
36030 this.doLayout(false, true);
36032 this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign, this.defaultOffsets), parentMenu);
36034 Ext.menu.Menu.superclass.show.call(this);
36039 showAt : function(xy, parentMenu){
36040 if(this.fireEvent('beforeshow', this) !== false){
36041 this.parentMenu = parentMenu;
36045 if(this.enableScrolling){
36049 xy[1] = this.constrainScroll(xy[1]);
36050 xy = [this.el.adjustForConstraints(xy)[0], xy[1]];
36053 xy = this.el.adjustForConstraints(xy);
36057 Ext.menu.Menu.superclass.onShow.call(this);
36060 this.fireEvent('autosize', this);
36065 this.hidden = false;
36067 this.fireEvent('show', this);
36071 constrainScroll : function(y){
36072 var max, full = this.ul.setHeight('auto').getHeight(),
36073 returnY = y, normalY, parentEl, scrollTop, viewHeight;
36075 parentEl = Ext.fly(this.el.dom.parentNode);
36076 scrollTop = parentEl.getScroll().top;
36077 viewHeight = parentEl.getViewSize().height;
36080 normalY = y - scrollTop;
36081 max = this.maxHeight ? this.maxHeight : viewHeight - normalY;
36082 if(full > viewHeight) {
36085 returnY = y - normalY;
36086 } else if(max < full) {
36087 returnY = y - (full - max);
36091 max = this.getHeight();
36094 if (this.maxHeight){
36095 max = Math.min(this.maxHeight, max);
36097 if(full > max && max > 0){
36098 this.activeMax = max - this.scrollerHeight * 2 - this.el.getFrameWidth('tb') - Ext.num(this.el.shadowOffset, 0);
36099 this.ul.setHeight(this.activeMax);
36100 this.createScrollers();
36101 this.el.select('.x-menu-scroller').setDisplayed('');
36103 this.ul.setHeight(full);
36104 this.el.select('.x-menu-scroller').setDisplayed('none');
36106 this.ul.dom.scrollTop = 0;
36110 createScrollers : function(){
36111 if(!this.scroller){
36114 top: this.el.insertFirst({
36116 cls: 'x-menu-scroller x-menu-scroller-top',
36119 bottom: this.el.createChild({
36121 cls: 'x-menu-scroller x-menu-scroller-bottom',
36125 this.scroller.top.hover(this.onScrollerIn, this.onScrollerOut, this);
36126 this.scroller.topRepeater = new Ext.util.ClickRepeater(this.scroller.top, {
36128 click: this.onScroll.createDelegate(this, [null, this.scroller.top], false)
36131 this.scroller.bottom.hover(this.onScrollerIn, this.onScrollerOut, this);
36132 this.scroller.bottomRepeater = new Ext.util.ClickRepeater(this.scroller.bottom, {
36134 click: this.onScroll.createDelegate(this, [null, this.scroller.bottom], false)
36140 onLayout : function(){
36141 if(this.isVisible()){
36142 if(this.enableScrolling){
36143 this.constrainScroll(this.el.getTop());
36151 focus : function(){
36153 this.doFocus.defer(50, this);
36157 doFocus : function(){
36159 this.focusEl.focus();
36164 hide : function(deep){
36165 if (!this.isDestroyed) {
36166 this.deepHide = deep;
36167 Ext.menu.Menu.superclass.hide.call(this);
36168 delete this.deepHide;
36173 onHide : function(){
36174 Ext.menu.Menu.superclass.onHide.call(this);
36175 this.deactivateActive();
36176 if(this.el && this.floating){
36179 var pm = this.parentMenu;
36180 if(this.deepHide === true && pm){
36184 pm.deactivateActive();
36190 lookupComponent : function(c){
36191 if(Ext.isString(c)){
36192 c = (c == 'separator' || c == '-') ? new Ext.menu.Separator() : new Ext.menu.TextItem(c);
36193 this.applyDefaults(c);
36195 if(Ext.isObject(c)){
36196 c = this.getMenuItem(c);
36197 }else if(c.tagName || c.el){
36198 c = new Ext.BoxComponent({
36206 applyDefaults : function(c){
36207 if(!Ext.isString(c)){
36208 c = Ext.menu.Menu.superclass.applyDefaults.call(this, c);
36209 var d = this.internalDefaults;
36212 Ext.applyIf(c.initialConfig, d);
36223 getMenuItem : function(config){
36224 if(!config.isXType){
36225 if(!config.xtype && Ext.isBoolean(config.checked)){
36226 return new Ext.menu.CheckItem(config)
36228 return Ext.create(config, this.defaultType);
36234 addSeparator : function(){
36235 return this.add(new Ext.menu.Separator());
36239 addElement : function(el){
36240 return this.add(new Ext.menu.BaseItem({
36246 addItem : function(item){
36247 return this.add(item);
36251 addMenuItem : function(config){
36252 return this.add(this.getMenuItem(config));
36256 addText : function(text){
36257 return this.add(new Ext.menu.TextItem(text));
36261 onDestroy : function(){
36262 Ext.EventManager.removeResizeListener(this.hide, this);
36263 var pm = this.parentMenu;
36264 if(pm && pm.activeChild == this){
36265 delete pm.activeChild;
36267 delete this.parentMenu;
36268 Ext.menu.Menu.superclass.onDestroy.call(this);
36269 Ext.menu.MenuMgr.unregister(this);
36271 this.keyNav.disable();
36273 var s = this.scroller;
36275 Ext.destroy(s.topRepeater, s.bottomRepeater, s.top, s.bottom);
36285 Ext.reg('menu', Ext.menu.Menu);
36288 Ext.menu.MenuNav = Ext.extend(Ext.KeyNav, function(){
36290 if(!m.tryActivate(m.items.indexOf(m.activeItem)-1, -1)){
36291 m.tryActivate(m.items.length-1, -1);
36294 function down(e, m){
36295 if(!m.tryActivate(m.items.indexOf(m.activeItem)+1, 1)){
36296 m.tryActivate(0, 1);
36300 constructor : function(menu){
36301 Ext.menu.MenuNav.superclass.constructor.call(this, menu.el);
36302 this.scope = this.menu = menu;
36305 doRelay : function(e, h){
36306 var k = e.getKey();
36308 if (this.menu.activeItem && this.menu.activeItem.isFormField && k != e.TAB) {
36311 if(!this.menu.activeItem && e.isNavKeyPress() && k != e.SPACE && k != e.RETURN){
36312 this.menu.tryActivate(0, 1);
36315 return h.call(this.scope || this, e, this.menu);
36318 tab: function(e, m) {
36331 right : function(e, m){
36333 m.activeItem.expandMenu(true);
36337 left : function(e, m){
36339 if(m.parentMenu && m.parentMenu.activeItem){
36340 m.parentMenu.activeItem.activate();
36344 enter : function(e, m){
36346 e.stopPropagation();
36347 m.activeItem.onClick(e);
36348 m.fireEvent('click', this, m.activeItem);
36355 Ext.menu.MenuMgr = function(){
36356 var menus, active, groups = {}, attached = false, lastShow = new Date();
36361 active = new Ext.util.MixedCollection();
36362 Ext.getDoc().addKeyListener(27, function(){
36363 if(active.length > 0){
36370 function hideAll(){
36371 if(active && active.length > 0){
36372 var c = active.clone();
36373 c.each(function(m){
36382 function onHide(m){
36384 if(active.length < 1){
36385 Ext.getDoc().un("mousedown", onMouseDown);
36391 function onShow(m){
36392 var last = active.last();
36393 lastShow = new Date();
36396 Ext.getDoc().on("mousedown", onMouseDown);
36400 m.getEl().setZIndex(parseInt(m.parentMenu.getEl().getStyle("z-index"), 10) + 3);
36401 m.parentMenu.activeChild = m;
36402 }else if(last && !last.isDestroyed && last.isVisible()){
36403 m.getEl().setZIndex(parseInt(last.getEl().getStyle("z-index"), 10) + 3);
36408 function onBeforeHide(m){
36410 m.activeChild.hide();
36412 if(m.autoHideTimer){
36413 clearTimeout(m.autoHideTimer);
36414 delete m.autoHideTimer;
36419 function onBeforeShow(m){
36420 var pm = m.parentMenu;
36421 if(!pm && !m.allowOtherMenus){
36423 }else if(pm && pm.activeChild){
36424 pm.activeChild.hide();
36429 function onMouseDown(e){
36430 if(lastShow.getElapsed() > 50 && active.length > 0 && !e.getTarget(".x-menu")){
36436 function onBeforeCheck(mi, state){
36438 var g = groups[mi.group];
36439 for(var i = 0, l = g.length; i < l; i++){
36441 g[i].setChecked(false);
36450 hideAll : function(){
36455 register : function(menu){
36459 menus[menu.id] = menu;
36461 beforehide: onBeforeHide,
36463 beforeshow: onBeforeShow,
36469 get : function(menu){
36470 if(typeof menu == "string"){
36474 return menus[menu];
36475 }else if(menu.events){
36477 }else if(typeof menu.length == 'number'){
36478 return new Ext.menu.Menu({items:menu});
36480 return Ext.create(menu, 'menu');
36485 unregister : function(menu){
36486 delete menus[menu.id];
36487 menu.un("beforehide", onBeforeHide);
36488 menu.un("hide", onHide);
36489 menu.un("beforeshow", onBeforeShow);
36490 menu.un("show", onShow);
36494 registerCheckable : function(menuItem){
36495 var g = menuItem.group;
36500 groups[g].push(menuItem);
36501 menuItem.on("beforecheckchange", onBeforeCheck);
36506 unregisterCheckable : function(menuItem){
36507 var g = menuItem.group;
36509 groups[g].remove(menuItem);
36510 menuItem.un("beforecheckchange", onBeforeCheck);
36514 getCheckedItem : function(groupId){
36515 var g = groups[groupId];
36517 for(var i = 0, l = g.length; i < l; i++){
36526 setCheckedItem : function(groupId, itemId){
36527 var g = groups[groupId];
36529 for(var i = 0, l = g.length; i < l; i++){
36530 if(g[i].id == itemId){
36531 g[i].setChecked(true);
36540 Ext.menu.BaseItem = Ext.extend(Ext.Component, {
36545 canActivate : false,
36547 activeClass : "x-menu-item-active",
36549 hideOnClick : true,
36551 clickHideDelay : 1,
36554 ctype : "Ext.menu.BaseItem",
36557 actionMode : "container",
36559 initComponent : function(){
36560 Ext.menu.BaseItem.superclass.initComponent.call(this);
36570 this.on("click", this.handler, this.scope);
36575 onRender : function(container, position){
36576 Ext.menu.BaseItem.superclass.onRender.apply(this, arguments);
36577 if(this.ownerCt && this.ownerCt instanceof Ext.menu.Menu){
36578 this.parentMenu = this.ownerCt;
36580 this.container.addClass('x-menu-list-item');
36581 this.mon(this.el, {
36583 click: this.onClick,
36584 mouseenter: this.activate,
36585 mouseleave: this.deactivate
36591 setHandler : function(handler, scope){
36593 this.un("click", this.handler, this.scope);
36595 this.on("click", this.handler = handler, this.scope = scope);
36599 onClick : function(e){
36600 if(!this.disabled && this.fireEvent("click", this, e) !== false
36601 && (this.parentMenu && this.parentMenu.fireEvent("itemclick", this, e) !== false)){
36602 this.handleClick(e);
36609 activate : function(){
36613 var li = this.container;
36614 li.addClass(this.activeClass);
36615 this.region = li.getRegion().adjust(2, 2, -2, -2);
36616 this.fireEvent("activate", this);
36621 deactivate : function(){
36622 this.container.removeClass(this.activeClass);
36623 this.fireEvent("deactivate", this);
36627 shouldDeactivate : function(e){
36628 return !this.region || !this.region.contains(e.getPoint());
36632 handleClick : function(e){
36633 var pm = this.parentMenu;
36634 if(this.hideOnClick){
36636 pm.hide.defer(this.clickHideDelay, pm, [true]);
36638 pm.deactivateActive();
36644 expandMenu : Ext.emptyFn,
36647 hideMenu : Ext.emptyFn
36649 Ext.reg('menubaseitem', Ext.menu.BaseItem);
36650 Ext.menu.TextItem = Ext.extend(Ext.menu.BaseItem, {
36653 hideOnClick : false,
36655 itemCls : "x-menu-text",
36657 constructor : function(config){
36658 if(typeof config == 'string'){
36659 config = {text: config}
36661 Ext.menu.TextItem.superclass.constructor.call(this, config);
36665 onRender : function(){
36666 var s = document.createElement("span");
36667 s.className = this.itemCls;
36668 s.innerHTML = this.text;
36670 Ext.menu.TextItem.superclass.onRender.apply(this, arguments);
36673 Ext.reg('menutextitem', Ext.menu.TextItem);
36674 Ext.menu.Separator = Ext.extend(Ext.menu.BaseItem, {
36676 itemCls : "x-menu-sep",
36678 hideOnClick : false,
36684 onRender : function(li){
36685 var s = document.createElement("span");
36686 s.className = this.itemCls;
36687 s.innerHTML = " ";
36689 li.addClass("x-menu-sep-li");
36690 Ext.menu.Separator.superclass.onRender.apply(this, arguments);
36693 Ext.reg('menuseparator', Ext.menu.Separator);
36694 Ext.menu.Item = Ext.extend(Ext.menu.BaseItem, {
36703 itemCls : 'x-menu-item',
36705 canActivate : true,
36712 ctype: 'Ext.menu.Item',
36714 initComponent : function(){
36715 Ext.menu.Item.superclass.initComponent.call(this);
36717 this.menu = Ext.menu.MenuMgr.get(this.menu);
36718 this.menu.ownerCt = this;
36723 onRender : function(container, position){
36724 if (!this.itemTpl) {
36725 this.itemTpl = Ext.menu.Item.prototype.itemTpl = new Ext.XTemplate(
36726 '<a id="{id}" class="{cls}" hidefocus="true" unselectable="on" href="{href}"',
36727 '<tpl if="hrefTarget">',
36728 ' target="{hrefTarget}"',
36731 '<img src="{icon}" class="x-menu-item-icon {iconCls}"/>',
36732 '<span class="x-menu-item-text">{text}</span>',
36736 var a = this.getTemplateArgs();
36737 this.el = position ? this.itemTpl.insertBefore(position, a, true) : this.itemTpl.append(container, a, true);
36738 this.iconEl = this.el.child('img.x-menu-item-icon');
36739 this.textEl = this.el.child('.x-menu-item-text');
36741 this.mon(this.el, 'click', Ext.emptyFn, null, { preventDefault: true });
36743 Ext.menu.Item.superclass.onRender.call(this, container, position);
36746 getTemplateArgs: function() {
36749 cls: this.itemCls + (this.menu ? ' x-menu-item-arrow' : '') + (this.cls ? ' ' + this.cls : ''),
36750 href: this.href || '#',
36751 hrefTarget: this.hrefTarget,
36752 icon: this.icon || Ext.BLANK_IMAGE_URL,
36753 iconCls: this.iconCls || '',
36754 text: this.itemText||this.text||' '
36759 setText : function(text){
36760 this.text = text||' ';
36762 this.textEl.update(this.text);
36763 this.parentMenu.layout.doAutoSize();
36768 setIconClass : function(cls){
36769 var oldCls = this.iconCls;
36770 this.iconCls = cls;
36772 this.iconEl.replaceClass(oldCls, this.iconCls);
36777 beforeDestroy: function(){
36779 delete this.menu.ownerCt;
36780 this.menu.destroy();
36782 Ext.menu.Item.superclass.beforeDestroy.call(this);
36786 handleClick : function(e){
36790 Ext.menu.Item.superclass.handleClick.apply(this, arguments);
36794 activate : function(autoExpand){
36795 if(Ext.menu.Item.superclass.activate.apply(this, arguments)){
36805 shouldDeactivate : function(e){
36806 if(Ext.menu.Item.superclass.shouldDeactivate.call(this, e)){
36807 if(this.menu && this.menu.isVisible()){
36808 return !this.menu.getEl().getRegion().contains(e.getPoint());
36816 deactivate : function(){
36817 Ext.menu.Item.superclass.deactivate.apply(this, arguments);
36822 expandMenu : function(autoActivate){
36823 if(!this.disabled && this.menu){
36824 clearTimeout(this.hideTimer);
36825 delete this.hideTimer;
36826 if(!this.menu.isVisible() && !this.showTimer){
36827 this.showTimer = this.deferExpand.defer(this.showDelay, this, [autoActivate]);
36828 }else if (this.menu.isVisible() && autoActivate){
36829 this.menu.tryActivate(0, 1);
36835 deferExpand : function(autoActivate){
36836 delete this.showTimer;
36837 this.menu.show(this.container, this.parentMenu.subMenuAlign || 'tl-tr?', this.parentMenu);
36839 this.menu.tryActivate(0, 1);
36844 hideMenu : function(){
36845 clearTimeout(this.showTimer);
36846 delete this.showTimer;
36847 if(!this.hideTimer && this.menu && this.menu.isVisible()){
36848 this.hideTimer = this.deferHide.defer(this.hideDelay, this);
36853 deferHide : function(){
36854 delete this.hideTimer;
36855 if(this.menu.over){
36856 this.parentMenu.setActiveItem(this, false);
36862 Ext.reg('menuitem', Ext.menu.Item);
36863 Ext.menu.CheckItem = Ext.extend(Ext.menu.Item, {
36866 itemCls : "x-menu-item x-menu-check-item",
36868 groupClass : "x-menu-group-item",
36874 ctype: "Ext.menu.CheckItem",
36876 initComponent : function(){
36877 Ext.menu.CheckItem.superclass.initComponent.call(this);
36880 "beforecheckchange" ,
36885 if(this.checkHandler){
36886 this.on('checkchange', this.checkHandler, this.scope);
36888 Ext.menu.MenuMgr.registerCheckable(this);
36892 onRender : function(c){
36893 Ext.menu.CheckItem.superclass.onRender.apply(this, arguments);
36895 this.el.addClass(this.groupClass);
36898 this.checked = false;
36899 this.setChecked(true, true);
36904 destroy : function(){
36905 Ext.menu.MenuMgr.unregisterCheckable(this);
36906 Ext.menu.CheckItem.superclass.destroy.apply(this, arguments);
36910 setChecked : function(state, suppressEvent){
36911 var suppress = suppressEvent === true;
36912 if(this.checked != state && (suppress || this.fireEvent("beforecheckchange", this, state) !== false)){
36913 if(this.container){
36914 this.container[state ? "addClass" : "removeClass"]("x-menu-item-checked");
36916 this.checked = state;
36918 this.fireEvent("checkchange", this, state);
36924 handleClick : function(e){
36925 if(!this.disabled && !(this.checked && this.group)){
36926 this.setChecked(!this.checked);
36928 Ext.menu.CheckItem.superclass.handleClick.apply(this, arguments);
36931 Ext.reg('menucheckitem', Ext.menu.CheckItem);
36932 Ext.menu.DateMenu = Ext.extend(Ext.menu.Menu, {
36934 enableScrolling : false,
36938 hideOnClick : true,
36946 cls : 'x-date-menu',
36952 initComponent : function(){
36953 this.on('beforeshow', this.onBeforeShow, this);
36954 if(this.strict = (Ext.isIE7 && Ext.isStrict)){
36955 this.on('show', this.onShow, this, {single: true, delay: 20});
36959 showSeparator: false,
36960 items: this.picker = new Ext.DatePicker(Ext.applyIf({
36961 internalRender: this.strict || !Ext.isIE,
36962 ctCls: 'x-menu-date-item',
36964 }, this.initialConfig))
36966 this.picker.purgeListeners();
36967 Ext.menu.DateMenu.superclass.initComponent.call(this);
36969 this.relayEvents(this.picker, ['select']);
36970 this.on('show', this.picker.focus, this.picker);
36971 this.on('select', this.menuHide, this);
36973 this.on('select', this.handler, this.scope || this);
36977 menuHide : function() {
36978 if(this.hideOnClick){
36983 onBeforeShow : function(){
36985 this.picker.hideMonthPicker(true);
36989 onShow : function(){
36990 var el = this.picker.getEl();
36991 el.setWidth(el.getWidth());
36994 Ext.reg('datemenu', Ext.menu.DateMenu);
36996 Ext.menu.ColorMenu = Ext.extend(Ext.menu.Menu, {
36998 enableScrolling : false,
37003 hideOnClick : true,
37005 cls : 'x-color-menu',
37019 initComponent : function(){
37022 showSeparator: false,
37023 items: this.palette = new Ext.ColorPalette(Ext.applyIf({
37025 }, this.initialConfig))
37027 this.palette.purgeListeners();
37028 Ext.menu.ColorMenu.superclass.initComponent.call(this);
37030 this.relayEvents(this.palette, ['select']);
37031 this.on('select', this.menuHide, this);
37033 this.on('select', this.handler, this.scope || this);
37037 menuHide : function(){
37038 if(this.hideOnClick){
37043 Ext.reg('colormenu', Ext.menu.ColorMenu);
37045 Ext.form.Field = Ext.extend(Ext.BoxComponent, {
37054 invalidClass : 'x-form-invalid',
37056 invalidText : 'The value in this field is invalid',
37058 focusClass : 'x-form-focus',
37061 validationEvent : 'keyup',
37063 validateOnBlur : true,
37065 validationDelay : 250,
37067 defaultAutoCreate : {tag: 'input', type: 'text', size: '20', autocomplete: 'off'},
37069 fieldClass : 'x-form-field',
37071 msgTarget : 'qtip',
37082 isFormField : true,
37091 initComponent : function(){
37092 Ext.form.Field.superclass.initComponent.call(this);
37110 getName : function(){
37111 return this.rendered && this.el.dom.name ? this.el.dom.name : this.name || this.id || '';
37115 onRender : function(ct, position){
37117 var cfg = this.getAutoCreate();
37120 cfg.name = this.name || this.id;
37122 if(this.inputType){
37123 cfg.type = this.inputType;
37127 Ext.form.Field.superclass.onRender.call(this, ct, position);
37128 if(this.submitValue === false){
37129 this.el.dom.removeAttribute('name');
37131 var type = this.el.dom.type;
37133 if(type == 'password'){
37136 this.el.addClass('x-form-'+type);
37139 this.setReadOnly(true);
37141 if(this.tabIndex !== undefined){
37142 this.el.dom.setAttribute('tabIndex', this.tabIndex);
37145 this.el.addClass([this.fieldClass, this.cls]);
37149 getItemCt : function(){
37150 return this.itemCt;
37154 initValue : function(){
37155 if(this.value !== undefined){
37156 this.setValue(this.value);
37157 }else if(!Ext.isEmpty(this.el.dom.value) && this.el.dom.value != this.emptyText){
37158 this.setValue(this.el.dom.value);
37161 this.originalValue = this.getValue();
37165 isDirty : function() {
37166 if(this.disabled || !this.rendered) {
37169 return String(this.getValue()) !== String(this.originalValue);
37173 setReadOnly : function(readOnly){
37175 this.el.dom.readOnly = readOnly;
37177 this.readOnly = readOnly;
37181 afterRender : function(){
37182 Ext.form.Field.superclass.afterRender.call(this);
37188 fireKey : function(e){
37189 if(e.isSpecialKey()){
37190 this.fireEvent('specialkey', this, e);
37195 reset : function(){
37196 this.setValue(this.originalValue);
37197 this.clearInvalid();
37201 initEvents : function(){
37202 this.mon(this.el, Ext.EventManager.useKeydown ? 'keydown' : 'keypress', this.fireKey, this);
37203 this.mon(this.el, 'focus', this.onFocus, this);
37207 this.mon(this.el, 'blur', this.onBlur, this, this.inEditor ? {buffer:10} : null);
37211 preFocus: Ext.emptyFn,
37214 onFocus : function(){
37216 if(this.focusClass){
37217 this.el.addClass(this.focusClass);
37219 if(!this.hasFocus){
37220 this.hasFocus = true;
37222 this.startValue = this.getValue();
37223 this.fireEvent('focus', this);
37228 beforeBlur : Ext.emptyFn,
37231 onBlur : function(){
37233 if(this.focusClass){
37234 this.el.removeClass(this.focusClass);
37236 this.hasFocus = false;
37237 if(this.validationEvent !== false && (this.validateOnBlur || this.validationEvent == 'blur')){
37240 var v = this.getValue();
37241 if(String(v) !== String(this.startValue)){
37242 this.fireEvent('change', this, v, this.startValue);
37244 this.fireEvent('blur', this);
37249 postBlur : Ext.emptyFn,
37252 isValid : function(preventMark){
37256 var restore = this.preventMark;
37257 this.preventMark = preventMark === true;
37258 var v = this.validateValue(this.processValue(this.getRawValue()));
37259 this.preventMark = restore;
37264 validate : function(){
37265 if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
37266 this.clearInvalid();
37273 processValue : function(value){
37278 validateValue : function(value) {
37280 var error = this.getErrors(value)[0];
37282 if (error == undefined) {
37285 this.markInvalid(error);
37291 getErrors: function() {
37296 getActiveError : function(){
37297 return this.activeError || '';
37301 markInvalid : function(msg){
37303 if (this.rendered && !this.preventMark) {
37304 msg = msg || this.invalidText;
37306 var mt = this.getMessageHandler();
37308 mt.mark(this, msg);
37309 }else if(this.msgTarget){
37310 this.el.addClass(this.invalidClass);
37311 var t = Ext.getDom(this.msgTarget);
37314 t.style.display = this.msgDisplay;
37319 this.setActiveError(msg);
37323 clearInvalid : function(){
37325 if (this.rendered && !this.preventMark) {
37326 this.el.removeClass(this.invalidClass);
37327 var mt = this.getMessageHandler();
37330 }else if(this.msgTarget){
37331 this.el.removeClass(this.invalidClass);
37332 var t = Ext.getDom(this.msgTarget);
37335 t.style.display = 'none';
37340 this.unsetActiveError();
37344 setActiveError: function(msg, suppressEvent) {
37345 this.activeError = msg;
37346 if (suppressEvent !== true) this.fireEvent('invalid', this, msg);
37350 unsetActiveError: function(suppressEvent) {
37351 delete this.activeError;
37352 if (suppressEvent !== true) this.fireEvent('valid', this);
37356 getMessageHandler : function(){
37357 return Ext.form.MessageTargets[this.msgTarget];
37361 getErrorCt : function(){
37362 return this.el.findParent('.x-form-element', 5, true) ||
37363 this.el.findParent('.x-form-field-wrap', 5, true);
37367 alignErrorEl : function(){
37368 this.errorEl.setWidth(this.getErrorCt().getWidth(true) - 20);
37372 alignErrorIcon : function(){
37373 this.errorIcon.alignTo(this.el, 'tl-tr', [2, 0]);
37377 getRawValue : function(){
37378 var v = this.rendered ? this.el.getValue() : Ext.value(this.value, '');
37379 if(v === this.emptyText){
37386 getValue : function(){
37387 if(!this.rendered) {
37390 var v = this.el.getValue();
37391 if(v === this.emptyText || v === undefined){
37398 setRawValue : function(v){
37399 return this.rendered ? (this.el.dom.value = (Ext.isEmpty(v) ? '' : v)) : '';
37403 setValue : function(v){
37406 this.el.dom.value = (Ext.isEmpty(v) ? '' : v);
37413 append : function(v){
37414 this.setValue([this.getValue(), v].join(''));
37424 Ext.form.MessageTargets = {
37426 mark: function(field, msg){
37427 field.el.addClass(field.invalidClass);
37428 field.el.dom.qtip = msg;
37429 field.el.dom.qclass = 'x-form-invalid-tip';
37431 Ext.QuickTips.enable();
37434 clear: function(field){
37435 field.el.removeClass(field.invalidClass);
37436 field.el.dom.qtip = '';
37440 mark: function(field, msg){
37441 field.el.addClass(field.invalidClass);
37442 field.el.dom.title = msg;
37444 clear: function(field){
37445 field.el.dom.title = '';
37449 mark: function(field, msg){
37450 field.el.addClass(field.invalidClass);
37451 if(!field.errorEl){
37452 var elp = field.getErrorCt();
37454 field.el.dom.title = msg;
37457 field.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
37458 field.on('resize', field.alignErrorEl, field);
37459 field.on('destroy', function(){
37460 Ext.destroy(this.errorEl);
37463 field.alignErrorEl();
37464 field.errorEl.update(msg);
37465 Ext.form.Field.msgFx[field.msgFx].show(field.errorEl, field);
37467 clear: function(field){
37468 field.el.removeClass(field.invalidClass);
37470 Ext.form.Field.msgFx[field.msgFx].hide(field.errorEl, field);
37472 field.el.dom.title = '';
37477 mark: function(field, msg){
37478 field.el.addClass(field.invalidClass);
37479 if(!field.errorIcon){
37480 var elp = field.getErrorCt();
37483 field.el.dom.title = msg;
37486 field.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
37487 if (field.ownerCt) {
37488 field.ownerCt.on('afterlayout', field.alignErrorIcon, field);
37489 field.ownerCt.on('expand', field.alignErrorIcon, field);
37491 field.on('resize', field.alignErrorIcon, field);
37492 field.on('destroy', function(){
37493 Ext.destroy(this.errorIcon);
37496 field.alignErrorIcon();
37497 field.errorIcon.dom.qtip = msg;
37498 field.errorIcon.dom.qclass = 'x-form-invalid-tip';
37499 field.errorIcon.show();
37501 clear: function(field){
37502 field.el.removeClass(field.invalidClass);
37503 if(field.errorIcon){
37504 field.errorIcon.dom.qtip = '';
37505 field.errorIcon.hide();
37507 field.el.dom.title = '';
37514 Ext.form.Field.msgFx = {
37516 show: function(msgEl, f){
37517 msgEl.setDisplayed('block');
37520 hide : function(msgEl, f){
37521 msgEl.setDisplayed(false).update('');
37526 show: function(msgEl, f){
37527 msgEl.slideIn('t', {stopFx:true});
37530 hide : function(msgEl, f){
37531 msgEl.slideOut('t', {stopFx:true,useDisplay:true});
37536 show: function(msgEl, f){
37537 msgEl.fixDisplay();
37538 msgEl.alignTo(f.el, 'tl-tr');
37539 msgEl.slideIn('l', {stopFx:true});
37542 hide : function(msgEl, f){
37543 msgEl.slideOut('l', {stopFx:true,useDisplay:true});
37547 Ext.reg('field', Ext.form.Field);
37549 Ext.form.TextField = Ext.extend(Ext.form.Field, {
37563 disableKeyFilter : false,
37569 maxLength : Number.MAX_VALUE,
37571 minLengthText : 'The minimum length for this field is {0}',
37573 maxLengthText : 'The maximum length for this field is {0}',
37575 selectOnFocus : false,
37577 blankText : 'This field is required',
37587 emptyClass : 'x-form-empty-field',
37591 initComponent : function(){
37592 Ext.form.TextField.superclass.initComponent.call(this);
37607 initEvents : function(){
37608 Ext.form.TextField.superclass.initEvents.call(this);
37609 if(this.validationEvent == 'keyup'){
37610 this.validationTask = new Ext.util.DelayedTask(this.validate, this);
37611 this.mon(this.el, 'keyup', this.filterValidation, this);
37613 else if(this.validationEvent !== false && this.validationEvent != 'blur'){
37614 this.mon(this.el, this.validationEvent, this.validate, this, {buffer: this.validationDelay});
37616 if(this.selectOnFocus || this.emptyText){
37617 this.mon(this.el, 'mousedown', this.onMouseDown, this);
37619 if(this.emptyText){
37620 this.applyEmptyText();
37623 if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Ext.form.VTypes[this.vtype+'Mask']))){
37624 this.mon(this.el, 'keypress', this.filterKeys, this);
37627 this.mon(this.el, 'keyup', this.onKeyUpBuffered, this, {buffer: 50});
37628 this.mon(this.el, 'click', this.autoSize, this);
37630 if(this.enableKeyEvents){
37631 this.mon(this.el, {
37633 keyup: this.onKeyUp,
37634 keydown: this.onKeyDown,
37635 keypress: this.onKeyPress
37640 onMouseDown: function(e){
37641 if(!this.hasFocus){
37642 this.mon(this.el, 'mouseup', Ext.emptyFn, this, { single: true, preventDefault: true });
37646 processValue : function(value){
37647 if(this.stripCharsRe){
37648 var newValue = value.replace(this.stripCharsRe, '');
37649 if(newValue !== value){
37650 this.setRawValue(newValue);
37657 filterValidation : function(e){
37658 if(!e.isNavKeyPress()){
37659 this.validationTask.delay(this.validationDelay);
37664 onDisable: function(){
37665 Ext.form.TextField.superclass.onDisable.call(this);
37667 this.el.dom.unselectable = 'on';
37672 onEnable: function(){
37673 Ext.form.TextField.superclass.onEnable.call(this);
37675 this.el.dom.unselectable = '';
37680 onKeyUpBuffered : function(e){
37681 if(this.doAutoSize(e)){
37687 doAutoSize : function(e){
37688 return !e.isNavKeyPress();
37692 onKeyUp : function(e){
37693 this.fireEvent('keyup', this, e);
37697 onKeyDown : function(e){
37698 this.fireEvent('keydown', this, e);
37702 onKeyPress : function(e){
37703 this.fireEvent('keypress', this, e);
37707 reset : function(){
37708 Ext.form.TextField.superclass.reset.call(this);
37709 this.applyEmptyText();
37712 applyEmptyText : function(){
37713 if(this.rendered && this.emptyText && this.getRawValue().length < 1 && !this.hasFocus){
37714 this.setRawValue(this.emptyText);
37715 this.el.addClass(this.emptyClass);
37720 preFocus : function(){
37722 if(this.emptyText){
37723 if(el.dom.value == this.emptyText){
37724 this.setRawValue('');
37726 el.removeClass(this.emptyClass);
37728 if(this.selectOnFocus){
37734 postBlur : function(){
37735 this.applyEmptyText();
37739 filterKeys : function(e){
37743 var k = e.getKey();
37744 if(Ext.isGecko && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
37747 var cc = String.fromCharCode(e.getCharCode());
37748 if(!Ext.isGecko && e.isSpecialKey() && !cc){
37751 if(!this.maskRe.test(cc)){
37756 setValue : function(v){
37757 if(this.emptyText && this.el && !Ext.isEmpty(v)){
37758 this.el.removeClass(this.emptyClass);
37760 Ext.form.TextField.superclass.setValue.apply(this, arguments);
37761 this.applyEmptyText();
37767 getErrors: function(value) {
37768 var errors = Ext.form.TextField.superclass.getErrors.apply(this, arguments);
37770 value = value || this.processValue(this.getRawValue());
37772 if (Ext.isFunction(this.validator)) {
37773 var msg = this.validator(value);
37774 if (msg !== true) {
37779 if (value.length < 1 || value === this.emptyText) {
37780 if (this.allowBlank) {
37784 errors.push(this.blankText);
37788 if (!this.allowBlank && (value.length < 1 || value === this.emptyText)) {
37789 errors.push(this.blankText);
37792 if (value.length < this.minLength) {
37793 errors.push(String.format(this.minLengthText, this.minLength));
37796 if (value.length > this.maxLength) {
37797 errors.push(String.format(this.maxLengthText, this.maxLength));
37801 var vt = Ext.form.VTypes;
37802 if(!vt[this.vtype](value, this)){
37803 errors.push(this.vtypeText || vt[this.vtype +'Text']);
37807 if (this.regex && !this.regex.test(value)) {
37808 errors.push(this.regexText);
37815 selectText : function(start, end){
37816 var v = this.getRawValue();
37817 var doFocus = false;
37819 start = start === undefined ? 0 : start;
37820 end = end === undefined ? v.length : end;
37821 var d = this.el.dom;
37822 if(d.setSelectionRange){
37823 d.setSelectionRange(start, end);
37824 }else if(d.createTextRange){
37825 var range = d.createTextRange();
37826 range.moveStart('character', start);
37827 range.moveEnd('character', end-v.length);
37830 doFocus = Ext.isGecko || Ext.isOpera;
37840 autoSize : function(){
37841 if(!this.grow || !this.rendered){
37845 this.metrics = Ext.util.TextMetrics.createInstance(this.el);
37848 var v = el.dom.value;
37849 var d = document.createElement('div');
37850 d.appendChild(document.createTextNode(v));
37855 var w = Math.min(this.growMax, Math.max(this.metrics.getWidth(v) + 10, this.growMin));
37856 this.el.setWidth(w);
37857 this.fireEvent('autosize', this, w);
37860 onDestroy: function(){
37861 if(this.validationTask){
37862 this.validationTask.cancel();
37863 this.validationTask = null;
37865 Ext.form.TextField.superclass.onDestroy.call(this);
37868 Ext.reg('textfield', Ext.form.TextField);
37870 Ext.form.TriggerField = Ext.extend(Ext.form.TextField, {
37874 defaultAutoCreate : {tag: "input", type: "text", size: "16", autocomplete: "off"},
37882 wrapFocusClass: 'x-trigger-wrap-focus',
37884 autoSize: Ext.emptyFn,
37888 deferHeight : true,
37892 actionMode: 'wrap',
37894 defaultTriggerWidth: 17,
37897 onResize : function(w, h){
37898 Ext.form.TriggerField.superclass.onResize.call(this, w, h);
37899 var tw = this.getTriggerWidth();
37900 if(Ext.isNumber(w)){
37901 this.el.setWidth(w - tw);
37903 this.wrap.setWidth(this.el.getWidth() + tw);
37906 getTriggerWidth: function(){
37907 var tw = this.trigger.getWidth();
37908 if(!this.hideTrigger && !this.readOnly && tw === 0){
37909 tw = this.defaultTriggerWidth;
37915 alignErrorIcon : function(){
37917 this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
37922 onRender : function(ct, position){
37923 this.doc = Ext.isIE ? Ext.getBody() : Ext.getDoc();
37924 Ext.form.TriggerField.superclass.onRender.call(this, ct, position);
37926 this.wrap = this.el.wrap({cls: 'x-form-field-wrap x-form-field-trigger-wrap'});
37927 this.trigger = this.wrap.createChild(this.triggerConfig ||
37928 {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.triggerClass});
37929 this.initTrigger();
37931 this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
37933 this.resizeEl = this.positionEl = this.wrap;
37936 getWidth: function() {
37937 return(this.el.getWidth() + this.trigger.getWidth());
37940 updateEditState: function(){
37942 if (this.readOnly) {
37943 this.el.dom.readOnly = true;
37944 this.el.addClass('x-trigger-noedit');
37945 this.mun(this.el, 'click', this.onTriggerClick, this);
37946 this.trigger.setDisplayed(false);
37948 if (!this.editable) {
37949 this.el.dom.readOnly = true;
37950 this.el.addClass('x-trigger-noedit');
37951 this.mon(this.el, 'click', this.onTriggerClick, this);
37953 this.el.dom.readOnly = false;
37954 this.el.removeClass('x-trigger-noedit');
37955 this.mun(this.el, 'click', this.onTriggerClick, this);
37957 this.trigger.setDisplayed(!this.hideTrigger);
37959 this.onResize(this.width || this.wrap.getWidth());
37963 setHideTrigger: function(hideTrigger){
37964 if(hideTrigger != this.hideTrigger){
37965 this.hideTrigger = hideTrigger;
37966 this.updateEditState();
37971 setEditable: function(editable){
37972 if(editable != this.editable){
37973 this.editable = editable;
37974 this.updateEditState();
37979 setReadOnly: function(readOnly){
37980 if(readOnly != this.readOnly){
37981 this.readOnly = readOnly;
37982 this.updateEditState();
37986 afterRender : function(){
37987 Ext.form.TriggerField.superclass.afterRender.call(this);
37988 this.updateEditState();
37992 initTrigger : function(){
37993 this.mon(this.trigger, 'click', this.onTriggerClick, this, {preventDefault:true});
37994 this.trigger.addClassOnOver('x-form-trigger-over');
37995 this.trigger.addClassOnClick('x-form-trigger-click');
37999 onDestroy : function(){
38000 Ext.destroy(this.trigger, this.wrap);
38001 if (this.mimicing){
38002 this.doc.un('mousedown', this.mimicBlur, this);
38005 Ext.form.TriggerField.superclass.onDestroy.call(this);
38009 onFocus : function(){
38010 Ext.form.TriggerField.superclass.onFocus.call(this);
38011 if(!this.mimicing){
38012 this.wrap.addClass(this.wrapFocusClass);
38013 this.mimicing = true;
38014 this.doc.on('mousedown', this.mimicBlur, this, {delay: 10});
38015 if(this.monitorTab){
38016 this.on('specialkey', this.checkTab, this);
38022 checkTab : function(me, e){
38023 if(e.getKey() == e.TAB){
38024 this.triggerBlur();
38029 onBlur : Ext.emptyFn,
38032 mimicBlur : function(e){
38033 if(!this.isDestroyed && !this.wrap.contains(e.target) && this.validateBlur(e)){
38034 this.triggerBlur();
38039 triggerBlur : function(){
38040 this.mimicing = false;
38041 this.doc.un('mousedown', this.mimicBlur, this);
38042 if(this.monitorTab && this.el){
38043 this.un('specialkey', this.checkTab, this);
38045 Ext.form.TriggerField.superclass.onBlur.call(this);
38047 this.wrap.removeClass(this.wrapFocusClass);
38051 beforeBlur : Ext.emptyFn,
38055 validateBlur : function(e){
38060 onTriggerClick : Ext.emptyFn
38068 Ext.form.TwinTriggerField = Ext.extend(Ext.form.TriggerField, {
38073 initComponent : function(){
38074 Ext.form.TwinTriggerField.superclass.initComponent.call(this);
38076 this.triggerConfig = {
38077 tag:'span', cls:'x-form-twin-triggers', cn:[
38078 {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger1Class},
38079 {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger2Class}
38083 getTrigger : function(index){
38084 return this.triggers[index];
38087 initTrigger : function(){
38088 var ts = this.trigger.select('.x-form-trigger', true);
38089 var triggerField = this;
38090 ts.each(function(t, all, index){
38091 var triggerIndex = 'Trigger'+(index+1);
38092 t.hide = function(){
38093 var w = triggerField.wrap.getWidth();
38094 this.dom.style.display = 'none';
38095 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
38096 this['hidden' + triggerIndex] = true;
38098 t.show = function(){
38099 var w = triggerField.wrap.getWidth();
38100 this.dom.style.display = '';
38101 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
38102 this['hidden' + triggerIndex] = false;
38105 if(this['hide'+triggerIndex]){
38106 t.dom.style.display = 'none';
38107 this['hidden' + triggerIndex] = true;
38109 this.mon(t, 'click', this['on'+triggerIndex+'Click'], this, {preventDefault:true});
38110 t.addClassOnOver('x-form-trigger-over');
38111 t.addClassOnClick('x-form-trigger-click');
38113 this.triggers = ts.elements;
38116 getTriggerWidth: function(){
38118 Ext.each(this.triggers, function(t, index){
38119 var triggerIndex = 'Trigger' + (index + 1),
38121 if(w === 0 && !this['hidden' + triggerIndex]){
38122 tw += this.defaultTriggerWidth;
38131 onDestroy : function() {
38132 Ext.destroy(this.triggers);
38133 Ext.form.TwinTriggerField.superclass.onDestroy.call(this);
38137 onTrigger1Click : Ext.emptyFn,
38139 onTrigger2Click : Ext.emptyFn
38141 Ext.reg('trigger', Ext.form.TriggerField);
38143 Ext.form.TextArea = Ext.extend(Ext.form.TextField, {
38148 growAppend : ' \n ',
38150 enterIsSpecial : false,
38153 preventScrollbars: false,
38157 onRender : function(ct, position){
38159 this.defaultAutoCreate = {
38161 style:"width:100px;height:60px;",
38162 autocomplete: "off"
38165 Ext.form.TextArea.superclass.onRender.call(this, ct, position);
38167 this.textSizeEl = Ext.DomHelper.append(document.body, {
38168 tag: "pre", cls: "x-form-grow-sizer"
38170 if(this.preventScrollbars){
38171 this.el.setStyle("overflow", "hidden");
38173 this.el.setHeight(this.growMin);
38177 onDestroy : function(){
38178 Ext.removeNode(this.textSizeEl);
38179 Ext.form.TextArea.superclass.onDestroy.call(this);
38182 fireKey : function(e){
38183 if(e.isSpecialKey() && (this.enterIsSpecial || (e.getKey() != e.ENTER || e.hasModifier()))){
38184 this.fireEvent("specialkey", this, e);
38189 doAutoSize : function(e){
38190 return !e.isNavKeyPress() || e.getKey() == e.ENTER;
38194 autoSize: function(){
38195 if(!this.grow || !this.textSizeEl){
38199 v = Ext.util.Format.htmlEncode(el.dom.value),
38200 ts = this.textSizeEl,
38203 Ext.fly(ts).setWidth(this.el.getWidth());
38205 v = "  ";
38207 v += this.growAppend;
38209 v = v.replace(/\n/g, ' <br />');
38213 h = Math.min(this.growMax, Math.max(ts.offsetHeight, this.growMin));
38214 if(h != this.lastHeight){
38215 this.lastHeight = h;
38216 this.el.setHeight(h);
38217 this.fireEvent("autosize", this, h);
38221 Ext.reg('textarea', Ext.form.TextArea);
38222 Ext.form.NumberField = Ext.extend(Ext.form.TextField, {
38226 fieldClass: "x-form-field x-form-num-field",
38228 allowDecimals : true,
38230 decimalSeparator : ".",
38232 decimalPrecision : 2,
38234 allowNegative : true,
38236 minValue : Number.NEGATIVE_INFINITY,
38238 maxValue : Number.MAX_VALUE,
38240 minText : "The minimum value for this field is {0}",
38242 maxText : "The maximum value for this field is {0}",
38244 nanText : "{0} is not a valid number",
38246 baseChars : "0123456789",
38249 initEvents : function(){
38250 var allowed = this.baseChars + '';
38251 if (this.allowDecimals) {
38252 allowed += this.decimalSeparator;
38254 if (this.allowNegative) {
38257 this.maskRe = new RegExp('[' + Ext.escapeRe(allowed) + ']');
38258 Ext.form.NumberField.superclass.initEvents.call(this);
38262 getErrors: function(value) {
38263 var errors = Ext.form.NumberField.superclass.getErrors.apply(this, arguments);
38265 value = value || this.processValue(this.getRawValue());
38267 if (value.length < 1) {
38271 value = String(value).replace(this.decimalSeparator, ".");
38274 errors.push(String.format(this.nanText, value));
38277 var num = this.parseValue(value);
38279 if(num < this.minValue){
38280 errors.push(String.format(this.minText, this.minValue));
38283 if(num > this.maxValue){
38284 errors.push(String.format(this.maxText, this.maxValue));
38290 getValue : function(){
38291 return this.fixPrecision(this.parseValue(Ext.form.NumberField.superclass.getValue.call(this)));
38294 setValue : function(v){
38295 v = Ext.isNumber(v) ? v : parseFloat(String(v).replace(this.decimalSeparator, "."));
38296 v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator);
38297 return Ext.form.NumberField.superclass.setValue.call(this, v);
38301 setMinValue : function(value){
38302 this.minValue = Ext.num(value, Number.NEGATIVE_INFINITY);
38306 setMaxValue : function(value){
38307 this.maxValue = Ext.num(value, Number.MAX_VALUE);
38311 parseValue : function(value){
38312 value = parseFloat(String(value).replace(this.decimalSeparator, "."));
38313 return isNaN(value) ? '' : value;
38317 fixPrecision : function(value){
38318 var nan = isNaN(value);
38319 if(!this.allowDecimals || this.decimalPrecision == -1 || nan || !value){
38320 return nan ? '' : value;
38322 return parseFloat(parseFloat(value).toFixed(this.decimalPrecision));
38325 beforeBlur : function(){
38326 var v = this.parseValue(this.getRawValue());
38327 if(!Ext.isEmpty(v)){
38328 this.setValue(this.fixPrecision(v));
38332 Ext.reg('numberfield', Ext.form.NumberField);
38333 Ext.form.DateField = Ext.extend(Ext.form.TriggerField, {
38337 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",
38339 disabledDaysText : "Disabled",
38341 disabledDatesText : "Disabled",
38343 minText : "The date in this field must be equal to or after {0}",
38345 maxText : "The date in this field must be equal to or before {0}",
38347 invalidText : "{0} is not a valid date - it must be in the format {1}",
38349 triggerClass : 'x-form-date-trigger',
38359 defaultAutoCreate : {tag: "input", type: "text", size: "10", autocomplete: "off"},
38365 initTimeFormat: 'H',
38368 safeParse : function(value, format) {
38369 if (/[gGhH]/.test(format.replace(/(\\.)/g, ''))) {
38371 return Date.parseDate(value, format);
38374 var parsedDate = Date.parseDate(value + ' ' + this.initTime, format + ' ' + this.initTimeFormat);
38376 if (parsedDate) return parsedDate.clearTime();
38380 initComponent : function(){
38381 Ext.form.DateField.superclass.initComponent.call(this);
38388 if(Ext.isString(this.minValue)){
38389 this.minValue = this.parseDate(this.minValue);
38391 if(Ext.isString(this.maxValue)){
38392 this.maxValue = this.parseDate(this.maxValue);
38394 this.disabledDatesRE = null;
38395 this.initDisabledDays();
38398 initEvents: function() {
38399 Ext.form.DateField.superclass.initEvents.call(this);
38400 this.keyNav = new Ext.KeyNav(this.el, {
38401 "down": function(e) {
38402 this.onTriggerClick();
38411 initDisabledDays : function(){
38412 if(this.disabledDates){
38413 var dd = this.disabledDates,
38414 len = dd.length - 1,
38417 Ext.each(dd, function(d, i){
38418 re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i];
38423 this.disabledDatesRE = new RegExp(re + ')');
38428 setDisabledDates : function(dd){
38429 this.disabledDates = dd;
38430 this.initDisabledDays();
38432 this.menu.picker.setDisabledDates(this.disabledDatesRE);
38437 setDisabledDays : function(dd){
38438 this.disabledDays = dd;
38440 this.menu.picker.setDisabledDays(dd);
38445 setMinValue : function(dt){
38446 this.minValue = (Ext.isString(dt) ? this.parseDate(dt) : dt);
38448 this.menu.picker.setMinDate(this.minValue);
38453 setMaxValue : function(dt){
38454 this.maxValue = (Ext.isString(dt) ? this.parseDate(dt) : dt);
38456 this.menu.picker.setMaxDate(this.maxValue);
38461 getErrors: function(value) {
38462 var errors = Ext.form.DateField.superclass.getErrors.apply(this, arguments);
38464 value = this.formatDate(value || this.processValue(this.getRawValue()));
38466 if (value.length < 1) {
38470 var svalue = value;
38471 value = this.parseDate(value);
38473 errors.push(String.format(this.invalidText, svalue, this.format));
38477 var time = value.getTime();
38478 if (this.minValue && time < this.minValue.getTime()) {
38479 errors.push(String.format(this.minText, this.formatDate(this.minValue)));
38482 if (this.maxValue && time > this.maxValue.getTime()) {
38483 errors.push(String.format(this.maxText, this.formatDate(this.maxValue)));
38486 if (this.disabledDays) {
38487 var day = value.getDay();
38489 for(var i = 0; i < this.disabledDays.length; i++) {
38490 if (day === this.disabledDays[i]) {
38491 errors.push(this.disabledDaysText);
38497 var fvalue = this.formatDate(value);
38498 if (this.disabledDatesRE && this.disabledDatesRE.test(fvalue)) {
38499 errors.push(String.format(this.disabledDatesText, fvalue));
38507 validateBlur : function(){
38508 return !this.menu || !this.menu.isVisible();
38512 getValue : function(){
38513 return this.parseDate(Ext.form.DateField.superclass.getValue.call(this)) || "";
38517 setValue : function(date){
38518 return Ext.form.DateField.superclass.setValue.call(this, this.formatDate(this.parseDate(date)));
38522 parseDate : function(value) {
38523 if(!value || Ext.isDate(value)){
38527 var v = this.safeParse(value, this.format),
38528 af = this.altFormats,
38529 afa = this.altFormatsArray;
38532 afa = afa || af.split("|");
38534 for (var i = 0, len = afa.length; i < len && !v; i++) {
38535 v = this.safeParse(value, afa[i]);
38542 onDestroy : function(){
38543 Ext.destroy(this.menu, this.keyNav);
38544 Ext.form.DateField.superclass.onDestroy.call(this);
38548 formatDate : function(date){
38549 return Ext.isDate(date) ? date.dateFormat(this.format) : date;
38555 onTriggerClick : function(){
38559 if(this.menu == null){
38560 this.menu = new Ext.menu.DateMenu({
38561 hideOnClick: false,
38562 focusOnSelect: false
38566 Ext.apply(this.menu.picker, {
38567 minDate : this.minValue,
38568 maxDate : this.maxValue,
38569 disabledDatesRE : this.disabledDatesRE,
38570 disabledDatesText : this.disabledDatesText,
38571 disabledDays : this.disabledDays,
38572 disabledDaysText : this.disabledDaysText,
38573 format : this.format,
38574 showToday : this.showToday,
38575 minText : String.format(this.minText, this.formatDate(this.minValue)),
38576 maxText : String.format(this.maxText, this.formatDate(this.maxValue))
38578 this.menu.picker.setValue(this.getValue() || new Date());
38579 this.menu.show(this.el, "tl-bl?");
38580 this.menuEvents('on');
38584 menuEvents: function(method){
38585 this.menu[method]('select', this.onSelect, this);
38586 this.menu[method]('hide', this.onMenuHide, this);
38587 this.menu[method]('show', this.onFocus, this);
38590 onSelect: function(m, d){
38592 this.fireEvent('select', this, d);
38596 onMenuHide: function(){
38597 this.focus(false, 60);
38598 this.menuEvents('un');
38602 beforeBlur : function(){
38603 var v = this.parseDate(this.getRawValue());
38614 Ext.reg('datefield', Ext.form.DateField);
38615 Ext.form.DisplayField = Ext.extend(Ext.form.Field, {
38616 validationEvent : false,
38617 validateOnBlur : false,
38618 defaultAutoCreate : {tag: "div"},
38620 fieldClass : "x-form-display-field",
38625 initEvents : Ext.emptyFn,
38627 isValid : function(){
38631 validate : function(){
38635 getRawValue : function(){
38636 var v = this.rendered ? this.el.dom.innerHTML : Ext.value(this.value, '');
38637 if(v === this.emptyText){
38640 if(this.htmlEncode){
38641 v = Ext.util.Format.htmlDecode(v);
38646 getValue : function(){
38647 return this.getRawValue();
38650 getName: function() {
38654 setRawValue : function(v){
38655 if(this.htmlEncode){
38656 v = Ext.util.Format.htmlEncode(v);
38658 return this.rendered ? (this.el.dom.innerHTML = (Ext.isEmpty(v) ? '' : v)) : (this.value = v);
38661 setValue : function(v){
38662 this.setRawValue(v);
38673 Ext.reg('displayfield', Ext.form.DisplayField);
38675 Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
38683 defaultAutoCreate : {tag: "input", type: "text", size: "24", autocomplete: "off"},
38693 selectedClass : 'x-combo-selected',
38697 triggerClass : 'x-form-arrow-trigger',
38701 listAlign : 'tl-bl?',
38707 triggerAction : 'query',
38719 selectOnFocus : false,
38721 queryParam : 'query',
38723 loadingText : 'Loading...',
38735 forceSelection : false,
38737 typeAheadDelay : 250,
38744 clearFilterOnReset : true,
38747 submitValue: undefined,
38752 initComponent : function(){
38753 Ext.form.ComboBox.superclass.initComponent.call(this);
38767 if(this.transform){
38768 var s = Ext.getDom(this.transform);
38769 if(!this.hiddenName){
38770 this.hiddenName = s.name;
38773 this.mode = 'local';
38774 var d = [], opts = s.options;
38775 for(var i = 0, len = opts.length;i < len; i++){
38777 value = (o.hasAttribute ? o.hasAttribute('value') : o.getAttributeNode('value').specified) ? o.value : o.text;
38778 if(o.selected && Ext.isEmpty(this.value, true)) {
38779 this.value = value;
38781 d.push([value, o.text]);
38783 this.store = new Ext.data.ArrayStore({
38785 fields: ['value', 'text'],
38789 this.valueField = 'value';
38790 this.displayField = 'text';
38793 if(!this.lazyRender){
38794 this.target = true;
38795 this.el = Ext.DomHelper.insertBefore(s, this.autoCreate || this.defaultAutoCreate);
38796 this.render(this.el.parentNode, s);
38801 else if(this.store){
38802 this.store = Ext.StoreMgr.lookup(this.store);
38803 if(this.store.autoCreated){
38804 this.displayField = this.valueField = 'field1';
38805 if(!this.store.expandData){
38806 this.displayField = 'field2';
38808 this.mode = 'local';
38812 this.selectedIndex = -1;
38813 if(this.mode == 'local'){
38814 if(!Ext.isDefined(this.initialConfig.queryDelay)){
38815 this.queryDelay = 10;
38817 if(!Ext.isDefined(this.initialConfig.minChars)){
38824 onRender : function(ct, position){
38825 if(this.hiddenName && !Ext.isDefined(this.submitValue)){
38826 this.submitValue = false;
38828 Ext.form.ComboBox.superclass.onRender.call(this, ct, position);
38829 if(this.hiddenName){
38830 this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName,
38831 id: (this.hiddenId||this.hiddenName)}, 'before', true);
38835 this.el.dom.setAttribute('autocomplete', 'off');
38838 if(!this.lazyInit){
38841 this.on('focus', this.initList, this, {single: true});
38846 initValue : function(){
38847 Ext.form.ComboBox.superclass.initValue.call(this);
38848 if(this.hiddenField){
38849 this.hiddenField.value =
38850 Ext.value(Ext.isDefined(this.hiddenValue) ? this.hiddenValue : this.value, '');
38854 getParentZIndex : function(){
38857 this.findParentBy(function(ct){
38858 zindex = parseInt(ct.getPositionEl().getStyle('z-index'), 10);
38866 initList : function(){
38868 var cls = 'x-combo-list',
38869 listParent = Ext.getDom(this.getListParent() || Ext.getBody()),
38870 zindex = parseInt(Ext.fly(listParent).getStyle('z-index'), 10);
38873 zindex = this.getParentZIndex();
38876 this.list = new Ext.Layer({
38877 parentEl: listParent,
38878 shadow: this.shadow,
38879 cls: [cls, this.listClass].join(' '),
38881 zindex: (zindex || 12000) + 5
38884 var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
38885 this.list.setSize(lw, 0);
38886 this.list.swallowEvent('mousewheel');
38887 this.assetHeight = 0;
38888 if(this.syncFont !== false){
38889 this.list.setStyle('font-size', this.el.getStyle('font-size'));
38892 this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
38893 this.assetHeight += this.header.getHeight();
38896 this.innerList = this.list.createChild({cls:cls+'-inner'});
38897 this.mon(this.innerList, 'mouseover', this.onViewOver, this);
38898 this.mon(this.innerList, 'mousemove', this.onViewMove, this);
38899 this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
38902 this.footer = this.list.createChild({cls:cls+'-ft'});
38903 this.pageTb = new Ext.PagingToolbar({
38905 pageSize: this.pageSize,
38906 renderTo:this.footer
38908 this.assetHeight += this.footer.getHeight();
38913 this.tpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';
38918 this.view = new Ext.DataView({
38919 applyTo: this.innerList,
38921 singleSelect: true,
38922 selectedClass: this.selectedClass,
38923 itemSelector: this.itemSelector || '.' + cls + '-item',
38924 emptyText: this.listEmptyText,
38925 deferEmptyText: false
38928 this.mon(this.view, {
38929 containerclick : this.onViewClick,
38930 click : this.onViewClick,
38934 this.bindStore(this.store, true);
38936 if(this.resizable){
38937 this.resizer = new Ext.Resizable(this.list, {
38938 pinned:true, handles:'se'
38940 this.mon(this.resizer, 'resize', function(r, w, h){
38941 this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
38942 this.listWidth = w;
38943 this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
38944 this.restrictHeight();
38947 this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
38953 getListParent : function() {
38954 return document.body;
38958 getStore : function(){
38963 bindStore : function(store, initial){
38964 if(this.store && !initial){
38965 if(this.store !== store && this.store.autoDestroy){
38966 this.store.destroy();
38968 this.store.un('beforeload', this.onBeforeLoad, this);
38969 this.store.un('load', this.onLoad, this);
38970 this.store.un('exception', this.collapse, this);
38975 this.view.bindStore(null);
38978 this.pageTb.bindStore(null);
38984 this.lastQuery = null;
38986 this.pageTb.bindStore(store);
38990 this.store = Ext.StoreMgr.lookup(store);
38993 beforeload: this.onBeforeLoad,
38995 exception: this.collapse
38999 this.view.bindStore(store);
39004 reset : function(){
39005 Ext.form.ComboBox.superclass.reset.call(this);
39006 if(this.clearFilterOnReset && this.mode == 'local'){
39007 this.store.clearFilter();
39012 initEvents : function(){
39013 Ext.form.ComboBox.superclass.initEvents.call(this);
39016 this.keyNav = new Ext.KeyNav(this.el, {
39017 "up" : function(e){
39018 this.inKeyMode = true;
39022 "down" : function(e){
39023 if(!this.isExpanded()){
39024 this.onTriggerClick();
39026 this.inKeyMode = true;
39031 "enter" : function(e){
39032 this.onViewClick();
39035 "esc" : function(e){
39039 "tab" : function(e){
39040 if (this.forceSelection === true) {
39043 this.onViewClick(false);
39050 doRelay : function(e, h, hname){
39051 if(hname == 'down' || this.scope.isExpanded()){
39053 var relay = Ext.KeyNav.prototype.doRelay.apply(this, arguments);
39054 if(!Ext.isIE && Ext.EventManager.useKeydown){
39056 this.scope.fireKey(e);
39063 forceKeyDown : true,
39064 defaultEventAction: 'stopEvent'
39066 this.queryDelay = Math.max(this.queryDelay || 10,
39067 this.mode == 'local' ? 10 : 250);
39068 this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);
39069 if(this.typeAhead){
39070 this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
39072 if(!this.enableKeyEvents){
39073 this.mon(this.el, 'keyup', this.onKeyUp, this);
39079 onDestroy : function(){
39081 this.dqTask.cancel();
39082 this.dqTask = null;
39084 this.bindStore(null);
39091 Ext.destroyMembers(this, 'hiddenField');
39092 Ext.form.ComboBox.superclass.onDestroy.call(this);
39096 fireKey : function(e){
39097 if (!this.isExpanded()) {
39098 Ext.form.ComboBox.superclass.fireKey.call(this, e);
39103 onResize : function(w, h){
39104 Ext.form.ComboBox.superclass.onResize.apply(this, arguments);
39105 if(!isNaN(w) && this.isVisible() && this.list){
39108 this.bufferSize = w;
39112 doResize: function(w){
39113 if(!Ext.isDefined(this.listWidth)){
39114 var lw = Math.max(w, this.minListWidth);
39115 this.list.setWidth(lw);
39116 this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
39121 onEnable : function(){
39122 Ext.form.ComboBox.superclass.onEnable.apply(this, arguments);
39123 if(this.hiddenField){
39124 this.hiddenField.disabled = false;
39129 onDisable : function(){
39130 Ext.form.ComboBox.superclass.onDisable.apply(this, arguments);
39131 if(this.hiddenField){
39132 this.hiddenField.disabled = true;
39137 onBeforeLoad : function(){
39138 if(!this.hasFocus){
39141 this.innerList.update(this.loadingText ?
39142 '<div class="loading-indicator">'+this.loadingText+'</div>' : '');
39143 this.restrictHeight();
39144 this.selectedIndex = -1;
39148 onLoad : function(){
39149 if(!this.hasFocus){
39152 if(this.store.getCount() > 0 || this.listEmptyText){
39154 this.restrictHeight();
39155 if(this.lastQuery == this.allQuery){
39157 this.el.dom.select();
39160 if(this.autoSelect !== false && !this.selectByValue(this.value, true)){
39161 this.select(0, true);
39164 if(this.autoSelect !== false){
39167 if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){
39168 this.taTask.delay(this.typeAheadDelay);
39178 onTypeAhead : function(){
39179 if(this.store.getCount() > 0){
39180 var r = this.store.getAt(0);
39181 var newValue = r.data[this.displayField];
39182 var len = newValue.length;
39183 var selStart = this.getRawValue().length;
39184 if(selStart != len){
39185 this.setRawValue(newValue);
39186 this.selectText(selStart, newValue.length);
39192 assertValue : function(){
39193 var val = this.getRawValue(),
39194 rec = this.findRecord(this.displayField, val);
39196 if(!rec && this.forceSelection){
39197 if(val.length > 0 && val != this.emptyText){
39198 this.el.dom.value = Ext.value(this.lastSelectionText, '');
39199 this.applyEmptyText();
39208 if (val == rec.get(this.displayField) && this.value == rec.get(this.valueField)){
39211 val = rec.get(this.valueField || this.displayField);
39213 this.setValue(val);
39218 onSelect : function(record, index){
39219 if(this.fireEvent('beforeselect', this, record, index) !== false){
39220 this.setValue(record.data[this.valueField || this.displayField]);
39222 this.fireEvent('select', this, record, index);
39227 getName: function(){
39228 var hf = this.hiddenField;
39229 return hf && hf.name ? hf.name : this.hiddenName || Ext.form.ComboBox.superclass.getName.call(this);
39233 getValue : function(){
39234 if(this.valueField){
39235 return Ext.isDefined(this.value) ? this.value : '';
39237 return Ext.form.ComboBox.superclass.getValue.call(this);
39242 clearValue : function(){
39243 if(this.hiddenField){
39244 this.hiddenField.value = '';
39246 this.setRawValue('');
39247 this.lastSelectionText = '';
39248 this.applyEmptyText();
39253 setValue : function(v){
39255 if(this.valueField){
39256 var r = this.findRecord(this.valueField, v);
39258 text = r.data[this.displayField];
39259 }else if(Ext.isDefined(this.valueNotFoundText)){
39260 text = this.valueNotFoundText;
39263 this.lastSelectionText = text;
39264 if(this.hiddenField){
39265 this.hiddenField.value = Ext.value(v, '');
39267 Ext.form.ComboBox.superclass.setValue.call(this, text);
39273 findRecord : function(prop, value){
39275 if(this.store.getCount() > 0){
39276 this.store.each(function(r){
39277 if(r.data[prop] == value){
39287 onViewMove : function(e, t){
39288 this.inKeyMode = false;
39292 onViewOver : function(e, t){
39293 if(this.inKeyMode){
39296 var item = this.view.findItemFromChild(t);
39298 var index = this.view.indexOf(item);
39299 this.select(index, false);
39304 onViewClick : function(doFocus){
39305 var index = this.view.getSelectedIndexes()[0],
39307 r = s.getAt(index);
39309 this.onSelect(r, index);
39313 if(doFocus !== false){
39320 restrictHeight : function(){
39321 this.innerList.dom.style.height = '';
39322 var inner = this.innerList.dom,
39323 pad = this.list.getFrameWidth('tb') + (this.resizable ? this.handleHeight : 0) + this.assetHeight,
39324 h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight),
39325 ha = this.getPosition()[1]-Ext.getBody().getScroll().top,
39326 hb = Ext.lib.Dom.getViewHeight()-ha-this.getSize().height,
39327 space = Math.max(ha, hb, this.minHeight || 0)-this.list.shadowOffset-pad-5;
39329 h = Math.min(h, space, this.maxHeight);
39331 this.innerList.setHeight(h);
39332 this.list.beginUpdate();
39333 this.list.setHeight(h+pad);
39334 this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
39335 this.list.endUpdate();
39339 isExpanded : function(){
39340 return this.list && this.list.isVisible();
39344 selectByValue : function(v, scrollIntoView){
39345 if(!Ext.isEmpty(v, true)){
39346 var r = this.findRecord(this.valueField || this.displayField, v);
39348 this.select(this.store.indexOf(r), scrollIntoView);
39356 select : function(index, scrollIntoView){
39357 this.selectedIndex = index;
39358 this.view.select(index);
39359 if(scrollIntoView !== false){
39360 var el = this.view.getNode(index);
39362 this.innerList.scrollChildIntoView(el, false);
39369 selectNext : function(){
39370 var ct = this.store.getCount();
39372 if(this.selectedIndex == -1){
39374 }else if(this.selectedIndex < ct-1){
39375 this.select(this.selectedIndex+1);
39381 selectPrev : function(){
39382 var ct = this.store.getCount();
39384 if(this.selectedIndex == -1){
39386 }else if(this.selectedIndex !== 0){
39387 this.select(this.selectedIndex-1);
39393 onKeyUp : function(e){
39394 var k = e.getKey();
39395 if(this.editable !== false && this.readOnly !== true && (k == e.BACKSPACE || !e.isSpecialKey())){
39398 this.dqTask.delay(this.queryDelay);
39400 Ext.form.ComboBox.superclass.onKeyUp.call(this, e);
39404 validateBlur : function(){
39405 return !this.list || !this.list.isVisible();
39409 initQuery : function(){
39410 this.doQuery(this.getRawValue());
39414 beforeBlur : function(){
39415 this.assertValue();
39419 postBlur : function(){
39420 Ext.form.ComboBox.superclass.postBlur.call(this);
39422 this.inKeyMode = false;
39426 doQuery : function(q, forceAll){
39427 q = Ext.isEmpty(q) ? '' : q;
39430 forceAll: forceAll,
39434 if(this.fireEvent('beforequery', qe)===false || qe.cancel){
39438 forceAll = qe.forceAll;
39439 if(forceAll === true || (q.length >= this.minChars)){
39440 if(this.lastQuery !== q){
39441 this.lastQuery = q;
39442 if(this.mode == 'local'){
39443 this.selectedIndex = -1;
39445 this.store.clearFilter();
39447 this.store.filter(this.displayField, q);
39451 this.store.baseParams[this.queryParam] = q;
39453 params: this.getParams(q)
39458 this.selectedIndex = -1;
39465 getParams : function(q){
39470 p.limit = this.pageSize;
39476 collapse : function(){
39477 if(!this.isExpanded()){
39481 Ext.getDoc().un('mousewheel', this.collapseIf, this);
39482 Ext.getDoc().un('mousedown', this.collapseIf, this);
39483 this.fireEvent('collapse', this);
39487 collapseIf : function(e){
39488 if(!this.isDestroyed && !e.within(this.wrap) && !e.within(this.list)){
39494 expand : function(){
39495 if(this.isExpanded() || !this.hasFocus){
39499 if(this.title || this.pageSize){
39500 this.assetHeight = 0;
39502 this.assetHeight += this.header.getHeight();
39505 this.assetHeight += this.footer.getHeight();
39509 if(this.bufferSize){
39510 this.doResize(this.bufferSize);
39511 delete this.bufferSize;
39513 this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
39516 var listParent = Ext.getDom(this.getListParent() || Ext.getBody()),
39517 zindex = parseInt(Ext.fly(listParent).getStyle('z-index') ,10);
39519 zindex = this.getParentZIndex();
39522 this.list.setZIndex(zindex + 5);
39526 this.innerList.setOverflow('auto');
39528 this.mon(Ext.getDoc(), {
39530 mousewheel: this.collapseIf,
39531 mousedown: this.collapseIf
39533 this.fireEvent('expand', this);
39539 onTriggerClick : function(){
39540 if(this.readOnly || this.disabled){
39543 if(this.isExpanded()){
39548 if(this.triggerAction == 'all') {
39549 this.doQuery(this.allQuery, true);
39551 this.doQuery(this.getRawValue());
39563 Ext.reg('combo', Ext.form.ComboBox);
39565 Ext.form.Checkbox = Ext.extend(Ext.form.Field, {
39567 focusClass : undefined,
39569 fieldClass : 'x-form-field',
39573 boxLabel: ' ',
39575 defaultAutoCreate : { tag: 'input', type: 'checkbox', autocomplete: 'off'},
39582 actionMode : 'wrap',
39585 initComponent : function(){
39586 Ext.form.Checkbox.superclass.initComponent.call(this);
39594 onResize : function(){
39595 Ext.form.Checkbox.superclass.onResize.apply(this, arguments);
39596 if(!this.boxLabel && !this.fieldLabel){
39597 this.el.alignTo(this.wrap, 'c-c');
39602 initEvents : function(){
39603 Ext.form.Checkbox.superclass.initEvents.call(this);
39604 this.mon(this.el, {
39606 click: this.onClick,
39607 change: this.onClick
39612 markInvalid : Ext.emptyFn,
39614 clearInvalid : Ext.emptyFn,
39617 onRender : function(ct, position){
39618 Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
39619 if(this.inputValue !== undefined){
39620 this.el.dom.value = this.inputValue;
39622 this.wrap = this.el.wrap({cls: 'x-form-check-wrap'});
39624 this.wrap.createChild({tag: 'label', htmlFor: this.el.id, cls: 'x-form-cb-label', html: this.boxLabel});
39627 this.setValue(true);
39629 this.checked = this.el.dom.checked;
39633 this.wrap.repaint();
39635 this.resizeEl = this.positionEl = this.wrap;
39639 onDestroy : function(){
39640 Ext.destroy(this.wrap);
39641 Ext.form.Checkbox.superclass.onDestroy.call(this);
39645 initValue : function() {
39646 this.originalValue = this.getValue();
39650 getValue : function(){
39652 return this.el.dom.checked;
39654 return this.checked;
39658 onClick : function(){
39659 if(this.el.dom.checked != this.checked){
39660 this.setValue(this.el.dom.checked);
39665 setValue : function(v){
39666 var checked = this.checked ;
39667 this.checked = (v === true || v === 'true' || v == '1' || String(v).toLowerCase() == 'on');
39669 this.el.dom.checked = this.checked;
39670 this.el.dom.defaultChecked = this.checked;
39672 if(checked != this.checked){
39673 this.fireEvent('check', this, this.checked);
39675 this.handler.call(this.scope || this, this, this.checked);
39681 Ext.reg('checkbox', Ext.form.Checkbox);
39683 Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {
39692 blankText : "You must select at least one item in this group",
39695 defaultType : 'checkbox',
39698 groupCls : 'x-form-check-group',
39701 initComponent: function(){
39706 this.on('change', this.validate, this);
39707 Ext.form.CheckboxGroup.superclass.initComponent.call(this);
39711 onRender : function(ct, position){
39717 cls: this.groupCls,
39720 bufferResize: false
39723 xtype: 'container',
39724 defaultType: this.defaultType,
39732 if(this.items[0].items){
39736 Ext.apply(panelCfg, {
39737 layoutConfig: {columns: this.items.length},
39738 defaults: this.defaults,
39741 for(var i=0, len=this.items.length; i<len; i++){
39742 Ext.applyIf(this.items[i], colCfg);
39750 var numCols, cols = [];
39752 if(typeof this.columns == 'string'){
39753 this.columns = this.items.length;
39755 if(!Ext.isArray(this.columns)){
39757 for(var i=0; i<this.columns; i++){
39758 cs.push((100/this.columns)*.01);
39763 numCols = this.columns.length;
39766 for(var i=0; i<numCols; i++){
39767 var cc = Ext.apply({items:[]}, colCfg);
39768 cc[this.columns[i] <= 1 ? 'columnWidth' : 'width'] = this.columns[i];
39770 cc.defaults = Ext.apply(cc.defaults || {}, this.defaults);
39777 var rows = Math.ceil(this.items.length / numCols), ri = 0;
39778 for(var i=0, len=this.items.length; i<len; i++){
39779 if(i>0 && i%rows==0){
39782 if(this.items[i].fieldLabel){
39783 this.items[i].hideLabel = false;
39785 cols[ri].items.push(this.items[i]);
39788 for(var i=0, len=this.items.length; i<len; i++){
39789 var ci = i % numCols;
39790 if(this.items[i].fieldLabel){
39791 this.items[i].hideLabel = false;
39793 cols[ci].items.push(this.items[i]);
39797 Ext.apply(panelCfg, {
39798 layoutConfig: {columns: numCols},
39803 this.panel = new Ext.Container(panelCfg);
39804 this.panel.ownerCt = this;
39805 this.el = this.panel.getEl();
39807 if(this.forId && this.itemCls){
39808 var l = this.el.up(this.itemCls).child('label', true);
39810 l.setAttribute('htmlFor', this.forId);
39814 var fields = this.panel.findBy(function(c){
39815 return c.isFormField;
39818 this.items = new Ext.util.MixedCollection();
39819 this.items.addAll(fields);
39821 Ext.form.CheckboxGroup.superclass.onRender.call(this, ct, position);
39824 initValue : function(){
39826 this.setValue.apply(this, this.buffered ? this.value : [this.value]);
39827 delete this.buffered;
39832 afterRender : function(){
39833 Ext.form.CheckboxGroup.superclass.afterRender.call(this);
39834 this.eachItem(function(item){
39835 item.on('check', this.fireChecked, this);
39836 item.inGroup = true;
39841 doLayout: function(){
39844 this.panel.forceLayout = this.ownerCt.forceLayout;
39845 this.panel.doLayout();
39850 fireChecked: function(){
39852 this.eachItem(function(item){
39857 this.fireEvent('change', this, arr);
39861 getErrors: function() {
39862 var errors = Ext.form.CheckboxGroup.superclass.getErrors.apply(this, arguments);
39864 if (!this.allowBlank) {
39867 this.eachItem(function(f){
39869 return (blank = false);
39873 if (blank) errors.push(this.blankText);
39880 isDirty: function(){
39882 if (this.disabled || !this.rendered) {
39888 this.eachItem(function(item){
39889 if(item.isDirty()){
39899 setReadOnly : function(readOnly){
39901 this.eachItem(function(item){
39902 item.setReadOnly(readOnly);
39905 this.readOnly = readOnly;
39909 onDisable : function(){
39910 this.eachItem(function(item){
39916 onEnable : function(){
39917 this.eachItem(function(item){
39923 onResize : function(w, h){
39924 this.panel.setSize(w, h);
39925 this.panel.doLayout();
39929 reset : function(){
39930 if (this.originalValue) {
39932 this.eachItem(function(c){
39935 c.originalValue = c.getValue();
39940 this.resetOriginal = true;
39941 this.setValue(this.originalValue);
39942 delete this.resetOriginal;
39944 this.eachItem(function(c){
39953 this.clearInvalid();
39954 }).defer(50, this);
39958 setValue: function(){
39960 this.onSetValue.apply(this, arguments);
39962 this.buffered = true;
39963 this.value = arguments;
39969 onSetValue: function(id, value){
39970 if(arguments.length == 1){
39971 if(Ext.isArray(id)){
39972 Ext.each(id, function(val, idx){
39973 if (Ext.isObject(val) && val.setValue){
39974 val.setValue(true);
39975 if (this.resetOriginal === true) {
39976 val.originalValue = val.getValue();
39979 var item = this.items.itemAt(idx);
39981 item.setValue(val);
39985 }else if(Ext.isObject(id)){
39988 var f = this.getBox(i);
39994 this.setValueForItem(id);
39997 var f = this.getBox(id);
40005 beforeDestroy: function(){
40006 Ext.destroy(this.panel);
40007 Ext.form.CheckboxGroup.superclass.beforeDestroy.call(this);
40011 setValueForItem : function(val){
40012 val = String(val).split(',');
40013 this.eachItem(function(item){
40014 if(val.indexOf(item.inputValue)> -1){
40015 item.setValue(true);
40021 getBox : function(id){
40023 this.eachItem(function(f){
40024 if(id == f || f.dataIndex == id || f.id == id || f.getName() == id){
40033 getValue : function(){
40035 this.eachItem(function(item){
40044 eachItem: function(fn, scope) {
40045 if(this.items && this.items.each){
40046 this.items.each(fn, scope || this);
40053 getRawValue : Ext.emptyFn,
40056 setRawValue : Ext.emptyFn
40060 Ext.reg('checkboxgroup', Ext.form.CheckboxGroup);
40062 Ext.form.CompositeField = Ext.extend(Ext.form.Field, {
40065 defaultMargins: '0 5 0 0',
40068 skipLastItemMargin: true,
40074 combineErrors: true,
40078 initComponent: function() {
40080 items = this.items,
40083 for (var i=0, j = items.length; i < j; i++) {
40086 labels.push(item.fieldLabel);
40089 Ext.apply(item, this.defaults);
40092 if (!(i == j - 1 && this.skipLastItemMargin)) {
40093 Ext.applyIf(item, {margins: this.defaultMargins});
40097 this.fieldLabel = this.fieldLabel || this.buildLabel(labels);
40100 this.fieldErrors = new Ext.util.MixedCollection(true, function(item) {
40104 this.fieldErrors.on({
40106 add : this.updateInvalidMark,
40107 remove : this.updateInvalidMark,
40108 replace: this.updateInvalidMark
40111 Ext.form.CompositeField.superclass.initComponent.apply(this, arguments);
40115 onRender: function(ct, position) {
40118 var innerCt = this.innerCt = new Ext.Container({
40121 items : this.items,
40122 cls : 'x-form-composite',
40123 defaultMargins: '0 3 0 0'
40126 this.el = innerCt.getEl();
40128 var fields = innerCt.findBy(function(c) {
40129 return c.isFormField;
40133 this.items = new Ext.util.MixedCollection();
40134 this.items.addAll(fields);
40138 if (this.combineErrors) {
40139 this.eachItem(function(field) {
40141 markInvalid : this.onFieldMarkInvalid.createDelegate(this, [field], 0),
40142 clearInvalid: this.onFieldClearInvalid.createDelegate(this, [field], 0)
40148 var l = this.el.parent().parent().child('label', true);
40150 l.setAttribute('for', this.items.items[0].id);
40154 Ext.form.CompositeField.superclass.onRender.apply(this, arguments);
40158 onFieldMarkInvalid: function(field, message) {
40159 var name = field.getName(),
40160 error = {field: name, error: message};
40162 this.fieldErrors.replace(name, error);
40164 field.el.addClass(field.invalidClass);
40168 onFieldClearInvalid: function(field) {
40169 this.fieldErrors.removeKey(field.getName());
40171 field.el.removeClass(field.invalidClass);
40175 updateInvalidMark: function() {
40176 var ieStrict = Ext.isIE6 && Ext.isStrict;
40178 if (this.fieldErrors.length == 0) {
40179 this.clearInvalid();
40183 this.clearInvalid.defer(50, this);
40186 var message = this.buildCombinedErrorMessage(this.fieldErrors.items);
40189 this.markInvalid(message);
40193 this.markInvalid(message);
40199 validateValue: function() {
40202 this.eachItem(function(field) {
40203 if (!field.isValid()) valid = false;
40210 buildCombinedErrorMessage: function(errors) {
40214 for (var i = 0, j = errors.length; i < j; i++) {
40217 combined.push(String.format("{0}: {1}", error.field, error.error));
40220 return combined.join("<br />");
40224 sortErrors: function() {
40225 var fields = this.items;
40227 this.fieldErrors.sort("ASC", function(a, b) {
40228 var findByName = function(key) {
40229 return function(field) {
40230 return field.getName() == key;
40234 var aIndex = fields.findIndexBy(findByName(a.field)),
40235 bIndex = fields.findIndexBy(findByName(b.field));
40237 return aIndex < bIndex ? -1 : 1;
40242 reset: function() {
40243 this.eachItem(function(item) {
40250 this.clearInvalid();
40251 }).defer(50, this);
40255 clearInvalidChildren: function() {
40256 this.eachItem(function(item) {
40257 item.clearInvalid();
40262 buildLabel: function(segments) {
40263 return segments.join(", ");
40267 isDirty: function(){
40269 if (this.disabled || !this.rendered) {
40274 this.eachItem(function(item){
40275 if(item.isDirty()){
40284 eachItem: function(fn, scope) {
40285 if(this.items && this.items.each){
40286 this.items.each(fn, scope || this);
40291 onResize: function(adjWidth, adjHeight, rawWidth, rawHeight) {
40292 var innerCt = this.innerCt;
40294 if (this.rendered && innerCt.rendered) {
40295 innerCt.setSize(adjWidth, adjHeight);
40298 Ext.form.CompositeField.superclass.onResize.apply(this, arguments);
40302 doLayout: function(shallow, force) {
40303 if (this.rendered) {
40304 var innerCt = this.innerCt;
40306 innerCt.forceLayout = this.ownerCt.forceLayout;
40307 innerCt.doLayout(shallow, force);
40312 beforeDestroy: function(){
40313 Ext.destroy(this.innerCt);
40315 Ext.form.CompositeField.superclass.beforeDestroy.call(this);
40319 setReadOnly : function(readOnly) {
40320 readOnly = readOnly || true;
40323 this.eachItem(function(item){
40324 item.setReadOnly(readOnly);
40327 this.readOnly = readOnly;
40330 onShow : function() {
40331 Ext.form.CompositeField.superclass.onShow.call(this);
40336 onDisable : function(){
40337 this.eachItem(function(item){
40343 onEnable : function(){
40344 this.eachItem(function(item){
40350 Ext.reg('compositefield', Ext.form.CompositeField);
40352 Ext.form.Radio = Ext.extend(Ext.form.Checkbox, {
40353 inputType: 'radio',
40356 markInvalid : Ext.emptyFn,
40358 clearInvalid : Ext.emptyFn,
40361 getGroupValue : function(){
40362 var p = this.el.up('form') || Ext.getBody();
40363 var c = p.child('input[name='+this.el.dom.name+']:checked', true);
40364 return c ? c.value : null;
40368 onClick : function(){
40369 if(this.el.dom.checked != this.checked){
40370 var els = this.getCheckEl().select('input[name=' + this.el.dom.name + ']');
40371 els.each(function(el){
40372 if(el.dom.id == this.id){
40373 this.setValue(true);
40375 Ext.getCmp(el.dom.id).setValue(false);
40382 setValue : function(v){
40383 if (typeof v == 'boolean') {
40384 Ext.form.Radio.superclass.setValue.call(this, v);
40385 } else if (this.rendered) {
40386 var r = this.getCheckEl().child('input[name=' + this.el.dom.name + '][value=' + v + ']', true);
40388 Ext.getCmp(r.id).setValue(true);
40395 getCheckEl: function(){
40397 return this.el.up('.x-form-radio-group')
40399 return this.el.up('form') || Ext.getBody();
40402 Ext.reg('radio', Ext.form.Radio);
40404 Ext.form.RadioGroup = Ext.extend(Ext.form.CheckboxGroup, {
40409 blankText : 'You must select one item in this group',
40412 defaultType : 'radio',
40415 groupCls : 'x-form-radio-group',
40420 getValue : function(){
40422 this.eachItem(function(item){
40432 onSetValue : function(id, value){
40433 if(arguments.length > 1){
40434 var f = this.getBox(id);
40438 this.eachItem(function(item){
40440 item.setValue(false);
40446 this.setValueForItem(id);
40450 setValueForItem : function(val){
40451 val = String(val).split(',')[0];
40452 this.eachItem(function(item){
40453 item.setValue(val == item.inputValue);
40458 fireChecked : function(){
40459 if(!this.checkTask){
40460 this.checkTask = new Ext.util.DelayedTask(this.bufferChecked, this);
40462 this.checkTask.delay(10);
40466 bufferChecked : function(){
40468 this.eachItem(function(item){
40474 this.fireEvent('change', this, out);
40477 onDestroy : function(){
40478 if(this.checkTask){
40479 this.checkTask.cancel();
40480 this.checkTask = null;
40482 Ext.form.RadioGroup.superclass.onDestroy.call(this);
40487 Ext.reg('radiogroup', Ext.form.RadioGroup);
40489 Ext.form.Hidden = Ext.extend(Ext.form.Field, {
40491 inputType : 'hidden',
40494 onRender : function(){
40495 Ext.form.Hidden.superclass.onRender.apply(this, arguments);
40499 initEvents : function(){
40500 this.originalValue = this.getValue();
40504 setSize : Ext.emptyFn,
40505 setWidth : Ext.emptyFn,
40506 setHeight : Ext.emptyFn,
40507 setPosition : Ext.emptyFn,
40508 setPagePosition : Ext.emptyFn,
40509 markInvalid : Ext.emptyFn,
40510 clearInvalid : Ext.emptyFn
40512 Ext.reg('hidden', Ext.form.Hidden);
40513 Ext.form.BasicForm = Ext.extend(Ext.util.Observable, {
40515 constructor: function(el, config){
40516 Ext.apply(this, config);
40517 if(Ext.isString(this.paramOrder)){
40518 this.paramOrder = this.paramOrder.split(/[\s,|]/);
40521 this.items = new Ext.util.MixedCollection(false, function(o){
40522 return o.getItemId();
40536 Ext.form.BasicForm.superclass.constructor.call(this);
40551 paramOrder: undefined,
40554 paramsAsHash: false,
40557 waitTitle: 'Please Wait...',
40560 activeAction : null,
40563 trackResetOnLoad : false,
40569 initEl : function(el){
40570 this.el = Ext.get(el);
40571 this.id = this.el.id || Ext.id();
40572 if(!this.standardSubmit){
40573 this.el.on('submit', this.onSubmit, this);
40575 this.el.addClass('x-form');
40584 onSubmit : function(e){
40589 destroy: function(bound){
40590 if(bound !== true){
40591 this.items.each(function(f){
40594 Ext.destroy(this.el);
40596 this.items.clear();
40597 this.purgeListeners();
40601 isValid : function(){
40603 this.items.each(function(f){
40612 isDirty : function(){
40614 this.items.each(function(f){
40624 doAction : function(action, options){
40625 if(Ext.isString(action)){
40626 action = new Ext.form.Action.ACTION_TYPES[action](this, options);
40628 if(this.fireEvent('beforeaction', this, action) !== false){
40629 this.beforeAction(action);
40630 action.run.defer(100, action);
40636 submit : function(options){
40637 options = options || {};
40638 if(this.standardSubmit){
40639 var v = options.clientValidation === false || this.isValid();
40641 var el = this.el.dom;
40642 if(this.url && Ext.isEmpty(el.action)){
40643 el.action = this.url;
40649 var submitAction = String.format('{0}submit', this.api ? 'direct' : '');
40650 this.doAction(submitAction, options);
40655 load : function(options){
40656 var loadAction = String.format('{0}load', this.api ? 'direct' : '');
40657 this.doAction(loadAction, options);
40662 updateRecord : function(record){
40663 record.beginEdit();
40664 var fs = record.fields;
40665 fs.each(function(f){
40666 var field = this.findField(f.name);
40668 record.set(f.name, field.getValue());
40676 loadRecord : function(record){
40677 this.setValues(record.data);
40682 beforeAction : function(action){
40684 this.items.each(function(f){
40685 if(f.isFormField && f.syncValue){
40689 var o = action.options;
40691 if(this.waitMsgTarget === true){
40692 this.el.mask(o.waitMsg, 'x-mask-loading');
40693 }else if(this.waitMsgTarget){
40694 this.waitMsgTarget = Ext.get(this.waitMsgTarget);
40695 this.waitMsgTarget.mask(o.waitMsg, 'x-mask-loading');
40697 Ext.MessageBox.wait(o.waitMsg, o.waitTitle || this.waitTitle);
40703 afterAction : function(action, success){
40704 this.activeAction = null;
40705 var o = action.options;
40707 if(this.waitMsgTarget === true){
40709 }else if(this.waitMsgTarget){
40710 this.waitMsgTarget.unmask();
40712 Ext.MessageBox.updateProgress(1);
40713 Ext.MessageBox.hide();
40720 Ext.callback(o.success, o.scope, [this, action]);
40721 this.fireEvent('actioncomplete', this, action);
40723 Ext.callback(o.failure, o.scope, [this, action]);
40724 this.fireEvent('actionfailed', this, action);
40729 findField : function(id) {
40730 var field = this.items.get(id);
40732 if (!Ext.isObject(field)) {
40734 var findMatchingField = function(f) {
40735 if (f.isFormField) {
40736 if (f.dataIndex == id || f.id == id || f.getName() == id) {
40739 } else if (f.isComposite && f.rendered) {
40740 return f.items.each(findMatchingField);
40745 this.items.each(findMatchingField);
40747 return field || null;
40752 markInvalid : function(errors){
40753 if (Ext.isArray(errors)) {
40754 for(var i = 0, len = errors.length; i < len; i++){
40755 var fieldError = errors[i];
40756 var f = this.findField(fieldError.id);
40758 f.markInvalid(fieldError.msg);
40764 if(!Ext.isFunction(errors[id]) && (field = this.findField(id))){
40765 field.markInvalid(errors[id]);
40774 setValues : function(values){
40775 if(Ext.isArray(values)){
40776 for(var i = 0, len = values.length; i < len; i++){
40778 var f = this.findField(v.id);
40780 f.setValue(v.value);
40781 if(this.trackResetOnLoad){
40782 f.originalValue = f.getValue();
40789 if(!Ext.isFunction(values[id]) && (field = this.findField(id))){
40790 field.setValue(values[id]);
40791 if(this.trackResetOnLoad){
40792 field.originalValue = field.getValue();
40801 getValues : function(asString){
40802 var fs = Ext.lib.Ajax.serializeForm(this.el.dom);
40803 if(asString === true){
40806 return Ext.urlDecode(fs);
40810 getFieldValues : function(dirtyOnly){
40815 this.items.each(function(f) {
40816 if (dirtyOnly !== true || f.isDirty()) {
40819 val = f.getValue();
40821 if(Ext.isDefined(key)){
40822 if(Ext.isArray(key)){
40836 clearInvalid : function(){
40837 this.items.each(function(f){
40844 reset : function(){
40845 this.items.each(function(f){
40853 this.items.addAll(Array.prototype.slice.call(arguments, 0));
40858 remove : function(field){
40859 this.items.remove(field);
40864 cleanDestroyed : function() {
40865 this.items.filterBy(function(o) { return !!o.isDestroyed; }).each(this.remove, this);
40869 render : function(){
40870 this.items.each(function(f){
40871 if(f.isFormField && !f.rendered && document.getElementById(f.id)){
40872 f.applyToMarkup(f.id);
40879 applyToFields : function(o){
40880 this.items.each(function(f){
40887 applyIfToFields : function(o){
40888 this.items.each(function(f){
40894 callFieldMethod : function(fnName, args){
40896 this.items.each(function(f){
40897 if(Ext.isFunction(f[fnName])){
40898 f[fnName].apply(f, args);
40906 Ext.BasicForm = Ext.form.BasicForm;
40908 Ext.FormPanel = Ext.extend(Ext.Panel, {
40919 minButtonWidth : 75,
40922 labelAlign : 'left',
40925 monitorValid : false,
40934 initComponent : function(){
40935 this.form = this.createForm();
40936 Ext.FormPanel.superclass.initComponent.call(this);
40940 cls: this.baseCls + '-body',
40941 method : this.method || 'POST',
40942 id : this.formId || Ext.id()
40944 if(this.fileUpload) {
40945 this.bodyCfg.enctype = 'multipart/form-data';
40954 this.relayEvents(this.form, ['beforeaction', 'actionfailed', 'actioncomplete']);
40958 createForm : function(){
40959 var config = Ext.applyIf({listeners: {}}, this.initialConfig);
40960 return new Ext.form.BasicForm(null, config);
40964 initFields : function(){
40966 var formPanel = this;
40967 var fn = function(c){
40968 if(formPanel.isField(c)){
40970 }else if(c.findBy && c != formPanel){
40971 formPanel.applySettings(c);
40973 if(c.items && c.items.each){
40974 c.items.each(fn, this);
40978 this.items.each(fn, this);
40982 applySettings: function(c){
40983 var ct = c.ownerCt;
40985 labelAlign: ct.labelAlign,
40986 labelWidth: ct.labelWidth,
40987 itemCls: ct.itemCls
40992 getLayoutTarget : function(){
40993 return this.form.el;
40997 getForm : function(){
41002 onRender : function(ct, position){
41004 Ext.FormPanel.superclass.onRender.call(this, ct, position);
41005 this.form.initEl(this.body);
41009 beforeDestroy : function(){
41010 this.stopMonitoring();
41011 this.form.destroy(true);
41012 Ext.FormPanel.superclass.beforeDestroy.call(this);
41016 isField : function(c) {
41017 return !!c.setValue && !!c.getValue && !!c.markInvalid && !!c.clearInvalid;
41021 initEvents : function(){
41022 Ext.FormPanel.superclass.initEvents.call(this);
41026 add: this.onAddEvent,
41027 remove: this.onRemoveEvent
41029 if(this.monitorValid){
41030 this.startMonitoring();
41035 onAdd: function(c){
41036 Ext.FormPanel.superclass.onAdd.call(this, c);
41037 this.processAdd(c);
41041 onAddEvent: function(ct, c){
41043 this.processAdd(c);
41048 processAdd : function(c){
41050 if(this.isField(c)){
41053 }else if(c.findBy){
41054 this.applySettings(c);
41055 this.form.add.apply(this.form, c.findBy(this.isField));
41060 onRemove: function(c){
41061 Ext.FormPanel.superclass.onRemove.call(this, c);
41062 this.processRemove(c);
41065 onRemoveEvent: function(ct, c){
41067 this.processRemove(c);
41072 processRemove: function(c){
41073 if(!this.destroying){
41075 if(this.isField(c)){
41076 this.form.remove(c);
41078 }else if (c.findBy){
41079 Ext.each(c.findBy(this.isField), this.form.remove, this.form);
41080 if (c.isDestroyed) {
41081 this.form.cleanDestroyed();
41088 startMonitoring : function(){
41089 if(!this.validTask){
41090 this.validTask = new Ext.util.TaskRunner();
41091 this.validTask.start({
41092 run : this.bindHandler,
41093 interval : this.monitorPoll || 200,
41100 stopMonitoring : function(){
41101 if(this.validTask){
41102 this.validTask.stopAll();
41103 this.validTask = null;
41109 this.form.load.apply(this.form, arguments);
41113 onDisable : function(){
41114 Ext.FormPanel.superclass.onDisable.call(this);
41116 this.form.items.each(function(){
41123 onEnable : function(){
41124 Ext.FormPanel.superclass.onEnable.call(this);
41126 this.form.items.each(function(){
41133 bindHandler : function(){
41135 this.form.items.each(function(f){
41136 if(!f.isValid(true)){
41142 var fitems = this.fbar.items.items;
41143 for(var i = 0, len = fitems.length; i < len; i++){
41144 var btn = fitems[i];
41145 if(btn.formBind === true && btn.disabled === valid){
41146 btn.setDisabled(!valid);
41150 this.fireEvent('clientvalidation', this, valid);
41153 Ext.reg('form', Ext.FormPanel);
41155 Ext.form.FormPanel = Ext.FormPanel;
41157 Ext.form.FieldSet = Ext.extend(Ext.Panel, {
41164 baseCls : 'x-fieldset',
41168 animCollapse : false,
41171 onRender : function(ct, position){
41173 this.el = document.createElement('fieldset');
41174 this.el.id = this.id;
41175 if (this.title || this.header || this.checkboxToggle) {
41176 this.el.appendChild(document.createElement('legend')).className = this.baseCls + '-header';
41180 Ext.form.FieldSet.superclass.onRender.call(this, ct, position);
41182 if(this.checkboxToggle){
41183 var o = typeof this.checkboxToggle == 'object' ?
41184 this.checkboxToggle :
41185 {tag: 'input', type: 'checkbox', name: this.checkboxName || this.id+'-checkbox'};
41186 this.checkbox = this.header.insertFirst(o);
41187 this.checkbox.dom.checked = !this.collapsed;
41188 this.mon(this.checkbox, 'click', this.onCheckClick, this);
41193 onCollapse : function(doAnim, animArg){
41195 this.checkbox.dom.checked = false;
41197 Ext.form.FieldSet.superclass.onCollapse.call(this, doAnim, animArg);
41202 onExpand : function(doAnim, animArg){
41204 this.checkbox.dom.checked = true;
41206 Ext.form.FieldSet.superclass.onExpand.call(this, doAnim, animArg);
41210 onCheckClick : function(){
41211 this[this.checkbox.dom.checked ? 'expand' : 'collapse']();
41249 Ext.reg('fieldset', Ext.form.FieldSet);
41251 Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
41253 enableFormat : true,
41255 enableFontSize : true,
41257 enableColors : true,
41259 enableAlignments : true,
41261 enableLists : true,
41263 enableSourceEdit : true,
41265 enableLinks : true,
41269 createLinkText : 'Please enter the URL for the link:',
41271 defaultLinkValue : 'http:/'+'/',
41280 defaultFont: 'tahoma',
41282 defaultValue: (Ext.isOpera || Ext.isIE6) ? ' ' : '​',
41285 actionMode: 'wrap',
41286 validationEvent : false,
41288 initialized : false,
41290 sourceEditMode : false,
41291 onFocus : Ext.emptyFn,
41293 hideMode:'offsets',
41294 defaultAutoCreate : {
41296 style:"width:500px;height:300px;",
41297 autocomplete: "off"
41301 initComponent : function(){
41321 createFontOptions : function(){
41322 var buf = [], fs = this.fontFamilies, ff, lc;
41323 for(var i = 0, len = fs.length; i< len; i++){
41325 lc = ff.toLowerCase();
41327 '<option value="',lc,'" style="font-family:',ff,';"',
41328 (this.defaultFont == lc ? ' selected="true">' : '>'),
41333 return buf.join('');
41337 createToolbar : function(editor){
41339 var tipsEnabled = Ext.QuickTips && Ext.QuickTips.isEnabled();
41342 function btn(id, toggle, handler){
41345 cls : 'x-btn-icon',
41346 iconCls: 'x-edit-'+id,
41347 enableToggle:toggle !== false,
41349 handler:handler||editor.relayBtnCmd,
41350 clickEvent:'mousedown',
41351 tooltip: tipsEnabled ? editor.buttonTips[id] || undefined : undefined,
41352 overflowText: editor.buttonTips[id].title || undefined,
41358 if(this.enableFont && !Ext.isSafari2){
41359 var fontSelectItem = new Ext.Toolbar.Item({
41362 cls:'x-font-select',
41363 html: this.createFontOptions()
41373 if(this.enableFormat){
41381 if(this.enableFontSize){
41384 btn('increasefontsize', false, this.adjustFont),
41385 btn('decreasefontsize', false, this.adjustFont)
41389 if(this.enableColors){
41392 itemId:'forecolor',
41394 iconCls: 'x-edit-forecolor',
41395 clickEvent:'mousedown',
41396 tooltip: tipsEnabled ? editor.buttonTips.forecolor || undefined : undefined,
41398 menu : new Ext.menu.ColorMenu({
41399 allowReselect: true,
41400 focus: Ext.emptyFn,
41405 select: function(cp, color){
41406 this.execCmd('forecolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
41410 clickEvent:'mousedown'
41413 itemId:'backcolor',
41415 iconCls: 'x-edit-backcolor',
41416 clickEvent:'mousedown',
41417 tooltip: tipsEnabled ? editor.buttonTips.backcolor || undefined : undefined,
41419 menu : new Ext.menu.ColorMenu({
41420 focus: Ext.emptyFn,
41423 allowReselect: true,
41426 select: function(cp, color){
41428 this.execCmd('useCSS', false);
41429 this.execCmd('hilitecolor', color);
41430 this.execCmd('useCSS', true);
41433 this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
41438 clickEvent:'mousedown'
41444 if(this.enableAlignments){
41447 btn('justifyleft'),
41448 btn('justifycenter'),
41449 btn('justifyright')
41453 if(!Ext.isSafari2){
41454 if(this.enableLinks){
41457 btn('createlink', false, this.createLink)
41461 if(this.enableLists){
41464 btn('insertorderedlist'),
41465 btn('insertunorderedlist')
41468 if(this.enableSourceEdit){
41471 btn('sourceedit', true, function(btn){
41472 this.toggleSourceEdit(!this.sourceEditMode);
41479 var tb = new Ext.Toolbar({
41480 renderTo: this.wrap.dom.firstChild,
41484 if (fontSelectItem) {
41485 this.fontSelect = fontSelectItem.el;
41487 this.mon(this.fontSelect, 'change', function(){
41488 var font = this.fontSelect.dom.value;
41489 this.relayCmd('fontname', font);
41495 this.mon(tb.el, 'click', function(e){
41496 e.preventDefault();
41500 this.tb.doLayout();
41503 onDisable: function(){
41505 Ext.form.HtmlEditor.superclass.onDisable.call(this);
41508 onEnable: function(){
41509 this.wrap.unmask();
41510 Ext.form.HtmlEditor.superclass.onEnable.call(this);
41513 setReadOnly: function(readOnly){
41515 Ext.form.HtmlEditor.superclass.setReadOnly.call(this, readOnly);
41516 if(this.initialized){
41518 this.getEditorBody().contentEditable = !readOnly;
41520 this.setDesignMode(!readOnly);
41522 var bd = this.getEditorBody();
41524 bd.style.cursor = this.readOnly ? 'default' : 'text';
41526 this.disableItems(readOnly);
41531 getDocMarkup : function(){
41532 var h = Ext.fly(this.iframe).getHeight() - this.iframePad * 2;
41533 return String.format('<html><head><style type="text/css">body{border: 0; margin: 0; padding: {0}px; height: {1}px; cursor: text}</style></head><body></body></html>', this.iframePad, h);
41537 getEditorBody : function(){
41538 var doc = this.getDoc();
41539 return doc.body || doc.documentElement;
41543 getDoc : function(){
41544 return Ext.isIE ? this.getWin().document : (this.iframe.contentDocument || this.getWin().document);
41548 getWin : function(){
41549 return Ext.isIE ? this.iframe.contentWindow : window.frames[this.iframe.name];
41553 onRender : function(ct, position){
41554 Ext.form.HtmlEditor.superclass.onRender.call(this, ct, position);
41555 this.el.dom.style.border = '0 none';
41556 this.el.dom.setAttribute('tabIndex', -1);
41557 this.el.addClass('x-hidden');
41559 this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;');
41561 this.wrap = this.el.wrap({
41562 cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
41565 this.createToolbar(this);
41567 this.disableItems(true);
41569 this.tb.doLayout();
41571 this.createIFrame();
41574 var sz = this.el.getSize();
41575 this.setSize(sz.width, this.height || sz.height);
41577 this.resizeEl = this.positionEl = this.wrap;
41580 createIFrame: function(){
41581 var iframe = document.createElement('iframe');
41582 iframe.name = Ext.id();
41583 iframe.frameBorder = '0';
41584 iframe.style.overflow = 'auto';
41586 this.wrap.dom.appendChild(iframe);
41587 this.iframe = iframe;
41589 this.monitorTask = Ext.TaskMgr.start({
41590 run: this.checkDesignMode,
41596 initFrame : function(){
41597 Ext.TaskMgr.stop(this.monitorTask);
41598 var doc = this.getDoc();
41599 this.win = this.getWin();
41602 doc.write(this.getDocMarkup());
41607 var doc = this.getDoc();
41608 if(doc.body || doc.readyState == 'complete'){
41609 Ext.TaskMgr.stop(task);
41610 this.setDesignMode(true);
41611 this.initEditor.defer(10, this);
41618 Ext.TaskMgr.start(task);
41622 checkDesignMode : function(){
41623 if(this.wrap && this.wrap.dom.offsetWidth){
41624 var doc = this.getDoc();
41628 if(!doc.editorInitialized || this.getDesignMode() != 'on'){
41635 setDesignMode : function(mode){
41637 if(doc = this.getDoc()){
41641 doc.designMode = (/on|true/i).test(String(mode).toLowerCase()) ?'on':'off';
41647 getDesignMode : function(){
41648 var doc = this.getDoc();
41649 if(!doc){ return ''; }
41650 return String(doc.designMode).toLowerCase();
41654 disableItems: function(disabled){
41655 if(this.fontSelect){
41656 this.fontSelect.dom.disabled = disabled;
41658 this.tb.items.each(function(item){
41659 if(item.getItemId() != 'sourceedit'){
41660 item.setDisabled(disabled);
41666 onResize : function(w, h){
41667 Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments);
41668 if(this.el && this.iframe){
41669 if(Ext.isNumber(w)){
41670 var aw = w - this.wrap.getFrameWidth('lr');
41671 this.el.setWidth(aw);
41672 this.tb.setWidth(aw);
41673 this.iframe.style.width = Math.max(aw, 0) + 'px';
41675 if(Ext.isNumber(h)){
41676 var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight();
41677 this.el.setHeight(ah);
41678 this.iframe.style.height = Math.max(ah, 0) + 'px';
41679 var bd = this.getEditorBody();
41681 bd.style.height = Math.max((ah - (this.iframePad*2)), 0) + 'px';
41688 toggleSourceEdit : function(sourceEditMode){
41693 if (sourceEditMode === undefined) {
41694 sourceEditMode = !this.sourceEditMode;
41696 this.sourceEditMode = sourceEditMode === true;
41697 var btn = this.tb.getComponent('sourceedit');
41699 if (btn.pressed !== this.sourceEditMode) {
41700 btn.toggle(this.sourceEditMode);
41701 if (!btn.xtbHidden) {
41705 if (this.sourceEditMode) {
41707 ls = this.getSize();
41709 iframeHeight = Ext.get(this.iframe).getHeight();
41711 this.disableItems(true);
41713 this.iframe.className = 'x-hidden';
41714 this.el.removeClass('x-hidden');
41715 this.el.dom.removeAttribute('tabIndex');
41717 this.el.dom.style.height = iframeHeight + 'px';
41720 elHeight = parseInt(this.el.dom.style.height, 10);
41721 if (this.initialized) {
41722 this.disableItems(this.readOnly);
41725 this.iframe.className = '';
41726 this.el.addClass('x-hidden');
41727 this.el.dom.setAttribute('tabIndex', -1);
41731 this.iframe.style.height = elHeight + 'px';
41733 this.fireEvent('editmodechange', this, this.sourceEditMode);
41737 createLink : function() {
41738 var url = prompt(this.createLinkText, this.defaultLinkValue);
41739 if(url && url != 'http:/'+'/'){
41740 this.relayCmd('createlink', url);
41745 initEvents : function(){
41746 this.originalValue = this.getValue();
41750 markInvalid : Ext.emptyFn,
41753 clearInvalid : Ext.emptyFn,
41756 setValue : function(v){
41757 Ext.form.HtmlEditor.superclass.setValue.call(this, v);
41763 cleanHtml: function(html) {
41764 html = String(html);
41766 html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');
41770 if(html.charCodeAt(0) == this.defaultValue.replace(/\D/g, '')){
41771 html = html.substring(1);
41777 syncValue : function(){
41778 if(this.initialized){
41779 var bd = this.getEditorBody();
41780 var html = bd.innerHTML;
41782 var bs = bd.getAttribute('style');
41783 var m = bs.match(/text-align:(.*?);/i);
41785 html = '<div style="'+m[0]+'">' + html + '</div>';
41788 html = this.cleanHtml(html);
41789 if(this.fireEvent('beforesync', this, html) !== false){
41790 this.el.dom.value = html;
41791 this.fireEvent('sync', this, html);
41797 getValue : function() {
41798 this[this.sourceEditMode ? 'pushValue' : 'syncValue']();
41799 return Ext.form.HtmlEditor.superclass.getValue.call(this);
41803 pushValue : function(){
41804 if(this.initialized){
41805 var v = this.el.dom.value;
41806 if(!this.activated && v.length < 1){
41807 v = this.defaultValue;
41809 if(this.fireEvent('beforepush', this, v) !== false){
41810 this.getEditorBody().innerHTML = v;
41813 this.setDesignMode(false);
41814 this.setDesignMode(true);
41816 this.fireEvent('push', this, v);
41823 deferFocus : function(){
41824 this.focus.defer(10, this);
41828 focus : function(){
41829 if(this.win && !this.sourceEditMode){
41837 initEditor : function(){
41840 var dbody = this.getEditorBody(),
41841 ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat', 'background-color', 'color'),
41845 ss['background-attachment'] = 'fixed';
41846 dbody.bgProperties = 'fixed';
41848 Ext.DomHelper.applyStyles(dbody, ss);
41850 doc = this.getDoc();
41854 Ext.EventManager.removeAll(doc);
41859 fn = this.onEditorEvent.createDelegate(this);
41860 Ext.EventManager.on(doc, {
41869 Ext.EventManager.on(doc, 'keypress', this.applyCommand, this);
41871 if(Ext.isIE || Ext.isWebKit || Ext.isOpera){
41872 Ext.EventManager.on(doc, 'keydown', this.fixKeys, this);
41874 doc.editorInitialized = true;
41875 this.initialized = true;
41877 this.setReadOnly(this.readOnly);
41878 this.fireEvent('initialize', this);
41883 onDestroy : function(){
41884 if(this.monitorTask){
41885 Ext.TaskMgr.stop(this.monitorTask);
41888 Ext.destroy(this.tb);
41889 var doc = this.getDoc();
41892 Ext.EventManager.removeAll(doc);
41893 for (var prop in doc){
41899 this.wrap.dom.innerHTML = '';
41900 this.wrap.remove();
41905 this.el.removeAllListeners();
41908 this.purgeListeners();
41912 onFirstFocus : function(){
41913 this.activated = true;
41914 this.disableItems(this.readOnly);
41917 var s = this.win.getSelection();
41918 if(!s.focusNode || s.focusNode.nodeType != 3){
41919 var r = s.getRangeAt(0);
41920 r.selectNodeContents(this.getEditorBody());
41925 this.execCmd('useCSS', true);
41926 this.execCmd('styleWithCSS', false);
41929 this.fireEvent('activate', this);
41933 adjustFont: function(btn){
41934 var adjust = btn.getItemId() == 'increasefontsize' ? 1 : -1,
41935 doc = this.getDoc(),
41936 v = parseInt(doc.queryCommandValue('FontSize') || 2, 10);
41937 if((Ext.isSafari && !Ext.isSafari2) || Ext.isChrome || Ext.isAir){
41953 v = v.constrain(1, 6);
41958 v = Math.max(1, v+adjust) + (Ext.isSafari ? 'px' : 0);
41960 this.execCmd('FontSize', v);
41964 onEditorEvent : function(e){
41965 this.updateToolbar();
41970 updateToolbar: function(){
41976 if(!this.activated){
41977 this.onFirstFocus();
41981 var btns = this.tb.items.map,
41982 doc = this.getDoc();
41984 if(this.enableFont && !Ext.isSafari2){
41985 var name = (doc.queryCommandValue('FontName')||this.defaultFont).toLowerCase();
41986 if(name != this.fontSelect.dom.value){
41987 this.fontSelect.dom.value = name;
41990 if(this.enableFormat){
41991 btns.bold.toggle(doc.queryCommandState('bold'));
41992 btns.italic.toggle(doc.queryCommandState('italic'));
41993 btns.underline.toggle(doc.queryCommandState('underline'));
41995 if(this.enableAlignments){
41996 btns.justifyleft.toggle(doc.queryCommandState('justifyleft'));
41997 btns.justifycenter.toggle(doc.queryCommandState('justifycenter'));
41998 btns.justifyright.toggle(doc.queryCommandState('justifyright'));
42000 if(!Ext.isSafari2 && this.enableLists){
42001 btns.insertorderedlist.toggle(doc.queryCommandState('insertorderedlist'));
42002 btns.insertunorderedlist.toggle(doc.queryCommandState('insertunorderedlist'));
42005 Ext.menu.MenuMgr.hideAll();
42011 relayBtnCmd : function(btn){
42012 this.relayCmd(btn.getItemId());
42016 relayCmd : function(cmd, value){
42019 this.execCmd(cmd, value);
42020 this.updateToolbar();
42021 }).defer(10, this);
42025 execCmd : function(cmd, value){
42026 var doc = this.getDoc();
42027 doc.execCommand(cmd, false, value === undefined ? null : value);
42032 applyCommand : function(e){
42034 var c = e.getCharCode(), cmd;
42036 c = String.fromCharCode(c);
42052 e.preventDefault();
42059 insertAtCursor : function(text){
42060 if(!this.activated){
42065 var doc = this.getDoc(),
42066 r = doc.selection.createRange();
42074 this.execCmd('InsertHTML', text);
42080 fixKeys : function(){
42082 return function(e){
42083 var k = e.getKey(),
42084 doc = this.getDoc(),
42088 r = doc.selection.createRange();
42091 r.pasteHTML(' ');
42094 }else if(k == e.ENTER){
42095 r = doc.selection.createRange();
42097 var target = r.parentElement();
42098 if(!target || target.tagName.toLowerCase() != 'li'){
42100 r.pasteHTML('<br />');
42107 }else if(Ext.isOpera){
42108 return function(e){
42109 var k = e.getKey();
42113 this.execCmd('InsertHTML',' ');
42117 }else if(Ext.isWebKit){
42118 return function(e){
42119 var k = e.getKey();
42122 this.execCmd('InsertText','\t');
42124 }else if(k == e.ENTER){
42126 this.execCmd('InsertHtml','<br /><br />');
42134 getToolbar : function(){
42141 title: 'Bold (Ctrl+B)',
42142 text: 'Make the selected text bold.',
42143 cls: 'x-html-editor-tip'
42146 title: 'Italic (Ctrl+I)',
42147 text: 'Make the selected text italic.',
42148 cls: 'x-html-editor-tip'
42151 title: 'Underline (Ctrl+U)',
42152 text: 'Underline the selected text.',
42153 cls: 'x-html-editor-tip'
42155 increasefontsize : {
42156 title: 'Grow Text',
42157 text: 'Increase the font size.',
42158 cls: 'x-html-editor-tip'
42160 decreasefontsize : {
42161 title: 'Shrink Text',
42162 text: 'Decrease the font size.',
42163 cls: 'x-html-editor-tip'
42166 title: 'Text Highlight Color',
42167 text: 'Change the background color of the selected text.',
42168 cls: 'x-html-editor-tip'
42171 title: 'Font Color',
42172 text: 'Change the color of the selected text.',
42173 cls: 'x-html-editor-tip'
42176 title: 'Align Text Left',
42177 text: 'Align text to the left.',
42178 cls: 'x-html-editor-tip'
42181 title: 'Center Text',
42182 text: 'Center text in the editor.',
42183 cls: 'x-html-editor-tip'
42186 title: 'Align Text Right',
42187 text: 'Align text to the right.',
42188 cls: 'x-html-editor-tip'
42190 insertunorderedlist : {
42191 title: 'Bullet List',
42192 text: 'Start a bulleted list.',
42193 cls: 'x-html-editor-tip'
42195 insertorderedlist : {
42196 title: 'Numbered List',
42197 text: 'Start a numbered list.',
42198 cls: 'x-html-editor-tip'
42201 title: 'Hyperlink',
42202 text: 'Make the selected text a hyperlink.',
42203 cls: 'x-html-editor-tip'
42206 title: 'Source Edit',
42207 text: 'Switch to source editing mode.',
42208 cls: 'x-html-editor-tip'
42247 Ext.reg('htmleditor', Ext.form.HtmlEditor);
42249 Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {
42251 minValue : undefined,
42253 maxValue : undefined,
42255 minText : "The time in this field must be equal to or after {0}",
42257 maxText : "The time in this field must be equal to or before {0}",
42259 invalidText : "{0} is not a valid time",
42263 altFormats : "g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H|gi a|hi a|giA|hiA|gi A|hi A",
42270 triggerAction: 'all',
42277 initDate: '1/1/2008',
42279 initDateFormat: 'j/n/Y',
42282 initComponent : function(){
42283 if(Ext.isDefined(this.minValue)){
42284 this.setMinValue(this.minValue, true);
42286 if(Ext.isDefined(this.maxValue)){
42287 this.setMaxValue(this.maxValue, true);
42290 this.generateStore(true);
42292 Ext.form.TimeField.superclass.initComponent.call(this);
42296 setMinValue: function(value, initial){
42297 this.setLimit(value, true, initial);
42302 setMaxValue: function(value, initial){
42303 this.setLimit(value, false, initial);
42308 generateStore: function(initial){
42309 var min = this.minValue || new Date(this.initDate).clearTime(),
42310 max = this.maxValue || new Date(this.initDate).clearTime().add('mi', (24 * 60) - 1),
42314 times.push(min.dateFormat(this.format));
42315 min = min.add('mi', this.increment);
42317 this.bindStore(times, initial);
42321 setLimit: function(value, isMin, initial){
42323 if(Ext.isString(value)){
42324 d = this.parseDate(value);
42325 }else if(Ext.isDate(value)){
42329 var val = new Date(this.initDate).clearTime();
42330 val.setHours(d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
42331 this[isMin ? 'minValue' : 'maxValue'] = val;
42333 this.generateStore();
42339 getValue : function(){
42340 var v = Ext.form.TimeField.superclass.getValue.call(this);
42341 return this.formatDate(this.parseDate(v)) || '';
42345 setValue : function(value){
42346 return Ext.form.TimeField.superclass.setValue.call(this, this.formatDate(this.parseDate(value)));
42350 validateValue : Ext.form.DateField.prototype.validateValue,
42352 formatDate : Ext.form.DateField.prototype.formatDate,
42354 parseDate: function(value) {
42355 if (!value || Ext.isDate(value)) {
42359 var id = this.initDate + ' ',
42360 idf = this.initDateFormat + ' ',
42361 v = Date.parseDate(id + value, idf + this.format),
42362 af = this.altFormats;
42365 if (!this.altFormatsArray) {
42366 this.altFormatsArray = af.split("|");
42368 for (var i = 0, afa = this.altFormatsArray, len = afa.length; i < len && !v; i++) {
42369 v = Date.parseDate(id + value, idf + afa[i]);
42376 Ext.reg('timefield', Ext.form.TimeField);
42377 Ext.form.SliderField = Ext.extend(Ext.form.Field, {
42386 actionMode: 'wrap',
42389 initComponent : function() {
42390 var cfg = Ext.copyTo({
42391 id: this.id + '-slider'
42392 }, this.initialConfig, ['vertical', 'minValue', 'maxValue', 'decimalPrecision', 'keyIncrement', 'increment', 'clickToChange', 'animate']);
42395 if (this.useTips) {
42396 var plug = this.tipText ? {getText: this.tipText} : {};
42397 cfg.plugins = [new Ext.slider.Tip(plug)];
42399 this.slider = new Ext.Slider(cfg);
42400 Ext.form.SliderField.superclass.initComponent.call(this);
42404 onRender : function(ct, position){
42405 this.autoCreate = {
42411 Ext.form.SliderField.superclass.onRender.call(this, ct, position);
42412 this.wrap = this.el.wrap({cls: 'x-form-field-wrap'});
42413 this.resizeEl = this.positionEl = this.wrap;
42414 this.slider.render(this.wrap);
42418 onResize : function(w, h, aw, ah){
42419 Ext.form.SliderField.superclass.onResize.call(this, w, h, aw, ah);
42420 this.slider.setSize(w, h);
42424 initEvents : function(){
42425 Ext.form.SliderField.superclass.initEvents.call(this);
42426 this.slider.on('change', this.onChange, this);
42430 onChange : function(slider, v){
42431 this.setValue(v, undefined, true);
42435 onEnable : function(){
42436 Ext.form.SliderField.superclass.onEnable.call(this);
42437 this.slider.enable();
42441 onDisable : function(){
42442 Ext.form.SliderField.superclass.onDisable.call(this);
42443 this.slider.disable();
42447 beforeDestroy : function(){
42448 Ext.destroy(this.slider);
42449 Ext.form.SliderField.superclass.beforeDestroy.call(this);
42453 alignErrorIcon : function(){
42454 this.errorIcon.alignTo(this.slider.el, 'tl-tr', [2, 0]);
42458 setMinValue : function(v){
42459 this.slider.setMinValue(v);
42464 setMaxValue : function(v){
42465 this.slider.setMaxValue(v);
42470 setValue : function(v, animate, silent){
42474 this.slider.setValue(v, animate);
42476 return Ext.form.SliderField.superclass.setValue.call(this, this.slider.getValue());
42480 getValue : function(){
42481 return this.slider.getValue();
42485 Ext.reg('sliderfield', Ext.form.SliderField);
42486 Ext.form.Label = Ext.extend(Ext.BoxComponent, {
42492 onRender : function(ct, position){
42494 this.el = document.createElement('label');
42495 this.el.id = this.getId();
42496 this.el.innerHTML = this.text ? Ext.util.Format.htmlEncode(this.text) : (this.html || '');
42498 this.el.setAttribute('for', this.forId);
42501 Ext.form.Label.superclass.onRender.call(this, ct, position);
42505 setText : function(t, encode){
42506 var e = encode === false;
42507 this[!e ? 'text' : 'html'] = t;
42508 delete this[e ? 'text' : 'html'];
42510 this.el.dom.innerHTML = encode !== false ? Ext.util.Format.htmlEncode(t) : t;
42516 Ext.reg('label', Ext.form.Label);
42517 Ext.form.Action = function(form, options){
42519 this.options = options || {};
42523 Ext.form.Action.CLIENT_INVALID = 'client';
42525 Ext.form.Action.SERVER_INVALID = 'server';
42527 Ext.form.Action.CONNECT_FAILURE = 'connect';
42529 Ext.form.Action.LOAD_FAILURE = 'load';
42531 Ext.form.Action.prototype = {
42552 run : function(options){
42557 success : function(response){
42562 handleResponse : function(response){
42567 failure : function(response){
42568 this.response = response;
42569 this.failureType = Ext.form.Action.CONNECT_FAILURE;
42570 this.form.afterAction(this, false);
42576 processResponse : function(response){
42577 this.response = response;
42578 if(!response.responseText && !response.responseXML){
42581 this.result = this.handleResponse(response);
42582 return this.result;
42586 getUrl : function(appendParams){
42587 var url = this.options.url || this.form.url || this.form.el.dom.action;
42589 var p = this.getParams();
42591 url = Ext.urlAppend(url, p);
42598 getMethod : function(){
42599 return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();
42603 getParams : function(){
42604 var bp = this.form.baseParams;
42605 var p = this.options.params;
42607 if(typeof p == "object"){
42608 p = Ext.urlEncode(Ext.applyIf(p, bp));
42609 }else if(typeof p == 'string' && bp){
42610 p += '&' + Ext.urlEncode(bp);
42613 p = Ext.urlEncode(bp);
42619 createCallback : function(opts){
42620 var opts = opts || {};
42622 success: this.success,
42623 failure: this.failure,
42625 timeout: (opts.timeout*1000) || (this.form.timeout*1000),
42626 upload: this.form.fileUpload ? this.success : undefined
42632 Ext.form.Action.Submit = function(form, options){
42633 Ext.form.Action.Submit.superclass.constructor.call(this, form, options);
42636 Ext.extend(Ext.form.Action.Submit, Ext.form.Action, {
42643 var o = this.options,
42644 method = this.getMethod(),
42645 isGet = method == 'GET';
42646 if(o.clientValidation === false || this.form.isValid()){
42647 if (o.submitEmptyText === false) {
42648 var fields = this.form.items,
42650 fields.each(function(f) {
42651 if (f.el.getValue() == f.emptyText) {
42652 emptyFields.push(f);
42653 f.el.dom.value = "";
42657 Ext.Ajax.request(Ext.apply(this.createCallback(o), {
42658 form:this.form.el.dom,
42659 url:this.getUrl(isGet),
42661 headers: o.headers,
42662 params:!isGet ? this.getParams() : null,
42663 isUpload: this.form.fileUpload
42665 if (o.submitEmptyText === false) {
42666 Ext.each(emptyFields, function(f) {
42667 if (f.applyEmptyText) {
42668 f.applyEmptyText();
42672 }else if (o.clientValidation !== false){
42673 this.failureType = Ext.form.Action.CLIENT_INVALID;
42674 this.form.afterAction(this, false);
42679 success : function(response){
42680 var result = this.processResponse(response);
42681 if(result === true || result.success){
42682 this.form.afterAction(this, true);
42686 this.form.markInvalid(result.errors);
42688 this.failureType = Ext.form.Action.SERVER_INVALID;
42689 this.form.afterAction(this, false);
42693 handleResponse : function(response){
42694 if(this.form.errorReader){
42695 var rs = this.form.errorReader.read(response);
42698 for(var i = 0, len = rs.records.length; i < len; i++) {
42699 var r = rs.records[i];
42700 errors[i] = r.data;
42703 if(errors.length < 1){
42707 success : rs.success,
42711 return Ext.decode(response.responseText);
42717 Ext.form.Action.Load = function(form, options){
42718 Ext.form.Action.Load.superclass.constructor.call(this, form, options);
42719 this.reader = this.form.reader;
42722 Ext.extend(Ext.form.Action.Load, Ext.form.Action, {
42728 Ext.Ajax.request(Ext.apply(
42729 this.createCallback(this.options), {
42730 method:this.getMethod(),
42731 url:this.getUrl(false),
42732 headers: this.options.headers,
42733 params:this.getParams()
42738 success : function(response){
42739 var result = this.processResponse(response);
42740 if(result === true || !result.success || !result.data){
42741 this.failureType = Ext.form.Action.LOAD_FAILURE;
42742 this.form.afterAction(this, false);
42745 this.form.clearInvalid();
42746 this.form.setValues(result.data);
42747 this.form.afterAction(this, true);
42751 handleResponse : function(response){
42752 if(this.form.reader){
42753 var rs = this.form.reader.read(response);
42754 var data = rs.records && rs.records[0] ? rs.records[0].data : null;
42756 success : rs.success,
42760 return Ext.decode(response.responseText);
42767 Ext.form.Action.DirectLoad = Ext.extend(Ext.form.Action.Load, {
42768 constructor: function(form, opts) {
42769 Ext.form.Action.DirectLoad.superclass.constructor.call(this, form, opts);
42771 type : 'directload',
42774 var args = this.getParams();
42775 args.push(this.success, this);
42776 this.form.api.load.apply(window, args);
42779 getParams : function() {
42780 var buf = [], o = {};
42781 var bp = this.form.baseParams;
42782 var p = this.options.params;
42783 Ext.apply(o, p, bp);
42784 var paramOrder = this.form.paramOrder;
42786 for(var i = 0, len = paramOrder.length; i < len; i++){
42787 buf.push(o[paramOrder[i]]);
42789 }else if(this.form.paramsAsHash){
42797 processResponse : function(result) {
42798 this.result = result;
42802 success : function(response, trans){
42803 if(trans.type == Ext.Direct.exceptions.SERVER){
42806 Ext.form.Action.DirectLoad.superclass.success.call(this, response);
42811 Ext.form.Action.DirectSubmit = Ext.extend(Ext.form.Action.Submit, {
42812 constructor : function(form, opts) {
42813 Ext.form.Action.DirectSubmit.superclass.constructor.call(this, form, opts);
42815 type : 'directsubmit',
42818 var o = this.options;
42819 if(o.clientValidation === false || this.form.isValid()){
42822 this.success.params = this.getParams();
42823 this.form.api.submit(this.form.el.dom, this.success, this);
42824 }else if (o.clientValidation !== false){
42825 this.failureType = Ext.form.Action.CLIENT_INVALID;
42826 this.form.afterAction(this, false);
42830 getParams : function() {
42832 var bp = this.form.baseParams;
42833 var p = this.options.params;
42834 Ext.apply(o, p, bp);
42840 processResponse : function(result) {
42841 this.result = result;
42845 success : function(response, trans){
42846 if(trans.type == Ext.Direct.exceptions.SERVER){
42849 Ext.form.Action.DirectSubmit.superclass.success.call(this, response);
42853 Ext.form.Action.ACTION_TYPES = {
42854 'load' : Ext.form.Action.Load,
42855 'submit' : Ext.form.Action.Submit,
42856 'directload' : Ext.form.Action.DirectLoad,
42857 'directsubmit' : Ext.form.Action.DirectSubmit
42860 Ext.form.VTypes = function(){
42862 var alpha = /^[a-zA-Z_]+$/,
42863 alphanum = /^[a-zA-Z0-9_]+$/,
42864 email = /^(\w+)([\-+.][\w]+)*@(\w[\-\w]*\.){1,5}([A-Za-z]){2,6}$/,
42865 url = /(((^https?)|(^ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
42870 'email' : function(v){
42871 return email.test(v);
42874 'emailText' : 'This field should be an e-mail address in the format "user@example.com"',
42876 'emailMask' : /[a-z0-9_\.\-@\+]/i,
42879 'url' : function(v){
42880 return url.test(v);
42883 'urlText' : 'This field should be a URL in the format "http:/'+'/www.example.com"',
42886 'alpha' : function(v){
42887 return alpha.test(v);
42890 'alphaText' : 'This field should only contain letters and _',
42892 'alphaMask' : /[a-z_]/i,
42895 'alphanum' : function(v){
42896 return alphanum.test(v);
42899 'alphanumText' : 'This field should only contain letters, numbers and _',
42901 'alphanumMask' : /[a-z0-9_]/i
42905 Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
42907 autoExpandColumn : false,
42909 autoExpandMax : 1000,
42911 autoExpandMin : 50,
42913 columnLines : false,
42919 ddText : '{0} selected row{1}',
42921 deferRowRender : true,
42925 enableColumnHide : true,
42927 enableColumnMove : true,
42929 enableDragDrop : false,
42931 enableHdMenu : true,
42937 minColumnWidth : 25,
42942 stripeRows : false,
42944 trackMouseOver : true,
42946 stateEvents : ['columnmove', 'columnresize', 'sortchange', 'groupchange'],
42961 initComponent : function(){
42962 Ext.grid.GridPanel.superclass.initComponent.call(this);
42964 if(this.columnLines){
42965 this.cls = (this.cls || '') + ' x-grid-with-col-lines';
42969 this.autoScroll = false;
42970 this.autoWidth = false;
42972 if(Ext.isArray(this.columns)){
42973 this.colModel = new Ext.grid.ColumnModel(this.columns);
42974 delete this.columns;
42979 this.store = this.ds;
42983 this.colModel = this.cm;
42987 this.selModel = this.sm;
42990 this.store = Ext.StoreMgr.lookup(this.store);
43025 'rowbodymousedown',
43028 'containermousedown',
43049 'containerdblclick',
43061 'headercontextmenu',
43063 'groupcontextmenu',
43065 'containercontextmenu',
43067 'rowbodycontextmenu',
43086 onRender : function(ct, position){
43087 Ext.grid.GridPanel.superclass.onRender.apply(this, arguments);
43089 var c = this.getGridEl();
43091 this.el.addClass('x-grid-panel');
43095 mousedown: this.onMouseDown,
43096 click: this.onClick,
43097 dblclick: this.onDblClick,
43098 contextmenu: this.onContextMenu
43101 this.relayEvents(c, ['mousedown','mouseup','mouseover','mouseout','keypress', 'keydown']);
43103 var view = this.getView();
43106 this.getSelectionModel().init(this);
43110 initEvents : function(){
43111 Ext.grid.GridPanel.superclass.initEvents.call(this);
43114 this.loadMask = new Ext.LoadMask(this.bwrap,
43115 Ext.apply({store:this.store}, this.loadMask));
43119 initStateEvents : function(){
43120 Ext.grid.GridPanel.superclass.initStateEvents.call(this);
43121 this.mon(this.colModel, 'hiddenchange', this.saveState, this, {delay: 100});
43124 applyState : function(state){
43125 var cm = this.colModel,
43126 cs = state.columns,
43127 store = this.store,
43133 for(var i = 0, len = cs.length; i < len; i++){
43135 c = cm.getColumnById(s.id);
43137 c.hidden = s.hidden;
43139 oldIndex = cm.getIndexById(s.id);
43141 cm.moveColumn(oldIndex, i);
43149 store[store.remoteSort ? 'setDefaultSort' : 'sort'](s.field, s.direction);
43156 store.clearGrouping();
43161 var o = Ext.apply({}, state);
43164 Ext.grid.GridPanel.superclass.applyState.call(this, o);
43167 getState : function(){
43168 var o = {columns: []},
43169 store = this.store,
43173 for(var i = 0, c; (c = this.colModel.config[i]); i++){
43179 o.columns[i].hidden = true;
43183 ss = store.getSortState();
43187 if(store.getGroupState){
43188 gs = store.getGroupState();
43198 afterRender : function(){
43199 Ext.grid.GridPanel.superclass.afterRender.call(this);
43201 this.on('bodyresize', v.layout, v);
43203 if(this.deferRowRender){
43204 if (!this.deferRowRenderTask){
43205 this.deferRowRenderTask = new Ext.util.DelayedTask(v.afterRender, this.view);
43207 this.deferRowRenderTask.delay(10);
43211 this.viewReady = true;
43215 reconfigure : function(store, colModel){
43216 var rendered = this.rendered;
43219 this.loadMask.destroy();
43220 this.loadMask = new Ext.LoadMask(this.bwrap,
43221 Ext.apply({}, {store:store}, this.initialConfig.loadMask));
43225 this.view.initData(store, colModel);
43227 this.store = store;
43228 this.colModel = colModel;
43230 this.view.refresh(true);
43232 this.fireEvent('reconfigure', this, store, colModel);
43236 onDestroy : function(){
43237 if (this.deferRowRenderTask && this.deferRowRenderTask.cancel){
43238 this.deferRowRenderTask.cancel();
43241 Ext.destroy(this.view, this.loadMask);
43242 }else if(this.store && this.store.autoDestroy){
43243 this.store.destroy();
43245 Ext.destroy(this.colModel, this.selModel);
43246 this.store = this.selModel = this.colModel = this.view = this.loadMask = null;
43247 Ext.grid.GridPanel.superclass.onDestroy.call(this);
43251 processEvent : function(name, e){
43252 this.view.processEvent(name, e);
43256 onClick : function(e){
43257 this.processEvent('click', e);
43261 onMouseDown : function(e){
43262 this.processEvent('mousedown', e);
43266 onContextMenu : function(e, t){
43267 this.processEvent('contextmenu', e);
43271 onDblClick : function(e){
43272 this.processEvent('dblclick', e);
43276 walkCells : function(row, col, step, fn, scope){
43277 var cm = this.colModel,
43278 clen = cm.getColumnCount(),
43280 rlen = ds.getCount(),
43294 if(fn.call(scope || this, row, col, cm) === true){
43312 if(fn.call(scope || this, row, col, cm) === true){
43324 getGridEl : function(){
43329 stopEditing : Ext.emptyFn,
43332 getSelectionModel : function(){
43333 if(!this.selModel){
43334 this.selModel = new Ext.grid.RowSelectionModel(
43335 this.disableSelection ? {selectRow: Ext.emptyFn} : null);
43337 return this.selModel;
43341 getStore : function(){
43346 getColumnModel : function(){
43347 return this.colModel;
43351 getView : function(){
43353 this.view = new Ext.grid.GridView(this.viewConfig);
43358 getDragDropText : function(){
43359 var count = this.selModel.getCount();
43360 return String.format(this.ddText, count, count == 1 ? '' : 's');
43414 Ext.reg('grid', Ext.grid.GridPanel);
43415 Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
43427 deferEmptyText : true,
43430 scrollOffset : undefined,
43439 sortClasses : ['sort-asc', 'sort-desc'],
43442 sortAscText : 'Sort Ascending',
43445 sortDescText : 'Sort Descending',
43448 columnsText : 'Columns',
43451 selectedRowClass : 'x-grid3-row-selected',
43455 tdClass : 'x-grid3-cell',
43456 hdCls : 'x-grid3-hd',
43460 cellSelectorDepth : 4,
43462 rowSelectorDepth : 10,
43465 rowBodySelectorDepth : 10,
43468 cellSelector : 'td.x-grid3-cell',
43470 rowSelector : 'div.x-grid3-row',
43473 rowBodySelector : 'div.x-grid3-row-body',
43476 firstRowCls: 'x-grid3-row-first',
43477 lastRowCls: 'x-grid3-row-last',
43478 rowClsRe: /(?:^|\s+)x-grid3-row-(first|last|alt)(?:\s+|$)/g,
43480 constructor : function(config){
43481 Ext.apply(this, config);
43485 'beforerowremoved',
43487 'beforerowsinserted',
43499 Ext.grid.GridView.superclass.constructor.call(this);
43505 initTemplates : function(){
43506 var ts = this.templates || {};
43508 ts.master = new Ext.Template(
43509 '<div class="x-grid3" hidefocus="true">',
43510 '<div class="x-grid3-viewport">',
43511 '<div class="x-grid3-header"><div class="x-grid3-header-inner"><div class="x-grid3-header-offset" style="{ostyle}">{header}</div></div><div class="x-clear"></div></div>',
43512 '<div class="x-grid3-scroller"><div class="x-grid3-body" style="{bstyle}">{body}</div><a href="#" class="x-grid3-focus" tabIndex="-1"></a></div>',
43514 '<div class="x-grid3-resize-marker"> </div>',
43515 '<div class="x-grid3-resize-proxy"> </div>',
43521 ts.header = new Ext.Template(
43522 '<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
43523 '<thead><tr class="x-grid3-hd-row">{cells}</tr></thead>',
43529 ts.hcell = new Ext.Template(
43530 '<td class="x-grid3-hd x-grid3-cell x-grid3-td-{id} {css}" style="{style}"><div {tooltip} {attr} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">', this.grid.enableHdMenu ? '<a class="x-grid3-hd-btn" href="#"></a>' : '',
43531 '{value}<img class="x-grid3-sort-icon" src="', Ext.BLANK_IMAGE_URL, '" />',
43537 ts.body = new Ext.Template('{rows}');
43541 ts.row = new Ext.Template(
43542 '<div class="x-grid3-row {alt}" style="{tstyle}"><table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
43543 '<tbody><tr>{cells}</tr>',
43544 (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>' : ''),
43545 '</tbody></table></div>'
43550 ts.cell = new Ext.Template(
43551 '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}" tabIndex="0" {cellAttr}>',
43552 '<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr}>{value}</div>',
43559 if(t && Ext.isFunction(t.compile) && !t.compiled){
43560 t.disableFormats = true;
43565 this.templates = ts;
43566 this.colRe = new RegExp('x-grid3-td-([^\\s]+)', '');
43570 fly : function(el){
43571 if(!this._flyweight){
43572 this._flyweight = new Ext.Element.Flyweight(document.body);
43574 this._flyweight.dom = el;
43575 return this._flyweight;
43579 getEditorParent : function(){
43580 return this.scroller.dom;
43584 initElements : function(){
43585 var E = Ext.Element;
43587 var el = this.grid.getGridEl().dom.firstChild;
43588 var cs = el.childNodes;
43590 this.el = new E(el);
43592 this.mainWrap = new E(cs[0]);
43593 this.mainHd = new E(this.mainWrap.dom.firstChild);
43595 if(this.grid.hideHeaders){
43596 this.mainHd.setDisplayed(false);
43599 this.innerHd = this.mainHd.dom.firstChild;
43600 this.scroller = new E(this.mainWrap.dom.childNodes[1]);
43602 this.scroller.setStyle('overflow-x', 'hidden');
43605 this.mainBody = new E(this.scroller.dom.firstChild);
43607 this.focusEl = new E(this.scroller.dom.childNodes[1]);
43608 this.focusEl.swallowEvent('click', true);
43610 this.resizeMarker = new E(cs[1]);
43611 this.resizeProxy = new E(cs[2]);
43615 getRows : function(){
43616 return this.hasRows() ? this.mainBody.dom.childNodes : [];
43622 findCell : function(el){
43626 return this.fly(el).findParent(this.cellSelector, this.cellSelectorDepth);
43630 findCellIndex : function(el, requiredCls){
43631 var cell = this.findCell(el);
43632 if(cell && (!requiredCls || this.fly(cell).hasClass(requiredCls))){
43633 return this.getCellIndex(cell);
43639 getCellIndex : function(el){
43641 var m = el.className.match(this.colRe);
43643 return this.cm.getIndexById(m[1]);
43650 findHeaderCell : function(el){
43651 var cell = this.findCell(el);
43652 return cell && this.fly(cell).hasClass(this.hdCls) ? cell : null;
43656 findHeaderIndex : function(el){
43657 return this.findCellIndex(el, this.hdCls);
43661 findRow : function(el){
43665 return this.fly(el).findParent(this.rowSelector, this.rowSelectorDepth);
43669 findRowIndex : function(el){
43670 var r = this.findRow(el);
43671 return r ? r.rowIndex : false;
43675 findRowBody : function(el){
43679 return this.fly(el).findParent(this.rowBodySelector, this.rowBodySelectorDepth);
43685 getRow : function(row){
43686 return this.getRows()[row];
43690 getCell : function(row, col){
43691 return this.getRow(row).getElementsByTagName('td')[col];
43695 getHeaderCell : function(index){
43696 return this.mainHd.dom.getElementsByTagName('td')[index];
43702 addRowClass : function(row, cls){
43703 var r = this.getRow(row);
43705 this.fly(r).addClass(cls);
43710 removeRowClass : function(row, cls){
43711 var r = this.getRow(row);
43713 this.fly(r).removeClass(cls);
43718 removeRow : function(row){
43719 Ext.removeNode(this.getRow(row));
43720 this.syncFocusEl(row);
43724 removeRows : function(firstRow, lastRow){
43725 var bd = this.mainBody.dom;
43726 for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
43727 Ext.removeNode(bd.childNodes[firstRow]);
43729 this.syncFocusEl(firstRow);
43735 getScrollState : function(){
43736 var sb = this.scroller.dom;
43737 return {left: sb.scrollLeft, top: sb.scrollTop};
43741 restoreScroll : function(state){
43742 var sb = this.scroller.dom;
43743 sb.scrollLeft = state.left;
43744 sb.scrollTop = state.top;
43748 scrollToTop : function(){
43749 this.scroller.dom.scrollTop = 0;
43750 this.scroller.dom.scrollLeft = 0;
43754 syncScroll : function(){
43755 this.syncHeaderScroll();
43756 var mb = this.scroller.dom;
43757 this.grid.fireEvent('bodyscroll', mb.scrollLeft, mb.scrollTop);
43761 syncHeaderScroll : function(){
43762 var mb = this.scroller.dom;
43763 this.innerHd.scrollLeft = mb.scrollLeft;
43764 this.innerHd.scrollLeft = mb.scrollLeft;
43768 updateSortIcon : function(col, dir){
43769 var sc = this.sortClasses;
43770 var hds = this.mainHd.select('td').removeClass(sc);
43771 hds.item(col).addClass(sc[dir == 'DESC' ? 1 : 0]);
43775 updateAllColumnWidths : function(){
43776 var tw = this.getTotalWidth(),
43777 clen = this.cm.getColumnCount(),
43782 for(i = 0; i < clen; i++){
43783 ws[i] = this.getColumnWidth(i);
43786 this.innerHd.firstChild.style.width = this.getOffsetWidth();
43787 this.innerHd.firstChild.firstChild.style.width = tw;
43788 this.mainBody.dom.style.width = tw;
43790 for(i = 0; i < clen; i++){
43791 var hd = this.getHeaderCell(i);
43792 hd.style.width = ws[i];
43795 var ns = this.getRows(), row, trow;
43796 for(i = 0, len = ns.length; i < len; i++){
43798 row.style.width = tw;
43799 if(row.firstChild){
43800 row.firstChild.style.width = tw;
43801 trow = row.firstChild.rows[0];
43802 for (var j = 0; j < clen; j++) {
43803 trow.childNodes[j].style.width = ws[j];
43808 this.onAllColumnWidthsUpdated(ws, tw);
43812 updateColumnWidth : function(col, width){
43813 var w = this.getColumnWidth(col);
43814 var tw = this.getTotalWidth();
43815 this.innerHd.firstChild.style.width = this.getOffsetWidth();
43816 this.innerHd.firstChild.firstChild.style.width = tw;
43817 this.mainBody.dom.style.width = tw;
43818 var hd = this.getHeaderCell(col);
43819 hd.style.width = w;
43821 var ns = this.getRows(), row;
43822 for(var i = 0, len = ns.length; i < len; i++){
43824 row.style.width = tw;
43825 if(row.firstChild){
43826 row.firstChild.style.width = tw;
43827 row.firstChild.rows[0].childNodes[col].style.width = w;
43831 this.onColumnWidthUpdated(col, w, tw);
43835 updateColumnHidden : function(col, hidden){
43836 var tw = this.getTotalWidth();
43837 this.innerHd.firstChild.style.width = this.getOffsetWidth();
43838 this.innerHd.firstChild.firstChild.style.width = tw;
43839 this.mainBody.dom.style.width = tw;
43840 var display = hidden ? 'none' : '';
43842 var hd = this.getHeaderCell(col);
43843 hd.style.display = display;
43845 var ns = this.getRows(), row;
43846 for(var i = 0, len = ns.length; i < len; i++){
43848 row.style.width = tw;
43849 if(row.firstChild){
43850 row.firstChild.style.width = tw;
43851 row.firstChild.rows[0].childNodes[col].style.display = display;
43855 this.onColumnHiddenUpdated(col, hidden, tw);
43856 delete this.lastViewWidth;
43861 doRender : function(columns, records, store, startRow, colCount, stripe) {
43862 var templates = this.templates,
43863 cellTemplate = templates.cell,
43864 rowTemplate = templates.row,
43865 last = colCount - 1;
43867 var tstyle = 'width:' + this.getTotalWidth() + ';';
43870 var rowBuffer = [],
43872 rowParams = {tstyle: tstyle},
43878 for (var j = 0, len = records.length; j < len; j++) {
43879 record = records[j];
43882 var rowIndex = j + startRow;
43885 for (var i = 0; i < colCount; i++) {
43886 column = columns[i];
43888 meta.id = column.id;
43889 meta.css = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
43890 meta.attr = meta.cellAttr = '';
43891 meta.style = column.style;
43892 meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store);
43894 if (Ext.isEmpty(meta.value)) {
43895 meta.value = ' ';
43898 if (this.markDirty && record.dirty && Ext.isDefined(record.modified[column.name])) {
43899 meta.css += ' x-grid3-dirty-cell';
43902 colBuffer[colBuffer.length] = cellTemplate.apply(meta);
43908 if (stripe && ((rowIndex + 1) % 2 === 0)) {
43909 alt[0] = 'x-grid3-row-alt';
43912 if (record.dirty) {
43913 alt[1] = ' x-grid3-dirty-row';
43916 rowParams.cols = colCount;
43918 if (this.getRowClass) {
43919 alt[2] = this.getRowClass(record, rowIndex, rowParams, store);
43922 rowParams.alt = alt.join(' ');
43923 rowParams.cells = colBuffer.join('');
43925 rowBuffer[rowBuffer.length] = rowTemplate.apply(rowParams);
43928 return rowBuffer.join('');
43932 processRows : function(startRow, skipStripe) {
43933 if (!this.ds || this.ds.getCount() < 1) {
43937 var rows = this.getRows(),
43941 skipStripe = skipStripe || !this.grid.stripeRows;
43942 startRow = startRow || 0;
43944 for (i = 0; i<len; i++) {
43949 r.className = r.className.replace(this.rowClsRe, ' ');
43950 if ((i + 1) % 2 === 0){
43951 r.className += ' x-grid3-row-alt';
43958 if (startRow === 0) {
43959 Ext.fly(rows[0]).addClass(this.firstRowCls);
43962 Ext.fly(rows[rows.length - 1]).addClass(this.lastRowCls);
43965 afterRender : function(){
43966 if(!this.ds || !this.cm){
43969 this.mainBody.dom.innerHTML = this.renderRows() || ' ';
43970 this.processRows(0, true);
43972 if(this.deferEmptyText !== true){
43973 this.applyEmptyText();
43975 this.grid.fireEvent('viewready', this.grid);
43979 renderUI : function() {
43980 var templates = this.templates,
43981 header = this.renderHeaders(),
43982 body = templates.body.apply({rows:' '});
43984 var html = templates.master.apply({
43987 ostyle: 'width:' + this.getOffsetWidth() + ';',
43988 bstyle: 'width:' + this.getTotalWidth() + ';'
43993 g.getGridEl().dom.innerHTML = html;
43995 this.initElements();
43998 Ext.fly(this.innerHd).on('click', this.handleHdDown, this);
44002 mouseover: this.handleHdOver,
44003 mouseout : this.handleHdOut,
44004 mousemove: this.handleHdMove
44007 this.scroller.on('scroll', this.syncScroll, this);
44008 if (g.enableColumnResize !== false) {
44009 this.splitZone = new Ext.grid.GridView.SplitDragZone(g, this.mainHd.dom);
44012 if (g.enableColumnMove) {
44013 this.columnDrag = new Ext.grid.GridView.ColumnDragZone(g, this.innerHd);
44014 this.columnDrop = new Ext.grid.HeaderDropZone(g, this.mainHd.dom);
44017 if (g.enableHdMenu !== false) {
44018 this.hmenu = new Ext.menu.Menu({id: g.id + '-hctx'});
44020 {itemId:'asc', text: this.sortAscText, cls: 'xg-hmenu-sort-asc'},
44021 {itemId:'desc', text: this.sortDescText, cls: 'xg-hmenu-sort-desc'}
44024 if (g.enableColumnHide !== false) {
44025 this.colMenu = new Ext.menu.Menu({id:g.id + '-hcols-menu'});
44028 beforeshow: this.beforeColMenuShow,
44029 itemclick : this.handleHdMenuClick
44031 this.hmenu.add('-', {
44033 hideOnClick: false,
44034 text: this.columnsText,
44035 menu: this.colMenu,
44036 iconCls: 'x-cols-icon'
44040 this.hmenu.on('itemclick', this.handleHdMenuClick, this);
44043 if (g.trackMouseOver) {
44046 mouseover: this.onRowOver,
44047 mouseout : this.onRowOut
44051 if (g.enableDragDrop || g.enableDrag) {
44052 this.dragZone = new Ext.grid.GridDragZone(g, {
44053 ddGroup : g.ddGroup || 'GridDD'
44057 this.updateHeaderSortState();
44061 processEvent : function(name, e) {
44062 var t = e.getTarget(),
44064 header = this.findHeaderIndex(t);
44065 g.fireEvent(name, e);
44066 if (header !== false) {
44067 g.fireEvent('header' + name, g, header, e);
44069 var row = this.findRowIndex(t),
44072 if (row !== false) {
44073 g.fireEvent('row' + name, g, row, e);
44074 cell = this.findCellIndex(t);
44075 if (cell !== false) {
44076 g.fireEvent('cell' + name, g, row, cell, e);
44078 body = this.findRowBody(t);
44080 g.fireEvent('rowbody' + name, g, row, e);
44084 g.fireEvent('container' + name, g, e);
44090 layout : function() {
44091 if(!this.mainBody){
44095 var c = g.getGridEl();
44096 var csize = c.getSize(true);
44097 var vw = csize.width;
44099 if(!g.hideHeaders && (vw < 20 || csize.height < 20)){
44104 this.scroller.dom.style.overflow = 'visible';
44106 this.scroller.dom.style.position = 'static';
44109 this.el.setSize(csize.width, csize.height);
44111 var hdHeight = this.mainHd.getHeight();
44112 var vh = csize.height - (hdHeight);
44114 this.scroller.setSize(vw, vh);
44116 this.innerHd.style.width = (vw)+'px';
44120 if(this.lastViewWidth != vw){
44121 this.fitColumns(false, false);
44122 this.lastViewWidth = vw;
44126 this.syncHeaderScroll();
44128 this.onLayout(vw, vh);
44133 onLayout : function(vw, vh){
44137 onColumnWidthUpdated : function(col, w, tw){
44141 onAllColumnWidthsUpdated : function(ws, tw){
44145 onColumnHiddenUpdated : function(col, hidden, tw){
44149 updateColumnText : function(col, text){
44153 afterMove : function(colIndex){
44159 init : function(grid){
44162 this.initTemplates();
44163 this.initData(grid.store, grid.colModel);
44168 getColumnId : function(index){
44169 return this.cm.getColumnId(index);
44173 getOffsetWidth : function() {
44174 return (this.cm.getTotalWidth() + this.getScrollOffset()) + 'px';
44177 getScrollOffset: function(){
44178 return Ext.num(this.scrollOffset, Ext.getScrollBarWidth());
44182 renderHeaders : function() {
44184 ts = this.templates,
44188 len = cm.getColumnCount(),
44191 for (var i = 0; i < len; i++) {
44192 p.id = cm.getColumnId(i);
44193 p.value = cm.getColumnHeader(i) || '';
44194 p.style = this.getColumnStyle(i, true);
44195 p.tooltip = this.getColumnTooltip(i);
44196 p.css = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
44198 if (cm.config[i].align == 'right') {
44199 p.istyle = 'padding-right:16px';
44203 cb[cb.length] = ct.apply(p);
44205 return ts.header.apply({cells: cb.join(''), tstyle:'width:'+this.getTotalWidth()+';'});
44209 getColumnTooltip : function(i){
44210 var tt = this.cm.getColumnTooltip(i);
44212 if(Ext.QuickTips.isEnabled()){
44213 return 'ext:qtip="'+tt+'"';
44215 return 'title="'+tt+'"';
44222 beforeUpdate : function(){
44223 this.grid.stopEditing(true);
44227 updateHeaders : function(){
44228 this.innerHd.firstChild.innerHTML = this.renderHeaders();
44229 this.innerHd.firstChild.style.width = this.getOffsetWidth();
44230 this.innerHd.firstChild.firstChild.style.width = this.getTotalWidth();
44234 focusRow : function(row){
44235 this.focusCell(row, 0, false);
44239 focusCell : function(row, col, hscroll){
44240 this.syncFocusEl(this.ensureVisible(row, col, hscroll));
44242 this.focusEl.focus();
44244 this.focusEl.focus.defer(1, this.focusEl);
44248 resolveCell : function(row, col, hscroll){
44249 if(!Ext.isNumber(row)){
44250 row = row.rowIndex;
44255 if(row < 0 || row >= this.ds.getCount()){
44258 col = (col !== undefined ? col : 0);
44260 var rowEl = this.getRow(row),
44262 colCount = cm.getColumnCount(),
44264 if(!(hscroll === false && col === 0)){
44265 while(col < colCount && cm.isHidden(col)){
44268 cellEl = this.getCell(row, col);
44271 return {row: rowEl, cell: cellEl};
44274 getResolvedXY : function(resolved){
44278 var s = this.scroller.dom, c = resolved.cell, r = resolved.row;
44279 return c ? Ext.fly(c).getXY() : [this.el.getX(), Ext.fly(r).getY()];
44282 syncFocusEl : function(row, col, hscroll){
44284 if(!Ext.isArray(xy)){
44285 row = Math.min(row, Math.max(0, this.getRows().length-1));
44289 xy = this.getResolvedXY(this.resolveCell(row, col, hscroll));
44291 this.focusEl.setXY(xy||this.scroller.getXY());
44294 ensureVisible : function(row, col, hscroll){
44295 var resolved = this.resolveCell(row, col, hscroll);
44296 if(!resolved || !resolved.row){
44300 var rowEl = resolved.row,
44301 cellEl = resolved.cell,
44302 c = this.scroller.dom,
44305 stop = this.el.dom;
44307 while(p && p != stop){
44308 ctop += p.offsetTop;
44309 p = p.offsetParent;
44312 ctop -= this.mainHd.dom.offsetHeight;
44313 stop = parseInt(c.scrollTop, 10);
44315 var cbot = ctop + rowEl.offsetHeight,
44316 ch = c.clientHeight,
44321 c.scrollTop = ctop;
44322 }else if(cbot > sbot){
44323 c.scrollTop = cbot-ch;
44326 if(hscroll !== false){
44327 var cleft = parseInt(cellEl.offsetLeft, 10);
44328 var cright = cleft + cellEl.offsetWidth;
44330 var sleft = parseInt(c.scrollLeft, 10);
44331 var sright = sleft + c.clientWidth;
44333 c.scrollLeft = cleft;
44334 }else if(cright > sright){
44335 c.scrollLeft = cright-c.clientWidth;
44338 return this.getResolvedXY(resolved);
44342 insertRows : function(dm, firstRow, lastRow, isUpdate) {
44343 var last = dm.getCount() - 1;
44344 if( !isUpdate && firstRow === 0 && lastRow >= last) {
44345 this.fireEvent('beforerowsinserted', this, firstRow, lastRow);
44347 this.fireEvent('rowsinserted', this, firstRow, lastRow);
44350 this.fireEvent('beforerowsinserted', this, firstRow, lastRow);
44352 var html = this.renderRows(firstRow, lastRow),
44353 before = this.getRow(firstRow);
44355 if(firstRow === 0){
44356 Ext.fly(this.getRow(0)).removeClass(this.firstRowCls);
44358 Ext.DomHelper.insertHtml('beforeBegin', before, html);
44360 var r = this.getRow(last - 1);
44362 Ext.fly(r).removeClass(this.lastRowCls);
44364 Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html);
44367 this.fireEvent('rowsinserted', this, firstRow, lastRow);
44368 this.processRows(firstRow);
44369 } else if (firstRow === 0 || firstRow >= last) {
44371 Ext.fly(this.getRow(firstRow)).addClass(firstRow === 0 ? this.firstRowCls : this.lastRowCls);
44374 this.syncFocusEl(firstRow);
44378 deleteRows : function(dm, firstRow, lastRow){
44379 if(dm.getRowCount()<1){
44382 this.fireEvent('beforerowsdeleted', this, firstRow, lastRow);
44384 this.removeRows(firstRow, lastRow);
44386 this.processRows(firstRow);
44387 this.fireEvent('rowsdeleted', this, firstRow, lastRow);
44392 getColumnStyle : function(col, isHeader){
44393 var style = !isHeader ? (this.cm.config[col].css || '') : '';
44394 style += 'width:'+this.getColumnWidth(col)+';';
44395 if(this.cm.isHidden(col)){
44396 style += 'display:none;';
44398 var align = this.cm.config[col].align;
44400 style += 'text-align:'+align+';';
44406 getColumnWidth : function(col){
44407 var w = this.cm.getColumnWidth(col);
44408 if(Ext.isNumber(w)){
44409 return (Ext.isBorderBox || (Ext.isWebKit && !Ext.isSafari2) ? w : (w - this.borderWidth > 0 ? w - this.borderWidth : 0)) + 'px';
44415 getTotalWidth : function(){
44416 return this.cm.getTotalWidth()+'px';
44420 fitColumns : function(preventRefresh, onlyExpand, omitColumn){
44421 var cm = this.cm, i;
44422 var tw = cm.getTotalWidth(false);
44423 var aw = this.grid.getGridEl().getWidth(true)-this.getScrollOffset();
44428 var extra = aw - tw;
44434 var vc = cm.getColumnCount(true);
44435 var ac = vc-(Ext.isNumber(omitColumn) ? 1 : 0);
44438 omitColumn = undefined;
44440 var colCount = cm.getColumnCount();
44445 for (i = 0; i < colCount; i++){
44446 if(!cm.isHidden(i) && !cm.isFixed(i) && i !== omitColumn){
44447 w = cm.getColumnWidth(i);
44454 var frac = (aw - cm.getTotalWidth())/width;
44455 while (cols.length){
44458 cm.setColumnWidth(i, Math.max(this.grid.minColumnWidth, Math.floor(w + w*frac)), true);
44461 if((tw = cm.getTotalWidth(false)) > aw){
44462 var adjustCol = ac != vc ? omitColumn : extraCol;
44463 cm.setColumnWidth(adjustCol, Math.max(1,
44464 cm.getColumnWidth(adjustCol)- (tw-aw)), true);
44467 if(preventRefresh !== true){
44468 this.updateAllColumnWidths();
44476 autoExpand : function(preventUpdate){
44477 var g = this.grid, cm = this.cm;
44478 if(!this.userResized && g.autoExpandColumn){
44479 var tw = cm.getTotalWidth(false);
44480 var aw = this.grid.getGridEl().getWidth(true)-this.getScrollOffset();
44482 var ci = cm.getIndexById(g.autoExpandColumn);
44483 var currentWidth = cm.getColumnWidth(ci);
44484 var cw = Math.min(Math.max(((aw-tw)+currentWidth), g.autoExpandMin), g.autoExpandMax);
44485 if(cw != currentWidth){
44486 cm.setColumnWidth(ci, cw, true);
44487 if(preventUpdate !== true){
44488 this.updateColumnWidth(ci, cw);
44496 getColumnData : function(){
44500 colCount = cm.getColumnCount();
44502 for (var i = 0; i < colCount; i++) {
44503 var name = cm.getDataIndex(i);
44506 name : (!Ext.isDefined(name) ? this.ds.fields.get(i).name : name),
44507 renderer: cm.getRenderer(i),
44508 scope : cm.getRendererScope(i),
44509 id : cm.getColumnId(i),
44510 style : this.getColumnStyle(i)
44518 renderRows : function(startRow, endRow){
44520 var g = this.grid, cm = g.colModel, ds = g.store, stripe = g.stripeRows;
44521 var colCount = cm.getColumnCount();
44523 if(ds.getCount() < 1){
44527 var cs = this.getColumnData();
44529 startRow = startRow || 0;
44530 endRow = !Ext.isDefined(endRow) ? ds.getCount()-1 : endRow;
44533 var rs = ds.getRange(startRow, endRow);
44535 return this.doRender(cs, rs, ds, startRow, colCount, stripe);
44539 renderBody : function(){
44540 var markup = this.renderRows() || ' ';
44541 return this.templates.body.apply({rows: markup});
44545 refreshRow : function(record){
44546 var ds = this.ds, index;
44547 if(Ext.isNumber(record)){
44549 record = ds.getAt(index);
44554 index = ds.indexOf(record);
44559 this.insertRows(ds, index, index, true);
44560 this.getRow(index).rowIndex = index;
44561 this.onRemove(ds, record, index+1, true);
44562 this.fireEvent('rowupdated', this, index, record);
44566 refresh : function(headersToo){
44567 this.fireEvent('beforerefresh', this);
44568 this.grid.stopEditing(true);
44570 var result = this.renderBody();
44571 this.mainBody.update(result).setWidth(this.getTotalWidth());
44572 if(headersToo === true){
44573 this.updateHeaders();
44574 this.updateHeaderSortState();
44576 this.processRows(0, true);
44578 this.applyEmptyText();
44579 this.fireEvent('refresh', this);
44583 applyEmptyText : function(){
44584 if(this.emptyText && !this.hasRows()){
44585 this.mainBody.update('<div class="x-grid-empty">' + this.emptyText + '</div>');
44590 updateHeaderSortState : function(){
44591 var state = this.ds.getSortState();
44596 if (!this.sortState || (this.sortState.field != state.field || this.sortState.direction != state.direction)) {
44597 this.grid.fireEvent('sortchange', this.grid, state);
44600 this.sortState = state;
44602 var sortColumn = this.cm.findColumnIndex(state.field);
44603 if (sortColumn != -1){
44604 var sortDir = state.direction;
44605 this.updateSortIcon(sortColumn, sortDir);
44610 clearHeaderSortState : function(){
44611 if (!this.sortState) {
44614 this.grid.fireEvent('sortchange', this.grid, null);
44615 this.mainHd.select('td').removeClass(this.sortClasses);
44616 delete this.sortState;
44620 destroy : function(){
44621 if (this.scrollToTopTask && this.scrollToTopTask.cancel){
44622 this.scrollToTopTask.cancel();
44625 Ext.menu.MenuMgr.unregister(this.colMenu);
44626 this.colMenu.destroy();
44627 delete this.colMenu;
44630 Ext.menu.MenuMgr.unregister(this.hmenu);
44631 this.hmenu.destroy();
44635 this.initData(null, null);
44636 this.purgeListeners();
44637 Ext.fly(this.innerHd).un("click", this.handleHdDown, this);
44639 if(this.grid.enableColumnMove){
44641 this.columnDrag.el,
44642 this.columnDrag.proxy.ghost,
44643 this.columnDrag.proxy.el,
44644 this.columnDrop.el,
44645 this.columnDrop.proxyTop,
44646 this.columnDrop.proxyBottom,
44647 this.columnDrag.dragData.ddel,
44648 this.columnDrag.dragData.header
44650 if (this.columnDrag.proxy.anim) {
44651 Ext.destroy(this.columnDrag.proxy.anim);
44653 delete this.columnDrag.proxy.ghost;
44654 delete this.columnDrag.dragData.ddel;
44655 delete this.columnDrag.dragData.header;
44656 this.columnDrag.destroy();
44657 delete Ext.dd.DDM.locationCache[this.columnDrag.id];
44658 delete this.columnDrag._domRef;
44660 delete this.columnDrop.proxyTop;
44661 delete this.columnDrop.proxyBottom;
44662 this.columnDrop.destroy();
44663 delete Ext.dd.DDM.locationCache["gridHeader" + this.grid.getGridEl().id];
44664 delete this.columnDrop._domRef;
44665 delete Ext.dd.DDM.ids[this.columnDrop.ddGroup];
44668 if (this.splitZone){
44669 this.splitZone.destroy();
44670 delete this.splitZone._domRef;
44671 delete Ext.dd.DDM.ids["gridSplitters" + this.grid.getGridEl().id];
44674 Ext.fly(this.innerHd).removeAllListeners();
44675 Ext.removeNode(this.innerHd);
44676 delete this.innerHd;
44693 delete this.grid.container;
44696 this.dragZone.destroy();
44699 Ext.dd.DDM.currentTarget = null;
44700 delete Ext.dd.DDM.locationCache[this.grid.getGridEl().id];
44702 Ext.EventManager.removeResizeListener(this.onWindowResize, this);
44706 onDenyColumnHide : function(){
44711 render : function(){
44713 var ct = this.grid.ownerCt;
44714 if (ct && ct.getLayout()){
44715 ct.on('afterlayout', function(){
44716 this.fitColumns(true, true);
44717 this.updateHeaders();
44718 }, this, {single: true});
44720 this.fitColumns(true, true);
44722 }else if(this.forceFit){
44723 this.fitColumns(true, false);
44724 }else if(this.grid.autoExpandColumn){
44725 this.autoExpand(true);
44733 initData : function(ds, cm){
44735 this.ds.un('load', this.onLoad, this);
44736 this.ds.un('datachanged', this.onDataChange, this);
44737 this.ds.un('add', this.onAdd, this);
44738 this.ds.un('remove', this.onRemove, this);
44739 this.ds.un('update', this.onUpdate, this);
44740 this.ds.un('clear', this.onClear, this);
44741 if(this.ds !== ds && this.ds.autoDestroy){
44749 datachanged: this.onDataChange,
44751 remove: this.onRemove,
44752 update: this.onUpdate,
44753 clear: this.onClear
44759 this.cm.un('configchange', this.onColConfigChange, this);
44760 this.cm.un('widthchange', this.onColWidthChange, this);
44761 this.cm.un('headerchange', this.onHeaderChange, this);
44762 this.cm.un('hiddenchange', this.onHiddenChange, this);
44763 this.cm.un('columnmoved', this.onColumnMove, this);
44766 delete this.lastViewWidth;
44769 configchange: this.onColConfigChange,
44770 widthchange: this.onColWidthChange,
44771 headerchange: this.onHeaderChange,
44772 hiddenchange: this.onHiddenChange,
44773 columnmoved: this.onColumnMove
44780 onDataChange : function(){
44782 this.updateHeaderSortState();
44783 this.syncFocusEl(0);
44787 onClear : function(){
44789 this.syncFocusEl(0);
44793 onUpdate : function(ds, record){
44794 this.refreshRow(record);
44798 onAdd : function(ds, records, index){
44799 this.insertRows(ds, index, index + (records.length-1));
44803 onRemove : function(ds, record, index, isUpdate){
44804 if(isUpdate !== true){
44805 this.fireEvent('beforerowremoved', this, index, record);
44807 this.removeRow(index);
44808 if(isUpdate !== true){
44809 this.processRows(index);
44810 this.applyEmptyText();
44811 this.fireEvent('rowremoved', this, index, record);
44816 onLoad : function(){
44818 if (!this.scrollToTopTask) {
44819 this.scrollToTopTask = new Ext.util.DelayedTask(this.scrollToTop, this);
44821 this.scrollToTopTask.delay(1);
44823 this.scrollToTop();
44828 onColWidthChange : function(cm, col, width){
44829 this.updateColumnWidth(col, width);
44833 onHeaderChange : function(cm, col, text){
44834 this.updateHeaders();
44838 onHiddenChange : function(cm, col, hidden){
44839 this.updateColumnHidden(col, hidden);
44843 onColumnMove : function(cm, oldIndex, newIndex){
44844 this.indexMap = null;
44845 var s = this.getScrollState();
44846 this.refresh(true);
44847 this.restoreScroll(s);
44848 this.afterMove(newIndex);
44849 this.grid.fireEvent('columnmove', oldIndex, newIndex);
44853 onColConfigChange : function(){
44854 delete this.lastViewWidth;
44855 this.indexMap = null;
44856 this.refresh(true);
44861 initUI : function(grid){
44862 grid.on('headerclick', this.onHeaderClick, this);
44866 initEvents : function(){
44870 onHeaderClick : function(g, index){
44871 if(this.headersDisabled || !this.cm.isSortable(index)){
44874 g.stopEditing(true);
44875 g.store.sort(this.cm.getDataIndex(index));
44879 onRowOver : function(e, t){
44881 if((row = this.findRowIndex(t)) !== false){
44882 this.addRowClass(row, 'x-grid3-row-over');
44887 onRowOut : function(e, t){
44889 if((row = this.findRowIndex(t)) !== false && !e.within(this.getRow(row), true)){
44890 this.removeRowClass(row, 'x-grid3-row-over');
44895 handleWheel : function(e){
44896 e.stopPropagation();
44900 onRowSelect : function(row){
44901 this.addRowClass(row, this.selectedRowClass);
44905 onRowDeselect : function(row){
44906 this.removeRowClass(row, this.selectedRowClass);
44910 onCellSelect : function(row, col){
44911 var cell = this.getCell(row, col);
44913 this.fly(cell).addClass('x-grid3-cell-selected');
44918 onCellDeselect : function(row, col){
44919 var cell = this.getCell(row, col);
44921 this.fly(cell).removeClass('x-grid3-cell-selected');
44926 onColumnSplitterMoved : function(i, w){
44927 this.userResized = true;
44928 var cm = this.grid.colModel;
44929 cm.setColumnWidth(i, w, true);
44932 this.fitColumns(true, false, i);
44933 this.updateAllColumnWidths();
44935 this.updateColumnWidth(i, w);
44936 this.syncHeaderScroll();
44939 this.grid.fireEvent('columnresize', i, w);
44943 handleHdMenuClick : function(item){
44944 var index = this.hdCtxIndex,
44947 id = item.getItemId();
44950 ds.sort(cm.getDataIndex(index), 'ASC');
44953 ds.sort(cm.getDataIndex(index), 'DESC');
44956 index = cm.getIndexById(id.substr(4));
44958 if(item.checked && cm.getColumnsBy(this.isHideableColumn, this).length <= 1){
44959 this.onDenyColumnHide();
44962 cm.setHidden(index, item.checked);
44969 isHideableColumn : function(c){
44974 beforeColMenuShow : function(){
44975 var cm = this.cm, colCount = cm.getColumnCount();
44976 this.colMenu.removeAll();
44977 for(var i = 0; i < colCount; i++){
44978 if(cm.config[i].hideable !== false){
44979 this.colMenu.add(new Ext.menu.CheckItem({
44980 itemId: 'col-'+cm.getColumnId(i),
44981 text: cm.getColumnHeader(i),
44982 checked: !cm.isHidden(i),
44984 disabled: cm.config[i].hideable === false
44991 handleHdDown : function(e, t){
44992 if(Ext.fly(t).hasClass('x-grid3-hd-btn')){
44994 var hd = this.findHeaderCell(t);
44995 Ext.fly(hd).addClass('x-grid3-hd-menu-open');
44996 var index = this.getCellIndex(hd);
44997 this.hdCtxIndex = index;
44998 var ms = this.hmenu.items, cm = this.cm;
44999 ms.get('asc').setDisabled(!cm.isSortable(index));
45000 ms.get('desc').setDisabled(!cm.isSortable(index));
45001 this.hmenu.on('hide', function(){
45002 Ext.fly(hd).removeClass('x-grid3-hd-menu-open');
45003 }, this, {single:true});
45004 this.hmenu.show(t, 'tl-bl?');
45009 handleHdOver : function(e, t){
45010 var hd = this.findHeaderCell(t);
45011 if(hd && !this.headersDisabled){
45012 this.activeHdRef = t;
45013 this.activeHdIndex = this.getCellIndex(hd);
45014 var fly = this.fly(hd);
45015 this.activeHdRegion = fly.getRegion();
45016 if(!this.cm.isMenuDisabled(this.activeHdIndex)){
45017 fly.addClass('x-grid3-hd-over');
45018 this.activeHdBtn = fly.child('.x-grid3-hd-btn');
45019 if(this.activeHdBtn){
45020 this.activeHdBtn.dom.style.height = (hd.firstChild.offsetHeight-1)+'px';
45027 handleHdMove : function(e, t){
45028 var hd = this.findHeaderCell(this.activeHdRef);
45029 if(hd && !this.headersDisabled){
45030 var hw = this.splitHandleWidth || 5,
45031 r = this.activeHdRegion,
45035 if(this.grid.enableColumnResize !== false){
45036 if(x - r.left <= hw && this.cm.isResizable(this.activeHdIndex-1)){
45037 cur = Ext.isAir ? 'move' : Ext.isWebKit ? 'e-resize' : 'col-resize';
45038 }else if(r.right - x <= (!this.activeHdBtn ? hw : 2) && this.cm.isResizable(this.activeHdIndex)){
45039 cur = Ext.isAir ? 'move' : Ext.isWebKit ? 'w-resize' : 'col-resize';
45047 handleHdOut : function(e, t){
45048 var hd = this.findHeaderCell(t);
45049 if(hd && (!Ext.isIE || !e.within(hd, true))){
45050 this.activeHdRef = null;
45051 this.fly(hd).removeClass('x-grid3-hd-over');
45052 hd.style.cursor = '';
45057 hasRows : function(){
45058 var fc = this.mainBody.dom.firstChild;
45059 return fc && fc.nodeType == 1 && fc.className != 'x-grid-empty';
45063 bind : function(d, c){
45064 this.initData(d, c);
45071 Ext.grid.GridView.SplitDragZone = Ext.extend(Ext.dd.DDProxy, {
45073 constructor: function(grid, hd){
45075 this.view = grid.getView();
45076 this.marker = this.view.resizeMarker;
45077 this.proxy = this.view.resizeProxy;
45078 Ext.grid.GridView.SplitDragZone.superclass.constructor.call(this, hd,
45079 'gridSplitters' + this.grid.getGridEl().id, {
45080 dragElId : Ext.id(this.proxy.dom), resizeFrame:false
45082 this.scroll = false;
45083 this.hw = this.view.splitHandleWidth || 5;
45086 b4StartDrag : function(x, y){
45087 this.dragHeadersDisabled = this.view.headersDisabled;
45088 this.view.headersDisabled = true;
45089 var h = this.view.mainWrap.getHeight();
45090 this.marker.setHeight(h);
45091 this.marker.show();
45092 this.marker.alignTo(this.view.getHeaderCell(this.cellIndex), 'tl-tl', [-2, 0]);
45093 this.proxy.setHeight(h);
45094 var w = this.cm.getColumnWidth(this.cellIndex),
45095 minw = Math.max(w-this.grid.minColumnWidth, 0);
45096 this.resetConstraints();
45097 this.setXConstraint(minw, 1000);
45098 this.setYConstraint(0, 0);
45099 this.minX = x - minw;
45100 this.maxX = x + 1000;
45102 Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
45105 allowHeaderDrag : function(e){
45109 handleMouseDown : function(e){
45110 var t = this.view.findHeaderCell(e.getTarget());
45111 if(t && this.allowHeaderDrag(e)){
45112 var xy = this.view.fly(t).getXY(),
45115 exy = e.getXY(), ex = exy[0],
45116 w = t.offsetWidth, adjust = false;
45118 if((ex - x) <= this.hw){
45120 }else if((x+w) - ex <= this.hw){
45123 if(adjust !== false){
45124 this.cm = this.grid.colModel;
45125 var ci = this.view.getCellIndex(t);
45127 if (ci + adjust < 0) {
45130 while(this.cm.isHidden(ci+adjust)){
45137 this.cellIndex = ci+adjust;
45138 this.split = t.dom;
45139 if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
45140 Ext.grid.GridView.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
45142 }else if(this.view.columnDrag){
45143 this.view.columnDrag.callHandleMouseDown(e);
45148 endDrag : function(e){
45149 this.marker.hide();
45151 endX = Math.max(this.minX, e.getPageX()),
45152 diff = endX - this.startPos,
45153 disabled = this.dragHeadersDisabled;
45155 v.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
45156 setTimeout(function(){
45157 v.headersDisabled = disabled;
45161 autoOffset : function(){
45162 this.setDelta(0,0);
45167 Ext.grid.HeaderDragZone = Ext.extend(Ext.dd.DragZone, {
45170 constructor : function(grid, hd, hd2){
45172 this.view = grid.getView();
45173 this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
45174 Ext.grid.HeaderDragZone.superclass.constructor.call(this, hd);
45176 this.setHandleElId(Ext.id(hd));
45177 this.setOuterHandleElId(Ext.id(hd2));
45179 this.scroll = false;
45182 getDragData : function(e){
45183 var t = Ext.lib.Event.getTarget(e),
45184 h = this.view.findHeaderCell(t);
45186 return {ddel: h.firstChild, header:h};
45191 onInitDrag : function(e){
45193 this.dragHeadersDisabled = this.view.headersDisabled;
45194 this.view.headersDisabled = true;
45195 var clone = this.dragData.ddel.cloneNode(true);
45196 clone.id = Ext.id();
45197 clone.style.width = Math.min(this.dragData.header.offsetWidth,this.maxDragWidth) + "px";
45198 this.proxy.update(clone);
45202 afterValidDrop : function(){
45203 this.completeDrop();
45206 afterInvalidDrop : function(){
45207 this.completeDrop();
45210 completeDrop: function(){
45212 disabled = this.dragHeadersDisabled;
45213 setTimeout(function(){
45214 v.headersDisabled = disabled;
45221 Ext.grid.HeaderDropZone = Ext.extend(Ext.dd.DropZone, {
45222 proxyOffsets : [-4, -9],
45223 fly: Ext.Element.fly,
45225 constructor : function(grid, hd, hd2){
45227 this.view = grid.getView();
45229 this.proxyTop = Ext.DomHelper.append(document.body, {
45230 cls:"col-move-top", html:" "
45232 this.proxyBottom = Ext.DomHelper.append(document.body, {
45233 cls:"col-move-bottom", html:" "
45235 this.proxyTop.hide = this.proxyBottom.hide = function(){
45236 this.setLeftTop(-100,-100);
45237 this.setStyle("visibility", "hidden");
45239 this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
45242 Ext.grid.HeaderDropZone.superclass.constructor.call(this, grid.getGridEl().dom);
45245 getTargetFromEvent : function(e){
45246 var t = Ext.lib.Event.getTarget(e),
45247 cindex = this.view.findCellIndex(t);
45248 if(cindex !== false){
45249 return this.view.getHeaderCell(cindex);
45253 nextVisible : function(h){
45254 var v = this.view, cm = this.grid.colModel;
45257 if(!cm.isHidden(v.getCellIndex(h))){
45265 prevVisible : function(h){
45266 var v = this.view, cm = this.grid.colModel;
45269 if(!cm.isHidden(v.getCellIndex(h))){
45277 positionIndicator : function(h, n, e){
45278 var x = Ext.lib.Event.getPageX(e),
45279 r = Ext.lib.Dom.getRegion(n.firstChild),
45282 py = r.top + this.proxyOffsets[1];
45283 if((r.right - x) <= (r.right-r.left)/2){
45284 px = r.right+this.view.borderWidth;
45291 if(this.grid.colModel.isFixed(this.view.getCellIndex(n))){
45295 px += this.proxyOffsets[0];
45296 this.proxyTop.setLeftTop(px, py);
45297 this.proxyTop.show();
45298 if(!this.bottomOffset){
45299 this.bottomOffset = this.view.mainHd.getHeight();
45301 this.proxyBottom.setLeftTop(px, py+this.proxyTop.dom.offsetHeight+this.bottomOffset);
45302 this.proxyBottom.show();
45306 onNodeEnter : function(n, dd, e, data){
45307 if(data.header != n){
45308 this.positionIndicator(data.header, n, e);
45312 onNodeOver : function(n, dd, e, data){
45313 var result = false;
45314 if(data.header != n){
45315 result = this.positionIndicator(data.header, n, e);
45318 this.proxyTop.hide();
45319 this.proxyBottom.hide();
45321 return result ? this.dropAllowed : this.dropNotAllowed;
45324 onNodeOut : function(n, dd, e, data){
45325 this.proxyTop.hide();
45326 this.proxyBottom.hide();
45329 onNodeDrop : function(n, dd, e, data){
45330 var h = data.header;
45332 var cm = this.grid.colModel,
45333 x = Ext.lib.Event.getPageX(e),
45334 r = Ext.lib.Dom.getRegion(n.firstChild),
45335 pt = (r.right - x) <= ((r.right-r.left)/2) ? "after" : "before",
45336 oldIndex = this.view.getCellIndex(h),
45337 newIndex = this.view.getCellIndex(n);
45341 if(oldIndex < newIndex){
45344 cm.moveColumn(oldIndex, newIndex);
45351 Ext.grid.GridView.ColumnDragZone = Ext.extend(Ext.grid.HeaderDragZone, {
45353 constructor : function(grid, hd){
45354 Ext.grid.GridView.ColumnDragZone.superclass.constructor.call(this, grid, hd, null);
45355 this.proxy.el.addClass('x-grid3-col-dd');
45358 handleMouseDown : function(e){
45361 callHandleMouseDown : function(e){
45362 Ext.grid.GridView.ColumnDragZone.superclass.handleMouseDown.call(this, e);
45366 Ext.grid.SplitDragZone = Ext.extend(Ext.dd.DDProxy, {
45367 fly: Ext.Element.fly,
45369 constructor : function(grid, hd, hd2){
45371 this.view = grid.getView();
45372 this.proxy = this.view.resizeProxy;
45373 Ext.grid.SplitDragZone.superclass.constructor.call(this, hd,
45374 "gridSplitters" + this.grid.getGridEl().id, {
45375 dragElId : Ext.id(this.proxy.dom), resizeFrame:false
45377 this.setHandleElId(Ext.id(hd));
45378 this.setOuterHandleElId(Ext.id(hd2));
45379 this.scroll = false;
45382 b4StartDrag : function(x, y){
45383 this.view.headersDisabled = true;
45384 this.proxy.setHeight(this.view.mainWrap.getHeight());
45385 var w = this.cm.getColumnWidth(this.cellIndex);
45386 var minw = Math.max(w-this.grid.minColumnWidth, 0);
45387 this.resetConstraints();
45388 this.setXConstraint(minw, 1000);
45389 this.setYConstraint(0, 0);
45390 this.minX = x - minw;
45391 this.maxX = x + 1000;
45393 Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
45397 handleMouseDown : function(e){
45398 var ev = Ext.EventObject.setEvent(e);
45399 var t = this.fly(ev.getTarget());
45400 if(t.hasClass("x-grid-split")){
45401 this.cellIndex = this.view.getCellIndex(t.dom);
45402 this.split = t.dom;
45403 this.cm = this.grid.colModel;
45404 if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
45405 Ext.grid.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
45410 endDrag : function(e){
45411 this.view.headersDisabled = false;
45412 var endX = Math.max(this.minX, Ext.lib.Event.getPageX(e));
45413 var diff = endX - this.startPos;
45414 this.view.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
45417 autoOffset : function(){
45418 this.setDelta(0,0);
45421 Ext.grid.GridDragZone = function(grid, config){
45422 this.view = grid.getView();
45423 Ext.grid.GridDragZone.superclass.constructor.call(this, this.view.mainBody.dom, config);
45424 this.scroll = false;
45426 this.ddel = document.createElement('div');
45427 this.ddel.className = 'x-grid-dd-wrap';
45430 Ext.extend(Ext.grid.GridDragZone, Ext.dd.DragZone, {
45431 ddGroup : "GridDD",
45434 getDragData : function(e){
45435 var t = Ext.lib.Event.getTarget(e);
45436 var rowIndex = this.view.findRowIndex(t);
45437 if(rowIndex !== false){
45438 var sm = this.grid.selModel;
45439 if(!sm.isSelected(rowIndex) || e.hasModifier()){
45440 sm.handleMouseDown(this.grid, rowIndex, e);
45442 return {grid: this.grid, ddel: this.ddel, rowIndex: rowIndex, selections:sm.getSelections()};
45448 onInitDrag : function(e){
45449 var data = this.dragData;
45450 this.ddel.innerHTML = this.grid.getDragDropText();
45451 this.proxy.update(this.ddel);
45456 afterRepair : function(){
45457 this.dragging = false;
45461 getRepairXY : function(e, data){
45465 onEndDrag : function(data, e){
45469 onValidDrop : function(dd, e, id){
45474 beforeInvalidDrop : function(e, id){
45479 Ext.grid.ColumnModel = Ext.extend(Ext.util.Observable, {
45483 defaultSortable: false,
45487 constructor : function(config){
45489 if(config.columns){
45490 Ext.apply(this, config);
45491 this.setConfig(config.columns, true);
45493 this.setConfig(config, true);
45507 Ext.grid.ColumnModel.superclass.constructor.call(this);
45511 getColumnId : function(index){
45512 return this.config[index].id;
45515 getColumnAt : function(index){
45516 return this.config[index];
45520 setConfig : function(config, initial){
45523 delete this.totalWidth;
45524 for(i = 0, len = this.config.length; i < len; i++){
45525 c = this.config[i];
45534 this.defaults = Ext.apply({
45535 width: this.defaultWidth,
45536 sortable: this.defaultSortable
45539 this.config = config;
45542 for(i = 0, len = config.length; i < len; i++){
45543 c = Ext.applyIf(config[i], this.defaults);
45545 if(Ext.isEmpty(c.id)){
45549 var Cls = Ext.grid.Column.types[c.xtype || 'gridcolumn'];
45553 this.lookup[c.id] = c;
45556 this.fireEvent('configchange', this);
45561 getColumnById : function(id){
45562 return this.lookup[id];
45566 getIndexById : function(id){
45567 for(var i = 0, len = this.config.length; i < len; i++){
45568 if(this.config[i].id == id){
45576 moveColumn : function(oldIndex, newIndex){
45577 var c = this.config[oldIndex];
45578 this.config.splice(oldIndex, 1);
45579 this.config.splice(newIndex, 0, c);
45580 this.dataMap = null;
45581 this.fireEvent("columnmoved", this, oldIndex, newIndex);
45585 getColumnCount : function(visibleOnly){
45586 if(visibleOnly === true){
45588 for(var i = 0, len = this.config.length; i < len; i++){
45589 if(!this.isHidden(i)){
45595 return this.config.length;
45599 getColumnsBy : function(fn, scope){
45601 for(var i = 0, len = this.config.length; i < len; i++){
45602 var c = this.config[i];
45603 if(fn.call(scope||this, c, i) === true){
45611 isSortable : function(col){
45612 return !!this.config[col].sortable;
45616 isMenuDisabled : function(col){
45617 return !!this.config[col].menuDisabled;
45621 getRenderer : function(col){
45622 if(!this.config[col].renderer){
45623 return Ext.grid.ColumnModel.defaultRenderer;
45625 return this.config[col].renderer;
45628 getRendererScope : function(col){
45629 return this.config[col].scope;
45633 setRenderer : function(col, fn){
45634 this.config[col].renderer = fn;
45638 getColumnWidth : function(col){
45639 return this.config[col].width;
45643 setColumnWidth : function(col, width, suppressEvent){
45644 this.config[col].width = width;
45645 this.totalWidth = null;
45646 if(!suppressEvent){
45647 this.fireEvent("widthchange", this, col, width);
45652 getTotalWidth : function(includeHidden){
45653 if(!this.totalWidth){
45654 this.totalWidth = 0;
45655 for(var i = 0, len = this.config.length; i < len; i++){
45656 if(includeHidden || !this.isHidden(i)){
45657 this.totalWidth += this.getColumnWidth(i);
45661 return this.totalWidth;
45665 getColumnHeader : function(col){
45666 return this.config[col].header;
45670 setColumnHeader : function(col, header){
45671 this.config[col].header = header;
45672 this.fireEvent("headerchange", this, col, header);
45676 getColumnTooltip : function(col){
45677 return this.config[col].tooltip;
45680 setColumnTooltip : function(col, tooltip){
45681 this.config[col].tooltip = tooltip;
45685 getDataIndex : function(col){
45686 return this.config[col].dataIndex;
45690 setDataIndex : function(col, dataIndex){
45691 this.config[col].dataIndex = dataIndex;
45695 findColumnIndex : function(dataIndex){
45696 var c = this.config;
45697 for(var i = 0, len = c.length; i < len; i++){
45698 if(c[i].dataIndex == dataIndex){
45706 isCellEditable : function(colIndex, rowIndex){
45707 var c = this.config[colIndex],
45711 return !!(ed || (!Ext.isDefined(ed) && c.editor));
45715 getCellEditor : function(colIndex, rowIndex){
45716 return this.config[colIndex].getCellEditor(rowIndex);
45720 setEditable : function(col, editable){
45721 this.config[col].editable = editable;
45725 isHidden : function(colIndex){
45726 return !!this.config[colIndex].hidden;
45730 isFixed : function(colIndex){
45731 return !!this.config[colIndex].fixed;
45735 isResizable : function(colIndex){
45736 return colIndex >= 0 && this.config[colIndex].resizable !== false && this.config[colIndex].fixed !== true;
45739 setHidden : function(colIndex, hidden){
45740 var c = this.config[colIndex];
45741 if(c.hidden !== hidden){
45743 this.totalWidth = null;
45744 this.fireEvent("hiddenchange", this, colIndex, hidden);
45749 setEditor : function(col, editor){
45750 this.config[col].setEditor(editor);
45754 destroy : function(){
45756 for(var i = 0, len = this.config.length; i < len; i++){
45757 c = this.config[i];
45762 this.purgeListeners();
45767 Ext.grid.ColumnModel.defaultRenderer = function(value){
45768 if(typeof value == "string" && value.length < 1){
45773 Ext.grid.AbstractSelectionModel = Ext.extend(Ext.util.Observable, {
45776 constructor : function(){
45777 this.locked = false;
45778 Ext.grid.AbstractSelectionModel.superclass.constructor.call(this);
45782 init : function(grid){
45784 if(this.lockOnInit){
45785 delete this.lockOnInit;
45786 this.locked = false;
45795 this.locked = true;
45801 beforerefresh: this.sortUnLock,
45802 refresh: this.sortLock
45805 this.lockOnInit = true;
45811 sortLock : function() {
45812 this.locked = true;
45816 sortUnLock : function() {
45817 this.locked = false;
45821 unlock : function(){
45823 this.locked = false;
45830 gv.un('beforerefresh', this.sortUnLock, this);
45831 gv.un('refresh', this.sortLock, this);
45833 delete this.lockOnInit;
45839 isLocked : function(){
45840 return this.locked;
45843 destroy: function(){
45845 this.purgeListeners();
45848 Ext.grid.RowSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel, {
45850 singleSelect : false,
45852 constructor : function(config){
45853 Ext.apply(this, config);
45854 this.selections = new Ext.util.MixedCollection(false, function(o){
45859 this.lastActive = false;
45871 Ext.grid.RowSelectionModel.superclass.constructor.call(this);
45876 initEvents : function(){
45878 if(!this.grid.enableDragDrop && !this.grid.enableDrag){
45879 this.grid.on('rowmousedown', this.handleMouseDown, this);
45882 this.rowNav = new Ext.KeyNav(this.grid.getGridEl(), {
45883 'up' : function(e){
45884 if(!e.shiftKey || this.singleSelect){
45885 this.selectPrevious(false);
45886 }else if(this.last !== false && this.lastActive !== false){
45887 var last = this.last;
45888 this.selectRange(this.last, this.lastActive-1);
45889 this.grid.getView().focusRow(this.lastActive);
45890 if(last !== false){
45894 this.selectFirstRow();
45897 'down' : function(e){
45898 if(!e.shiftKey || this.singleSelect){
45899 this.selectNext(false);
45900 }else if(this.last !== false && this.lastActive !== false){
45901 var last = this.last;
45902 this.selectRange(this.last, this.lastActive+1);
45903 this.grid.getView().focusRow(this.lastActive);
45904 if(last !== false){
45908 this.selectFirstRow();
45914 this.grid.getView().on({
45916 refresh: this.onRefresh,
45917 rowupdated: this.onRowUpdated,
45918 rowremoved: this.onRemove
45923 onRefresh : function(){
45924 var ds = this.grid.store, index;
45925 var s = this.getSelections();
45926 this.clearSelections(true);
45927 for(var i = 0, len = s.length; i < len; i++){
45929 if((index = ds.indexOfId(r.id)) != -1){
45930 this.selectRow(index, true);
45933 if(s.length != this.selections.getCount()){
45934 this.fireEvent('selectionchange', this);
45939 onRemove : function(v, index, r){
45940 if(this.selections.remove(r) !== false){
45941 this.fireEvent('selectionchange', this);
45946 onRowUpdated : function(v, index, r){
45947 if(this.isSelected(r)){
45948 v.onRowSelect(index);
45953 selectRecords : function(records, keepExisting){
45955 this.clearSelections();
45957 var ds = this.grid.store;
45958 for(var i = 0, len = records.length; i < len; i++){
45959 this.selectRow(ds.indexOf(records[i]), true);
45964 getCount : function(){
45965 return this.selections.length;
45969 selectFirstRow : function(){
45974 selectLastRow : function(keepExisting){
45975 this.selectRow(this.grid.store.getCount() - 1, keepExisting);
45979 selectNext : function(keepExisting){
45980 if(this.hasNext()){
45981 this.selectRow(this.last+1, keepExisting);
45982 this.grid.getView().focusRow(this.last);
45989 selectPrevious : function(keepExisting){
45990 if(this.hasPrevious()){
45991 this.selectRow(this.last-1, keepExisting);
45992 this.grid.getView().focusRow(this.last);
45999 hasNext : function(){
46000 return this.last !== false && (this.last+1) < this.grid.store.getCount();
46004 hasPrevious : function(){
46005 return !!this.last;
46010 getSelections : function(){
46011 return [].concat(this.selections.items);
46015 getSelected : function(){
46016 return this.selections.itemAt(0);
46020 each : function(fn, scope){
46021 var s = this.getSelections();
46022 for(var i = 0, len = s.length; i < len; i++){
46023 if(fn.call(scope || this, s[i], i) === false){
46031 clearSelections : function(fast){
46032 if(this.isLocked()){
46036 var ds = this.grid.store;
46037 var s = this.selections;
46038 s.each(function(r){
46039 this.deselectRow(ds.indexOfId(r.id));
46043 this.selections.clear();
46050 selectAll : function(){
46051 if(this.isLocked()){
46054 this.selections.clear();
46055 for(var i = 0, len = this.grid.store.getCount(); i < len; i++){
46056 this.selectRow(i, true);
46061 hasSelection : function(){
46062 return this.selections.length > 0;
46066 isSelected : function(index){
46067 var r = Ext.isNumber(index) ? this.grid.store.getAt(index) : index;
46068 return (r && this.selections.key(r.id) ? true : false);
46072 isIdSelected : function(id){
46073 return (this.selections.key(id) ? true : false);
46077 handleMouseDown : function(g, rowIndex, e){
46078 if(e.button !== 0 || this.isLocked()){
46081 var view = this.grid.getView();
46082 if(e.shiftKey && !this.singleSelect && this.last !== false){
46083 var last = this.last;
46084 this.selectRange(last, rowIndex, e.ctrlKey);
46086 view.focusRow(rowIndex);
46088 var isSelected = this.isSelected(rowIndex);
46089 if(e.ctrlKey && isSelected){
46090 this.deselectRow(rowIndex);
46091 }else if(!isSelected || this.getCount() > 1){
46092 this.selectRow(rowIndex, e.ctrlKey || e.shiftKey);
46093 view.focusRow(rowIndex);
46099 selectRows : function(rows, keepExisting){
46101 this.clearSelections();
46103 for(var i = 0, len = rows.length; i < len; i++){
46104 this.selectRow(rows[i], true);
46109 selectRange : function(startRow, endRow, keepExisting){
46111 if(this.isLocked()){
46115 this.clearSelections();
46117 if(startRow <= endRow){
46118 for(i = startRow; i <= endRow; i++){
46119 this.selectRow(i, true);
46122 for(i = startRow; i >= endRow; i--){
46123 this.selectRow(i, true);
46129 deselectRange : function(startRow, endRow, preventViewNotify){
46130 if(this.isLocked()){
46133 for(var i = startRow; i <= endRow; i++){
46134 this.deselectRow(i, preventViewNotify);
46139 selectRow : function(index, keepExisting, preventViewNotify){
46140 if(this.isLocked() || (index < 0 || index >= this.grid.store.getCount()) || (keepExisting && this.isSelected(index))){
46143 var r = this.grid.store.getAt(index);
46144 if(r && this.fireEvent('beforerowselect', this, index, keepExisting, r) !== false){
46145 if(!keepExisting || this.singleSelect){
46146 this.clearSelections();
46148 this.selections.add(r);
46149 this.last = this.lastActive = index;
46150 if(!preventViewNotify){
46151 this.grid.getView().onRowSelect(index);
46153 this.fireEvent('rowselect', this, index, r);
46154 this.fireEvent('selectionchange', this);
46159 deselectRow : function(index, preventViewNotify){
46160 if(this.isLocked()){
46163 if(this.last == index){
46166 if(this.lastActive == index){
46167 this.lastActive = false;
46169 var r = this.grid.store.getAt(index);
46171 this.selections.remove(r);
46172 if(!preventViewNotify){
46173 this.grid.getView().onRowDeselect(index);
46175 this.fireEvent('rowdeselect', this, index, r);
46176 this.fireEvent('selectionchange', this);
46181 restoreLast : function(){
46183 this.last = this._last;
46188 acceptsNav : function(row, col, cm){
46189 return !cm.isHidden(col) && cm.isCellEditable(col, row);
46193 onEditorKey : function(field, e){
46194 var k = e.getKey(),
46198 ed = g.activeEditor,
46200 var shift = e.shiftKey;
46205 newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
46207 newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
46209 }else if(k == e.ENTER){
46210 if(this.moveEditorOnEnter !== false){
46212 newCell = g.walkCells(last.row - 1, last.col, -1, this.acceptsNav, this);
46214 newCell = g.walkCells(last.row + 1, last.col, 1, this.acceptsNav, this);
46226 if(g.isEditor && g.editing){
46227 ae = g.activeEditor;
46228 if(ae && ae.field.triggerBlur){
46230 ae.field.triggerBlur();
46233 g.startEditing(r, c);
46237 destroy : function(){
46239 this.rowNav.disable();
46240 this.rowNav = null;
46242 Ext.grid.RowSelectionModel.superclass.destroy.call(this);
46245 Ext.grid.Column = Ext.extend(Object, {
46272 constructor : function(config){
46273 Ext.apply(this, config);
46275 if(Ext.isString(this.renderer)){
46276 this.renderer = Ext.util.Format[this.renderer];
46277 }else if(Ext.isObject(this.renderer)){
46278 this.scope = this.renderer.scope;
46279 this.renderer = this.renderer.fn;
46285 var ed = this.editor;
46286 delete this.editor;
46287 this.setEditor(ed);
46291 renderer : function(value){
46292 if(Ext.isString(value) && value.length < 1){
46299 getEditor: function(rowIndex){
46300 return this.editable !== false ? this.editor : null;
46304 setEditor : function(editor){
46305 var ed = this.editor;
46308 ed.gridEditor.destroy();
46309 delete ed.gridEditor;
46314 this.editor = null;
46317 if(!editor.isXType){
46318 editor = Ext.create(editor, 'textfield');
46320 this.editor = editor;
46325 getCellEditor: function(rowIndex){
46326 var ed = this.getEditor(rowIndex);
46329 if(!ed.gridEditor){
46330 ed.gridEditor = new Ext.grid.GridEditor(ed);
46332 ed = ed.gridEditor;
46340 Ext.grid.BooleanColumn = Ext.extend(Ext.grid.Column, {
46344 falseText: 'false',
46346 undefinedText: ' ',
46348 constructor: function(cfg){
46349 Ext.grid.BooleanColumn.superclass.constructor.call(this, cfg);
46350 var t = this.trueText, f = this.falseText, u = this.undefinedText;
46351 this.renderer = function(v){
46352 if(v === undefined){
46355 if(!v || v === 'false'){
46364 Ext.grid.NumberColumn = Ext.extend(Ext.grid.Column, {
46366 format : '0,000.00',
46367 constructor: function(cfg){
46368 Ext.grid.NumberColumn.superclass.constructor.call(this, cfg);
46369 this.renderer = Ext.util.Format.numberRenderer(this.format);
46374 Ext.grid.DateColumn = Ext.extend(Ext.grid.Column, {
46377 constructor: function(cfg){
46378 Ext.grid.DateColumn.superclass.constructor.call(this, cfg);
46379 this.renderer = Ext.util.Format.dateRenderer(this.format);
46384 Ext.grid.TemplateColumn = Ext.extend(Ext.grid.Column, {
46386 constructor: function(cfg){
46387 Ext.grid.TemplateColumn.superclass.constructor.call(this, cfg);
46388 var tpl = (!Ext.isPrimitive(this.tpl) && this.tpl.compile) ? this.tpl : new Ext.XTemplate(this.tpl);
46389 this.renderer = function(value, p, r){
46390 return tpl.apply(r.data);
46397 Ext.grid.Column.types = {
46398 gridcolumn : Ext.grid.Column,
46399 booleancolumn: Ext.grid.BooleanColumn,
46400 numbercolumn: Ext.grid.NumberColumn,
46401 datecolumn: Ext.grid.DateColumn,
46402 templatecolumn: Ext.grid.TemplateColumn
46404 Ext.grid.RowNumberer = Ext.extend(Object, {
46412 constructor : function(config){
46413 Ext.apply(this, config);
46415 this.renderer = this.renderer.createDelegate(this);
46425 rowspan: undefined,
46428 renderer : function(v, p, record, rowIndex){
46430 p.cellAttr = 'rowspan="'+this.rowspan+'"';
46435 Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, {
46439 header : '<div class="x-grid3-hd-checker"> </div>',
46446 menuDisabled : true,
46452 constructor : function(){
46453 Ext.grid.CheckboxSelectionModel.superclass.constructor.apply(this, arguments);
46455 if(this.checkOnly){
46456 this.handleMouseDown = Ext.emptyFn;
46461 initEvents : function(){
46462 Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this);
46463 this.grid.on('render', function(){
46464 var view = this.grid.getView();
46465 view.mainBody.on('mousedown', this.onMouseDown, this);
46466 Ext.fly(view.innerHd).on('mousedown', this.onHdMouseDown, this);
46473 handleMouseDown : function() {
46474 Ext.grid.CheckboxSelectionModel.superclass.handleMouseDown.apply(this, arguments);
46475 this.mouseHandled = true;
46479 onMouseDown : function(e, t){
46480 if(e.button === 0 && t.className == 'x-grid3-row-checker'){
46482 var row = e.getTarget('.x-grid3-row');
46485 if(!this.mouseHandled && row){
46486 var index = row.rowIndex;
46487 if(this.isSelected(index)){
46488 this.deselectRow(index);
46490 this.selectRow(index, true);
46491 this.grid.getView().focusRow(index);
46495 this.mouseHandled = false;
46499 onHdMouseDown : function(e, t){
46500 if(t.className == 'x-grid3-hd-checker'){
46502 var hd = Ext.fly(t.parentNode);
46503 var isChecked = hd.hasClass('x-grid3-hd-checker-on');
46505 hd.removeClass('x-grid3-hd-checker-on');
46506 this.clearSelections();
46508 hd.addClass('x-grid3-hd-checker-on');
46515 renderer : function(v, p, record){
46516 return '<div class="x-grid3-row-checker"> </div>';
46519 Ext.grid.CellSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel, {
46521 constructor : function(config){
46522 Ext.apply(this, config);
46524 this.selection = null;
46528 "beforecellselect",
46535 Ext.grid.CellSelectionModel.superclass.constructor.call(this);
46539 initEvents : function(){
46540 this.grid.on('cellmousedown', this.handleMouseDown, this);
46541 this.grid.on(Ext.EventManager.useKeydown ? 'keydown' : 'keypress', this.handleKeyDown, this);
46542 this.grid.getView().on({
46544 refresh: this.onViewChange,
46545 rowupdated: this.onRowUpdated,
46546 beforerowremoved: this.clearSelections,
46547 beforerowsinserted: this.clearSelections
46549 if(this.grid.isEditor){
46550 this.grid.on('beforeedit', this.beforeEdit, this);
46555 beforeEdit : function(e){
46556 this.select(e.row, e.column, false, true, e.record);
46560 onRowUpdated : function(v, index, r){
46561 if(this.selection && this.selection.record == r){
46562 v.onCellSelect(index, this.selection.cell[1]);
46567 onViewChange : function(){
46568 this.clearSelections(true);
46572 getSelectedCell : function(){
46573 return this.selection ? this.selection.cell : null;
46577 clearSelections : function(preventNotify){
46578 var s = this.selection;
46580 if(preventNotify !== true){
46581 this.grid.view.onCellDeselect(s.cell[0], s.cell[1]);
46583 this.selection = null;
46584 this.fireEvent("selectionchange", this, null);
46589 hasSelection : function(){
46590 return this.selection ? true : false;
46594 handleMouseDown : function(g, row, cell, e){
46595 if(e.button !== 0 || this.isLocked()){
46598 this.select(row, cell);
46602 select : function(rowIndex, colIndex, preventViewNotify, preventFocus, r){
46603 if(this.fireEvent("beforecellselect", this, rowIndex, colIndex) !== false){
46604 this.clearSelections();
46605 r = r || this.grid.store.getAt(rowIndex);
46608 cell : [rowIndex, colIndex]
46610 if(!preventViewNotify){
46611 var v = this.grid.getView();
46612 v.onCellSelect(rowIndex, colIndex);
46613 if(preventFocus !== true){
46614 v.focusCell(rowIndex, colIndex);
46617 this.fireEvent("cellselect", this, rowIndex, colIndex);
46618 this.fireEvent("selectionchange", this, this.selection);
46623 isSelectable : function(rowIndex, colIndex, cm){
46624 return !cm.isHidden(colIndex);
46628 onEditorKey: function(field, e){
46629 if(e.getKey() == e.TAB){
46630 this.handleKeyDown(e);
46635 handleKeyDown : function(e){
46636 if(!e.isNavKeyPress()){
46640 var k = e.getKey(),
46642 s = this.selection,
46644 walk = function(row, col, step){
46645 return g.walkCells(
46649 g.isEditor && g.editing ? sm.acceptsNav : sm.isSelectable,
46653 cell, newCell, r, c, ae;
46668 cell = walk(0, 0, 1);
46670 this.select(cell[0], cell[1]);
46682 newCell = walk(r, c - 1, -1);
46684 newCell = walk(r, c + 1, 1);
46688 newCell = walk(r + 1, c, 1);
46691 newCell = walk(r - 1, c, -1);
46694 newCell = walk(r, c + 1, 1);
46697 newCell = walk(r, c - 1, -1);
46700 if (g.isEditor && !g.editing) {
46701 g.startEditing(r, c);
46714 if(g.isEditor && g.editing){
46715 ae = g.activeEditor;
46716 if(ae && ae.field.triggerBlur){
46718 ae.field.triggerBlur();
46720 g.startEditing(r, c);
46725 acceptsNav : function(row, col, cm){
46726 return !cm.isHidden(col) && cm.isCellEditable(col, row);
46729 Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, {
46734 forceValidation: false,
46742 autoEncode : false,
46746 trackMouseOver: false,
46749 initComponent : function(){
46750 Ext.grid.EditorGridPanel.superclass.initComponent.call(this);
46752 if(!this.selModel){
46754 this.selModel = new Ext.grid.CellSelectionModel();
46757 this.activeEditor = null;
46770 initEvents : function(){
46771 Ext.grid.EditorGridPanel.superclass.initEvents.call(this);
46773 this.getGridEl().on('mousewheel', this.stopEditing.createDelegate(this, [true]), this);
46774 this.on('columnresize', this.stopEditing, this, [true]);
46776 if(this.clicksToEdit == 1){
46777 this.on("cellclick", this.onCellDblClick, this);
46779 var view = this.getView();
46780 if(this.clicksToEdit == 'auto' && view.mainBody){
46781 view.mainBody.on('mousedown', this.onAutoEditClick, this);
46783 this.on('celldblclick', this.onCellDblClick, this);
46787 onResize : function(){
46788 Ext.grid.EditorGridPanel.superclass.onResize.apply(this, arguments);
46789 var ae = this.activeEditor;
46790 if(this.editing && ae){
46796 onCellDblClick : function(g, row, col){
46797 this.startEditing(row, col);
46801 onAutoEditClick : function(e, t){
46802 if(e.button !== 0){
46805 var row = this.view.findRowIndex(t),
46806 col = this.view.findCellIndex(t);
46807 if(row !== false && col !== false){
46808 this.stopEditing();
46809 if(this.selModel.getSelectedCell){
46810 var sc = this.selModel.getSelectedCell();
46811 if(sc && sc[0] === row && sc[1] === col){
46812 this.startEditing(row, col);
46815 if(this.selModel.isSelected(row)){
46816 this.startEditing(row, col);
46823 onEditComplete : function(ed, value, startValue){
46824 this.editing = false;
46825 this.lastActiveEditor = this.activeEditor;
46826 this.activeEditor = null;
46829 field = this.colModel.getDataIndex(ed.col);
46830 value = this.postEditValue(value, startValue, r, field);
46831 if(this.forceValidation === true || String(value) !== String(startValue)){
46836 originalValue: startValue,
46842 if(this.fireEvent("validateedit", e) !== false && !e.cancel && String(value) !== String(startValue)){
46843 r.set(field, e.value);
46845 this.fireEvent("afteredit", e);
46848 this.view.focusCell(ed.row, ed.col);
46852 startEditing : function(row, col){
46853 this.stopEditing();
46854 if(this.colModel.isCellEditable(col, row)){
46855 this.view.ensureVisible(row, col, true);
46856 var r = this.store.getAt(row),
46857 field = this.colModel.getDataIndex(col),
46862 value: r.data[field],
46867 if(this.fireEvent("beforeedit", e) !== false && !e.cancel){
46868 this.editing = true;
46869 var ed = this.colModel.getCellEditor(col, row);
46874 ed.parentEl = this.view.getEditorParent(ed);
46879 c.field.focus(false, true);
46884 specialkey: function(field, e){
46885 this.getSelectionModel().onEditorKey(field, e);
46887 complete: this.onEditComplete,
46888 canceledit: this.stopEditing.createDelegate(this, [true])
46900 this.activeEditor = ed;
46903 ed.selectSameEditor = (this.activeEditor == this.lastActiveEditor);
46904 var v = this.preEditValue(r, field);
46905 ed.startEdit(this.view.getCell(row, col).firstChild, Ext.isDefined(v) ? v : '');
46909 delete ed.selectSameEditor;
46916 preEditValue : function(r, field){
46917 var value = r.data[field];
46918 return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlDecode(value) : value;
46922 postEditValue : function(value, originalValue, r, field){
46923 return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlEncode(value) : value;
46927 stopEditing : function(cancel){
46930 var ae = this.lastActiveEditor = this.activeEditor;
46932 ae[cancel === true ? 'cancelEdit' : 'completeEdit']();
46933 this.view.focusCell(ae.row, ae.col);
46935 this.activeEditor = null;
46937 this.editing = false;
46940 Ext.reg('editorgrid', Ext.grid.EditorGridPanel);
46942 Ext.grid.GridEditor = function(field, config){
46943 Ext.grid.GridEditor.superclass.constructor.call(this, field, config);
46944 field.monitorTab = false;
46947 Ext.extend(Ext.grid.GridEditor, Ext.Editor, {
46948 alignment: "tl-tl",
46951 cls: "x-small-editor x-grid-editor",
46955 Ext.grid.PropertyRecord = Ext.data.Record.create([
46956 {name:'name',type:'string'}, 'value'
46960 Ext.grid.PropertyStore = Ext.extend(Ext.util.Observable, {
46962 constructor : function(grid, source){
46964 this.store = new Ext.data.Store({
46965 recordType : Ext.grid.PropertyRecord
46967 this.store.on('update', this.onUpdate, this);
46969 this.setSource(source);
46971 Ext.grid.PropertyStore.superclass.constructor.call(this);
46975 setSource : function(o){
46977 this.store.removeAll();
46980 if(this.isEditableValue(o[k])){
46981 data.push(new Ext.grid.PropertyRecord({name: k, value: o[k]}, k));
46984 this.store.loadRecords({records: data}, {}, true);
46988 onUpdate : function(ds, record, type){
46989 if(type == Ext.data.Record.EDIT){
46990 var v = record.data.value;
46991 var oldValue = record.modified.value;
46992 if(this.grid.fireEvent('beforepropertychange', this.source, record.id, v, oldValue) !== false){
46993 this.source[record.id] = v;
46995 this.grid.fireEvent('propertychange', this.source, record.id, v, oldValue);
47003 getProperty : function(row){
47004 return this.store.getAt(row);
47008 isEditableValue: function(val){
47009 return Ext.isPrimitive(val) || Ext.isDate(val);
47013 setValue : function(prop, value, create){
47014 var r = this.getRec(prop);
47016 r.set('value', value);
47017 this.source[prop] = value;
47020 this.source[prop] = value;
47021 r = new Ext.grid.PropertyRecord({name: prop, value: value}, prop);
47028 remove : function(prop){
47029 var r = this.getRec(prop);
47031 this.store.remove(r);
47032 delete this.source[prop];
47037 getRec : function(prop){
47038 return this.store.getById(prop);
47042 getSource : function(){
47043 return this.source;
47048 Ext.grid.PropertyColumnModel = Ext.extend(Ext.grid.ColumnModel, {
47051 valueText : 'Value',
47052 dateFormat : 'm/j/Y',
47054 falseText: 'false',
47056 constructor : function(grid, store){
47061 g.PropertyColumnModel.superclass.constructor.call(this, [
47062 {header: this.nameText, width:50, sortable: true, dataIndex:'name', id: 'name', menuDisabled:true},
47063 {header: this.valueText, width:50, resizable:false, dataIndex: 'value', id: 'value', menuDisabled:true}
47065 this.store = store;
47067 var bfield = new f.Field({
47068 autoCreate: {tag: 'select', children: [
47069 {tag: 'option', value: 'true', html: this.trueText},
47070 {tag: 'option', value: 'false', html: this.falseText}
47072 getValue : function(){
47073 return this.el.dom.value == 'true';
47077 'date' : new g.GridEditor(new f.DateField({selectOnFocus:true})),
47078 'string' : new g.GridEditor(new f.TextField({selectOnFocus:true})),
47079 'number' : new g.GridEditor(new f.NumberField({selectOnFocus:true, style:'text-align:left;'})),
47080 'boolean' : new g.GridEditor(bfield, {
47084 this.renderCellDelegate = this.renderCell.createDelegate(this);
47085 this.renderPropDelegate = this.renderProp.createDelegate(this);
47089 renderDate : function(dateVal){
47090 return dateVal.dateFormat(this.dateFormat);
47094 renderBool : function(bVal){
47095 return this[bVal ? 'trueText' : 'falseText'];
47099 isCellEditable : function(colIndex, rowIndex){
47100 return colIndex == 1;
47104 getRenderer : function(col){
47106 this.renderCellDelegate : this.renderPropDelegate;
47110 renderProp : function(v){
47111 return this.getPropertyName(v);
47115 renderCell : function(val, meta, rec){
47116 var renderer = this.grid.customRenderers[rec.get('name')];
47118 return renderer.apply(this, arguments);
47121 if(Ext.isDate(val)){
47122 rv = this.renderDate(val);
47123 }else if(typeof val == 'boolean'){
47124 rv = this.renderBool(val);
47126 return Ext.util.Format.htmlEncode(rv);
47130 getPropertyName : function(name){
47131 var pn = this.grid.propertyNames;
47132 return pn && pn[name] ? pn[name] : name;
47136 getCellEditor : function(colIndex, rowIndex){
47137 var p = this.store.getProperty(rowIndex),
47139 val = p.data.value;
47140 if(this.grid.customEditors[n]){
47141 return this.grid.customEditors[n];
47143 if(Ext.isDate(val)){
47144 return this.editors.date;
47145 }else if(typeof val == 'number'){
47146 return this.editors.number;
47147 }else if(typeof val == 'boolean'){
47148 return this.editors['boolean'];
47150 return this.editors.string;
47155 destroy : function(){
47156 Ext.grid.PropertyColumnModel.superclass.destroy.call(this);
47157 for(var ed in this.editors){
47158 Ext.destroy(this.editors[ed]);
47164 Ext.grid.PropertyGrid = Ext.extend(Ext.grid.EditorGridPanel, {
47172 enableColumnMove:false,
47174 trackMouseOver: false,
47176 enableHdMenu : false,
47182 initComponent : function(){
47183 this.customRenderers = this.customRenderers || {};
47184 this.customEditors = this.customEditors || {};
47185 this.lastEditRow = null;
47186 var store = new Ext.grid.PropertyStore(this);
47187 this.propStore = store;
47188 var cm = new Ext.grid.PropertyColumnModel(this, store);
47189 store.store.sort('name', 'ASC');
47192 'beforepropertychange',
47197 this.ds = store.store;
47198 Ext.grid.PropertyGrid.superclass.initComponent.call(this);
47200 this.mon(this.selModel, 'beforecellselect', function(sm, rowIndex, colIndex){
47201 if(colIndex === 0){
47202 this.startEditing.defer(200, this, [rowIndex, 1]);
47209 onRender : function(){
47210 Ext.grid.PropertyGrid.superclass.onRender.apply(this, arguments);
47212 this.getGridEl().addClass('x-props-grid');
47216 afterRender: function(){
47217 Ext.grid.PropertyGrid.superclass.afterRender.apply(this, arguments);
47219 this.setSource(this.source);
47224 setSource : function(source){
47225 this.propStore.setSource(source);
47229 getSource : function(){
47230 return this.propStore.getSource();
47234 setProperty : function(prop, value, create){
47235 this.propStore.setValue(prop, value, create);
47239 removeProperty : function(prop){
47240 this.propStore.remove(prop);
47248 Ext.reg("propertygrid", Ext.grid.PropertyGrid);
47250 Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
47253 groupByText : 'Group By This Field',
47255 showGroupsText : 'Show in Groups',
47257 hideGroupedColumn : false,
47259 showGroupName : true,
47261 startCollapsed : false,
47263 enableGrouping : true,
47265 enableGroupingMenu : true,
47267 enableNoGroups : true,
47269 emptyGroupText : '(None)',
47273 groupTextTpl : '{text}',
47276 groupMode: 'value',
47281 initTemplates : function(){
47282 Ext.grid.GroupingView.superclass.initTemplates.call(this);
47285 var sm = this.grid.getSelectionModel();
47286 sm.on(sm.selectRow ? 'beforerowselect' : 'beforecellselect',
47287 this.onBeforeRowSelect, this);
47289 if(!this.startGroup){
47290 this.startGroup = new Ext.XTemplate(
47291 '<div id="{groupId}" class="x-grid-group {cls}">',
47292 '<div id="{groupId}-hd" class="x-grid-group-hd" style="{style}"><div class="x-grid-group-title">', this.groupTextTpl ,'</div></div>',
47293 '<div id="{groupId}-bd" class="x-grid-group-body">'
47296 this.startGroup.compile();
47298 if (!this.endGroup) {
47299 this.endGroup = '</div></div>';
47304 findGroup : function(el){
47305 return Ext.fly(el).up('.x-grid-group', this.mainBody.dom);
47309 getGroups : function(){
47310 return this.hasRows() ? this.mainBody.dom.childNodes : [];
47314 onAdd : function(ds, records, index) {
47315 if (this.canGroup() && !this.ignoreAdd) {
47316 var ss = this.getScrollState();
47317 this.fireEvent('beforerowsinserted', ds, index, index + (records.length-1));
47319 this.restoreScroll(ss);
47320 this.fireEvent('rowsinserted', ds, index, index + (records.length-1));
47321 } else if (!this.canGroup()) {
47322 Ext.grid.GroupingView.superclass.onAdd.apply(this, arguments);
47327 onRemove : function(ds, record, index, isUpdate){
47328 Ext.grid.GroupingView.superclass.onRemove.apply(this, arguments);
47329 var g = document.getElementById(record._groupId);
47330 if(g && g.childNodes[1].childNodes.length < 1){
47333 this.applyEmptyText();
47337 refreshRow : function(record){
47338 if(this.ds.getCount()==1){
47341 this.isUpdating = true;
47342 Ext.grid.GroupingView.superclass.refreshRow.apply(this, arguments);
47343 this.isUpdating = false;
47348 beforeMenuShow : function(){
47349 var item, items = this.hmenu.items, disabled = this.cm.config[this.hdCtxIndex].groupable === false;
47350 if((item = items.get('groupBy'))){
47351 item.setDisabled(disabled);
47353 if((item = items.get('showGroups'))){
47354 item.setDisabled(disabled);
47355 item.setChecked(this.enableGrouping, true);
47360 renderUI : function(){
47361 Ext.grid.GroupingView.superclass.renderUI.call(this);
47362 this.mainBody.on('mousedown', this.interceptMouse, this);
47364 if(this.enableGroupingMenu && this.hmenu){
47365 this.hmenu.add('-',{
47367 text: this.groupByText,
47368 handler: this.onGroupByClick,
47370 iconCls:'x-group-by-icon'
47372 if(this.enableNoGroups){
47374 itemId:'showGroups',
47375 text: this.showGroupsText,
47377 checkHandler: this.onShowGroupsClick,
47381 this.hmenu.on('beforeshow', this.beforeMenuShow, this);
47385 processEvent: function(name, e){
47386 Ext.grid.GroupingView.superclass.processEvent.call(this, name, e);
47387 var hd = e.getTarget('.x-grid-group-hd', this.mainBody);
47390 var field = this.getGroupField(),
47391 prefix = this.getPrefix(field),
47392 groupValue = hd.id.substring(prefix.length);
47395 groupValue = groupValue.substr(0, groupValue.length - 3);
47397 this.grid.fireEvent('group' + name, this.grid, field, groupValue, e);
47404 onGroupByClick : function(){
47405 this.enableGrouping = true;
47406 this.grid.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex));
47407 this.grid.fireEvent('groupchange', this, this.grid.store.getGroupState());
47408 this.beforeMenuShow();
47413 onShowGroupsClick : function(mi, checked){
47414 this.enableGrouping = checked;
47416 this.onGroupByClick();
47418 this.grid.store.clearGrouping();
47419 this.grid.fireEvent('groupchange', this, null);
47424 toggleRowIndex : function(rowIndex, expanded){
47425 if(!this.canGroup()){
47428 var row = this.getRow(rowIndex);
47430 this.toggleGroup(this.findGroup(row), expanded);
47435 toggleGroup : function(group, expanded){
47436 var gel = Ext.get(group);
47437 expanded = Ext.isDefined(expanded) ? expanded : gel.hasClass('x-grid-group-collapsed');
47438 if(this.state[gel.id] !== expanded){
47439 this.grid.stopEditing(true);
47440 this.state[gel.id] = expanded;
47441 gel[expanded ? 'removeClass' : 'addClass']('x-grid-group-collapsed');
47446 toggleAllGroups : function(expanded){
47447 var groups = this.getGroups();
47448 for(var i = 0, len = groups.length; i < len; i++){
47449 this.toggleGroup(groups[i], expanded);
47454 expandAllGroups : function(){
47455 this.toggleAllGroups(true);
47459 collapseAllGroups : function(){
47460 this.toggleAllGroups(false);
47464 interceptMouse : function(e){
47465 var hd = e.getTarget('.x-grid-group-hd', this.mainBody);
47468 this.toggleGroup(hd.parentNode);
47473 getGroup : function(v, r, groupRenderer, rowIndex, colIndex, ds){
47474 var g = groupRenderer ? groupRenderer(v, {}, r, rowIndex, colIndex, ds) : String(v);
47475 if(g === '' || g === ' '){
47476 g = this.cm.config[colIndex].emptyGroupText || this.emptyGroupText;
47482 getGroupField : function(){
47483 return this.grid.store.getGroupState();
47487 afterRender : function(){
47488 if(!this.ds || !this.cm){
47491 Ext.grid.GroupingView.superclass.afterRender.call(this);
47492 if(this.grid.deferRowRender){
47493 this.updateGroupWidths();
47498 renderRows : function(){
47499 var groupField = this.getGroupField();
47500 var eg = !!groupField;
47502 if(this.hideGroupedColumn) {
47503 var colIndex = this.cm.findColumnIndex(groupField),
47504 hasLastGroupField = Ext.isDefined(this.lastGroupField);
47505 if(!eg && hasLastGroupField){
47506 this.mainBody.update('');
47507 this.cm.setHidden(this.cm.findColumnIndex(this.lastGroupField), false);
47508 delete this.lastGroupField;
47509 }else if (eg && !hasLastGroupField){
47510 this.lastGroupField = groupField;
47511 this.cm.setHidden(colIndex, true);
47512 }else if (eg && hasLastGroupField && groupField !== this.lastGroupField) {
47513 this.mainBody.update('');
47514 var oldIndex = this.cm.findColumnIndex(this.lastGroupField);
47515 this.cm.setHidden(oldIndex, false);
47516 this.lastGroupField = groupField;
47517 this.cm.setHidden(colIndex, true);
47520 return Ext.grid.GroupingView.superclass.renderRows.apply(
47525 doRender : function(cs, rs, ds, startRow, colCount, stripe){
47530 if(!this.canGroup() || this.isUpdating){
47531 return Ext.grid.GroupingView.superclass.doRender.apply(this, arguments);
47534 var groupField = this.getGroupField(),
47535 colIndex = this.cm.findColumnIndex(groupField),
47537 gstyle = 'width:' + this.getTotalWidth() + ';',
47538 cfg = this.cm.config[colIndex],
47539 groupRenderer = cfg.groupRenderer || cfg.renderer,
47540 prefix = this.showGroupName ? (cfg.groupName || cfg.header)+': ' : '',
47542 curGroup, i, len, gid;
47544 for(i = 0, len = rs.length; i < len; i++){
47545 var rowIndex = startRow + i,
47547 gvalue = r.data[groupField];
47549 g = this.getGroup(gvalue, r, groupRenderer, rowIndex, colIndex, ds);
47550 if(!curGroup || curGroup.group != g){
47551 gid = this.constructId(gvalue, groupField, colIndex);
47554 this.state[gid] = !(Ext.isDefined(this.state[gid]) ? !this.state[gid] : this.startCollapsed);
47560 startRow: rowIndex,
47562 cls: this.state[gid] ? '' : 'x-grid-group-collapsed',
47565 groups.push(curGroup);
47567 curGroup.rs.push(r);
47573 for(i = 0, len = groups.length; i < len; i++){
47575 this.doGroupStart(buf, g, cs, ds, colCount);
47576 buf[buf.length] = Ext.grid.GroupingView.superclass.doRender.call(
47577 this, cs, g.rs, ds, g.startRow, colCount, stripe);
47579 this.doGroupEnd(buf, g, cs, ds, colCount);
47581 return buf.join('');
47585 getGroupId : function(value){
47586 var field = this.getGroupField();
47587 return this.constructId(value, field, this.cm.findColumnIndex(field));
47591 constructId : function(value, field, idx){
47592 var cfg = this.cm.config[idx],
47593 groupRenderer = cfg.groupRenderer || cfg.renderer,
47594 val = (this.groupMode == 'value') ? value : this.getGroup(value, {data:{}}, groupRenderer, 0, idx, this.ds);
47596 return this.getPrefix(field) + Ext.util.Format.htmlEncode(val);
47600 canGroup : function(){
47601 return this.enableGrouping && !!this.getGroupField();
47605 getPrefix: function(field){
47606 return this.grid.getGridEl().id + '-gp-' + field + '-';
47610 doGroupStart : function(buf, g, cs, ds, colCount){
47611 buf[buf.length] = this.startGroup.apply(g);
47615 doGroupEnd : function(buf, g, cs, ds, colCount){
47616 buf[buf.length] = this.endGroup;
47620 getRows : function(){
47621 if(!this.canGroup()){
47622 return Ext.grid.GroupingView.superclass.getRows.call(this);
47625 gs = this.getGroups(),
47631 for(; i < len; ++i){
47632 g = gs[i].childNodes[1];
47635 for(j = 0, jlen = g.length; j < jlen; ++j){
47636 r[r.length] = g[j];
47644 updateGroupWidths : function(){
47645 if(!this.canGroup() || !this.hasRows()){
47648 var tw = Math.max(this.cm.getTotalWidth(), this.el.dom.offsetWidth-this.getScrollOffset()) +'px';
47649 var gs = this.getGroups();
47650 for(var i = 0, len = gs.length; i < len; i++){
47651 gs[i].firstChild.style.width = tw;
47656 onColumnWidthUpdated : function(col, w, tw){
47657 Ext.grid.GroupingView.superclass.onColumnWidthUpdated.call(this, col, w, tw);
47658 this.updateGroupWidths();
47662 onAllColumnWidthsUpdated : function(ws, tw){
47663 Ext.grid.GroupingView.superclass.onAllColumnWidthsUpdated.call(this, ws, tw);
47664 this.updateGroupWidths();
47668 onColumnHiddenUpdated : function(col, hidden, tw){
47669 Ext.grid.GroupingView.superclass.onColumnHiddenUpdated.call(this, col, hidden, tw);
47670 this.updateGroupWidths();
47674 onLayout : function(){
47675 this.updateGroupWidths();
47679 onBeforeRowSelect : function(sm, rowIndex){
47680 this.toggleRowIndex(rowIndex, true);
47684 Ext.grid.GroupingView.GROUP_ID = 1000;