4 var EXTUTIL = Ext.util,
9 EXTUTIL.Observable = function(){
11 var me = this, e = me.events;
19 EXTUTIL.Observable.prototype = {
21 filterOptRe : /^(?:scope|delay|buffer|single)$/,
24 fireEvent : function(){
25 var a = Array.prototype.slice.call(arguments, 0),
26 ename = a[0].toLowerCase(),
29 ce = me.events[ename],
33 if (me.eventsSuspended === TRUE) {
34 if (q = me.eventQueue) {
38 else if(typeof ce == 'object') {
40 if(ce.fire.apply(ce, a.slice(1)) === FALSE) {
43 c = me.getBubbleTarget && me.getBubbleTarget();
44 if(c && c.enableBubble) {
46 if(!cc || typeof cc != 'object' || !cc.bubble) {
47 c.enableBubble(ename);
49 return c.fireEvent.apply(c, a);
54 ret = ce.fire.apply(ce, a);
61 addListener : function(eventName, fn, scope, o){
67 if (typeof eventName == 'object') {
71 if (!me.filterOptRe.test(e)) {
72 me.addListener(e, oe.fn || oe, oe.scope || o.scope, oe.fn ? oe : o);
76 eventName = eventName.toLowerCase();
77 ce = me.events[eventName] || TRUE;
78 if (typeof ce == 'boolean') {
79 me.events[eventName] = ce = new EXTUTIL.Event(me, eventName);
81 ce.addListener(fn, scope, typeof o == 'object' ? o : {});
86 removeListener : function(eventName, fn, scope){
87 var ce = this.events[eventName.toLowerCase()];
88 if (typeof ce == 'object') {
89 ce.removeListener(fn, scope);
94 purgeListeners : function(){
95 var events = this.events,
100 if(typeof evt == 'object'){
101 evt.clearListeners();
107 addEvents : function(o){
109 me.events = me.events || {};
110 if (typeof o == 'string') {
114 me.events[a[i]] = me.events[a[i]] || TRUE;
117 Ext.applyIf(me.events, o);
122 hasListener : function(eventName){
123 var e = this.events[eventName.toLowerCase()];
124 return typeof e == 'object' && e.listeners.length > 0;
128 suspendEvents : function(queueSuspended){
129 this.eventsSuspended = TRUE;
130 if(queueSuspended && !this.eventQueue){
131 this.eventQueue = [];
136 resumeEvents : function(){
138 queued = me.eventQueue || [];
139 me.eventsSuspended = FALSE;
140 delete me.eventQueue;
141 EACH(queued, function(e) {
142 me.fireEvent.apply(me, e);
147 var OBSERVABLE = EXTUTIL.Observable.prototype;
149 OBSERVABLE.on = OBSERVABLE.addListener;
151 OBSERVABLE.un = OBSERVABLE.removeListener;
154 EXTUTIL.Observable.releaseCapture = function(o){
155 o.fireEvent = OBSERVABLE.fireEvent;
158 function createTargeted(h, o, scope){
160 if(o.target == arguments[0]){
161 h.apply(scope, Array.prototype.slice.call(arguments, 0));
166 function createBuffered(h, o, l, scope){
167 l.task = new EXTUTIL.DelayedTask();
169 l.task.delay(o.buffer, h, scope, Array.prototype.slice.call(arguments, 0));
173 function createSingle(h, e, fn, scope){
175 e.removeListener(fn, scope);
176 return h.apply(scope, arguments);
180 function createDelayed(h, o, l, scope){
182 var task = new EXTUTIL.DelayedTask(),
183 args = Array.prototype.slice.call(arguments, 0);
188 task.delay(o.delay || 10, function(){
189 l.tasks.remove(task);
190 h.apply(scope, args);
195 EXTUTIL.Event = function(obj, name){
201 EXTUTIL.Event.prototype = {
202 addListener : function(fn, scope, options){
205 scope = scope || me.obj;
206 if(!me.isListening(fn, scope)){
207 l = me.createListener(fn, scope, options);
209 me.listeners = me.listeners.slice(0);
211 me.listeners.push(l);
215 createListener: function(fn, scope, o){
217 scope = scope || this.obj;
224 h = createTargeted(h, o, scope);
227 h = createDelayed(h, o, l, scope);
230 h = createSingle(h, this, fn, scope);
233 h = createBuffered(h, o, l, scope);
239 findListener : function(fn, scope){
240 var list = this.listeners,
244 scope = scope || this.obj;
248 if(l.fn == fn && l.scope == scope){
256 isListening : function(fn, scope){
257 return this.findListener(fn, scope) != -1;
260 removeListener : function(fn, scope){
266 if((index = me.findListener(fn, scope)) != -1){
268 me.listeners = me.listeners.slice(0);
270 l = me.listeners[index];
275 k = l.tasks && l.tasks.length;
282 me.listeners.splice(index, 1);
289 clearListeners : function(){
294 me.removeListener(l[i].fn, l[i].scope);
300 listeners = me.listeners,
301 len = listeners.length,
307 var args = Array.prototype.slice.call(arguments, 0);
308 for (; i < len; i++) {
310 if(l && l.fireFn.apply(l.scope || me.obj || window, args) === FALSE) {
311 return (me.firing = FALSE);
322 Ext.DomHelper = function(){
323 var tempTableEl = null,
324 emptyTags = /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i,
325 tableRe = /^table|tbody|tr|td$/i,
326 confRe = /tag|children|cn|html$/i,
327 tableElRe = /td|tr|tbody/i,
328 cssRe = /([a-z0-9-]+)\s*:\s*([^;\s]+(?:\s*[^;\s]+)*);?/gi,
332 afterbegin = 'afterbegin',
333 afterend = 'afterend',
334 beforebegin = 'beforebegin',
335 beforeend = 'beforeend',
344 function doInsert(el, o, returnElement, pos, sibling, append){
345 var newNode = pub.insertHtml(pos, Ext.getDom(el), createHtml(o));
346 return returnElement ? Ext.get(newNode, true) : newNode;
350 function createHtml(o){
357 if(typeof o == "string"){
359 } else if (Ext.isArray(o)) {
360 for (var i=0; i < o.length; i++) {
362 b += createHtml(o[i]);
366 b += '<' + (o.tag = o.tag || 'div');
369 if(!confRe.test(attr)){
370 if (typeof val == "object") {
371 b += ' ' + attr + '="';
373 b += key + ':' + val[key] + ';';
377 b += ' ' + ({cls : 'class', htmlFor : 'for'}[attr] || attr) + '="' + val + '"';
382 if (emptyTags.test(o.tag)) {
386 if ((cn = o.children || o.cn)) {
391 b += '</' + o.tag + '>';
397 function ieTable(depth, s, h, e){
398 tempTableEl.innerHTML = [s, h, e].join('');
406 if(ns = el.nextSibling){
407 var df = document.createDocumentFragment();
419 function insertIntoTable(tag, where, el, html) {
423 tempTableEl = tempTableEl || document.createElement('div');
425 if(tag == 'td' && (where == afterbegin || where == beforeend) ||
426 !tableElRe.test(tag) && (where == beforebegin || where == afterend)) {
429 before = where == beforebegin ? el :
430 where == afterend ? el.nextSibling :
431 where == afterbegin ? el.firstChild : null;
433 if (where == beforebegin || where == afterend) {
437 if (tag == 'td' || (tag == 'tr' && (where == beforeend || where == afterbegin))) {
438 node = ieTable(4, trs, html, tre);
439 } else if ((tag == 'tbody' && (where == beforeend || where == afterbegin)) ||
440 (tag == 'tr' && (where == beforebegin || where == afterend))) {
441 node = ieTable(3, tbs, html, tbe);
443 node = ieTable(2, ts, html, te);
445 el.insertBefore(node, before);
452 markup : function(o){
453 return createHtml(o);
457 applyStyles : function(el, styles){
462 if (typeof styles == "function") {
463 styles = styles.call();
465 if (typeof styles == "string") {
468 while ((matches = cssRe.exec(styles))) {
469 el.setStyle(matches[1], matches[2]);
471 } else if (typeof styles == "object") {
478 insertHtml : function(where, el, html){
487 where = where.toLowerCase();
489 hash[beforebegin] = ['BeforeBegin', 'previousSibling'];
490 hash[afterend] = ['AfterEnd', 'nextSibling'];
492 if (el.insertAdjacentHTML) {
493 if(tableRe.test(el.tagName) && (rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html))){
497 hash[afterbegin] = ['AfterBegin', 'firstChild'];
498 hash[beforeend] = ['BeforeEnd', 'lastChild'];
499 if ((hashVal = hash[where])) {
500 el.insertAdjacentHTML(hashVal[0], html);
501 return el[hashVal[1]];
504 range = el.ownerDocument.createRange();
505 setStart = 'setStart' + (endRe.test(where) ? 'After' : 'Before');
508 frag = range.createContextualFragment(html);
509 el.parentNode.insertBefore(frag, where == beforebegin ? el : el.nextSibling);
510 return el[(where == beforebegin ? 'previous' : 'next') + 'Sibling'];
512 rangeEl = (where == afterbegin ? 'first' : 'last') + 'Child';
514 range[setStart](el[rangeEl]);
515 frag = range.createContextualFragment(html);
516 if(where == afterbegin){
517 el.insertBefore(frag, el.firstChild);
519 el.appendChild(frag);
527 throw 'Illegal insertion point -> "' + where + '"';
531 insertBefore : function(el, o, returnElement){
532 return doInsert(el, o, returnElement, beforebegin);
536 insertAfter : function(el, o, returnElement){
537 return doInsert(el, o, returnElement, afterend, 'nextSibling');
541 insertFirst : function(el, o, returnElement){
542 return doInsert(el, o, returnElement, afterbegin, 'firstChild');
546 append : function(el, o, returnElement){
547 return doInsert(el, o, returnElement, beforeend, '', true);
551 overwrite : function(el, o, returnElement){
553 el.innerHTML = createHtml(o);
554 return returnElement ? Ext.get(el.firstChild) : el.firstChild;
557 createHtml : createHtml
562 Ext.Template = function(html){
568 if (Ext.isArray(html)) {
569 html = html.join("");
570 } else if (a.length > 1) {
571 for(var i = 0, len = a.length; i < len; i++){
573 if(typeof v == 'object'){
589 Ext.Template.prototype = {
591 re : /\{([\w-]+)\}/g,
595 applyTemplate : function(values){
599 me.compiled(values) :
600 me.html.replace(me.re, function(m, name){
601 return values[name] !== undefined ? values[name] : "";
606 set : function(html, compile){
610 return compile ? me.compile() : me;
614 compile : function(){
616 sep = Ext.isGecko ? "+" : ",";
618 function fn(m, name){
619 name = "values['" + name + "']";
620 return "'"+ sep + '(' + name + " == undefined ? '' : " + name + ')' + sep + "'";
623 eval("this.compiled = function(values){ return " + (Ext.isGecko ? "'" : "['") +
624 me.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) +
625 (Ext.isGecko ? "';};" : "'].join('');};"));
630 insertFirst: function(el, values, returnElement){
631 return this.doInsert('afterBegin', el, values, returnElement);
635 insertBefore: function(el, values, returnElement){
636 return this.doInsert('beforeBegin', el, values, returnElement);
640 insertAfter : function(el, values, returnElement){
641 return this.doInsert('afterEnd', el, values, returnElement);
645 append : function(el, values, returnElement){
646 return this.doInsert('beforeEnd', el, values, returnElement);
649 doInsert : function(where, el, values, returnEl){
651 var newNode = Ext.DomHelper.insertHtml(where, el, this.applyTemplate(values));
652 return returnEl ? Ext.get(newNode, true) : newNode;
656 overwrite : function(el, values, returnElement){
658 el.innerHTML = this.applyTemplate(values);
659 return returnElement ? Ext.get(el.firstChild, true) : el.firstChild;
663 Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;
666 Ext.Template.from = function(el, config){
668 return new Ext.Template(el.value || el.innerHTML, config || '');
672 Ext.DomQuery = function(){
677 trimRe = /^\s+|\s+$/g,
678 tplRe = /\{(\d+)\}/g,
679 modeRe = /^(\s?[\/>+~]\s?|\s|$)/,
680 tagTokenRe = /^(#)?([\w-\*]+)/,
681 nthRe = /(\d*)n\+?(\d*)/,
686 isIE = window.ActiveXObject ? true : false,
691 eval("var batch = 30803;");
695 function child(parent, index){
697 n = parent.firstChild;
711 while((n = n.nextSibling) && n.nodeType != 1);
717 while((n = n.previousSibling) && n.nodeType != 1);
723 function children(parent){
724 var n = parent.firstChild,
728 nextNode = n.nextSibling;
730 if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){
731 parent.removeChild(n);
734 n.nodeIndex = ++nodeIndex;
744 function byClassName(nodeSet, cls){
748 var result = [], ri = -1;
749 for(var i = 0, ci; ci = nodeSet[i]; i++){
750 if((' '+ci.className+' ').indexOf(cls) != -1){
757 function attrValue(n, attr){
759 if(!n.tagName && typeof n.length != "undefined"){
769 if(attr == "class" || attr == "className"){
772 return n.getAttribute(attr) || n[attr];
780 function getNodes(ns, mode, tagName){
781 var result = [], ri = -1, cs;
785 tagName = tagName || "*";
787 if(typeof ns.getElementsByTagName != "undefined"){
794 for(var i = 0, ni; ni = ns[i]; i++){
795 cs = ni.getElementsByTagName(tagName);
796 for(var j = 0, ci; ci = cs[j]; j++){
802 } else if(mode == "/" || mode == ">"){
803 var utag = tagName.toUpperCase();
804 for(var i = 0, ni, cn; ni = ns[i]; i++){
806 for(var j = 0, cj; cj = cn[j]; j++){
807 if(cj.nodeName == utag || cj.nodeName == tagName || tagName == '*'){
814 }else if(mode == "+"){
815 var utag = tagName.toUpperCase();
816 for(var i = 0, n; n = ns[i]; i++){
817 while((n = n.nextSibling) && n.nodeType != 1);
818 if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){
824 }else if(mode == "~"){
825 var utag = tagName.toUpperCase();
826 for(var i = 0, n; n = ns[i]; i++){
827 while((n = n.nextSibling)){
828 if (n.nodeName == utag || n.nodeName == tagName || tagName == '*'){
837 function concat(a, b){
841 for(var i = 0, l = b.length; i < l; i++){
847 function byTag(cs, tagName){
848 if(cs.tagName || cs == document){
854 var result = [], ri = -1;
855 tagName = tagName.toLowerCase();
856 for(var i = 0, ci; ci = cs[i]; i++){
857 if(ci.nodeType == 1 && ci.tagName.toLowerCase() == tagName){
864 function byId(cs, id){
865 if(cs.tagName || cs == document){
871 var result = [], ri = -1;
872 for(var i = 0, ci; ci = cs[i]; i++){
873 if(ci && ci.id == id){
883 function byAttribute(cs, attr, value, op, custom){
886 useGetStyle = custom == "{",
887 fn = Ext.DomQuery.operators[op],
892 for(var i = 0, ci; ci = cs[i]; i++){
894 if(ci.nodeType != 1){
899 xml = Ext.DomQuery.isXml(ci);
906 a = Ext.DomQuery.getStyle(ci, attr);
907 } else if (attr == "class" || attr == "className"){
909 } else if (attr == "for"){
911 } else if (attr == "href"){
914 a = ci.getAttribute("href", 2);
916 a = ci.getAttribute(attr);
919 a = ci.getAttribute(attr);
921 if((fn && fn(a, value)) || (!fn && a)){
928 function byPseudo(cs, name, value){
929 return Ext.DomQuery.pseudos[name](cs, value);
932 function nodupIEXml(cs){
935 cs[0].setAttribute("_nodup", d);
937 for(var i = 1, len = cs.length; i < len; i++){
939 if(!c.getAttribute("_nodup") != d){
940 c.setAttribute("_nodup", d);
944 for(var i = 0, len = cs.length; i < len; i++){
945 cs[i].removeAttribute("_nodup");
954 var len = cs.length, c, i, r = cs, cj, ri = -1;
955 if(!len || typeof cs.nodeType != "undefined" || len == 1){
958 if(isIE && typeof cs[0].selectSingleNode != "undefined"){
959 return nodupIEXml(cs);
963 for(i = 1; c = cs[i]; i++){
968 for(var j = 0; j < i; j++){
971 for(j = i+1; cj = cs[j]; j++){
983 function quickDiffIEXml(c1, c2){
986 for(var i = 0, len = c1.length; i < len; i++){
987 c1[i].setAttribute("_qdiff", d);
989 for(var i = 0, len = c2.length; i < len; i++){
990 if(c2[i].getAttribute("_qdiff") != d){
994 for(var i = 0, len = c1.length; i < len; i++){
995 c1[i].removeAttribute("_qdiff");
1000 function quickDiff(c1, c2){
1001 var len1 = c1.length,
1007 if(isIE && typeof c1[0].selectSingleNode != "undefined"){
1008 return quickDiffIEXml(c1, c2);
1010 for(var i = 0; i < len1; i++){
1013 for(var i = 0, len = c2.length; i < len; i++){
1014 if(c2[i]._qdiff != d){
1015 r[r.length] = c2[i];
1021 function quickId(ns, mode, root, id){
1023 var d = root.ownerDocument || root;
1024 return d.getElementById(id);
1026 ns = getNodes(ns, mode, "*");
1027 return byId(ns, id);
1031 getStyle : function(el, name){
1032 return Ext.fly(el).getStyle(name);
1035 compile : function(path, type){
1036 type = type || "select";
1039 var fn = ["var f = function(root){\n var mode; ++batch; var n = root || document;\n"],
1042 matchers = Ext.DomQuery.matchers,
1043 matchersLn = matchers.length,
1046 lmode = path.match(modeRe);
1048 if(lmode && lmode[1]){
1049 fn[fn.length] = 'mode="'+lmode[1].replace(trimRe, "")+'";';
1050 path = path.replace(lmode[1], "");
1054 while(path.substr(0, 1)=="/"){
1055 path = path.substr(1);
1058 while(path && lastPath != path){
1060 var tokenMatch = path.match(tagTokenRe);
1061 if(type == "select"){
1064 if(tokenMatch[1] == "#"){
1065 fn[fn.length] = 'n = quickId(n, mode, root, "'+tokenMatch[2]+'");';
1067 fn[fn.length] = 'n = getNodes(n, mode, "'+tokenMatch[2]+'");';
1069 path = path.replace(tokenMatch[0], "");
1070 }else if(path.substr(0, 1) != '@'){
1071 fn[fn.length] = 'n = getNodes(n, mode, "*");';
1076 if(tokenMatch[1] == "#"){
1077 fn[fn.length] = 'n = byId(n, "'+tokenMatch[2]+'");';
1079 fn[fn.length] = 'n = byTag(n, "'+tokenMatch[2]+'");';
1081 path = path.replace(tokenMatch[0], "");
1084 while(!(modeMatch = path.match(modeRe))){
1085 var matched = false;
1086 for(var j = 0; j < matchersLn; j++){
1087 var t = matchers[j];
1088 var m = path.match(t.re);
1090 fn[fn.length] = t.select.replace(tplRe, function(x, i){
1093 path = path.replace(m[0], "");
1100 throw 'Error parsing selector, parsing failed at "' + path + '"';
1104 fn[fn.length] = 'mode="'+modeMatch[1].replace(trimRe, "")+'";';
1105 path = path.replace(modeMatch[1], "");
1109 fn[fn.length] = "return nodup(n);\n}";
1117 jsSelect: function(path, root, type){
1119 root = root || document;
1121 if(typeof root == "string"){
1122 root = document.getElementById(root);
1124 var paths = path.split(","),
1128 for(var i = 0, len = paths.length; i < len; i++){
1129 var subPath = paths[i].replace(trimRe, "");
1131 if(!cache[subPath]){
1132 cache[subPath] = Ext.DomQuery.compile(subPath);
1133 if(!cache[subPath]){
1134 throw subPath + " is not a valid selector";
1137 var result = cache[subPath](root);
1138 if(result && result != document){
1139 results = results.concat(result);
1145 if(paths.length > 1){
1146 return nodup(results);
1150 isXml: function(el) {
1151 var docEl = (el ? el.ownerDocument || el : 0).documentElement;
1152 return docEl ? docEl.nodeName !== "HTML" : false;
1154 select : document.querySelectorAll ? function(path, root, type) {
1155 root = root || document;
1156 if (!Ext.DomQuery.isXml(root)) {
1158 var cs = root.querySelectorAll(path);
1159 return Ext.toArray(cs);
1163 return Ext.DomQuery.jsSelect.call(this, path, root, type);
1164 } : function(path, root, type) {
1165 return Ext.DomQuery.jsSelect.call(this, path, root, type);
1169 selectNode : function(path, root){
1170 return Ext.DomQuery.select(path, root)[0];
1174 selectValue : function(path, root, defaultValue){
1175 path = path.replace(trimRe, "");
1176 if(!valueCache[path]){
1177 valueCache[path] = Ext.DomQuery.compile(path, "select");
1179 var n = valueCache[path](root), v;
1180 n = n[0] ? n[0] : n;
1186 if (typeof n.normalize == 'function') n.normalize();
1188 v = (n && n.firstChild ? n.firstChild.nodeValue : null);
1189 return ((v === null||v === undefined||v==='') ? defaultValue : v);
1193 selectNumber : function(path, root, defaultValue){
1194 var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0);
1195 return parseFloat(v);
1199 is : function(el, ss){
1200 if(typeof el == "string"){
1201 el = document.getElementById(el);
1203 var isArray = Ext.isArray(el),
1204 result = Ext.DomQuery.filter(isArray ? el : [el], ss);
1205 return isArray ? (result.length == el.length) : (result.length > 0);
1209 filter : function(els, ss, nonMatches){
1210 ss = ss.replace(trimRe, "");
1211 if(!simpleCache[ss]){
1212 simpleCache[ss] = Ext.DomQuery.compile(ss, "simple");
1214 var result = simpleCache[ss](els);
1215 return nonMatches ? quickDiff(result, els) : result;
1221 select: 'n = byClassName(n, " {1} ");'
1223 re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,
1224 select: 'n = byPseudo(n, "{1}", "{2}");'
1226 re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,
1227 select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'
1230 select: 'n = byId(n, "{1}");'
1233 select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
1239 "=" : function(a, v){
1242 "!=" : function(a, v){
1245 "^=" : function(a, v){
1246 return a && a.substr(0, v.length) == v;
1248 "$=" : function(a, v){
1249 return a && a.substr(a.length-v.length) == v;
1251 "*=" : function(a, v){
1252 return a && a.indexOf(v) !== -1;
1254 "%=" : function(a, v){
1255 return (a % v) == 0;
1257 "|=" : function(a, v){
1258 return a && (a == v || a.substr(0, v.length+1) == v+'-');
1260 "~=" : function(a, v){
1261 return a && (' '+a+' ').indexOf(' '+v+' ') != -1;
1267 "first-child" : function(c){
1268 var r = [], ri = -1, n;
1269 for(var i = 0, ci; ci = n = c[i]; i++){
1270 while((n = n.previousSibling) && n.nodeType != 1);
1278 "last-child" : function(c){
1279 var r = [], ri = -1, n;
1280 for(var i = 0, ci; ci = n = c[i]; i++){
1281 while((n = n.nextSibling) && n.nodeType != 1);
1289 "nth-child" : function(c, a) {
1290 var r = [], ri = -1,
1291 m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a),
1292 f = (m[1] || 1) - 0, l = m[2] - 0;
1293 for(var i = 0, n; n = c[i]; i++){
1294 var pn = n.parentNode;
1295 if (batch != pn._batch) {
1297 for(var cn = pn.firstChild; cn; cn = cn.nextSibling){
1298 if(cn.nodeType == 1){
1305 if (l == 0 || n.nodeIndex == l){
1308 } else if ((n.nodeIndex + l) % f == 0){
1316 "only-child" : function(c){
1317 var r = [], ri = -1;;
1318 for(var i = 0, ci; ci = c[i]; i++){
1319 if(!prev(ci) && !next(ci)){
1326 "empty" : function(c){
1327 var r = [], ri = -1;
1328 for(var i = 0, ci; ci = c[i]; i++){
1329 var cns = ci.childNodes, j = 0, cn, empty = true;
1332 if(cn.nodeType == 1 || cn.nodeType == 3){
1344 "contains" : function(c, v){
1345 var r = [], ri = -1;
1346 for(var i = 0, ci; ci = c[i]; i++){
1347 if((ci.textContent||ci.innerText||'').indexOf(v) != -1){
1354 "nodeValue" : function(c, v){
1355 var r = [], ri = -1;
1356 for(var i = 0, ci; ci = c[i]; i++){
1357 if(ci.firstChild && ci.firstChild.nodeValue == v){
1364 "checked" : function(c){
1365 var r = [], ri = -1;
1366 for(var i = 0, ci; ci = c[i]; i++){
1367 if(ci.checked == true){
1374 "not" : function(c, ss){
1375 return Ext.DomQuery.filter(c, ss, true);
1378 "any" : function(c, selectors){
1379 var ss = selectors.split('|'),
1381 for(var i = 0, ci; ci = c[i]; i++){
1382 for(var j = 0; s = ss[j]; j++){
1383 if(Ext.DomQuery.is(ci, s)){
1392 "odd" : function(c){
1393 return this["nth-child"](c, "odd");
1396 "even" : function(c){
1397 return this["nth-child"](c, "even");
1400 "nth" : function(c, a){
1401 return c[a-1] || [];
1404 "first" : function(c){
1408 "last" : function(c){
1409 return c[c.length-1] || [];
1412 "has" : function(c, ss){
1413 var s = Ext.DomQuery.select,
1415 for(var i = 0, ci; ci = c[i]; i++){
1416 if(s(ss, ci).length > 0){
1423 "next" : function(c, ss){
1424 var is = Ext.DomQuery.is,
1426 for(var i = 0, ci; ci = c[i]; i++){
1435 "prev" : function(c, ss){
1436 var is = Ext.DomQuery.is,
1438 for(var i = 0, ci; ci = c[i]; i++){
1451 Ext.query = Ext.DomQuery.select;
1453 Ext.util.DelayedTask = function(fn, scope, args){
1459 fn.apply(scope, args || []);
1463 me.delay = function(delay, newFn, newScope, newArgs){
1466 scope = newScope || scope;
1467 args = newArgs || args;
1468 id = setInterval(call, delay);
1472 me.cancel = function(){
1482 Ext.Element = function(element, forceNew){
1483 var dom = typeof element == "string" ?
1484 DOC.getElementById(element) : element,
1487 if(!dom) return null;
1491 if(!forceNew && id && Ext.elCache[id]){
1492 return Ext.elCache[id].el;
1499 this.id = id || Ext.id(dom);
1502 var DH = Ext.DomHelper,
1508 set : function(o, useSet){
1512 useSet = (useSet !== false) && !!el.setAttribute;
1515 if (o.hasOwnProperty(attr)) {
1517 if (attr == 'style') {
1518 DH.applyStyles(el, val);
1519 } else if (attr == 'cls') {
1521 } else if (useSet) {
1522 el.setAttribute(attr, val);
1583 is : function(simpleSelector){
1584 return Ext.DomQuery.is(this.dom, simpleSelector);
1588 focus : function(defer, dom) {
1590 dom = dom || me.dom;
1593 me.focus.defer(defer, null, [null, dom]);
1610 getValue : function(asNumber){
1611 var val = this.dom.value;
1612 return asNumber ? parseInt(val, 10) : val;
1616 addListener : function(eventName, fn, scope, options){
1617 Ext.EventManager.on(this.dom, eventName, fn, scope || this, options);
1622 removeListener : function(eventName, fn, scope){
1623 Ext.EventManager.removeListener(this.dom, eventName, fn, scope || this);
1628 removeAllListeners : function(){
1629 Ext.EventManager.removeAll(this.dom);
1634 purgeAllListeners : function() {
1635 Ext.EventManager.purgeElement(this, true);
1639 addUnits : function(size){
1640 if(size === "" || size == "auto" || size === undefined){
1642 } else if(!isNaN(size) || !unitPattern.test(size)){
1643 size = size + (this.defaultUnit || 'px');
1649 load : function(url, params, cb){
1650 Ext.Ajax.request(Ext.apply({
1652 url: url.url || url,
1655 indicatorText: url.indicatorText || ''
1656 }, Ext.isObject(url) ? url : {}));
1661 isBorderBox : function(){
1662 return Ext.isBorderBox || Ext.isForcedBorderBox || noBoxAdjust[(this.dom.tagName || "").toLowerCase()];
1666 remove : function(){
1672 Ext.removeNode(dom);
1677 hover : function(overFn, outFn, scope, options){
1679 me.on('mouseenter', overFn, scope || me.dom, options);
1680 me.on('mouseleave', outFn, scope || me.dom, options);
1685 contains : function(el){
1686 return !el ? false : Ext.lib.Dom.isAncestor(this.dom, el.dom ? el.dom : el);
1690 getAttributeNS : function(ns, name){
1691 return this.getAttribute(name, ns);
1695 getAttribute : Ext.isIE ? function(name, ns){
1697 type = typeof d[ns + ":" + name];
1699 if(['undefined', 'unknown'].indexOf(type) == -1){
1700 return d[ns + ":" + name];
1703 } : function(name, ns){
1705 return d.getAttributeNS(ns, name) || d.getAttribute(ns + ":" + name) || d.getAttribute(name) || d[name];
1709 update : function(html) {
1711 this.dom.innerHTML = html;
1717 var ep = El.prototype;
1719 El.addMethods = function(o){
1724 ep.on = ep.addListener;
1727 ep.un = ep.removeListener;
1730 ep.autoBoxAdjust = true;
1733 var unitPattern = /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i,
1739 El.get = function(el){
1743 if(!el){ return null; }
1744 if (typeof el == "string") {
1745 if (!(elm = DOC.getElementById(el))) {
1748 if (EC[el] && EC[el].el) {
1752 ex = El.addToCache(new El(elm));
1755 } else if (el.tagName) {
1759 if (EC[id] && EC[id].el) {
1763 ex = El.addToCache(new El(el));
1766 } else if (el instanceof El) {
1772 if (Ext.isIE && (el.id == undefined || el.id == '')) {
1775 el.dom = DOC.getElementById(el.id) || el.dom;
1779 } else if(el.isComposite) {
1781 } else if(Ext.isArray(el)) {
1782 return El.select(el);
1783 } else if(el == DOC) {
1786 var f = function(){};
1787 f.prototype = El.prototype;
1796 El.addToCache = function(el, id){
1807 El.data = function(el, key, value){
1812 var c = EC[el.id].data;
1813 if(arguments.length == 2){
1816 return (c[key] = value);
1823 function garbageCollect(){
1824 if(!Ext.enableGarbageCollector){
1825 clearInterval(El.collectorThreadId);
1856 if(!d || !d.parentNode || (!d.offsetParent && !DOC.getElementById(eid))){
1857 if(Ext.enableListenerCollection){
1858 Ext.EventManager.removeAll(d);
1869 EC = Ext.elCache = t;
1873 El.collectorThreadId = setInterval(garbageCollect, 30000);
1875 var flyFn = function(){};
1876 flyFn.prototype = El.prototype;
1879 El.Flyweight = function(dom){
1883 El.Flyweight.prototype = new flyFn();
1884 El.Flyweight.prototype.isFlyweight = true;
1885 El._flyweights = {};
1888 El.fly = function(el, named){
1890 named = named || '_global';
1892 if (el = Ext.getDom(el)) {
1893 (El._flyweights[named] = El._flyweights[named] || new El.Flyweight()).dom = el;
1894 ret = El._flyweights[named];
1906 var noBoxAdjust = Ext.isStrict ? {
1909 input:1, select:1, textarea:1
1911 if(Ext.isIE || Ext.isGecko){
1912 noBoxAdjust['button'] = 1;
1917 Ext.Element.addMethods(function(){
1918 var PARENTNODE = 'parentNode',
1919 NEXTSIBLING = 'nextSibling',
1920 PREVIOUSSIBLING = 'previousSibling',
1926 findParent : function(simpleSelector, maxDepth, returnEl){
1931 if(Ext.isGecko && Object.prototype.toString.call(p) == '[object XULElement]') {
1934 maxDepth = maxDepth || 50;
1935 if (isNaN(maxDepth)) {
1936 stopEl = Ext.getDom(maxDepth);
1937 maxDepth = Number.MAX_VALUE;
1939 while(p && p.nodeType == 1 && depth < maxDepth && p != b && p != stopEl){
1940 if(DQ.is(p, simpleSelector)){
1941 return returnEl ? GET(p) : p;
1950 findParentNode : function(simpleSelector, maxDepth, returnEl){
1951 var p = Ext.fly(this.dom.parentNode, '_internal');
1952 return p ? p.findParent(simpleSelector, maxDepth, returnEl) : null;
1956 up : function(simpleSelector, maxDepth){
1957 return this.findParentNode(simpleSelector, maxDepth, true);
1961 select : function(selector){
1962 return Ext.Element.select(selector, this.dom);
1966 query : function(selector){
1967 return DQ.select(selector, this.dom);
1971 child : function(selector, returnDom){
1972 var n = DQ.selectNode(selector, this.dom);
1973 return returnDom ? n : GET(n);
1977 down : function(selector, returnDom){
1978 var n = DQ.selectNode(" > " + selector, this.dom);
1979 return returnDom ? n : GET(n);
1983 parent : function(selector, returnDom){
1984 return this.matchNode(PARENTNODE, PARENTNODE, selector, returnDom);
1988 next : function(selector, returnDom){
1989 return this.matchNode(NEXTSIBLING, NEXTSIBLING, selector, returnDom);
1993 prev : function(selector, returnDom){
1994 return this.matchNode(PREVIOUSSIBLING, PREVIOUSSIBLING, selector, returnDom);
1999 first : function(selector, returnDom){
2000 return this.matchNode(NEXTSIBLING, 'firstChild', selector, returnDom);
2004 last : function(selector, returnDom){
2005 return this.matchNode(PREVIOUSSIBLING, 'lastChild', selector, returnDom);
2008 matchNode : function(dir, start, selector, returnDom){
2009 var n = this.dom[start];
2011 if(n.nodeType == 1 && (!selector || DQ.is(n, selector))){
2012 return !returnDom ? GET(n) : n;
2020 Ext.Element.addMethods(
2022 var GETDOM = Ext.getDom,
2028 appendChild: function(el){
2029 return GET(el).appendTo(this);
2033 appendTo: function(el){
2034 GETDOM(el).appendChild(this.dom);
2039 insertBefore: function(el){
2040 (el = GETDOM(el)).parentNode.insertBefore(this.dom, el);
2045 insertAfter: function(el){
2046 (el = GETDOM(el)).parentNode.insertBefore(this.dom, el.nextSibling);
2051 insertFirst: function(el, returnDom){
2053 if(el.nodeType || el.dom || typeof el == 'string'){
2055 this.dom.insertBefore(el, this.dom.firstChild);
2056 return !returnDom ? GET(el) : el;
2058 return this.createChild(el, this.dom.firstChild, returnDom);
2063 replace: function(el){
2065 this.insertBefore(el);
2071 replaceWith: function(el){
2074 if(el.nodeType || el.dom || typeof el == 'string'){
2076 me.dom.parentNode.insertBefore(el, me.dom);
2078 el = DH.insertBefore(me.dom, el);
2081 delete Ext.elCache[me.id];
2082 Ext.removeNode(me.dom);
2083 me.id = Ext.id(me.dom = el);
2084 Ext.Element.addToCache(me.isFlyweight ? new Ext.Element(me.dom) : me);
2089 createChild: function(config, insertBefore, returnDom){
2090 config = config || {tag:'div'};
2091 return insertBefore ?
2092 DH.insertBefore(insertBefore, config, returnDom !== true) :
2093 DH[!this.dom.firstChild ? 'overwrite' : 'append'](this.dom, config, returnDom !== true);
2097 wrap: function(config, returnDom){
2098 var newEl = DH.insertBefore(this.dom, config || {tag: "div"}, !returnDom);
2099 newEl.dom ? newEl.dom.appendChild(this.dom) : newEl.appendChild(this.dom);
2104 insertHtml : function(where, html, returnEl){
2105 var el = DH.insertHtml(where, this.dom, html);
2106 return returnEl ? Ext.get(el) : el;
2110 Ext.Element.addMethods(function(){
2112 var supports = Ext.supports,
2114 camelRe = /(-[a-z])/gi,
2115 view = document.defaultView,
2116 opacityRe = /alpha\(opacity=(.*)\)/i,
2117 trimRe = /^\s+|\s+$/g,
2121 PADDING = "padding",
2131 ISCLIPPED = 'isClipped',
2132 OVERFLOW = 'overflow',
2133 OVERFLOWX = 'overflow-x',
2134 OVERFLOWY = 'overflow-y',
2135 ORIGINALCLIP = 'originalClip',
2137 borders = {l: BORDER + LEFT + WIDTH, r: BORDER + RIGHT + WIDTH, t: BORDER + TOP + WIDTH, b: BORDER + BOTTOM + WIDTH},
2138 paddings = {l: PADDING + LEFT, r: PADDING + RIGHT, t: PADDING + TOP, b: PADDING + BOTTOM},
2139 margins = {l: MARGIN + LEFT, r: MARGIN + RIGHT, t: MARGIN + TOP, b: MARGIN + BOTTOM},
2140 data = Ext.Element.data;
2144 function camelFn(m, a) {
2145 return a.charAt(1).toUpperCase();
2148 function chkCache(prop) {
2149 return propCache[prop] || (propCache[prop] = prop == 'float' ? (supports.cssFloat ? 'cssFloat' : 'styleFloat') : prop.replace(camelRe, camelFn));
2154 adjustWidth : function(width) {
2156 var isNum = (typeof width == "number");
2157 if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
2158 width -= (me.getBorderWidth("lr") + me.getPadding("lr"));
2160 return (isNum && width < 0) ? 0 : width;
2164 adjustHeight : function(height) {
2166 var isNum = (typeof height == "number");
2167 if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
2168 height -= (me.getBorderWidth("tb") + me.getPadding("tb"));
2170 return (isNum && height < 0) ? 0 : height;
2175 addClass : function(className){
2182 if (!Ext.isArray(className)) {
2183 if (typeof className == 'string' && !this.hasClass(className)) {
2184 me.dom.className += " " + className;
2188 for (i = 0, len = className.length; i < len; i++) {
2190 if (typeof v == 'string' && (' ' + me.dom.className + ' ').indexOf(' ' + v + ' ') == -1) {
2195 me.dom.className += " " + cls.join(" ");
2202 removeClass : function(className){
2209 if (!Ext.isArray(className)){
2210 className = [className];
2212 if (me.dom && me.dom.className) {
2213 elClasses = me.dom.className.replace(trimRe, '').split(spacesRe);
2214 for (i = 0, len = className.length; i < len; i++) {
2216 if (typeof cls == 'string') {
2217 cls = cls.replace(trimRe, '');
2218 idx = elClasses.indexOf(cls);
2220 elClasses.splice(idx, 1);
2224 me.dom.className = elClasses.join(" ");
2230 radioClass : function(className){
2231 var cn = this.dom.parentNode.childNodes,
2235 className = Ext.isArray(className) ? className : [className];
2236 for (i = 0, len = cn.length; i < len; i++) {
2238 if (v && v.nodeType == 1) {
2239 Ext.fly(v, '_internal').removeClass(className);
2242 return this.addClass(className);
2246 toggleClass : function(className){
2247 return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);
2251 hasClass : function(className){
2252 return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1;
2256 replaceClass : function(oldClassName, newClassName){
2257 return this.removeClass(oldClassName).addClass(newClassName);
2260 isStyle : function(style, val) {
2261 return this.getStyle(style) == val;
2265 getStyle : function(){
2266 return view && view.getComputedStyle ?
2277 prop = chkCache(prop);
2278 out = (v = el.style[prop]) ? v :
2279 (cs = view.getComputedStyle(el, "")) ? cs[prop] : null;
2283 if(prop == 'marginRight' && out != '0px' && !supports.correctRightMargin){
2284 display = el.style.display;
2285 el.style.display = 'inline-block';
2286 out = view.getComputedStyle(el, '').marginRight;
2287 el.style.display = display;
2290 if(prop == 'backgroundColor' && out == 'rgba(0, 0, 0, 0)' && !supports.correctTransparentColor){
2291 out = 'transparent';
2300 if(el == document) return null;
2301 if (prop == 'opacity') {
2302 if (el.style.filter.match) {
2303 if(m = el.style.filter.match(opacityRe)){
2304 var fv = parseFloat(m[1]);
2306 return fv ? fv / 100 : 0;
2312 prop = chkCache(prop);
2313 return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);
2318 getColor : function(attr, defaultValue, prefix){
2319 var v = this.getStyle(attr),
2320 color = (typeof prefix != 'undefined') ? prefix : '#',
2323 if(!v || (/transparent|inherit/.test(v))) {
2324 return defaultValue;
2327 Ext.each(v.slice(4, v.length -1).split(','), function(s){
2328 h = parseInt(s, 10);
2329 color += (h < 16 ? '0' : '') + h.toString(16);
2332 v = v.replace('#', '');
2333 color += v.length == 3 ? v.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : v;
2335 return(color.length > 5 ? color.toLowerCase() : defaultValue);
2339 setStyle : function(prop, value){
2342 if (typeof prop != 'object') {
2347 for (style in prop) {
2348 value = prop[style];
2349 style == 'opacity' ?
2350 this.setOpacity(value) :
2351 this.dom.style[chkCache(style)] = value;
2357 setOpacity : function(opacity, animate){
2361 if(!animate || !me.anim){
2363 var opac = opacity < 1 ? 'alpha(opacity=' + opacity * 100 + ')' : '',
2364 val = s.filter.replace(opacityRe, '').replace(trimRe, '');
2367 s.filter = val + (val.length > 0 ? ' ' : '') + opac;
2369 s.opacity = opacity;
2372 me.anim({opacity: {to: opacity}}, me.preanim(arguments, 1), null, .35, 'easeIn');
2378 clearOpacity : function(){
2379 var style = this.dom.style;
2381 if(!Ext.isEmpty(style.filter)){
2382 style.filter = style.filter.replace(opacityRe, '').replace(trimRe, '');
2385 style.opacity = style['-moz-opacity'] = style['-khtml-opacity'] = '';
2391 getHeight : function(contentHeight){
2394 hidden = Ext.isIE && me.isStyle('display', 'none'),
2395 h = MATH.max(dom.offsetHeight, hidden ? 0 : dom.clientHeight) || 0;
2397 h = !contentHeight ? h : h - me.getBorderWidth("tb") - me.getPadding("tb");
2398 return h < 0 ? 0 : h;
2402 getWidth : function(contentWidth){
2405 hidden = Ext.isIE && me.isStyle('display', 'none'),
2406 w = MATH.max(dom.offsetWidth, hidden ? 0 : dom.clientWidth) || 0;
2407 w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");
2408 return w < 0 ? 0 : w;
2412 setWidth : function(width, animate){
2414 width = me.adjustWidth(width);
2415 !animate || !me.anim ?
2416 me.dom.style.width = me.addUnits(width) :
2417 me.anim({width : {to : width}}, me.preanim(arguments, 1));
2422 setHeight : function(height, animate){
2424 height = me.adjustHeight(height);
2425 !animate || !me.anim ?
2426 me.dom.style.height = me.addUnits(height) :
2427 me.anim({height : {to : height}}, me.preanim(arguments, 1));
2432 getBorderWidth : function(side){
2433 return this.addStyles(side, borders);
2437 getPadding : function(side){
2438 return this.addStyles(side, paddings);
2446 if(!data(dom, ISCLIPPED)){
2447 data(dom, ISCLIPPED, true);
2448 data(dom, ORIGINALCLIP, {
2449 o: me.getStyle(OVERFLOW),
2450 x: me.getStyle(OVERFLOWX),
2451 y: me.getStyle(OVERFLOWY)
2453 me.setStyle(OVERFLOW, HIDDEN);
2454 me.setStyle(OVERFLOWX, HIDDEN);
2455 me.setStyle(OVERFLOWY, HIDDEN);
2461 unclip : function(){
2465 if(data(dom, ISCLIPPED)){
2466 data(dom, ISCLIPPED, false);
2467 var o = data(dom, ORIGINALCLIP);
2469 me.setStyle(OVERFLOW, o.o);
2472 me.setStyle(OVERFLOWX, o.x);
2475 me.setStyle(OVERFLOWY, o.y);
2482 addStyles : function(sides, styles){
2484 sidesArr = sides.match(wordsRe),
2488 len = sidesArr.length;
2489 for (i = 0; i < len; i++) {
2491 size = side && parseInt(this.getStyle(styles[side]), 10);
2493 ttlSize += MATH.abs(size);
2505 var D = Ext.lib.Dom,
2510 POSITION = "position",
2512 RELATIVE = "relative",
2516 Ext.Element.addMethods({
2519 return D.getX(this.dom);
2524 return D.getY(this.dom);
2529 return D.getXY(this.dom);
2533 getOffsetsTo : function(el){
2534 var o = this.getXY(),
2535 e = Ext.fly(el, '_internal').getXY();
2536 return [o[0]-e[0],o[1]-e[1]];
2540 setX : function(x, animate){
2541 return this.setXY([x, this.getY()], this.animTest(arguments, animate, 1));
2545 setY : function(y, animate){
2546 return this.setXY([this.getX(), y], this.animTest(arguments, animate, 1));
2550 setLeft : function(left){
2551 this.setStyle(LEFT, this.addUnits(left));
2556 setTop : function(top){
2557 this.setStyle(TOP, this.addUnits(top));
2562 setRight : function(right){
2563 this.setStyle(RIGHT, this.addUnits(right));
2568 setBottom : function(bottom){
2569 this.setStyle(BOTTOM, this.addUnits(bottom));
2574 setXY : function(pos, animate){
2576 if(!animate || !me.anim){
2577 D.setXY(me.dom, pos);
2579 me.anim({points: {to: pos}}, me.preanim(arguments, 1), 'motion');
2585 setLocation : function(x, y, animate){
2586 return this.setXY([x, y], this.animTest(arguments, animate, 2));
2590 moveTo : function(x, y, animate){
2591 return this.setXY([x, y], this.animTest(arguments, animate, 2));
2595 getLeft : function(local){
2596 return !local ? this.getX() : parseInt(this.getStyle(LEFT), 10) || 0;
2600 getRight : function(local){
2602 return !local ? me.getX() + me.getWidth() : (me.getLeft(true) + me.getWidth()) || 0;
2606 getTop : function(local) {
2607 return !local ? this.getY() : parseInt(this.getStyle(TOP), 10) || 0;
2611 getBottom : function(local){
2613 return !local ? me.getY() + me.getHeight() : (me.getTop(true) + me.getHeight()) || 0;
2617 position : function(pos, zIndex, x, y){
2620 if(!pos && me.isStyle(POSITION, STATIC)){
2621 me.setStyle(POSITION, RELATIVE);
2623 me.setStyle(POSITION, pos);
2626 me.setStyle(ZINDEX, zIndex);
2628 if(x || y) me.setXY([x || false, y || false]);
2632 clearPositioning : function(value){
2633 value = value || '';
2646 getPositioning : function(){
2647 var l = this.getStyle(LEFT);
2648 var t = this.getStyle(TOP);
2650 "position" : this.getStyle(POSITION),
2652 "right" : l ? "" : this.getStyle(RIGHT),
2654 "bottom" : t ? "" : this.getStyle(BOTTOM),
2655 "z-index" : this.getStyle(ZINDEX)
2660 setPositioning : function(pc){
2662 style = me.dom.style;
2666 if(pc.right == AUTO){
2669 if(pc.bottom == AUTO){
2677 translatePoints : function(x, y){
2678 y = isNaN(x[1]) ? y : x[1];
2679 x = isNaN(x[0]) ? x : x[0];
2681 relative = me.isStyle(POSITION, RELATIVE),
2683 l = parseInt(me.getStyle(LEFT), 10),
2684 t = parseInt(me.getStyle(TOP), 10);
2686 l = !isNaN(l) ? l : (relative ? 0 : me.dom.offsetLeft);
2687 t = !isNaN(t) ? t : (relative ? 0 : me.dom.offsetTop);
2689 return {left: (x - o[0] + l), top: (y - o[1] + t)};
2692 animTest : function(args, animate, i) {
2693 return !!animate && this.preanim ? this.preanim(args, i) : false;
2697 Ext.Element.addMethods({
2699 isScrollable : function(){
2701 return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth;
2705 scrollTo : function(side, value){
2706 this.dom["scroll" + (/top/i.test(side) ? "Top" : "Left")] = value;
2711 getScroll : function(){
2715 docElement = doc.documentElement,
2720 if(d == doc || d == body){
2721 if(Ext.isIE && Ext.isStrict){
2722 l = docElement.scrollLeft;
2723 t = docElement.scrollTop;
2725 l = window.pageXOffset;
2726 t = window.pageYOffset;
2728 ret = {left: l || (body ? body.scrollLeft : 0), top: t || (body ? body.scrollTop : 0)};
2730 ret = {left: d.scrollLeft, top: d.scrollTop};
2736 Ext.Element.VISIBILITY = 1;
2738 Ext.Element.DISPLAY = 2;
2741 Ext.Element.OFFSETS = 3;
2744 Ext.Element.ASCLASS = 4;
2747 Ext.Element.visibilityCls = 'x-hide-nosize';
2749 Ext.Element.addMethods(function(){
2750 var El = Ext.Element,
2751 OPACITY = "opacity",
2752 VISIBILITY = "visibility",
2753 DISPLAY = "display",
2755 OFFSETS = "offsets",
2756 ASCLASS = "asclass",
2759 ORIGINALDISPLAY = 'originalDisplay',
2760 VISMODE = 'visibilityMode',
2761 ISVISIBLE = 'isVisible',
2763 getDisplay = function(dom){
2764 var d = data(dom, ORIGINALDISPLAY);
2765 if(d === undefined){
2766 data(dom, ORIGINALDISPLAY, d = '');
2770 getVisMode = function(dom){
2771 var m = data(dom, VISMODE);
2772 if(m === undefined){
2773 data(dom, VISMODE, m = 1);
2780 originalDisplay : "",
2784 setVisibilityMode : function(visMode){
2785 data(this.dom, VISMODE, visMode);
2790 animate : function(args, duration, onComplete, easing, animType){
2791 this.anim(args, {duration: duration, callback: onComplete, easing: easing}, animType);
2796 anim : function(args, opt, animType, defaultDur, defaultEase, cb){
2797 animType = animType || 'run';
2800 anim = Ext.lib.Anim[animType](
2803 (opt.duration || defaultDur) || .35,
2804 (opt.easing || defaultEase) || 'easeOut',
2807 if(opt.callback) opt.callback.call(opt.scope || me, me, opt);
2816 preanim : function(a, i){
2817 return !a[i] ? false : (typeof a[i] == 'object' ? a[i]: {duration: a[i+1], callback: a[i+2], easing: a[i+3]});
2821 isVisible : function() {
2824 visible = data(dom, ISVISIBLE);
2826 if(typeof visible == 'boolean'){
2830 visible = !me.isStyle(VISIBILITY, HIDDEN) &&
2831 !me.isStyle(DISPLAY, NONE) &&
2832 !((getVisMode(dom) == El.ASCLASS) && me.hasClass(me.visibilityCls || El.visibilityCls));
2834 data(dom, ISVISIBLE, visible);
2839 setVisible : function(visible, animate){
2840 var me = this, isDisplay, isVisibility, isOffsets, isNosize,
2842 visMode = getVisMode(dom);
2846 if (typeof animate == 'string'){
2849 visMode = El.DISPLAY;
2852 visMode = El.VISIBILITY;
2855 visMode = El.OFFSETS;
2859 visMode = El.ASCLASS;
2862 me.setVisibilityMode(visMode);
2866 if (!animate || !me.anim) {
2867 if(visMode == El.ASCLASS ){
2869 me[visible?'removeClass':'addClass'](me.visibilityCls || El.visibilityCls);
2871 } else if (visMode == El.DISPLAY){
2873 return me.setDisplayed(visible);
2875 } else if (visMode == El.OFFSETS){
2878 me.hideModeStyles = {
2879 position: me.getStyle('position'),
2880 top: me.getStyle('top'),
2881 left: me.getStyle('left')
2883 me.applyStyles({position: 'absolute', top: '-10000px', left: '-10000px'});
2885 me.applyStyles(me.hideModeStyles || {position: '', top: '', left: ''});
2886 delete me.hideModeStyles;
2891 dom.style.visibility = visible ? "visible" : HIDDEN;
2897 me.setVisible(true);
2899 me.anim({opacity: { to: (visible?1:0) }},
2900 me.preanim(arguments, 1),
2905 visible || me.setVisible(false).setOpacity(1);
2908 data(dom, ISVISIBLE, visible);
2914 hasMetrics : function(){
2916 return this.isVisible() || (getVisMode(dom) == El.VISIBILITY);
2920 toggle : function(animate){
2922 me.setVisible(!me.isVisible(), me.preanim(arguments, 0));
2927 setDisplayed : function(value) {
2928 if(typeof value == "boolean"){
2929 value = value ? getDisplay(this.dom) : NONE;
2931 this.setStyle(DISPLAY, value);
2936 fixDisplay : function(){
2938 if(me.isStyle(DISPLAY, NONE)){
2939 me.setStyle(VISIBILITY, HIDDEN);
2940 me.setStyle(DISPLAY, getDisplay(this.dom));
2941 if(me.isStyle(DISPLAY, NONE)){
2942 me.setStyle(DISPLAY, "block");
2948 hide : function(animate){
2950 if (typeof animate == 'string'){
2951 this.setVisible(false, animate);
2954 this.setVisible(false, this.preanim(arguments, 0));
2959 show : function(animate){
2961 if (typeof animate == 'string'){
2962 this.setVisible(true, animate);
2965 this.setVisible(true, this.preanim(arguments, 0));
2972 UNDEFINED = undefined,
2986 ABSOLUTE = "absolute",
2987 VISIBLE = "visible",
2989 POSITION = "position",
2990 EASEOUT = "easeOut",
2992 flyEl = new Ext.Element.Flyweight(),
2994 getObject = function(o){
2997 fly = function(dom){
2999 flyEl.id = Ext.id(dom);
3003 getQueue = function(id){
3009 setQueue = function(id, value){
3014 Ext.enableFx = TRUE;
3021 switchStatements : function(key, fn, argHash){
3022 return fn.apply(this, argHash[key]);
3026 slideIn : function(anchor, o){
3042 anchor = anchor || "t";
3044 me.queueFx(o, function(){
3045 xy = fly(dom).getXY();
3047 fly(dom).fixDisplay();
3050 r = fly(dom).getFxRestore();
3051 b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight};
3052 b.right = b.x + b.width;
3053 b.bottom = b.y + b.height;
3056 fly(dom).setWidth(b.width).setHeight(b.height);
3059 wrap = fly(dom).fxWrap(r.pos, o, HIDDEN);
3061 st.visibility = VISIBLE;
3062 st.position = ABSOLUTE;
3066 fly(dom).fxUnwrap(wrap, r.pos, o);
3068 st.height = r.height;
3069 fly(dom).afterFx(o);
3073 pt = {to: [b.x, b.y]};
3075 bh = {to: b.height};
3077 function argCalc(wrap, style, ww, wh, sXY, sXYval, s1, s2, w, h, p){
3079 fly(wrap).setWidth(ww).setHeight(wh);
3081 fly(wrap)[sXY](sXYval);
3083 style[s1] = style[s2] = "0";
3096 args = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, {
3097 t : [wrap, st, b.width, 0, NULL, NULL, LEFT, BOTTOM, NULL, bh, NULL],
3098 l : [wrap, st, 0, b.height, NULL, NULL, RIGHT, TOP, bw, NULL, NULL],
3099 r : [wrap, st, b.width, b.height, SETX, b.right, LEFT, TOP, NULL, NULL, pt],
3100 b : [wrap, st, b.width, b.height, SETY, b.bottom, LEFT, TOP, NULL, bh, pt],
3101 tl : [wrap, st, 0, 0, NULL, NULL, RIGHT, BOTTOM, bw, bh, pt],
3102 bl : [wrap, st, 0, 0, SETY, b.y + b.height, RIGHT, TOP, bw, bh, pt],
3103 br : [wrap, st, 0, 0, SETXY, [b.right, b.bottom], LEFT, TOP, bw, bh, pt],
3104 tr : [wrap, st, 0, 0, SETX, b.x + b.width, LEFT, BOTTOM, bw, bh, pt]
3107 st.visibility = VISIBLE;
3110 arguments.callee.anim = fly(wrap).fxanim(args,
3121 slideOut : function(anchor, o){
3133 anchor = anchor || "t";
3135 me.queueFx(o, function(){
3138 r = fly(dom).getFxRestore();
3139 b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight};
3140 b.right = b.x + b.width;
3141 b.bottom = b.y + b.height;
3144 fly(dom).setWidth(b.width).setHeight(b.height);
3147 wrap = fly(dom).fxWrap(r.pos, o, VISIBLE);
3149 st.visibility = VISIBLE;
3150 st.position = ABSOLUTE;
3151 fly(wrap).setWidth(b.width).setHeight(b.height);
3154 o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();
3155 fly(dom).fxUnwrap(wrap, r.pos, o);
3157 st.height = r.height;
3158 fly(dom).afterFx(o);
3161 function argCalc(style, s1, s2, p1, v1, p2, v2, p3, v3){
3164 style[s1] = style[s2] = "0";
3176 a = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, {
3177 t : [st, LEFT, BOTTOM, HEIGHT, zero],
3178 l : [st, RIGHT, TOP, WIDTH, zero],
3179 r : [st, LEFT, TOP, WIDTH, zero, POINTS, {to : [b.right, b.y]}],
3180 b : [st, LEFT, TOP, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}],
3181 tl : [st, RIGHT, BOTTOM, WIDTH, zero, HEIGHT, zero],
3182 bl : [st, RIGHT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}],
3183 br : [st, LEFT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x + b.width, b.bottom]}],
3184 tr : [st, LEFT, BOTTOM, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.right, b.y]}]
3187 arguments.callee.anim = fly(wrap).fxanim(a,
3207 me.queueFx(o, function(){
3208 width = fly(dom).getWidth();
3209 height = fly(dom).getHeight();
3210 fly(dom).clearOpacity();
3214 r = fly(dom).getFxRestore();
3217 o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();
3218 fly(dom).clearOpacity();
3219 fly(dom).setPositioning(r.pos);
3221 st.height = r.height;
3223 fly(dom).afterFx(o);
3226 arguments.callee.anim = fly(dom).fxanim({
3227 width : {to : fly(dom).adjustWidth(width * 2)},
3228 height : {to : fly(dom).adjustHeight(height * 2)},
3229 points : {by : [-width * .5, -height * .5]},
3231 fontSize: {to : 200, unit: "%"}
3243 switchOff : function(o){
3250 me.queueFx(o, function(){
3251 fly(dom).clearOpacity();
3255 r = fly(dom).getFxRestore();
3258 o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();
3259 fly(dom).clearOpacity();
3260 fly(dom).setPositioning(r.pos);
3262 st.height = r.height;
3263 fly(dom).afterFx(o);
3266 fly(dom).fxanim({opacity : {to : 0.3}},
3272 fly(dom).clearOpacity();
3276 points : {by : [0, fly(dom).getHeight() * .5]}
3290 highlight : function(color, o){
3294 attr = o.attr || "backgroundColor",
3298 me.queueFx(o, function(){
3299 fly(dom).clearOpacity();
3303 dom.style[attr] = restore;
3304 fly(dom).afterFx(o);
3306 restore = dom.style[attr];
3307 a[attr] = {from: color || "ffff9c", to: o.endColor || fly(dom).getColor(attr) || "ffffff"};
3308 arguments.callee.anim = fly(dom).fxanim(a,
3319 frame : function(color, count, o){
3326 me.queueFx(o, function(){
3327 color = color || '#C3DAF9';
3328 if(color.length == 6){
3329 color = '#' + color;
3334 var xy = fly(dom).getXY(),
3335 b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight},
3337 proxy = fly(document.body || document.documentElement).createChild({
3339 position : ABSOLUTE,
3341 border : '0px solid ' + color
3344 return proxy.queueFx({}, animFn);
3348 arguments.callee.anim = {
3357 var scale = Ext.isBorderBox ? 2 : 1;
3358 active = proxy.anim({
3359 top : {from : b.y, to : b.y - 20},
3360 left : {from : b.x, to : b.x - 20},
3361 borderWidth : {from : 0, to : 10},
3362 opacity : {from : 1, to : 0},
3363 height : {from : b.height, to : b.height + 20 * scale},
3364 width : {from : b.width, to : b.width + 20 * scale}
3366 duration: o.duration || 1,
3367 callback: function() {
3369 --count > 0 ? queue() : fly(dom).afterFx(o);
3372 arguments.callee.anim = {
3385 pause : function(seconds){
3389 this.queueFx({}, function(){
3390 t = setTimeout(function(){
3391 fly(dom).afterFx({});
3393 arguments.callee.anim = {
3397 fly(dom).afterFx({});
3405 fadeIn : function(o){
3409 to = o.endOpacity || 1;
3411 me.queueFx(o, function(){
3412 fly(dom).setOpacity(0);
3413 fly(dom).fixDisplay();
3414 dom.style.visibility = VISIBLE;
3415 arguments.callee.anim = fly(dom).fxanim({opacity:{to:to}},
3416 o, NULL, .5, EASEOUT, function(){
3418 fly(dom).clearOpacity();
3420 fly(dom).afterFx(o);
3427 fadeOut : function(o){
3432 to = o.endOpacity || 0;
3434 me.queueFx(o, function(){
3435 arguments.callee.anim = fly(dom).fxanim({
3436 opacity : {to : to}},
3443 Ext.Element.data(dom, 'visibilityMode') == Ext.Element.DISPLAY || o.useDisplay ?
3444 style.display = "none" :
3445 style.visibility = HIDDEN;
3447 fly(dom).clearOpacity();
3449 fly(dom).afterFx(o);
3456 scale : function(w, h, o){
3457 this.shift(Ext.apply({}, o, {
3465 shift : function(o){
3470 this.queueFx(o, function(){
3471 for (var prop in o) {
3472 if (o[prop] != UNDEFINED) {
3473 a[prop] = {to : o[prop]};
3477 a.width ? a.width.to = fly(dom).adjustWidth(o.width) : a;
3478 a.height ? a.height.to = fly(dom).adjustWidth(o.height) : a;
3480 if (a.x || a.y || a.xy) {
3482 {to : [ a.x ? a.x.to : fly(dom).getX(),
3483 a.y ? a.y.to : fly(dom).getY()]};
3486 arguments.callee.anim = fly(dom).fxanim(a,
3492 fly(dom).afterFx(o);
3499 ghost : function(anchor, o){
3504 a = {opacity: {to: 0}, points: {}},
3510 anchor = anchor || "b";
3512 me.queueFx(o, function(){
3514 r = fly(dom).getFxRestore();
3515 w = fly(dom).getWidth();
3516 h = fly(dom).getHeight();
3519 o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();
3520 fly(dom).clearOpacity();
3521 fly(dom).setPositioning(r.pos);
3523 st.height = r.height;
3524 fly(dom).afterFx(o);
3527 pt.by = fly(dom).switchStatements(anchor.toLowerCase(), function(v1,v2){ return [v1, v2];}, {
3538 arguments.callee.anim = fly(dom).fxanim(a,
3548 syncFx : function(){
3550 me.fxDefaults = Ext.apply(me.fxDefaults || {}, {
3559 sequenceFx : function(){
3561 me.fxDefaults = Ext.apply(me.fxDefaults || {}, {
3570 nextFx : function(){
3571 var ef = getQueue(this.dom.id)[0];
3578 hasActiveFx : function(){
3579 return getQueue(this.dom.id)[0];
3583 stopFx : function(finish){
3586 if(me.hasActiveFx()){
3587 var cur = getQueue(id)[0];
3588 if(cur && cur.anim){
3589 if(cur.anim.isAnimated){
3590 setQueue(id, [cur]);
3591 cur.anim.stop(finish !== undefined ? finish : TRUE);
3601 beforeFx : function(o){
3602 if(this.hasActiveFx() && !o.concurrent){
3613 hasFxBlock : function(){
3614 var q = getQueue(this.dom.id);
3615 return q && q[0] && q[0].block;
3619 queueFx : function(o, fn){
3620 var me = fly(this.dom);
3621 if(!me.hasFxBlock()){
3622 Ext.applyIf(o, me.fxDefaults);
3624 var run = me.beforeFx(o);
3626 getQueue(me.dom.id).push(fn);
3638 fxWrap : function(pos, o, vis){
3642 if(!o.wrap || !(wrap = Ext.getDom(o.wrap))){
3644 wrapXY = fly(dom).getXY();
3646 var div = document.createElement("div");
3647 div.style.visibility = vis;
3648 wrap = dom.parentNode.insertBefore(div, dom);
3649 fly(wrap).setPositioning(pos);
3650 if(fly(wrap).isStyle(POSITION, "static")){
3651 fly(wrap).position("relative");
3653 fly(dom).clearPositioning('auto');
3655 wrap.appendChild(dom);
3657 fly(wrap).setXY(wrapXY);
3664 fxUnwrap : function(wrap, pos, o){
3666 fly(dom).clearPositioning();
3667 fly(dom).setPositioning(pos);
3669 var pn = fly(wrap).dom.parentNode;
3670 pn.insertBefore(dom, wrap);
3676 getFxRestore : function(){
3677 var st = this.dom.style;
3678 return {pos: this.getPositioning(), width: st.width, height : st.height};
3682 afterFx : function(o){
3686 fly(dom).setStyle(o.afterStyle);
3689 fly(dom).addClass(o.afterCls);
3691 if(o.remove == TRUE){
3695 o.callback.call(o.scope, fly(dom));
3698 getQueue(id).shift();
3704 fxanim : function(args, opt, animType, defaultDur, defaultEase, cb){
3705 animType = animType || 'run';
3707 var anim = Ext.lib.Anim[animType](
3710 (opt.duration || defaultDur) || .35,
3711 (opt.easing || defaultEase) || EASEOUT,
3721 Ext.Fx.resize = Ext.Fx.scale;
3725 Ext.Element.addMethods(Ext.Fx);
3728 Ext.CompositeElementLite = function(els, root){
3731 this.add(els, root);
3732 this.el = new Ext.Element.Flyweight();
3735 Ext.CompositeElementLite.prototype = {
3739 getElement : function(el){
3748 transformElement : function(el){
3749 return Ext.getDom(el);
3753 getCount : function(){
3754 return this.elements.length;
3757 add : function(els, root){
3759 elements = me.elements;
3763 if(typeof els == "string"){
3764 els = Ext.Element.selectorFunction(els, root);
3765 }else if(els.isComposite){
3767 }else if(!Ext.isIterable(els)){
3771 for(var i = 0, len = els.length; i < len; ++i){
3772 elements.push(me.transformElement(els[i]));
3777 invoke : function(fn, args){
3784 for(i = 0; i < len; i++) {
3787 Ext.Element.prototype[fn].apply(me.getElement(e), args);
3793 item : function(index){
3795 el = me.elements[index],
3799 out = me.getElement(el);
3805 addListener : function(eventName, handler, scope, opt){
3806 var els = this.elements,
3810 for(i = 0; i<len; i++) {
3813 Ext.EventManager.on(e, eventName, handler, scope || e, opt);
3819 each : function(fn, scope){
3825 for(i = 0; i<len; i++) {
3828 e = this.getElement(e);
3829 if(fn.call(scope || e, e, me, i) === false){
3838 fill : function(els){
3846 filter : function(selector){
3849 fn = Ext.isFunction(selector) ? selector
3851 return el.is(selector);
3854 me.each(function(el, self, i) {
3855 if (fn(el, i) !== false) {
3856 els[els.length] = me.transformElement(el);
3865 indexOf : function(el){
3866 return this.elements.indexOf(this.transformElement(el));
3870 replaceElement : function(el, replacement, domReplace){
3871 var index = !isNaN(el) ? el : this.indexOf(el),
3874 replacement = Ext.getDom(replacement);
3876 d = this.elements[index];
3877 d.parentNode.insertBefore(replacement, d);
3880 this.elements.splice(index, 1, replacement);
3891 Ext.CompositeElementLite.prototype.on = Ext.CompositeElementLite.prototype.addListener;
3894 Ext.CompositeElementLite.importElementMethods = function() {
3896 ElProto = Ext.Element.prototype,
3897 CelProto = Ext.CompositeElementLite.prototype;
3899 for (fnName in ElProto) {
3900 if (typeof ElProto[fnName] == 'function'){
3902 CelProto[fnName] = CelProto[fnName] || function() {
3903 return this.invoke(fnName, arguments);
3905 }).call(CelProto, fnName);
3911 Ext.CompositeElementLite.importElementMethods();
3914 Ext.Element.selectorFunction = Ext.DomQuery.select;
3918 Ext.Element.select = function(selector, root){
3920 if(typeof selector == "string"){
3921 els = Ext.Element.selectorFunction(selector, root);
3922 }else if(selector.length !== undefined){
3925 throw "Invalid selector";
3927 return new Ext.CompositeElementLite(els);
3930 Ext.select = Ext.Element.select;
3932 var BEFOREREQUEST = "beforerequest",
3933 REQUESTCOMPLETE = "requestcomplete",
3934 REQUESTEXCEPTION = "requestexception",
3935 UNDEFINED = undefined,
3942 Ext.data.Connection = function(config){
3943 Ext.apply(this, config);
3952 Ext.data.Connection.superclass.constructor.call(this);
3955 Ext.extend(Ext.data.Connection, Ext.util.Observable, {
3966 disableCaching: true,
3969 disableCachingParam: '_dc',
3972 request : function(o){
3974 if(me.fireEvent(BEFOREREQUEST, me, o)){
3976 if(!Ext.isEmpty(o.indicatorText)){
3977 me.indicatorText = '<div class="loading-indicator">'+o.indicatorText+"</div>";
3979 if(me.indicatorText) {
3980 Ext.getDom(o.el).innerHTML = me.indicatorText;
3982 o.success = (Ext.isFunction(o.success) ? o.success : function(){}).createInterceptor(function(response) {
3983 Ext.getDom(o.el).innerHTML = response.responseText;
3988 url = o.url || me.url,
3990 cb = {success: me.handleResponse,
3991 failure: me.handleFailure,
3993 argument: {options: o},
3994 timeout : Ext.num(o.timeout, me.timeout)
4000 if (Ext.isFunction(p)) {
4001 p = p.call(o.scope||WINDOW, o);
4004 p = Ext.urlEncode(me.extraParams, Ext.isObject(p) ? Ext.urlEncode(p) : p);
4006 if (Ext.isFunction(url)) {
4007 url = url.call(o.scope || WINDOW, o);
4010 if((form = Ext.getDom(o.form))){
4011 url = url || form.action;
4012 if(o.isUpload || (/multipart\/form-data/i.test(form.getAttribute("enctype")))) {
4013 return me.doFormUpload.call(me, o, p, url);
4015 serForm = Ext.lib.Ajax.serializeForm(form);
4016 p = p ? (p + '&' + serForm) : serForm;
4019 method = o.method || me.method || ((p || o.xmlData || o.jsonData) ? POST : GET);
4021 if(method === GET && (me.disableCaching && o.disableCaching !== false) || o.disableCaching === true){
4022 var dcp = o.disableCachingParam || me.disableCachingParam;
4023 url = Ext.urlAppend(url, dcp + '=' + (new Date().getTime()));
4026 o.headers = Ext.apply(o.headers || {}, me.defaultHeaders || {});
4028 if(o.autoAbort === true || me.autoAbort) {
4032 if((method == GET || o.xmlData || o.jsonData) && p){
4033 url = Ext.urlAppend(url, p);
4036 return (me.transId = Ext.lib.Ajax.request(method, url, cb, p, o));
4038 return o.callback ? o.callback.apply(o.scope, [o,UNDEFINED,UNDEFINED]) : null;
4043 isLoading : function(transId){
4044 return transId ? Ext.lib.Ajax.isCallInProgress(transId) : !! this.transId;
4048 abort : function(transId){
4049 if(transId || this.isLoading()){
4050 Ext.lib.Ajax.abort(transId || this.transId);
4055 handleResponse : function(response){
4056 this.transId = false;
4057 var options = response.argument.options;
4058 response.argument = options ? options.argument : null;
4059 this.fireEvent(REQUESTCOMPLETE, this, response, options);
4060 if(options.success){
4061 options.success.call(options.scope, response, options);
4063 if(options.callback){
4064 options.callback.call(options.scope, options, true, response);
4069 handleFailure : function(response, e){
4070 this.transId = false;
4071 var options = response.argument.options;
4072 response.argument = options ? options.argument : null;
4073 this.fireEvent(REQUESTEXCEPTION, this, response, options, e);
4074 if(options.failure){
4075 options.failure.call(options.scope, response, options);
4077 if(options.callback){
4078 options.callback.call(options.scope, options, false, response);
4083 doFormUpload : function(o, ps, url){
4086 frame = doc.createElement('iframe'),
4087 form = Ext.getDom(o.form),
4090 encoding = 'multipart/form-data',
4092 target: form.target,
4093 method: form.method,
4094 encoding: form.encoding,
4095 enctype: form.enctype,
4100 Ext.fly(frame).set({
4104 src: Ext.SSL_SECURE_URL
4107 doc.body.appendChild(frame);
4111 document.frames[id].name = id;
4120 action: url || buf.action
4124 Ext.iterate(Ext.urlDecode(ps, false), function(k, v){
4125 hd = doc.createElement('input');
4131 form.appendChild(hd);
4138 r = {responseText : '',
4140 argument : o.argument},
4145 doc = frame.contentWindow.document || frame.contentDocument || WINDOW.frames[id].document;
4148 if(/textarea/i.test((firstChild = doc.body.firstChild || {}).tagName)){
4149 r.responseText = firstChild.value;
4151 r.responseText = doc.body.innerHTML;
4155 r.responseXML = doc.XMLDocument || doc;
4160 Ext.EventManager.removeListener(frame, LOAD, cb, me);
4162 me.fireEvent(REQUESTCOMPLETE, me, r, o);
4164 function runCallback(fn, scope, args){
4165 if(Ext.isFunction(fn)){
4166 fn.apply(scope, args);
4170 runCallback(o.success, o.scope, [r, o]);
4171 runCallback(o.callback, o.scope, [o, true, r]);
4173 if(!me.debugUploads){
4174 setTimeout(function(){Ext.removeNode(frame);}, 100);
4178 Ext.EventManager.on(frame, LOAD, cb, this);
4181 Ext.fly(form).set(buf);
4182 Ext.each(hiddens, function(h) {
4190 Ext.Ajax = new Ext.data.Connection({
4211 serializeForm : function(form){
4212 return Ext.lib.Ajax.serializeForm(form);
4216 Ext.util.JSON = new (function(){
4217 var useHasOwn = !!{}.hasOwnProperty,
4218 isNative = function() {
4219 var useNative = null;
4222 if (useNative === null) {
4223 useNative = Ext.USE_NATIVE_JSON && window.JSON && JSON.toString() == '[object JSON]';
4230 return n < 10 ? "0" + n : n;
4232 doDecode = function(json){
4233 return eval("(" + json + ")");
4235 doEncode = function(o){
4236 if(!Ext.isDefined(o) || o === null){
4238 }else if(Ext.isArray(o)){
4239 return encodeArray(o);
4240 }else if(Ext.isDate(o)){
4241 return Ext.util.JSON.encodeDate(o);
4242 }else if(Ext.isString(o)){
4243 return encodeString(o);
4244 }else if(typeof o == "number"){
4246 return isFinite(o) ? String(o) : "null";
4247 }else if(Ext.isBoolean(o)){
4250 var a = ["{"], b, i, v;
4253 if(!o.getElementsByTagName){
4254 if(!useHasOwn || o.hasOwnProperty(i)) {
4265 a.push(doEncode(i), ":",
4266 v === null ? "null" : doEncode(v));
4285 encodeString = function(s){
4286 if (/["\\\x00-\x1f]/.test(s)) {
4287 return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) {
4294 Math.floor(c / 16).toString(16) +
4295 (c % 16).toString(16);
4298 return '"' + s + '"';
4300 encodeArray = function(o){
4301 var a = ["["], b, i, l = o.length, v;
4302 for (i = 0; i < l; i += 1) {
4313 a.push(v === null ? "null" : Ext.util.JSON.encode(v));
4322 this.encodeDate = function(o){
4323 return '"' + o.getFullYear() + "-" +
4324 pad(o.getMonth() + 1) + "-" +
4325 pad(o.getDate()) + "T" +
4326 pad(o.getHours()) + ":" +
4327 pad(o.getMinutes()) + ":" +
4328 pad(o.getSeconds()) + '"';
4332 this.encode = function() {
4334 return function(o) {
4337 ec = isNative() ? JSON.stringify : doEncode;
4345 this.decode = function() {
4347 return function(json) {
4350 dc = isNative() ? JSON.parse : doDecode;
4358 Ext.encode = Ext.util.JSON.encode;
4360 Ext.decode = Ext.util.JSON.decode;
4362 Ext.EventManager = function(){
4365 docReadyState = false,
4366 DETECT_NATIVE = Ext.isGecko || Ext.isWebKit || Ext.isSafari,
4371 DOMCONTENTLOADED = "DOMContentLoaded",
4372 COMPLETE = 'complete',
4373 propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,
4375 specialElCache = [];
4380 len = specialElCache.length,
4385 if (el.getElementById || el.navigator) {
4387 for(; i < len; ++i){
4388 o = specialElCache[i];
4397 specialElCache.push({
4406 if(!Ext.elCache[id]){
4407 Ext.Element.addToCache(new Ext.Element(el), id);
4409 Ext.elCache[id].skipGC = true;
4417 function addListener(el, ename, fn, task, wrap, scope){
4418 el = Ext.getDom(el);
4420 es = Ext.elCache[id].events,
4423 wfn = E.on(el, ename, wrap);
4424 es[ename] = es[ename] || [];
4427 es[ename].push([fn, wrap, scope, wfn, task]);
4433 if(el.addEventListener && ename == "mousewheel"){
4434 var args = ["DOMMouseScroll", wrap, false];
4435 el.addEventListener.apply(el, args);
4436 Ext.EventManager.addListener(WINDOW, 'unload', function(){
4437 el.removeEventListener.apply(el, args);
4442 if(el == DOC && ename == "mousedown"){
4443 Ext.EventManager.stoppedMouseDownEvent.addListener(wrap);
4447 function doScrollChk(){
4454 DOC.documentElement.doScroll('left');
4463 function checkReadyState(e){
4465 if(Ext.isIE && doScrollChk()){
4468 if(DOC.readyState == COMPLETE){
4472 docReadyState || (docReadyProcId = setTimeout(arguments.callee, 2));
4477 function checkStyleSheets(e){
4478 styles || (styles = Ext.query('style, link[rel=stylesheet]'));
4479 if(styles.length == DOC.styleSheets.length){
4483 docReadyState || (docReadyProcId = setTimeout(arguments.callee, 2));
4487 function OperaDOMContentLoaded(e){
4488 DOC.removeEventListener(DOMCONTENTLOADED, arguments.callee, false);
4492 function fireDocReady(e){
4494 docReadyState = true;
4497 clearTimeout(docReadyProcId);
4500 DOC.removeEventListener(DOMCONTENTLOADED, fireDocReady, false);
4502 if(Ext.isIE && checkReadyState.bindIE){
4503 DOC.detachEvent('onreadystatechange', checkReadyState);
4505 E.un(WINDOW, "load", arguments.callee);
4507 if(docReadyEvent && !Ext.isReady){
4509 docReadyEvent.fire();
4510 docReadyEvent.listeners = [];
4515 function initDocReady(){
4516 docReadyEvent || (docReadyEvent = new Ext.util.Event());
4517 if (DETECT_NATIVE) {
4518 DOC.addEventListener(DOMCONTENTLOADED, fireDocReady, false);
4524 if(!checkReadyState()){
4525 checkReadyState.bindIE = true;
4526 DOC.attachEvent('onreadystatechange', checkReadyState);
4529 }else if(Ext.isOpera ){
4533 (DOC.readyState == COMPLETE && checkStyleSheets()) ||
4534 DOC.addEventListener(DOMCONTENTLOADED, OperaDOMContentLoaded, false);
4536 }else if (Ext.isWebKit){
4541 E.on(WINDOW, "load", fireDocReady);
4544 function createTargeted(h, o){
4546 var args = Ext.toArray(arguments);
4547 if(o.target == Ext.EventObject.setEvent(args[0]).target){
4548 h.apply(this, args);
4553 function createBuffered(h, o, task){
4556 task.delay(o.buffer, h, null, [new Ext.EventObjectImpl(e)]);
4560 function createSingle(h, el, ename, fn, scope){
4562 Ext.EventManager.removeListener(el, ename, fn, scope);
4567 function createDelayed(h, o, fn){
4569 var task = new Ext.util.DelayedTask(h);
4573 fn.tasks.push(task);
4574 task.delay(o.delay || 10, h, null, [new Ext.EventObjectImpl(e)]);
4578 function listen(element, ename, opt, fn, scope){
4579 var o = (!opt || typeof opt == "boolean") ? {} : opt,
4580 el = Ext.getDom(element), task;
4583 scope = scope || o.scope;
4586 throw "Error listening for \"" + ename + '\". Element "' + element + '" doesn\'t exist.';
4593 e = Ext.EventObject.setEvent(e);
4596 if(!(t = e.getTarget(o.delegate, el))){
4605 if (o.preventDefault) {
4608 if (o.stopPropagation) {
4609 e.stopPropagation();
4611 if (o.normalized === false) {
4615 fn.call(scope || el, e, t, o);
4618 h = createTargeted(h, o);
4621 h = createDelayed(h, o, fn);
4624 h = createSingle(h, el, ename, fn, scope);
4627 task = new Ext.util.DelayedTask(h);
4628 h = createBuffered(h, o, task);
4631 addListener(el, ename, fn, task, h, scope);
4637 addListener : function(element, eventName, fn, scope, options){
4638 if(typeof eventName == 'object'){
4639 var o = eventName, e, val;
4642 if(!propRe.test(e)){
4643 if(Ext.isFunction(val)){
4645 listen(element, e, o, val, o.scope);
4648 listen(element, e, val);
4653 listen(element, eventName, options, fn, scope);
4658 removeListener : function(el, eventName, fn, scope){
4659 el = Ext.getDom(el);
4661 f = el && (Ext.elCache[id].events)[eventName] || [],
4662 wrap, i, l, k, len, fnc;
4664 for (i = 0, len = f.length; i < len; i++) {
4667 if (Ext.isArray(fnc = f[i]) && fnc[0] == fn && (!scope || fnc[2] == scope)) {
4671 k = fn.tasks && fn.tasks.length;
4674 fn.tasks[k].cancel();
4679 E.un(el, eventName, E.extAdapter ? fnc[3] : wrap);
4682 if(wrap && el.addEventListener && eventName == "mousewheel"){
4683 el.removeEventListener("DOMMouseScroll", wrap, false);
4687 if(wrap && el == DOC && eventName == "mousedown"){
4688 Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
4692 if (f.length === 0) {
4693 delete Ext.elCache[id].events[eventName];
4695 for (k in Ext.elCache[id].events) {
4698 Ext.elCache[id].events = {};
4705 removeAll : function(el){
4706 el = Ext.getDom(el);
4708 ec = Ext.elCache[id] || {},
4709 es = ec.events || {},
4710 f, i, len, ename, fn, k, wrap;
4713 if(es.hasOwnProperty(ename)){
4716 for (i = 0, len = f.length; i < len; i++) {
4721 if(fn[0].tasks && (k = fn[0].tasks.length)) {
4723 fn[0].tasks[k].cancel();
4728 E.un(el, ename, E.extAdapter ? fn[3] : wrap);
4731 if(el.addEventListener && wrap && ename == "mousewheel"){
4732 el.removeEventListener("DOMMouseScroll", wrap, false);
4736 if(wrap && el == DOC && ename == "mousedown"){
4737 Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
4742 if (Ext.elCache[id]) {
4743 Ext.elCache[id].events = {};
4747 getListeners : function(el, eventName) {
4748 el = Ext.getDom(el);
4750 ec = Ext.elCache[id] || {},
4751 es = ec.events || {},
4753 if (es && es[eventName]) {
4754 return es[eventName];
4760 purgeElement : function(el, recurse, eventName) {
4761 el = Ext.getDom(el);
4763 ec = Ext.elCache[id] || {},
4764 es = ec.events || {},
4767 if (es && es.hasOwnProperty(eventName)) {
4769 for (i = 0, len = f.length; i < len; i++) {
4770 Ext.EventManager.removeListener(el, eventName, f[i][0]);
4774 Ext.EventManager.removeAll(el);
4776 if (recurse && el && el.childNodes) {
4777 for (i = 0, len = el.childNodes.length; i < len; i++) {
4778 Ext.EventManager.purgeElement(el.childNodes[i], recurse, eventName);
4783 _unload : function() {
4785 for (el in Ext.elCache) {
4786 Ext.EventManager.removeAll(el);
4789 delete Ext.Element._flyweights;
4795 ajax = Ext.lib.Ajax;
4796 (typeof ajax.conn == 'object') ? conn = ajax.conn : conn = {};
4800 ajax.abort({conn: c, tId: tid});
4805 onDocumentReady : function(fn, scope, options){
4807 docReadyEvent || (docReadyEvent = new Ext.util.Event());
4808 docReadyEvent.addListener(fn, scope, options);
4809 docReadyEvent.fire();
4810 docReadyEvent.listeners = [];
4812 if (!docReadyEvent) {
4815 options = options || {};
4816 options.delay = options.delay || 1;
4817 docReadyEvent.addListener(fn, scope, options);
4822 fireDocReady : fireDocReady
4825 pub.on = pub.addListener;
4827 pub.un = pub.removeListener;
4829 pub.stoppedMouseDownEvent = new Ext.util.Event();
4833 Ext.onReady = Ext.EventManager.onDocumentReady;
4838 var initExtCss = function() {
4840 var bd = document.body || document.getElementsByTagName('body')[0];
4846 Ext.isIE ? "ext-ie " + (Ext.isIE6 ? 'ext-ie6' : (Ext.isIE7 ? 'ext-ie7' : 'ext-ie8'))
4847 : Ext.isGecko ? "ext-gecko " + (Ext.isGecko2 ? 'ext-gecko2' : 'ext-gecko3')
4848 : Ext.isOpera ? "ext-opera"
4849 : Ext.isWebKit ? "ext-webkit" : ""];
4852 cls.push("ext-safari " + (Ext.isSafari2 ? 'ext-safari2' : (Ext.isSafari3 ? 'ext-safari3' : 'ext-safari4')));
4853 } else if(Ext.isChrome) {
4854 cls.push("ext-chrome");
4858 cls.push("ext-mac");
4861 cls.push("ext-linux");
4865 if (Ext.isStrict || Ext.isBorderBox) {
4866 var p = bd.parentNode;
4868 Ext.fly(p, '_internal').addClass(((Ext.isStrict && Ext.isIE ) || (!Ext.enableForcedBoxModel && !Ext.isIE)) ? ' ext-strict' : ' ext-border-box');
4873 if (Ext.enableForcedBoxModel && !Ext.isIE) {
4874 Ext.isForcedBorderBox = true;
4875 cls.push("ext-forced-border-box");
4878 Ext.fly(bd, '_internal').addClass(cls);
4882 if (!initExtCss()) {
4883 Ext.onReady(initExtCss);
4889 var supports = Ext.apply(Ext.supports, {
4891 correctRightMargin: true,
4894 correctTransparentColor: true,
4900 var supportTests = function(){
4901 var div = document.createElement('div'),
4906 div.innerHTML = '<div style="height:30px;width:50px;"><div style="height:20px;width:20px;"></div></div><div style="float:left;background-color:transparent;">';
4907 doc.body.appendChild(div);
4908 last = div.lastChild;
4910 if((view = doc.defaultView)){
4911 if(view.getComputedStyle(div.firstChild.firstChild, null).marginRight != '0px'){
4912 supports.correctRightMargin = false;
4914 if(view.getComputedStyle(last, null).backgroundColor != 'transparent'){
4915 supports.correctTransparentColor = false;
4918 supports.cssFloat = !!last.style.cssFloat;
4919 doc.body.removeChild(div);
4925 Ext.onReady(supportTests);
4931 Ext.EventObject = function(){
4932 var E = Ext.lib.Event,
4933 clickRe = /(dbl)?click/,
4948 btnMap = Ext.isIE ? {1:0,4:1,2:2} : {0:0,1:1,2:2};
4950 Ext.EventObjectImpl = function(e){
4952 this.setEvent(e.browserEvent || e);
4956 Ext.EventObjectImpl.prototype = {
4958 setEvent : function(e){
4960 if(e == me || (e && e.browserEvent)){
4963 me.browserEvent = e;
4966 me.button = e.button ? btnMap[e.button] : (e.which ? e.which - 1 : -1);
4967 if(clickRe.test(e.type) && me.button == -1){
4971 me.shiftKey = e.shiftKey;
4973 me.ctrlKey = e.ctrlKey || e.metaKey || false;
4974 me.altKey = e.altKey;
4976 me.keyCode = e.keyCode;
4977 me.charCode = e.charCode;
4979 me.target = E.getTarget(e);
4984 me.shiftKey = false;
4996 stopEvent : function(){
4998 if(me.browserEvent){
4999 if(me.browserEvent.type == 'mousedown'){
5000 Ext.EventManager.stoppedMouseDownEvent.fire(me);
5002 E.stopEvent(me.browserEvent);
5007 preventDefault : function(){
5008 if(this.browserEvent){
5009 E.preventDefault(this.browserEvent);
5014 stopPropagation : function(){
5016 if(me.browserEvent){
5017 if(me.browserEvent.type == 'mousedown'){
5018 Ext.EventManager.stoppedMouseDownEvent.fire(me);
5020 E.stopPropagation(me.browserEvent);
5025 getCharCode : function(){
5026 return this.charCode || this.keyCode;
5030 getKey : function(){
5031 return this.normalizeKey(this.keyCode || this.charCode);
5035 normalizeKey: function(k){
5036 return Ext.isSafari ? (safariKeys[k] || k) : k;
5040 getPageX : function(){
5045 getPageY : function(){
5055 getTarget : function(selector, maxDepth, returnEl){
5056 return selector ? Ext.fly(this.target).findParent(selector, maxDepth, returnEl) : (returnEl ? Ext.get(this.target) : this.target);
5060 getRelatedTarget : function(){
5061 return this.browserEvent ? E.getRelatedTarget(this.browserEvent) : null;
5065 getWheelDelta : function(){
5066 var e = this.browserEvent;
5069 delta = e.wheelDelta/120;
5071 delta = -e.detail/3;
5077 within : function(el, related, allowEl){
5079 var t = this[related ? "getRelatedTarget" : "getTarget"]();
5080 return t && ((allowEl ? (t == Ext.getDom(el)) : false) || Ext.fly(el).contains(t));
5086 return new Ext.EventObjectImpl();
5089 Ext.Loader = Ext.apply({}, {
5091 load: function(fileList, callback, scope, preserveOrder) {
5092 var scope = scope || this,
5093 head = document.getElementsByTagName("head")[0],
5094 fragment = document.createDocumentFragment(),
5095 numFiles = fileList.length,
5100 var loadFileIndex = function(index) {
5102 me.buildScriptTag(fileList[index], onFileLoaded)
5107 var onFileLoaded = function() {
5111 if (numFiles == loadedFiles && typeof callback == 'function') {
5112 callback.call(scope);
5114 if (preserveOrder === true) {
5115 loadFileIndex(loadedFiles);
5120 if (preserveOrder === true) {
5121 loadFileIndex.call(this, 0);
5124 Ext.each(fileList, function(file, index) {
5125 fragment.appendChild(
5126 this.buildScriptTag(file, onFileLoaded)
5130 head.appendChild(fragment);
5135 buildScriptTag: function(filename, callback) {
5136 var script = document.createElement('script');
5137 script.type = "text/javascript";
5138 script.src = filename;
5141 if (script.readyState) {
5142 script.onreadystatechange = function() {
5143 if (script.readyState == "loaded" || script.readyState == "complete") {
5144 script.onreadystatechange = null;
5149 script.onload = callback;
5157 Ext.ns("Ext.grid", "Ext.list", "Ext.dd", "Ext.tree", "Ext.form", "Ext.menu",
5158 "Ext.state", "Ext.layout", "Ext.app", "Ext.ux", "Ext.chart", "Ext.direct");
5161 Ext.apply(Ext, function(){
5168 emptyFn : function(){},
5171 BLANK_IMAGE_URL : Ext.isIE6 || Ext.isIE7 || Ext.isAir ?
5172 'http:/' + '/www.extjs.com/s.gif' :
5173 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
5175 extendX : function(supr, fn){
5176 return Ext.extend(supr, fn(supr.prototype));
5180 getDoc : function(){
5181 return Ext.get(document);
5185 num : function(v, defaultValue){
5186 v = Number(Ext.isEmpty(v) || Ext.isArray(v) || typeof v == 'boolean' || (typeof v == 'string' && v.trim().length == 0) ? NaN : v);
5187 return isNaN(v) ? defaultValue : v;
5191 value : function(v, defaultValue, allowBlank){
5192 return Ext.isEmpty(v, allowBlank) ? defaultValue : v;
5196 escapeRe : function(s) {
5197 return s.replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1");
5200 sequence : function(o, name, fn, scope){
5201 o[name] = o[name].createSequence(fn, scope);
5205 addBehaviors : function(o){
5207 Ext.onReady(function(){
5208 Ext.addBehaviors(o);
5216 if ((parts = b.split('@'))[1]) {
5219 cache[s] = Ext.select(s);
5221 cache[s].on(parts[1], o[b]);
5229 getScrollBarWidth: function(force){
5234 if(force === true || scrollWidth === null){
5236 var div = Ext.getBody().createChild('<div class="x-hide-offsets" style="width:100px;height:50px;overflow:hidden;"><div style="height:200px;"></div></div>'),
5237 child = div.child('div', true);
5238 var w1 = child.offsetWidth;
5239 div.setStyle('overflow', (Ext.isWebKit || Ext.isGecko) ? 'auto' : 'scroll');
5240 var w2 = child.offsetWidth;
5243 scrollWidth = w1 - w2 + 2;
5250 combine : function(){
5251 var as = arguments, l = as.length, r = [];
5252 for(var i = 0; i < l; i++){
5256 }else if(a.length !== undefined && !a.substr){
5257 r = r.concat(Array.prototype.slice.call(a, 0));
5266 copyTo : function(dest, source, names){
5267 if(typeof names == 'string'){
5268 names = names.split(/[,;\s]/);
5270 Ext.each(names, function(name){
5271 if(source.hasOwnProperty(name)){
5272 dest[name] = source[name];
5279 destroy : function(){
5280 Ext.each(arguments, function(arg){
5282 if(Ext.isArray(arg)){
5283 this.destroy.apply(this, arg);
5284 }else if(typeof arg.destroy == 'function'){
5294 destroyMembers : function(o, arg1, arg2, etc){
5295 for(var i = 1, a = arguments, len = a.length; i < len; i++) {
5296 Ext.destroy(o[a[i]]);
5302 clean : function(arr){
5304 Ext.each(arr, function(v){
5313 unique : function(arr){
5317 Ext.each(arr, function(v) {
5327 flatten : function(arr){
5329 function rFlatten(a) {
5330 Ext.each(a, function(v) {
5339 return rFlatten(arr);
5343 min : function(arr, comp){
5345 comp = comp || function(a,b){ return a < b ? -1 : 1; };
5346 Ext.each(arr, function(v) {
5347 ret = comp(ret, v) == -1 ? ret : v;
5353 max : function(arr, comp){
5355 comp = comp || function(a,b){ return a > b ? 1 : -1; };
5356 Ext.each(arr, function(v) {
5357 ret = comp(ret, v) == 1 ? ret : v;
5363 mean : function(arr){
5364 return arr.length > 0 ? Ext.sum(arr) / arr.length : undefined;
5368 sum : function(arr){
5370 Ext.each(arr, function(v) {
5377 partition : function(arr, truth){
5379 Ext.each(arr, function(v, i, a) {
5380 ret[ (truth && truth(v, i, a)) || (!truth && v) ? 0 : 1].push(v);
5386 invoke : function(arr, methodName){
5388 args = Array.prototype.slice.call(arguments, 2);
5389 Ext.each(arr, function(v,i) {
5390 if (v && typeof v[methodName] == 'function') {
5391 ret.push(v[methodName].apply(v, args));
5393 ret.push(undefined);
5400 pluck : function(arr, prop){
5402 Ext.each(arr, function(v) {
5403 ret.push( v[prop] );
5410 var parts = Ext.partition(arguments, function( val ){ return typeof val != 'function'; }),
5413 len = Ext.max(Ext.pluck(arrs, "length")),
5416 for (var i = 0; i < len; i++) {
5419 ret[i] = fn.apply(fn, Ext.pluck(arrs, i));
5421 for (var j = 0, aLen = arrs.length; j < aLen; j++){
5422 ret[i].push( arrs[j][i] );
5430 getCmp : function(id){
5431 return Ext.ComponentMgr.get(id);
5435 useShims: E.isIE6 || (E.isMac && E.isGecko2),
5440 if(o === undefined || o === null){
5447 if(t == 'object' && o.nodeName) {
5448 switch(o.nodeType) {
5449 case 1: return 'element';
5450 case 3: return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace';
5453 if(t == 'object' || t == 'function') {
5454 switch(o.constructor) {
5455 case Array: return 'array';
5456 case RegExp: return 'regexp';
5457 case Date: return 'date';
5459 if(typeof o.length == 'number' && typeof o.item == 'function') {
5466 intercept : function(o, name, fn, scope){
5467 o[name] = o[name].createInterceptor(fn, scope);
5471 callback : function(cb, scope, args, delay){
5472 if(typeof cb == 'function'){
5474 cb.defer(delay, scope, args || []);
5476 cb.apply(scope, args || []);
5484 Ext.apply(Function.prototype, {
5486 createSequence : function(fcn, scope){
5488 return (typeof fcn != 'function') ?
5491 var retval = method.apply(this || window, arguments);
5492 fcn.apply(scope || this || window, arguments);
5500 Ext.applyIf(String, {
5503 escape : function(string) {
5504 return string.replace(/('|\\)/g, "\\$1");
5508 leftPad : function (val, size, ch) {
5509 var result = String(val);
5513 while (result.length < size) {
5514 result = ch + result;
5521 String.prototype.toggle = function(value, other){
5522 return this == value ? other : value;
5526 String.prototype.trim = function(){
5527 var re = /^\s+|\s+$/g;
5528 return function(){ return this.replace(re, ""); };
5533 Date.prototype.getElapsed = function(date) {
5534 return Math.abs((date || new Date()).getTime()-this.getTime());
5539 Ext.applyIf(Number.prototype, {
5541 constrain : function(min, max){
5542 return Math.min(Math.max(this, min), max);
5545 Ext.lib.Dom.getRegion = function(el) {
5546 return Ext.lib.Region.getRegion(el);
5547 }; Ext.lib.Region = function(t, r, b, l) {
5557 Ext.lib.Region.prototype = {
5558 contains : function(region) {
5560 return ( region.left >= me.left &&
5561 region.right <= me.right &&
5562 region.top >= me.top &&
5563 region.bottom <= me.bottom );
5567 getArea : function() {
5569 return ( (me.bottom - me.top) * (me.right - me.left) );
5572 intersect : function(region) {
5574 t = Math.max(me.top, region.top),
5575 r = Math.min(me.right, region.right),
5576 b = Math.min(me.bottom, region.bottom),
5577 l = Math.max(me.left, region.left);
5579 if (b >= t && r >= l) {
5580 return new Ext.lib.Region(t, r, b, l);
5584 union : function(region) {
5586 t = Math.min(me.top, region.top),
5587 r = Math.max(me.right, region.right),
5588 b = Math.max(me.bottom, region.bottom),
5589 l = Math.min(me.left, region.left);
5591 return new Ext.lib.Region(t, r, b, l);
5594 constrainTo : function(r) {
5596 me.top = me.top.constrain(r.top, r.bottom);
5597 me.bottom = me.bottom.constrain(r.top, r.bottom);
5598 me.left = me.left.constrain(r.left, r.right);
5599 me.right = me.right.constrain(r.left, r.right);
5603 adjust : function(t, l, b, r) {
5613 Ext.lib.Region.getRegion = function(el) {
5614 var p = Ext.lib.Dom.getXY(el),
5616 r = p[0] + el.offsetWidth,
5617 b = p[1] + el.offsetHeight,
5620 return new Ext.lib.Region(t, r, b, l);
5621 }; Ext.lib.Point = function(x, y) {
5622 if (Ext.isArray(x)) {
5627 me.x = me.right = me.left = me[0] = x;
5628 me.y = me.top = me.bottom = me[1] = y;
5631 Ext.lib.Point.prototype = new Ext.lib.Region();
5633 Ext.apply(Ext.DomHelper,
5636 afterbegin = 'afterbegin',
5637 afterend = 'afterend',
5638 beforebegin = 'beforebegin',
5639 beforeend = 'beforeend',
5640 confRe = /tag|children|cn|html$/i;
5643 function doInsert(el, o, returnElement, pos, sibling, append){
5644 el = Ext.getDom(el);
5647 newNode = createDom(o, null);
5649 el.appendChild(newNode);
5651 (sibling == 'firstChild' ? el : el.parentNode).insertBefore(newNode, el[sibling] || el);
5654 newNode = Ext.DomHelper.insertHtml(pos, el, Ext.DomHelper.createHtml(o));
5656 return returnElement ? Ext.get(newNode, true) : newNode;
5661 function createDom(o, parentNode){
5669 if (Ext.isArray(o)) {
5670 el = doc.createDocumentFragment();
5671 for (var i = 0, l = o.length; i < l; i++) {
5672 createDom(o[i], el);
5674 } else if (typeof o == 'string') {
5675 el = doc.createTextNode(o);
5677 el = doc.createElement( o.tag || 'div' );
5678 useSet = !!el.setAttribute;
5679 for (var attr in o) {
5680 if(!confRe.test(attr)){
5686 el.setAttribute(attr, val);
5693 Ext.DomHelper.applyStyles(el, o.style);
5695 if ((cn = o.children || o.cn)) {
5697 } else if (o.html) {
5698 el.innerHTML = o.html;
5702 parentNode.appendChild(el);
5709 createTemplate : function(o){
5710 var html = Ext.DomHelper.createHtml(o);
5711 return new Ext.Template(html);
5718 insertBefore : function(el, o, returnElement){
5719 return doInsert(el, o, returnElement, beforebegin);
5723 insertAfter : function(el, o, returnElement){
5724 return doInsert(el, o, returnElement, afterend, 'nextSibling');
5728 insertFirst : function(el, o, returnElement){
5729 return doInsert(el, o, returnElement, afterbegin, 'firstChild');
5733 append: function(el, o, returnElement){
5734 return doInsert(el, o, returnElement, beforeend, '', true);
5738 createDom: createDom
5743 Ext.apply(Ext.Template.prototype, {
5745 disableFormats : false,
5749 re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
5750 argsRe : /^\s*['"](.*)["']\s*$/,
5752 compileBRe : /(\r\n|\n)/g,
5756 * Returns an HTML fragment of this template with the specified values applied.
5757 * @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'})
5758 * @return {String} The HTML fragment
5761 applyTemplate : function(values){
5763 useF = me.disableFormats !== true,
5764 fm = Ext.util.Format,
5768 return me.compiled(values);
5770 function fn(m, name, format, args){
5771 if (format && useF) {
5772 if (format.substr(0, 5) == "this.") {
5773 return tpl.call(format.substr(5), values[name], values);
5776 // quoted values are required for strings in compiled templates,
5777 // but for non compiled we need to strip them
5778 // quoted reversed for jsmin
5780 args = args.split(',');
5781 for(var i = 0, len = args.length; i < len; i++){
5782 args[i] = args[i].replace(re, "$1");
5784 args = [values[name]].concat(args);
5786 args = [values[name]];
5788 return fm[format].apply(fm, args);
5791 return values[name] !== undefined ? values[name] : "";
5794 return me.html.replace(me.re, fn);
5798 * Compiles the template into an internal function, eliminating the RegEx overhead.
5799 * @return {Ext.Template} this
5802 compile : function(){
5804 fm = Ext.util.Format,
5805 useF = me.disableFormats !== true,
5806 sep = Ext.isGecko ? "+" : ",",
5809 function fn(m, name, format, args){
5811 args = args ? ',' + args : "";
5812 if(format.substr(0, 5) != "this."){
5813 format = "fm." + format + '(';
5815 format = 'this.call("'+ format.substr(5) + '", ';
5819 args= ''; format = "(values['" + name + "'] == undefined ? '' : ";
5821 return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'";
5824 // branched to use + in gecko and [].join() in others
5826 body = "this.compiled = function(values){ return '" +
5827 me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn) +
5830 body = ["this.compiled = function(values){ return ['"];
5831 body.push(me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn));
5832 body.push("'].join('');};");
5833 body = body.join('');
5839 // private function used to call members
5840 call : function(fnName, value, allValues){
5841 return this[fnName](value, allValues);
5844 Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;
5846 * @class Ext.util.Functions
5849 Ext.util.Functions = {
5851 * Creates an interceptor function. The passed function is called before the original one. If it returns false,
5852 * the original one is not called. The resulting function returns the results of the original function.
5853 * The passed function is called with the parameters of the original function. Example usage:
5855 var sayHi = function(name){
5856 alert('Hi, ' + name);
5859 sayHi('Fred'); // alerts "Hi, Fred"
5861 // create a new function that validates input without
5862 // directly modifying the original function:
5863 var sayHiToFriend = Ext.createInterceptor(sayHi, function(name){
5864 return name == 'Brian';
5867 sayHiToFriend('Fred'); // no alert
5868 sayHiToFriend('Brian'); // alerts "Hi, Brian"
5870 * @param {Function} origFn The original function.
5871 * @param {Function} newFn The function to call before the original
5872 * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the passed function is executed.
5873 * <b>If omitted, defaults to the scope in which the original function is called or the browser window.</b>
5874 * @return {Function} The new function
5876 createInterceptor: function(origFn, newFn, scope) {
5877 var method = origFn;
5878 if (!Ext.isFunction(newFn)) {
5886 newFn.method = origFn;
5887 return (newFn.apply(scope || me || window, args) !== false) ?
5888 origFn.apply(me || window, args) :
5895 * Creates a delegate (callback) that sets the scope to obj.
5896 * Call directly on any function. Example: <code>Ext.createDelegate(this.myFunction, this, [arg1, arg2])</code>
5897 * Will create a function that is automatically scoped to obj so that the <tt>this</tt> variable inside the
5898 * callback points to obj. Example usage:
5900 var sayHi = function(name){
5901 // Note this use of "this.text" here. This function expects to
5902 // execute within a scope that contains a text property. In this
5903 // example, the "this" variable is pointing to the btn object that
5904 // was passed in createDelegate below.
5905 alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.');
5908 var btn = new Ext.Button({
5910 renderTo: Ext.getBody()
5913 // This callback will execute in the scope of the
5914 // button instance. Clicking the button alerts
5915 // "Hi, Fred. You clicked the "Say Hi" button."
5916 btn.on('click', Ext.createDelegate(sayHi, btn, ['Fred']));
5918 * @param {Function} fn The function to delegate.
5919 * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
5920 * <b>If omitted, defaults to the browser window.</b>
5921 * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
5922 * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
5923 * if a number the args are inserted at the specified position
5924 * @return {Function} The new function
5926 createDelegate: function(fn, obj, args, appendArgs) {
5927 if (!Ext.isFunction(fn)) {
5931 var callArgs = args || arguments;
5932 if (appendArgs === true) {
5933 callArgs = Array.prototype.slice.call(arguments, 0);
5934 callArgs = callArgs.concat(args);
5936 else if (Ext.isNumber(appendArgs)) {
5937 callArgs = Array.prototype.slice.call(arguments, 0);
5938 // copy arguments first
5939 var applyArgs = [appendArgs, 0].concat(args);
5940 // create method call params
5941 Array.prototype.splice.apply(callArgs, applyArgs);
5944 return fn.apply(obj || window, callArgs);
5949 * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage:
5951 var sayHi = function(name){
5952 alert('Hi, ' + name);
5955 // executes immediately:
5958 // executes after 2 seconds:
5959 Ext.defer(sayHi, 2000, this, ['Fred']);
5961 // this syntax is sometimes useful for deferring
5962 // execution of an anonymous function:
5963 Ext.defer(function(){
5967 * @param {Function} fn The function to defer.
5968 * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)
5969 * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
5970 * <b>If omitted, defaults to the browser window.</b>
5971 * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
5972 * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
5973 * if a number the args are inserted at the specified position
5974 * @return {Number} The timeout id that can be used with clearTimeout
5976 defer: function(fn, millis, obj, args, appendArgs) {
5977 fn = Ext.util.Functions.createDelegate(fn, obj, args, appendArgs);
5979 return setTimeout(fn, millis);
5987 * Create a combined function call sequence of the original function + the passed function.
5988 * The resulting function returns the results of the original function.
5989 * The passed fcn is called with the parameters of the original function. Example usage:
5992 var sayHi = function(name){
5993 alert('Hi, ' + name);
5996 sayHi('Fred'); // alerts "Hi, Fred"
5998 var sayGoodbye = Ext.createSequence(sayHi, function(name){
5999 alert('Bye, ' + name);
6002 sayGoodbye('Fred'); // both alerts show
6004 * @param {Function} origFn The original function.
6005 * @param {Function} newFn The function to sequence
6006 * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed.
6007 * If omitted, defaults to the scope in which the original function is called or the browser window.
6008 * @return {Function} The new function
6010 createSequence: function(origFn, newFn, scope) {
6011 if (!Ext.isFunction(newFn)) {
6016 var retval = origFn.apply(this || window, arguments);
6017 newFn.apply(scope || this || window, arguments);
6025 * Shorthand for {@link Ext.util.Functions#defer}
6026 * @param {Function} fn The function to defer.
6027 * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)
6028 * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
6029 * <b>If omitted, defaults to the browser window.</b>
6030 * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
6031 * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
6032 * if a number the args are inserted at the specified position
6033 * @return {Number} The timeout id that can be used with clearTimeout
6038 Ext.defer = Ext.util.Functions.defer;
6041 * Shorthand for {@link Ext.util.Functions#createInterceptor}
6042 * @param {Function} origFn The original function.
6043 * @param {Function} newFn The function to call before the original
6044 * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the passed function is executed.
6045 * <b>If omitted, defaults to the scope in which the original function is called or the browser window.</b>
6046 * @return {Function} The new function
6051 Ext.createInterceptor = Ext.util.Functions.createInterceptor;
6054 * Shorthand for {@link Ext.util.Functions#createSequence}
6055 * @param {Function} origFn The original function.
6056 * @param {Function} newFn The function to sequence
6057 * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed.
6058 * If omitted, defaults to the scope in which the original function is called or the browser window.
6059 * @return {Function} The new function
6064 Ext.createSequence = Ext.util.Functions.createSequence;
6067 * Shorthand for {@link Ext.util.Functions#createDelegate}
6068 * @param {Function} fn The function to delegate.
6069 * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
6070 * <b>If omitted, defaults to the browser window.</b>
6071 * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
6072 * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
6073 * if a number the args are inserted at the specified position
6074 * @return {Function} The new function
6078 Ext.createDelegate = Ext.util.Functions.createDelegate;
6080 * @class Ext.util.Observable
6082 Ext.apply(Ext.util.Observable.prototype, function(){
6083 // this is considered experimental (along with beforeMethod, afterMethod, removeMethodListener?)
6084 // allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call
6086 function getMethodEvent(method){
6087 var e = (this.methodEvents = this.methodEvents ||
6088 {})[method], returnValue, v, cancel, obj = this;
6091 this.methodEvents[method] = e = {};
6092 e.originalFn = this[method];
6093 e.methodName = method;
6097 var makeCall = function(fn, scope, args){
6098 if((v = fn.apply(scope || obj, args)) !== undefined){
6099 if (typeof v == 'object') {
6100 if(v.returnValue !== undefined){
6101 returnValue = v.returnValue;
6105 cancel = !!v.cancel;
6117 this[method] = function(){
6118 var args = Array.prototype.slice.call(arguments, 0),
6120 returnValue = v = undefined;
6123 for(var i = 0, len = e.before.length; i < len; i++){
6125 makeCall(b.fn, b.scope, args);
6131 if((v = e.originalFn.apply(obj, args)) !== undefined){
6135 for(var i = 0, len = e.after.length; i < len; i++){
6137 makeCall(b.fn, b.scope, args);
6149 // these are considered experimental
6150 // allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call
6151 // adds an 'interceptor' called before the original method
6152 beforeMethod : function(method, fn, scope){
6153 getMethodEvent.call(this, method).before.push({
6159 // adds a 'sequence' called after the original method
6160 afterMethod : function(method, fn, scope){
6161 getMethodEvent.call(this, method).after.push({
6167 removeMethodListener: function(method, fn, scope){
6168 var e = this.getMethodEvent(method);
6169 for(var i = 0, len = e.before.length; i < len; i++){
6170 if(e.before[i].fn == fn && e.before[i].scope == scope){
6171 e.before.splice(i, 1);
6175 for(var i = 0, len = e.after.length; i < len; i++){
6176 if(e.after[i].fn == fn && e.after[i].scope == scope){
6177 e.after.splice(i, 1);
6184 * Relays selected events from the specified Observable as if the events were fired by <tt><b>this</b></tt>.
6185 * @param {Object} o The Observable whose events this object is to relay.
6186 * @param {Array} events Array of event names to relay.
6188 relayEvents : function(o, events){
6190 function createHandler(ename){
6192 return me.fireEvent.apply(me, [ename].concat(Array.prototype.slice.call(arguments, 0)));
6195 for(var i = 0, len = events.length; i < len; i++){
6196 var ename = events[i];
6197 me.events[ename] = me.events[ename] || true;
6198 o.on(ename, createHandler(ename), me);
6203 * <p>Enables events fired by this Observable to bubble up an owner hierarchy by calling
6204 * <code>this.getBubbleTarget()</code> if present. There is no implementation in the Observable base class.</p>
6205 * <p>This is commonly used by Ext.Components to bubble events to owner Containers. See {@link Ext.Component.getBubbleTarget}. The default
6206 * implementation in Ext.Component returns the Component's immediate owner. But if a known target is required, this can be overridden to
6207 * access the required target more quickly.</p>
6208 * <p>Example:</p><pre><code>
6209 Ext.override(Ext.form.Field, {
6211 initComponent : Ext.form.Field.prototype.initComponent.createSequence(function() {
6212 this.enableBubble('change');
6216 getBubbleTarget : function() {
6217 if (!this.formPanel) {
6218 this.formPanel = this.findParentByType('form');
6220 return this.formPanel;
6224 var myForm = new Ext.formPanel({
6225 title: 'User Details',
6230 change: function() {
6232 myForm.header.setStyle('color', 'red');
6237 * @param {String/Array} events The event name to bubble, or an Array of event names.
6239 enableBubble : function(events){
6241 if(!Ext.isEmpty(events)){
6242 events = Ext.isArray(events) ? events : Array.prototype.slice.call(arguments, 0);
6243 for(var i = 0, len = events.length; i < len; i++){
6244 var ename = events[i];
6245 ename = ename.toLowerCase();
6246 var ce = me.events[ename] || true;
6247 if (typeof ce == 'boolean') {
6248 ce = new Ext.util.Event(me, ename);
6249 me.events[ename] = ce;
6260 Ext.util.Observable.capture = function(o, fn, scope){
6261 o.fireEvent = o.fireEvent.createInterceptor(fn, scope);
6266 Ext.util.Observable.observeClass = function(c, listeners){
6269 Ext.apply(c, new Ext.util.Observable());
6270 Ext.util.Observable.capture(c.prototype, c.fireEvent, c);
6272 if(typeof listeners == 'object'){
6279 Ext.apply(Ext.EventManager, function(){
6285 propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,
6291 useKeydown = Ext.isWebKit ?
6292 Ext.num(navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1]) >= 525 :
6293 !((Ext.isGecko && !Ext.isWindows) || Ext.isOpera);
6297 doResizeEvent: function(){
6298 var h = D.getViewHeight(),
6299 w = D.getViewWidth();
6302 if(curHeight != h || curWidth != w){
6303 resizeEvent.fire(curWidth = w, curHeight = h);
6308 onWindowResize : function(fn, scope, options){
6310 resizeEvent = new Ext.util.Event();
6311 resizeTask = new Ext.util.DelayedTask(this.doResizeEvent);
6312 Ext.EventManager.on(window, "resize", this.fireWindowResize, this);
6314 resizeEvent.addListener(fn, scope, options);
6318 fireWindowResize : function(){
6320 resizeTask.delay(100);
6325 onTextResize : function(fn, scope, options){
6327 textEvent = new Ext.util.Event();
6328 var textEl = new Ext.Element(document.createElement('div'));
6329 textEl.dom.className = 'x-text-resize';
6330 textEl.dom.innerHTML = 'X';
6331 textEl.appendTo(document.body);
6332 textSize = textEl.dom.offsetHeight;
6333 setInterval(function(){
6334 if(textEl.dom.offsetHeight != textSize){
6335 textEvent.fire(textSize, textSize = textEl.dom.offsetHeight);
6337 }, this.textResizeInterval);
6339 textEvent.addListener(fn, scope, options);
6343 removeResizeListener : function(fn, scope){
6345 resizeEvent.removeListener(fn, scope);
6350 fireResize : function(){
6352 resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
6357 textResizeInterval : 50,
6363 getKeyEvent : function(){
6364 return useKeydown ? 'keydown' : 'keypress';
6369 useKeydown: useKeydown
6373 Ext.EventManager.on = Ext.EventManager.addListener;
6376 Ext.apply(Ext.EventObjectImpl.prototype, {
6556 isNavKeyPress : function(){
6558 k = this.normalizeKey(me.keyCode);
6559 return (k >= 33 && k <= 40) ||
6565 isSpecialKey : function(){
6566 var k = this.normalizeKey(this.keyCode);
6567 return (this.type == 'keypress' && this.ctrlKey) ||
6568 this.isNavKeyPress() ||
6569 (k == this.BACKSPACE) ||
6570 (k >= 16 && k <= 20) ||
6571 (k >= 44 && k <= 46);
6574 getPoint : function(){
6575 return new Ext.lib.Point(this.xy[0], this.xy[1]);
6579 hasModifier : function(){
6580 return ((this.ctrlKey || this.altKey) || this.shiftKey);
6583 Ext.Element.addMethods({
6585 swallowEvent : function(eventName, preventDefault) {
6588 e.stopPropagation();
6589 if (preventDefault) {
6594 if (Ext.isArray(eventName)) {
6595 Ext.each(eventName, function(e) {
6600 me.on(eventName, fn);
6605 relayEvent : function(eventName, observable) {
6606 this.on(eventName, function(e) {
6607 observable.fireEvent(eventName, e);
6612 clean : function(forceReclean) {
6618 if (Ext.Element.data(dom, 'isCleaned') && forceReclean !== true) {
6623 var nx = n.nextSibling;
6624 if (n.nodeType == 3 && !(/\S/.test(n.nodeValue))) {
6632 Ext.Element.data(dom, 'isCleaned', true);
6638 var updateManager = this.getUpdater();
6639 updateManager.update.apply(updateManager, arguments);
6645 getUpdater : function() {
6646 return this.updateManager || (this.updateManager = new Ext.Updater(this));
6650 update : function(html, loadScripts, callback) {
6656 if (loadScripts !== true) {
6657 this.dom.innerHTML = html;
6658 if (typeof callback == 'function') {
6667 html += '<span id="' + id + '"></span>';
6669 Ext.lib.Event.onAvailable(id, function() {
6671 hd = DOC.getElementsByTagName("head")[0],
6672 re = /(?:<script([^>]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig,
6673 srcRe = /\ssrc=([\'\"])(.*?)\1/i,
6674 typeRe = /\stype=([\'\"])(.*?)\1/i,
6682 while ((match = re.exec(html))) {
6684 srcMatch = attrs ? attrs.match(srcRe) : false;
6685 if (srcMatch && srcMatch[2]) {
6686 s = DOC.createElement("script");
6687 s.src = srcMatch[2];
6688 typeMatch = attrs.match(typeRe);
6689 if (typeMatch && typeMatch[2]) {
6690 s.type = typeMatch[2];
6693 } else if (match[2] && match[2].length > 0) {
6694 if (window.execScript) {
6695 window.execScript(match[2]);
6697 window.eval(match[2]);
6702 el = DOC.getElementById(id);
6707 if (typeof callback == 'function') {
6711 dom.innerHTML = html.replace(/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig, "");
6716 removeAllListeners : function() {
6717 this.removeAnchor();
6718 Ext.EventManager.removeAll(this.dom);
6723 createProxy : function(config, renderTo, matchBox) {
6724 config = (typeof config == 'object') ? config : {tag : "div", cls: config};
6727 proxy = renderTo ? Ext.DomHelper.append(renderTo, config, true) :
6728 Ext.DomHelper.insertBefore(me.dom, config, true);
6730 if (matchBox && me.setBox && me.getBox) {
6731 proxy.setBox(me.getBox());
6737 Ext.Element.prototype.getUpdateManager = Ext.Element.prototype.getUpdater;
6739 Ext.Element.addMethods({
6741 getAnchorXY : function(anchor, local, s){
6744 anchor = (anchor || "tl").toLowerCase();
6748 vp = me.dom == document.body || me.dom == document,
6749 w = s.width || vp ? Ext.lib.Dom.getViewWidth() : me.getWidth(),
6750 h = s.height || vp ? Ext.lib.Dom.getViewHeight() : me.getHeight(),
6754 scroll = me.getScroll(),
6755 extraX = vp ? scroll.left : !local ? o[0] : 0,
6756 extraY = vp ? scroll.top : !local ? o[1] : 0,
6758 c : [r(w * 0.5), r(h * 0.5)],
6759 t : [r(w * 0.5), 0],
6760 l : [0, r(h * 0.5)],
6761 r : [w, r(h * 0.5)],
6762 b : [r(w * 0.5), h],
6770 return [xy[0] + extraX, xy[1] + extraY];
6774 anchorTo : function(el, alignment, offsets, animate, monitorScroll, callback){
6777 scroll = !Ext.isEmpty(monitorScroll),
6778 action = function(){
6779 Ext.fly(dom).alignTo(el, alignment, offsets, animate);
6780 Ext.callback(callback, Ext.fly(dom));
6782 anchor = this.getAnchor();
6785 this.removeAnchor();
6791 Ext.EventManager.onWindowResize(action, null);
6794 Ext.EventManager.on(window, 'scroll', action, null,
6795 {buffer: !isNaN(monitorScroll) ? monitorScroll : 50});
6802 removeAnchor : function(){
6804 anchor = this.getAnchor();
6806 if(anchor && anchor.fn){
6807 Ext.EventManager.removeResizeListener(anchor.fn);
6809 Ext.EventManager.un(window, 'scroll', anchor.fn);
6817 getAnchor : function(){
6818 var data = Ext.Element.data,
6823 var anchor = data(dom, '_anchor');
6826 anchor = data(dom, '_anchor', {});
6832 getAlignToXY : function(el, p, o){
6836 throw "Element.alignToXY with an element that doesn't exist";
6840 p = (!p || p == "?" ? "tl-bl?" : (!(/-/).test(p) && p !== "" ? "tl-" + p : p || "tl-bl")).toLowerCase();
6852 dw = Ext.lib.Dom.getViewWidth() -10,
6853 dh = Ext.lib.Dom.getViewHeight()-10,
6861 docElement = doc.documentElement,
6863 scrollX = (docElement.scrollLeft || docBody.scrollLeft || 0)+5,
6864 scrollY = (docElement.scrollTop || docBody.scrollTop || 0)+5,
6868 m = p.match(/^([a-z]+)-([a-z]+)(\?)?$/);
6871 throw "Element.alignTo with an invalid alignment " + p;
6880 a1 = me.getAnchorXY(p1, true);
6881 a2 = el.getAnchorXY(p2, false);
6883 x = a2[0] - a1[0] + o[0];
6884 y = a2[1] - a1[1] + o[1];
6894 p1x = p1.charAt(p1.length-1);
6896 p2x = p2.charAt(p2.length-1);
6897 swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t"));
6898 swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r"));
6901 if (x + w > dw + scrollX) {
6902 x = swapX ? r.left-w : dw+scrollX-w;
6905 x = swapX ? r.right : scrollX;
6907 if (y + h > dh + scrollY) {
6908 y = swapY ? r.top-h : dh+scrollY-h;
6911 y = swapY ? r.bottom : scrollY;
6918 alignTo : function(element, position, offsets, animate){
6920 return me.setXY(me.getAlignToXY(element, position, offsets),
6921 me.preanim && !!animate ? me.preanim(arguments, 3) : false);
6925 adjustForConstraints : function(xy, parent, offsets){
6926 return this.getConstrainToXY(parent || document, false, offsets, xy) || xy;
6930 getConstrainToXY : function(el, local, offsets, proposedXY){
6931 var os = {top:0, left:0, bottom:0, right: 0};
6933 return function(el, local, offsets, proposedXY){
6935 offsets = offsets ? Ext.applyIf(offsets, os) : os;
6937 var vw, vh, vx = 0, vy = 0;
6938 if(el.dom == document.body || el.dom == document){
6939 vw =Ext.lib.Dom.getViewWidth();
6940 vh = Ext.lib.Dom.getViewHeight();
6942 vw = el.dom.clientWidth;
6943 vh = el.dom.clientHeight;
6945 var vxy = el.getXY();
6951 var s = el.getScroll();
6953 vx += offsets.left + s.left;
6954 vy += offsets.top + s.top;
6956 vw -= offsets.right;
6957 vh -= offsets.bottom;
6961 xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]),
6962 x = xy[0], y = xy[1],
6963 offset = this.getConstrainOffset(),
6964 w = this.dom.offsetWidth + offset,
6965 h = this.dom.offsetHeight + offset;
6988 return moved ? [x, y] : false;
7048 getConstrainOffset : function(){
7053 getCenterXY : function(){
7054 return this.getAlignToXY(document, 'c-c');
7058 center : function(centerIn){
7059 return this.alignTo(centerIn || document, 'c-c');
7063 Ext.Element.addMethods({
7065 select : function(selector, unique){
7066 return Ext.Element.select(selector, unique, this.dom);
7069 Ext.apply(Ext.Element.prototype, function() {
7070 var GETDOM = Ext.getDom,
7076 insertSibling: function(el, where, returnDom){
7079 isAfter = (where || 'before').toLowerCase() == 'after',
7082 if(Ext.isArray(el)){
7084 Ext.each(el, function(e) {
7085 rt = Ext.fly(insertEl, '_internal').insertSibling(e, where, returnDom);
7095 if(el.nodeType || el.dom){
7096 rt = me.dom.parentNode.insertBefore(GETDOM(el), isAfter ? me.dom.nextSibling : me.dom);
7101 if (isAfter && !me.dom.nextSibling) {
7102 rt = DH.append(me.dom.parentNode, el, !returnDom);
7104 rt = DH[isAfter ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom);
7113 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>';
7115 Ext.Element.addMethods(function(){
7116 var INTERNAL = "_internal",
7117 pxMatch = /(\d+\.?\d+)px/;
7120 applyStyles : function(style){
7121 Ext.DomHelper.applyStyles(this.dom, style);
7126 getStyles : function(){
7128 Ext.each(arguments, function(v) {
7129 ret[v] = this.getStyle(v);
7136 setOverflow : function(v){
7138 if(v=='auto' && Ext.isMac && Ext.isGecko2){
7139 dom.style.overflow = 'hidden';
7140 (function(){dom.style.overflow = 'auto';}).defer(1);
7142 dom.style.overflow = v;
7147 boxWrap : function(cls){
7148 cls = cls || 'x-box';
7149 var el = Ext.get(this.insertHtml("beforeBegin", "<div class='" + cls + "'>" + String.format(Ext.Element.boxMarkup, cls) + "</div>"));
7150 Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom);
7155 setSize : function(width, height, animate){
7157 if(typeof width == 'object'){
7158 height = width.height;
7159 width = width.width;
7161 width = me.adjustWidth(width);
7162 height = me.adjustHeight(height);
7163 if(!animate || !me.anim){
7164 me.dom.style.width = me.addUnits(width);
7165 me.dom.style.height = me.addUnits(height);
7167 me.anim({width: {to: width}, height: {to: height}}, me.preanim(arguments, 2));
7173 getComputedHeight : function(){
7175 h = Math.max(me.dom.offsetHeight, me.dom.clientHeight);
7177 h = parseFloat(me.getStyle('height')) || 0;
7178 if(!me.isBorderBox()){
7179 h += me.getFrameWidth('tb');
7186 getComputedWidth : function(){
7187 var w = Math.max(this.dom.offsetWidth, this.dom.clientWidth);
7189 w = parseFloat(this.getStyle('width')) || 0;
7190 if(!this.isBorderBox()){
7191 w += this.getFrameWidth('lr');
7198 getFrameWidth : function(sides, onlyContentBox){
7199 return onlyContentBox && this.isBorderBox() ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides));
7203 addClassOnOver : function(className){
7206 Ext.fly(this, INTERNAL).addClass(className);
7209 Ext.fly(this, INTERNAL).removeClass(className);
7216 addClassOnFocus : function(className){
7217 this.on("focus", function(){
7218 Ext.fly(this, INTERNAL).addClass(className);
7220 this.on("blur", function(){
7221 Ext.fly(this, INTERNAL).removeClass(className);
7227 addClassOnClick : function(className){
7229 this.on("mousedown", function(){
7230 Ext.fly(dom, INTERNAL).addClass(className);
7231 var d = Ext.getDoc(),
7233 Ext.fly(dom, INTERNAL).removeClass(className);
7234 d.removeListener("mouseup", fn);
7236 d.on("mouseup", fn);
7243 getViewSize : function(){
7246 isDoc = (d == doc || d == doc.body);
7250 var extdom = Ext.lib.Dom;
7252 width : extdom.getViewWidth(),
7253 height : extdom.getViewHeight()
7259 width : d.clientWidth,
7260 height : d.clientHeight
7267 getStyleSize : function(){
7272 isDoc = (d == doc || d == doc.body),
7277 var extdom = Ext.lib.Dom;
7279 width : extdom.getViewWidth(),
7280 height : extdom.getViewHeight()
7284 if(s.width && s.width != 'auto'){
7285 w = parseFloat(s.width);
7286 if(me.isBorderBox()){
7287 w -= me.getFrameWidth('lr');
7291 if(s.height && s.height != 'auto'){
7292 h = parseFloat(s.height);
7293 if(me.isBorderBox()){
7294 h -= me.getFrameWidth('tb');
7298 return {width: w || me.getWidth(true), height: h || me.getHeight(true)};
7302 getSize : function(contentSize){
7303 return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)};
7307 repaint : function(){
7309 this.addClass("x-repaint");
7310 setTimeout(function(){
7311 Ext.fly(dom).removeClass("x-repaint");
7317 unselectable : function(){
7318 this.dom.unselectable = "on";
7319 return this.swallowEvent("selectstart", true).
7320 applyStyles("-moz-user-select:none;-khtml-user-select:none;").
7321 addClass("x-unselectable");
7325 getMargins : function(side){
7328 hash = {t:"top", l:"left", r:"right", b: "bottom"},
7332 for (key in me.margins){
7333 o[hash[key]] = parseFloat(me.getStyle(me.margins[key])) || 0;
7337 return me.addStyles.call(me, side, me.margins);
7343 Ext.Element.addMethods({
7345 setBox : function(box, adjust, animate){
7349 if((adjust && !me.autoBoxAdjust) && !me.isBorderBox()){
7350 w -= (me.getBorderWidth("lr") + me.getPadding("lr"));
7351 h -= (me.getBorderWidth("tb") + me.getPadding("tb"));
7353 me.setBounds(box.x, box.y, w, h, me.animTest.call(me, arguments, animate, 2));
7358 getBox : function(contentBox, local) {
7363 getBorderWidth = me.getBorderWidth,
7364 getPadding = me.getPadding,
7372 left = parseInt(me.getStyle("left"), 10) || 0;
7373 top = parseInt(me.getStyle("top"), 10) || 0;
7376 var el = me.dom, w = el.offsetWidth, h = el.offsetHeight, bx;
7378 bx = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: w, height: h};
7380 l = getBorderWidth.call(me, "l") + getPadding.call(me, "l");
7381 r = getBorderWidth.call(me, "r") + getPadding.call(me, "r");
7382 t = getBorderWidth.call(me, "t") + getPadding.call(me, "t");
7383 b = getBorderWidth.call(me, "b") + getPadding.call(me, "b");
7384 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)};
7386 bx.right = bx.x + bx.width;
7387 bx.bottom = bx.y + bx.height;
7392 move : function(direction, distance, animate){
7397 left = [x - distance, y],
7398 right = [x + distance, y],
7399 top = [x, y - distance],
7400 bottom = [x, y + distance],
7414 direction = direction.toLowerCase();
7415 me.moveTo(hash[direction][0], hash[direction][1], me.animTest.call(me, arguments, animate, 2));
7419 setLeftTop : function(left, top){
7421 style = me.dom.style;
7422 style.left = me.addUnits(left);
7423 style.top = me.addUnits(top);
7428 getRegion : function(){
7429 return Ext.lib.Dom.getRegion(this.dom);
7433 setBounds : function(x, y, width, height, animate){
7435 if (!animate || !me.anim) {
7436 me.setSize(width, height);
7437 me.setLocation(x, y);
7439 me.anim({points: {to: [x, y]},
7440 width: {to: me.adjustWidth(width)},
7441 height: {to: me.adjustHeight(height)}},
7442 me.preanim(arguments, 4),
7449 setRegion : function(region, animate) {
7450 return this.setBounds(region.left, region.top, region.right-region.left, region.bottom-region.top, this.animTest.call(this, arguments, animate, 1));
7453 Ext.Element.addMethods({
7455 scrollTo : function(side, value, animate) {
7457 var top = /top/i.test(side),
7461 if (!animate || !me.anim) {
7463 prop = 'scroll' + (top ? 'Top' : 'Left');
7468 prop = 'scroll' + (top ? 'Left' : 'Top');
7469 me.anim({scroll: {to: top ? [dom[prop], value] : [value, dom[prop]]}}, me.preanim(arguments, 2), 'scroll');
7475 scrollIntoView : function(container, hscroll) {
7476 var c = Ext.getDom(container) || Ext.getBody().dom,
7478 o = this.getOffsetsTo(c),
7479 l = o[0] + c.scrollLeft,
7480 t = o[1] + c.scrollTop,
7481 b = t + el.offsetHeight,
7482 r = l + el.offsetWidth,
7483 ch = c.clientHeight,
7484 ct = parseInt(c.scrollTop, 10),
7485 cl = parseInt(c.scrollLeft, 10),
7487 cr = cl + c.clientWidth;
7489 if (el.offsetHeight > ch || t < ct) {
7496 c.scrollTop = c.scrollTop;
7498 if (hscroll !== false) {
7499 if (el.offsetWidth > c.clientWidth || l < cl) {
7503 c.scrollLeft = r - c.clientWidth;
7505 c.scrollLeft = c.scrollLeft;
7511 scrollChildIntoView : function(child, hscroll) {
7512 Ext.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll);
7516 scroll : function(direction, distance, animate) {
7517 if (!this.isScrollable()) {
7521 l = el.scrollLeft, t = el.scrollTop,
7522 w = el.scrollWidth, h = el.scrollHeight,
7523 cw = el.clientWidth, ch = el.clientHeight,
7524 scrolled = false, v,
7526 l: Math.min(l + distance, w-cw),
7527 r: v = Math.max(l - distance, 0),
7528 t: Math.max(t - distance, 0),
7529 b: Math.min(t + distance, h-ch)
7534 direction = direction.substr(0, 1);
7535 if ((v = hash[direction]) > -1) {
7537 this.scrollTo(direction == 'l' || direction == 'r' ? 'left' : 'top', v, this.preanim(arguments, 2));
7542 Ext.Element.addMethods(
7544 var VISIBILITY = "visibility",
7545 DISPLAY = "display",
7548 XMASKED = "x-masked",
7549 XMASKEDRELATIVE = "x-masked-relative",
7550 data = Ext.Element.data;
7554 isVisible : function(deep) {
7555 var vis = !this.isStyle(VISIBILITY, HIDDEN) && !this.isStyle(DISPLAY, NONE),
7556 p = this.dom.parentNode;
7558 if (deep !== true || !vis) {
7562 while (p && !(/^body/i.test(p.tagName))) {
7563 if (!Ext.fly(p, '_isVisible').isVisible()) {
7572 isDisplayed : function() {
7573 return !this.isStyle(DISPLAY, NONE);
7577 enableDisplayMode : function(display) {
7578 this.setVisibilityMode(Ext.Element.DISPLAY);
7580 if (!Ext.isEmpty(display)) {
7581 data(this.dom, 'originalDisplay', display);
7588 mask : function(msg, msgCls) {
7592 EXTELMASKMSG = "ext-el-mask-msg",
7596 if (!(/^body/i.test(dom.tagName) && me.getStyle('position') == 'static')) {
7597 me.addClass(XMASKEDRELATIVE);
7599 if (el = data(dom, 'maskMsg')) {
7602 if (el = data(dom, 'mask')) {
7606 mask = dh.append(dom, {cls : "ext-el-mask"}, true);
7607 data(dom, 'mask', mask);
7609 me.addClass(XMASKED);
7610 mask.setDisplayed(true);
7612 if (typeof msg == 'string') {
7613 var mm = dh.append(dom, {cls : EXTELMASKMSG, cn:{tag:'div'}}, true);
7614 data(dom, 'maskMsg', mm);
7615 mm.dom.className = msgCls ? EXTELMASKMSG + " " + msgCls : EXTELMASKMSG;
7616 mm.dom.firstChild.innerHTML = msg;
7617 mm.setDisplayed(true);
7622 if (Ext.isIE && !(Ext.isIE7 && Ext.isStrict) && me.getStyle('height') == 'auto') {
7623 mask.setSize(undefined, me.getHeight());
7630 unmask : function() {
7633 mask = data(dom, 'mask'),
7634 maskMsg = data(dom, 'maskMsg');
7639 data(dom, 'maskMsg', undefined);
7643 data(dom, 'mask', undefined);
7644 me.removeClass([XMASKED, XMASKEDRELATIVE]);
7649 isMasked : function() {
7650 var m = data(this.dom, 'mask');
7651 return m && m.isVisible();
7655 createShim : function() {
7656 var el = document.createElement('iframe'),
7659 el.frameBorder = '0';
7660 el.className = 'ext-shim';
7661 el.src = Ext.SSL_SECURE_URL;
7662 shim = Ext.get(this.dom.parentNode.insertBefore(el, this.dom));
7663 shim.autoBoxAdjust = false;
7669 Ext.Element.addMethods({
7671 addKeyListener : function(key, fn, scope){
7673 if(typeof key != 'object' || Ext.isArray(key)){
7689 return new Ext.KeyMap(this, config);
7693 addKeyMap : function(config){
7694 return new Ext.KeyMap(this, config);
7700 Ext.CompositeElementLite.importElementMethods();
7701 Ext.apply(Ext.CompositeElementLite.prototype, {
7702 addElements : function(els, root){
7706 if(typeof els == "string"){
7707 els = Ext.Element.selectorFunction(els, root);
7709 var yels = this.elements;
7710 Ext.each(els, function(e) {
7711 yels.push(Ext.get(e));
7718 return this.item(0);
7723 return this.item(this.getCount()-1);
7727 contains : function(el){
7728 return this.indexOf(el) != -1;
7732 removeElement : function(keys, removeDom){
7734 els = this.elements,
7736 Ext.each(keys, function(val){
7737 if ((el = (els[val] || els[val = me.indexOf(val)]))) {
7752 Ext.CompositeElement = Ext.extend(Ext.CompositeElementLite, {
7754 constructor : function(els, root){
7756 this.add(els, root);
7760 getElement : function(el){
7766 transformElement : function(el){
7778 Ext.Element.select = function(selector, unique, root){
7780 if(typeof selector == "string"){
7781 els = Ext.Element.selectorFunction(selector, root);
7782 }else if(selector.length !== undefined){
7785 throw "Invalid selector";
7788 return (unique === true) ? new Ext.CompositeElement(els) : new Ext.CompositeElementLite(els);
7792 Ext.select = Ext.Element.select;
7793 Ext.UpdateManager = Ext.Updater = Ext.extend(Ext.util.Observable,
7795 var BEFOREUPDATE = "beforeupdate",
7797 FAILURE = "failure";
7800 function processSuccess(response){
7802 me.transaction = null;
7803 if (response.argument.form && response.argument.reset) {
7805 response.argument.form.reset();
7808 if (me.loadScripts) {
7809 me.renderer.render(me.el, response, me,
7810 updateComplete.createDelegate(me, [response]));
7812 me.renderer.render(me.el, response, me);
7813 updateComplete.call(me, response);
7818 function updateComplete(response, type, success){
7819 this.fireEvent(type || UPDATE, this.el, response);
7820 if(Ext.isFunction(response.argument.callback)){
7821 response.argument.callback.call(response.argument.scope, this.el, Ext.isEmpty(success) ? true : false, response, response.argument.options);
7826 function processFailure(response){
7827 updateComplete.call(this, response, FAILURE, !!(this.transaction = null));
7831 constructor: function(el, forceNew){
7834 if(!forceNew && el.updateManager){
7835 return el.updateManager;
7840 me.defaultUrl = null;
7851 Ext.apply(me, Ext.Updater.defaults);
7860 me.transaction = null;
7862 me.refreshDelegate = me.refresh.createDelegate(me);
7864 me.updateDelegate = me.update.createDelegate(me);
7866 me.formUpdateDelegate = (me.formUpdate || function(){}).createDelegate(me);
7869 me.renderer = me.renderer || me.getDefaultRenderer();
7871 Ext.Updater.superclass.constructor.call(me);
7875 setRenderer : function(renderer){
7876 this.renderer = renderer;
7880 getRenderer : function(){
7881 return this.renderer;
7885 getDefaultRenderer: function() {
7886 return new Ext.Updater.BasicRenderer();
7890 setDefaultUrl : function(defaultUrl){
7891 this.defaultUrl = defaultUrl;
7900 update : function(url, params, callback, discardUrl){
7905 if(me.fireEvent(BEFOREUPDATE, me.el, url, params) !== false){
7906 if(Ext.isObject(url)){
7909 params = params || cfg.params;
7910 callback = callback || cfg.callback;
7911 discardUrl = discardUrl || cfg.discardUrl;
7912 callerScope = cfg.scope;
7913 if(!Ext.isEmpty(cfg.nocache)){me.disableCaching = cfg.nocache;};
7914 if(!Ext.isEmpty(cfg.text)){me.indicatorText = '<div class="loading-indicator">'+cfg.text+"</div>";};
7915 if(!Ext.isEmpty(cfg.scripts)){me.loadScripts = cfg.scripts;};
7916 if(!Ext.isEmpty(cfg.timeout)){me.timeout = cfg.timeout;};
7921 me.defaultUrl = url;
7923 if(Ext.isFunction(url)){
7927 var o = Ext.apply({}, {
7929 params: (Ext.isFunction(params) && callerScope) ? params.createDelegate(callerScope) : params,
7930 success: processSuccess,
7931 failure: processFailure,
7933 callback: undefined,
7934 timeout: (me.timeout*1000),
7935 disableCaching: me.disableCaching,
7940 "callback": callback,
7941 "scope": callerScope || window,
7946 me.transaction = Ext.Ajax.request(o);
7951 formUpdate : function(form, url, reset, callback){
7953 if(me.fireEvent(BEFOREUPDATE, me.el, form, url) !== false){
7954 if(Ext.isFunction(url)){
7957 form = Ext.getDom(form);
7958 me.transaction = Ext.Ajax.request({
7961 success: processSuccess,
7962 failure: processFailure,
7964 timeout: (me.timeout*1000),
7968 "callback": callback,
7972 me.showLoading.defer(1, me);
7977 startAutoRefresh : function(interval, url, params, callback, refreshNow){
7980 me.update(url || me.defaultUrl, params, callback, true);
7982 if(me.autoRefreshProcId){
7983 clearInterval(me.autoRefreshProcId);
7985 me.autoRefreshProcId = setInterval(me.update.createDelegate(me, [url || me.defaultUrl, params, callback, true]), interval * 1000);
7989 stopAutoRefresh : function(){
7990 if(this.autoRefreshProcId){
7991 clearInterval(this.autoRefreshProcId);
7992 delete this.autoRefreshProcId;
7997 isAutoRefreshing : function(){
7998 return !!this.autoRefreshProcId;
8002 showLoading : function(){
8003 if(this.showLoadIndicator){
8004 this.el.dom.innerHTML = this.indicatorText;
8010 if(this.transaction){
8011 Ext.Ajax.abort(this.transaction);
8016 isUpdating : function(){
8017 return this.transaction ? Ext.Ajax.isLoading(this.transaction) : false;
8021 refresh : function(callback){
8022 if(this.defaultUrl){
8023 this.update(this.defaultUrl, null, callback, true);
8030 Ext.Updater.defaults = {
8034 disableCaching : false,
8036 showLoadIndicator : true,
8038 indicatorText : '<div class="loading-indicator">Loading...</div>',
8040 loadScripts : false,
8042 sslBlankUrl : Ext.SSL_SECURE_URL
8047 Ext.Updater.updateElement = function(el, url, params, options){
8048 var um = Ext.get(el).getUpdater();
8049 Ext.apply(um, options);
8050 um.update(url, params, options ? options.callback : null);
8054 Ext.Updater.BasicRenderer = function(){};
8056 Ext.Updater.BasicRenderer.prototype = {
8058 render : function(el, response, updateManager, callback){
8059 el.update(response.responseText, updateManager.loadScripts, callback);
8068 Date.useStrict = false;
8074 function xf(format) {
8075 var args = Array.prototype.slice.call(arguments, 1);
8076 return format.replace(/\{(\d+)\}/g, function(m, i) {
8083 Date.formatCodeToRegex = function(character, currentGroup) {
8085 var p = Date.parseCodes[character];
8088 p = typeof p == 'function'? p() : p;
8089 Date.parseCodes[character] = p;
8092 return p ? Ext.applyIf({
8093 c: p.c ? xf(p.c, currentGroup || "{0}") : p.c
8097 s:Ext.escapeRe(character)
8102 var $f = Date.formatCodeToRegex;
8107 "M$": function(input, strict) {
8110 var re = new RegExp('\\/Date\\(([-+])?(\\d+)(?:[+-]\\d{4})?\\)\\/');
8111 var r = (input || '').match(re);
8112 return r? new Date(((r[1] || '') + r[2]) * 1) : null;
8121 return '\\/Date(' + this.getTime() + ')\\/';
8195 getShortMonthName : function(month) {
8196 return Date.monthNames[month].substring(0, 3);
8200 getShortDayName : function(day) {
8201 return Date.dayNames[day].substring(0, 3);
8205 getMonthNumber : function(name) {
8207 return Date.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()];
8212 d: "String.leftPad(this.getDate(), 2, '0')",
8213 D: "Date.getShortDayName(this.getDay())",
8214 j: "this.getDate()",
8215 l: "Date.dayNames[this.getDay()]",
8216 N: "(this.getDay() ? this.getDay() : 7)",
8217 S: "this.getSuffix()",
8219 z: "this.getDayOfYear()",
8220 W: "String.leftPad(this.getWeekOfYear(), 2, '0')",
8221 F: "Date.monthNames[this.getMonth()]",
8222 m: "String.leftPad(this.getMonth() + 1, 2, '0')",
8223 M: "Date.getShortMonthName(this.getMonth())",
8224 n: "(this.getMonth() + 1)",
8225 t: "this.getDaysInMonth()",
8226 L: "(this.isLeapYear() ? 1 : 0)",
8227 o: "(this.getFullYear() + (this.getWeekOfYear() == 1 && this.getMonth() > 0 ? +1 : (this.getWeekOfYear() >= 52 && this.getMonth() < 11 ? -1 : 0)))",
8228 Y: "String.leftPad(this.getFullYear(), 4, '0')",
8229 y: "('' + this.getFullYear()).substring(2, 4)",
8230 a: "(this.getHours() < 12 ? 'am' : 'pm')",
8231 A: "(this.getHours() < 12 ? 'AM' : 'PM')",
8232 g: "((this.getHours() % 12) ? this.getHours() % 12 : 12)",
8233 G: "this.getHours()",
8234 h: "String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0')",
8235 H: "String.leftPad(this.getHours(), 2, '0')",
8236 i: "String.leftPad(this.getMinutes(), 2, '0')",
8237 s: "String.leftPad(this.getSeconds(), 2, '0')",
8238 u: "String.leftPad(this.getMilliseconds(), 3, '0')",
8239 O: "this.getGMTOffset()",
8240 P: "this.getGMTOffset(true)",
8241 T: "this.getTimezone()",
8242 Z: "(this.getTimezoneOffset() * -60)",
8245 for (var c = "Y-m-dTH:i:sP", code = [], i = 0, l = c.length; i < l; ++i) {
8246 var e = c.charAt(i);
8247 code.push(e == "T" ? "'T'" : Date.getFormatCode(e));
8249 return code.join(" + ");
8253 U: "Math.round(this.getTime() / 1000)"
8257 isValid : function(y, m, d, h, i, s, ms) {
8265 var dt = new Date(y < 100 ? 100 : y, m - 1, d, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);
8267 return y == dt.getFullYear() &&
8268 m == dt.getMonth() + 1 &&
8269 d == dt.getDate() &&
8270 h == dt.getHours() &&
8271 i == dt.getMinutes() &&
8272 s == dt.getSeconds() &&
8273 ms == dt.getMilliseconds();
8277 parseDate : function(input, format, strict) {
8278 var p = Date.parseFunctions;
8279 if (p[format] == null) {
8280 Date.createParser(format);
8282 return p[format](input, Ext.isDefined(strict) ? strict : Date.useStrict);
8286 getFormatCode : function(character) {
8287 var f = Date.formatCodes[character];
8290 f = typeof f == 'function'? f() : f;
8291 Date.formatCodes[character] = f;
8295 return f || ("'" + String.escape(character) + "'");
8299 createFormat : function(format) {
8304 for (var i = 0; i < format.length; ++i) {
8305 ch = format.charAt(i);
8306 if (!special && ch == "\\") {
8308 } else if (special) {
8310 code.push("'" + String.escape(ch) + "'");
8312 code.push(Date.getFormatCode(ch));
8315 Date.formatFunctions[format] = new Function("return " + code.join('+'));
8319 createParser : function() {
8321 "var dt, y, m, d, h, i, s, ms, o, z, zz, u, v,",
8322 "def = Date.defaults,",
8323 "results = String(input).match(Date.parseRegexes[{0}]);",
8329 "v = new Date(u * 1000);",
8334 "dt = (new Date()).clearTime();",
8337 "y = Ext.num(y, Ext.num(def.y, dt.getFullYear()));",
8338 "m = Ext.num(m, Ext.num(def.m - 1, dt.getMonth()));",
8339 "d = Ext.num(d, Ext.num(def.d, dt.getDate()));",
8342 "h = Ext.num(h, Ext.num(def.h, dt.getHours()));",
8343 "i = Ext.num(i, Ext.num(def.i, dt.getMinutes()));",
8344 "s = Ext.num(s, Ext.num(def.s, dt.getSeconds()));",
8345 "ms = Ext.num(ms, Ext.num(def.ms, dt.getMilliseconds()));",
8347 "if(z >= 0 && y >= 0){",
8353 "v = new Date(y < 100 ? 100 : y, 0, 1, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);",
8356 "v = !strict? v : (strict === true && (z <= 364 || (v.isLeapYear() && z <= 365))? v.add(Date.DAY, z) : null);",
8357 "}else if(strict === true && !Date.isValid(y, m + 1, d, h, i, s, ms)){",
8362 "v = new Date(y < 100 ? 100 : y, m, d, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);",
8371 "v = v.add(Date.SECOND, -v.getTimezoneOffset() * 60 - zz);",
8374 "v = v.add(Date.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));",
8381 return function(format) {
8382 var regexNum = Date.parseRegexes.length,
8392 for (; i < format.length; ++i) {
8393 ch = format.charAt(i);
8394 if (!special && ch == "\\") {
8396 } else if (special) {
8398 regex.push(String.escape(ch));
8400 obj = $f(ch, currentGroup);
8401 currentGroup += obj.g;
8403 if (obj.g && obj.c) {
8417 Date.parseRegexes[regexNum] = new RegExp("^" + regex.join('') + "$", 'i');
8418 Date.parseFunctions[format] = new Function("input", "strict", xf(code, regexNum, calc.join('')));
8427 c:"d = parseInt(results[{0}], 10);\n",
8432 c:"d = parseInt(results[{0}], 10);\n",
8436 for (var a = [], i = 0; i < 7; a.push(Date.getShortDayName(i)), ++i);
8440 s:"(?:" + a.join("|") +")"
8447 s:"(?:" + Date.dayNames.join("|") + ")"
8467 c:"z = parseInt(results[{0}], 10);\n",
8478 c:"m = parseInt(Date.getMonthNumber(results[{0}]), 10);\n",
8479 s:"(" + Date.monthNames.join("|") + ")"
8483 for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i);
8484 return Ext.applyIf({
8485 s:"(" + a.join("|") + ")"
8490 c:"m = parseInt(results[{0}], 10) - 1;\n",
8495 c:"m = parseInt(results[{0}], 10) - 1;\n",
8513 c:"y = parseInt(results[{0}], 10);\n",
8518 c:"var ty = parseInt(results[{0}], 10);\n"
8519 + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n",
8530 c:"if (/(am)/i.test(results[{0}])) {\n"
8531 + "if (!h || h == 12) { h = 0; }\n"
8532 + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",
8540 c:"h = parseInt(results[{0}], 10);\n",
8548 c:"h = parseInt(results[{0}], 10);\n",
8553 c:"i = parseInt(results[{0}], 10);\n",
8558 c:"s = parseInt(results[{0}], 10);\n",
8563 c:"ms = results[{0}]; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n",
8569 "o = results[{0}];",
8570 "var sn = o.substring(0,1),",
8571 "hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60),",
8572 "mn = o.substring(3,5) % 60;",
8573 "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"
8580 "o = results[{0}];",
8581 "var sn = o.substring(0,1),",
8582 "hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60),",
8583 "mn = o.substring(4,6) % 60;",
8584 "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"
8586 s: "([+\-]\\d{2}:\\d{2})"
8595 c:"zz = results[{0}] * 1;\n"
8596 + "zz = (-43200 <= zz && zz <= 50400)? zz : null;\n",
8597 s:"([+\-]?\\d{1,5})"
8608 {c:"ms = results[7] || '0'; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n"},
8611 "if(results[8] == 'Z'){",
8613 "}else if (results[8].indexOf(':') > -1){",
8622 for (var i = 0, l = arr.length; i < l; ++i) {
8623 calc.push(arr[i].c);
8631 "(?:", "-", arr[1].s,
8632 "(?:", "-", arr[2].s,
8635 arr[3].s, ":", arr[4].s,
8636 "(?::", arr[5].s, ")?",
8637 "(?:(?:\\.|,)(\\d+))?",
8638 "(Z|(?:[-+]\\d{2}(?::)?\\d{2}))?",
8647 c:"u = parseInt(results[{0}], 10);\n",
8655 Ext.apply(Date.prototype, {
8657 dateFormat : function(format) {
8658 if (Date.formatFunctions[format] == null) {
8659 Date.createFormat(format);
8661 return Date.formatFunctions[format].call(this);
8665 getTimezone : function() {
8678 return this.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, "");
8682 getGMTOffset : function(colon) {
8683 return (this.getTimezoneOffset() > 0 ? "-" : "+")
8684 + String.leftPad(Math.floor(Math.abs(this.getTimezoneOffset()) / 60), 2, "0")
8685 + (colon ? ":" : "")
8686 + String.leftPad(Math.abs(this.getTimezoneOffset() % 60), 2, "0");
8690 getDayOfYear: function() {
8693 m = this.getMonth(),
8696 for (i = 0, d.setDate(1), d.setMonth(0); i < m; d.setMonth(++i)) {
8697 num += d.getDaysInMonth();
8699 return num + this.getDate() - 1;
8703 getWeekOfYear : function() {
8709 var DC3 = Date.UTC(this.getFullYear(), this.getMonth(), this.getDate() + 3) / ms1d,
8710 AWN = Math.floor(DC3 / 7),
8711 Wyr = new Date(AWN * ms7d).getUTCFullYear();
8713 return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
8718 isLeapYear : function() {
8719 var year = this.getFullYear();
8720 return !!((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
8724 getFirstDayOfMonth : function() {
8725 var day = (this.getDay() - (this.getDate() - 1)) % 7;
8726 return (day < 0) ? (day + 7) : day;
8730 getLastDayOfMonth : function() {
8731 return this.getLastDateOfMonth().getDay();
8736 getFirstDateOfMonth : function() {
8737 return new Date(this.getFullYear(), this.getMonth(), 1);
8741 getLastDateOfMonth : function() {
8742 return new Date(this.getFullYear(), this.getMonth(), this.getDaysInMonth());
8746 getDaysInMonth: function() {
8747 var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
8750 var m = this.getMonth();
8752 return m == 1 && this.isLeapYear() ? 29 : daysInMonth[m];
8757 getSuffix : function() {
8758 switch (this.getDate()) {
8775 clone : function() {
8776 return new Date(this.getTime());
8780 isDST : function() {
8783 return new Date(this.getFullYear(), 0, 1).getTimezoneOffset() != this.getTimezoneOffset();
8787 clearTime : function(clone) {
8789 return this.clone().clearTime();
8793 var d = this.getDate();
8799 this.setMilliseconds(0);
8801 if (this.getDate() != d) {
8806 for (var hr = 1, c = this.add(Date.HOUR, hr); c.getDate() != d; hr++, c = this.add(Date.HOUR, hr));
8809 this.setHours(c.getHours());
8816 add : function(interval, value) {
8817 var d = this.clone();
8818 if (!interval || value === 0) return d;
8820 switch(interval.toLowerCase()) {
8822 d.setMilliseconds(this.getMilliseconds() + value);
8825 d.setSeconds(this.getSeconds() + value);
8828 d.setMinutes(this.getMinutes() + value);
8831 d.setHours(this.getHours() + value);
8834 d.setDate(this.getDate() + value);
8837 var day = this.getDate();
8839 day = Math.min(day, this.getFirstDateOfMonth().add('mo', value).getLastDateOfMonth().getDate());
8842 d.setMonth(this.getMonth() + value);
8845 d.setFullYear(this.getFullYear() + value);
8852 between : function(start, end) {
8853 var t = this.getTime();
8854 return start.getTime() <= t && t <= end.getTime();
8860 Date.prototype.format = Date.prototype.dateFormat;
8864 if (Ext.isSafari && (navigator.userAgent.match(/WebKit\/(\d+)/)[1] || NaN) < 420) {
8865 Ext.apply(Date.prototype, {
8866 _xMonth : Date.prototype.setMonth,
8867 _xDate : Date.prototype.setDate,
8871 setMonth : function(num) {
8873 var n = Math.ceil(-num),
8874 back_year = Math.ceil(n / 12),
8875 month = (n % 12) ? 12 - n % 12 : 0;
8877 this.setFullYear(this.getFullYear() - back_year);
8879 return this._xMonth(month);
8881 return this._xMonth(num);
8888 setDate : function(d) {
8891 return this.setTime(this.getTime() - (this.getDate() - d) * 864e5);
8900 Ext.util.MixedCollection = function(allowFunctions, keyFn){
8916 this.allowFunctions = allowFunctions === true;
8918 this.getKey = keyFn;
8920 Ext.util.MixedCollection.superclass.constructor.call(this);
8923 Ext.extend(Ext.util.MixedCollection, Ext.util.Observable, {
8926 allowFunctions : false,
8929 add : function(key, o){
8930 if(arguments.length == 1){
8932 key = this.getKey(o);
8934 if(typeof key != 'undefined' && key !== null){
8935 var old = this.map[key];
8936 if(typeof old != 'undefined'){
8937 return this.replace(key, o);
8943 this.keys.push(key);
8944 this.fireEvent('add', this.length-1, o, key);
8949 getKey : function(o){
8954 replace : function(key, o){
8955 if(arguments.length == 1){
8957 key = this.getKey(o);
8959 var old = this.map[key];
8960 if(typeof key == 'undefined' || key === null || typeof old == 'undefined'){
8961 return this.add(key, o);
8963 var index = this.indexOfKey(key);
8964 this.items[index] = o;
8966 this.fireEvent('replace', key, old, o);
8971 addAll : function(objs){
8972 if(arguments.length > 1 || Ext.isArray(objs)){
8973 var args = arguments.length > 1 ? arguments : objs;
8974 for(var i = 0, len = args.length; i < len; i++){
8978 for(var key in objs){
8979 if(this.allowFunctions || typeof objs[key] != 'function'){
8980 this.add(key, objs[key]);
8987 each : function(fn, scope){
8988 var items = [].concat(this.items);
8989 for(var i = 0, len = items.length; i < len; i++){
8990 if(fn.call(scope || items[i], items[i], i, len) === false){
8997 eachKey : function(fn, scope){
8998 for(var i = 0, len = this.keys.length; i < len; i++){
8999 fn.call(scope || window, this.keys[i], this.items[i], i, len);
9004 find : function(fn, scope){
9005 for(var i = 0, len = this.items.length; i < len; i++){
9006 if(fn.call(scope || window, this.items[i], this.keys[i])){
9007 return this.items[i];
9014 insert : function(index, key, o){
9015 if(arguments.length == 2){
9017 key = this.getKey(o);
9019 if(this.containsKey(key)){
9020 this.suspendEvents();
9021 this.removeKey(key);
9022 this.resumeEvents();
9024 if(index >= this.length){
9025 return this.add(key, o);
9028 this.items.splice(index, 0, o);
9029 if(typeof key != 'undefined' && key !== null){
9032 this.keys.splice(index, 0, key);
9033 this.fireEvent('add', index, o, key);
9038 remove : function(o){
9039 return this.removeAt(this.indexOf(o));
9043 removeAt : function(index){
9044 if(index < this.length && index >= 0){
9046 var o = this.items[index];
9047 this.items.splice(index, 1);
9048 var key = this.keys[index];
9049 if(typeof key != 'undefined'){
9050 delete this.map[key];
9052 this.keys.splice(index, 1);
9053 this.fireEvent('remove', o, key);
9060 removeKey : function(key){
9061 return this.removeAt(this.indexOfKey(key));
9065 getCount : function(){
9070 indexOf : function(o){
9071 return this.items.indexOf(o);
9075 indexOfKey : function(key){
9076 return this.keys.indexOf(key);
9080 item : function(key){
9081 var mk = this.map[key],
9082 item = mk !== undefined ? mk : (typeof key == 'number') ? this.items[key] : undefined;
9083 return typeof item != 'function' || this.allowFunctions ? item : null;
9087 itemAt : function(index){
9088 return this.items[index];
9092 key : function(key){
9093 return this.map[key];
9097 contains : function(o){
9098 return this.indexOf(o) != -1;
9102 containsKey : function(key){
9103 return typeof this.map[key] != 'undefined';
9112 this.fireEvent('clear');
9117 return this.items[0];
9122 return this.items[this.length-1];
9126 _sort : function(property, dir, fn){
9128 dsc = String(dir).toUpperCase() == 'DESC' ? -1 : 1,
9136 fn = fn || function(a, b) {
9141 for(i = 0, len = items.length; i < len; i++){
9150 c.sort(function(a, b){
9151 var v = fn(a[property], b[property]) * dsc;
9153 v = (a.index < b.index ? -1 : 1);
9159 for(i = 0, len = c.length; i < len; i++){
9160 items[i] = c[i].value;
9164 this.fireEvent('sort', this);
9168 sort : function(dir, fn){
9169 this._sort('value', dir, fn);
9173 reorder: function(mapping) {
9174 this.suspendEvents();
9176 var items = this.items,
9178 length = items.length,
9184 for (oldIndex in mapping) {
9185 order[mapping[oldIndex]] = items[oldIndex];
9188 for (index = 0; index < length; index++) {
9189 if (mapping[index] == undefined) {
9190 remaining.push(items[index]);
9194 for (index = 0; index < length; index++) {
9195 if (order[index] == undefined) {
9196 order[index] = remaining.shift();
9203 this.resumeEvents();
9204 this.fireEvent('sort', this);
9208 keySort : function(dir, fn){
9209 this._sort('key', dir, fn || function(a, b){
9210 var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase();
9211 return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
9216 getRange : function(start, end){
9217 var items = this.items;
9218 if(items.length < 1){
9222 end = Math.min(typeof end == 'undefined' ? this.length-1 : end, this.length-1);
9225 for(i = start; i <= end; i++) {
9226 r[r.length] = items[i];
9229 for(i = start; i >= end; i--) {
9230 r[r.length] = items[i];
9237 filter : function(property, value, anyMatch, caseSensitive){
9238 if(Ext.isEmpty(value, false)){
9239 return this.clone();
9241 value = this.createValueMatcher(value, anyMatch, caseSensitive);
9242 return this.filterBy(function(o){
9243 return o && value.test(o[property]);
9248 filterBy : function(fn, scope){
9249 var r = new Ext.util.MixedCollection();
9250 r.getKey = this.getKey;
9251 var k = this.keys, it = this.items;
9252 for(var i = 0, len = it.length; i < len; i++){
9253 if(fn.call(scope||this, it[i], k[i])){
9261 findIndex : function(property, value, start, anyMatch, caseSensitive){
9262 if(Ext.isEmpty(value, false)){
9265 value = this.createValueMatcher(value, anyMatch, caseSensitive);
9266 return this.findIndexBy(function(o){
9267 return o && value.test(o[property]);
9272 findIndexBy : function(fn, scope, start){
9273 var k = this.keys, it = this.items;
9274 for(var i = (start||0), len = it.length; i < len; i++){
9275 if(fn.call(scope||this, it[i], k[i])){
9283 createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) {
9285 var er = Ext.escapeRe;
9286 value = String(value);
9288 if (anyMatch === true) {
9291 value = '^' + er(value);
9292 if (exactMatch === true) {
9296 value = new RegExp(value, caseSensitive ? '' : 'i');
9303 var r = new Ext.util.MixedCollection();
9304 var k = this.keys, it = this.items;
9305 for(var i = 0, len = it.length; i < len; i++){
9308 r.getKey = this.getKey;
9313 Ext.util.MixedCollection.prototype.get = Ext.util.MixedCollection.prototype.item;
9315 Ext.AbstractManager = Ext.extend(Object, {
9318 constructor: function(config) {
9319 Ext.apply(this, config || {});
9322 this.all = new Ext.util.MixedCollection();
9329 return this.all.get(id);
9333 register: function(item) {
9338 unregister: function(item) {
9339 this.all.remove(item);
9343 registerType : function(type, cls){
9344 this.types[type] = cls;
9345 cls[this.typeName] = type;
9349 isRegistered : function(type){
9350 return this.types[type] !== undefined;
9354 create: function(config, defaultType) {
9355 var type = config[this.typeName] || config.type || defaultType,
9356 Constructor = this.types[type];
9358 if (Constructor == undefined) {
9359 throw new Error(String.format("The '{0}' type has not been registered with this manager", type));
9362 return new Constructor(config);
9366 onAvailable : function(id, fn, scope){
9369 all.on("add", function(index, o){
9371 fn.call(scope || o, o);
9372 all.un("add", fn, scope);
9377 Ext.util.Format = function() {
9378 var trimRe = /^\s+|\s+$/g,
9379 stripTagsRE = /<\/?[^>]+>/gi,
9380 stripScriptsRe = /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,
9385 ellipsis : function(value, len, word) {
9386 if (value && value.length > len) {
9388 var vs = value.substr(0, len - 2),
9389 index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?'));
9390 if (index == -1 || index < (len - 15)) {
9391 return value.substr(0, len - 3) + "...";
9393 return vs.substr(0, index) + "...";
9396 return value.substr(0, len - 3) + "...";
9403 undef : function(value) {
9404 return value !== undefined ? value : "";
9408 defaultValue : function(value, defaultValue) {
9409 return value !== undefined && value !== '' ? value : defaultValue;
9413 htmlEncode : function(value) {
9414 return !value ? value : String(value).replace(/&/g, "&").replace(/>/g, ">").replace(/</g, "<").replace(/"/g, """);
9418 htmlDecode : function(value) {
9419 return !value ? value : String(value).replace(/>/g, ">").replace(/</g, "<").replace(/"/g, '"').replace(/&/g, "&");
9423 trim : function(value) {
9424 return String(value).replace(trimRe, "");
9428 substr : function(value, start, length) {
9429 return String(value).substr(start, length);
9433 lowercase : function(value) {
9434 return String(value).toLowerCase();
9438 uppercase : function(value) {
9439 return String(value).toUpperCase();
9443 capitalize : function(value) {
9444 return !value ? value : value.charAt(0).toUpperCase() + value.substr(1).toLowerCase();
9448 call : function(value, fn) {
9449 if (arguments.length > 2) {
9450 var args = Array.prototype.slice.call(arguments, 2);
9451 args.unshift(value);
9452 return eval(fn).apply(window, args);
9454 return eval(fn).call(window, value);
9459 usMoney : function(v) {
9460 v = (Math.round((v-0)*100))/100;
9461 v = (v == Math.floor(v)) ? v + ".00" : ((v*10 == Math.floor(v*10)) ? v + "0" : v);
9463 var ps = v.split('.'),
9465 sub = ps[1] ? '.'+ ps[1] : '.00',
9467 while (r.test(whole)) {
9468 whole = whole.replace(r, '$1' + ',' + '$2');
9471 if (v.charAt(0) == '-') {
9472 return '-$' + v.substr(1);
9478 date : function(v, format) {
9482 if (!Ext.isDate(v)) {
9483 v = new Date(Date.parse(v));
9485 return v.dateFormat(format || "m/d/Y");
9489 dateRenderer : function(format) {
9490 return function(v) {
9491 return Ext.util.Format.date(v, format);
9496 stripTags : function(v) {
9497 return !v ? v : String(v).replace(stripTagsRE, "");
9501 stripScripts : function(v) {
9502 return !v ? v : String(v).replace(stripScriptsRe, "");
9506 fileSize : function(size) {
9508 return size + " bytes";
9509 } else if (size < 1048576) {
9510 return (Math.round(((size*10) / 1024))/10) + " KB";
9512 return (Math.round(((size*10) / 1048576))/10) + " MB";
9520 return function(v, a){
9522 fns[a] = new Function('v', 'return v ' + a + ';');
9529 round : function(value, precision) {
9530 var result = Number(value);
9531 if (typeof precision == 'number') {
9532 precision = Math.pow(10, precision);
9533 result = Math.round(value * precision) / precision;
9539 number: function(v, format) {
9543 v = Ext.num(v, NaN);
9553 if (format.substr(format.length - 2) == '/i') {
9554 format = format.substr(0, format.length - 2);
9560 var hasComma = format.indexOf(comma) != -1,
9561 psplit = (i18n ? format.replace(/[^\d\,]/g, '') : format.replace(/[^\d\.]/g, '')).split(dec);
9563 if (1 < psplit.length) {
9564 v = v.toFixed(psplit[1].length);
9565 } else if(2 < psplit.length) {
9566 throw ('NumberFormatException: invalid format, formats should have no more than 1 period: ' + format);
9571 var fnum = v.toString();
9573 psplit = fnum.split('.');
9576 var cnum = psplit[0],
9579 m = Math.floor(j / 3),
9580 n = cnum.length % 3 || 3,
9583 for (i = 0; i < j; i += n) {
9588 parr[parr.length] = cnum.substr(i, n);
9591 fnum = parr.join(comma);
9593 fnum += dec + psplit[1];
9597 fnum = psplit[0] + dec + psplit[1];
9601 return (neg ? '-' : '') + format.replace(/[\d,?\.?]+/, fnum);
9605 numberRenderer : function(format) {
9606 return function(v) {
9607 return Ext.util.Format.number(v, format);
9612 plural : function(v, s, p) {
9613 return v +' ' + (v == 1 ? s : (p ? p : s+'s'));
9617 nl2br : function(v) {
9618 return Ext.isEmpty(v) ? '' : v.replace(nl2brRe, '<br/>');
9623 Ext.XTemplate = function(){
9624 Ext.XTemplate.superclass.constructor.apply(this, arguments);
9628 re = /<tpl\b[^>]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/,
9629 nameRe = /^<tpl\b[^>]*?for="(.*?)"/,
9630 ifRe = /^<tpl\b[^>]*?if="(.*?)"/,
9631 execRe = /^<tpl\b[^>]*?exec="(.*?)"/,
9640 WITHVALUES = 'with(values){ ';
9642 s = ['<tpl>', s, '</tpl>'].join('');
9644 while((m = s.match(re))){
9645 var m2 = m[0].match(nameRe),
9646 m3 = m[0].match(ifRe),
9647 m4 = m[0].match(execRe),
9651 name = m2 && m2[1] ? m2[1] : '';
9654 exp = m3 && m3[1] ? m3[1] : null;
9656 fn = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + RETURN +(Ext.util.Format.htmlDecode(exp))+'; }');
9660 exp = m4 && m4[1] ? m4[1] : null;
9662 exec = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES +(Ext.util.Format.htmlDecode(exp))+'; }');
9667 case '.': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + VALUES + '; }'); break;
9668 case '..': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + PARENT + '; }'); break;
9669 default: name = new Function(VALUES, PARENT, WITHVALUES + RETURN + name + '; }');
9679 s = s.replace(m[0], '{xtpl'+ id + '}');
9682 for(var i = tpls.length-1; i >= 0; --i){
9683 me.compileTpl(tpls[i]);
9685 me.master = tpls[tpls.length-1];
9688 Ext.extend(Ext.XTemplate, Ext.Template, {
9690 re : /\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\\]\s?[\d\.\+\-\*\\\(\)]+)?\}/g,
9692 codeRe : /\{\[((?:\\\]|.|\n)*?)\]\}/g,
9695 applySubTemplate : function(id, values, parent, xindex, xcount){
9701 if ((t.test && !t.test.call(me, values, parent, xindex, xcount)) ||
9702 (t.exec && t.exec.call(me, values, parent, xindex, xcount))) {
9705 vs = t.target ? t.target.call(me, values, parent) : values;
9707 parent = t.target ? values : parent;
9708 if(t.target && Ext.isArray(vs)){
9709 for(var i = 0, len = vs.length; i < len; i++){
9710 buf[buf.length] = t.compiled.call(me, vs[i], parent, i+1, len);
9712 return buf.join('');
9714 return t.compiled.call(me, vs, parent, xindex, xcount);
9718 compileTpl : function(tpl){
9719 var fm = Ext.util.Format,
9720 useF = this.disableFormats !== true,
9721 sep = Ext.isGecko ? "+" : ",",
9724 function fn(m, name, format, args, math){
9725 if(name.substr(0, 4) == 'xtpl'){
9726 return "'"+ sep +'this.applySubTemplate('+name.substr(4)+', values, parent, xindex, xcount)'+sep+"'";
9731 }else if(name === '#'){
9733 }else if(name.indexOf('.') != -1){
9736 v = "values['" + name + "']";
9739 v = '(' + v + math + ')';
9741 if (format && useF) {
9742 args = args ? ',' + args : "";
9743 if(format.substr(0, 5) != "this."){
9744 format = "fm." + format + '(';
9746 format = 'this.call("'+ format.substr(5) + '", ';
9750 args= ''; format = "("+v+" === undefined ? '' : ";
9752 return "'"+ sep + format + v + args + ")"+sep+"'";
9755 function codeFn(m, code){
9757 return "'" + sep + '(' + code.replace(/\\'/g, "'") + ')' + sep + "'";
9762 body = "tpl.compiled = function(values, parent, xindex, xcount){ return '" +
9763 tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn) +
9766 body = ["tpl.compiled = function(values, parent, xindex, xcount){ return ['"];
9767 body.push(tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn));
9768 body.push("'].join('');};");
9769 body = body.join('');
9776 applyTemplate : function(values){
9777 return this.master.compiled.call(this, values, {}, 1, 1);
9781 compile : function(){return this;}
9789 Ext.XTemplate.prototype.apply = Ext.XTemplate.prototype.applyTemplate;
9792 Ext.XTemplate.from = function(el){
9793 el = Ext.getDom(el);
9794 return new Ext.XTemplate(el.value || el.innerHTML);
9797 Ext.util.CSS = function(){
9801 var camelRe = /(-[a-z])/gi;
9802 var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };
9806 createStyleSheet : function(cssText, id){
9808 var head = doc.getElementsByTagName("head")[0];
9809 var rules = doc.createElement("style");
9810 rules.setAttribute("type", "text/css");
9812 rules.setAttribute("id", id);
9815 head.appendChild(rules);
9816 ss = rules.styleSheet;
9817 ss.cssText = cssText;
9820 rules.appendChild(doc.createTextNode(cssText));
9822 rules.cssText = cssText;
9824 head.appendChild(rules);
9825 ss = rules.styleSheet ? rules.styleSheet : (rules.sheet || doc.styleSheets[doc.styleSheets.length-1]);
9827 this.cacheStyleSheet(ss);
9832 removeStyleSheet : function(id){
9833 var existing = doc.getElementById(id);
9835 existing.parentNode.removeChild(existing);
9840 swapStyleSheet : function(id, url){
9841 this.removeStyleSheet(id);
9842 var ss = doc.createElement("link");
9843 ss.setAttribute("rel", "stylesheet");
9844 ss.setAttribute("type", "text/css");
9845 ss.setAttribute("id", id);
9846 ss.setAttribute("href", url);
9847 doc.getElementsByTagName("head")[0].appendChild(ss);
9851 refreshCache : function(){
9852 return this.getRules(true);
9856 cacheStyleSheet : function(ss){
9861 var ssRules = ss.cssRules || ss.rules;
9862 for(var j = ssRules.length-1; j >= 0; --j){
9863 rules[ssRules[j].selectorText.toLowerCase()] = ssRules[j];
9869 getRules : function(refreshCache){
9870 if(rules === null || refreshCache){
9872 var ds = doc.styleSheets;
9873 for(var i =0, len = ds.length; i < len; i++){
9875 this.cacheStyleSheet(ds[i]);
9883 getRule : function(selector, refreshCache){
9884 var rs = this.getRules(refreshCache);
9885 if(!Ext.isArray(selector)){
9886 return rs[selector.toLowerCase()];
9888 for(var i = 0; i < selector.length; i++){
9889 if(rs[selector[i]]){
9890 return rs[selector[i].toLowerCase()];
9898 updateRule : function(selector, property, value){
9899 if(!Ext.isArray(selector)){
9900 var rule = this.getRule(selector);
9902 rule.style[property.replace(camelRe, camelFn)] = value;
9906 for(var i = 0; i < selector.length; i++){
9907 if(this.updateRule(selector[i], property, value)){
9916 Ext.util.ClickRepeater = Ext.extend(Ext.util.Observable, {
9918 constructor : function(el, config){
9919 this.el = Ext.get(el);
9920 this.el.unselectable();
9922 Ext.apply(this, config);
9934 this.disabled = true;
9940 this.on("click", this.handler, this.scope || this);
9943 Ext.util.ClickRepeater.superclass.constructor.call(this);
9948 preventDefault : true,
9949 stopDefault : false,
9955 this.el.on('mousedown', this.handleMouseDown, this);
9957 this.el.on('dblclick', this.handleDblClick, this);
9959 if(this.preventDefault || this.stopDefault){
9960 this.el.on('click', this.eventOptions, this);
9963 this.disabled = false;
9967 disable: function( force){
9968 if(force || !this.disabled){
9969 clearTimeout(this.timer);
9970 if(this.pressClass){
9971 this.el.removeClass(this.pressClass);
9973 Ext.getDoc().un('mouseup', this.handleMouseUp, this);
9974 this.el.removeAllListeners();
9976 this.disabled = true;
9980 setDisabled: function(disabled){
9981 this[disabled ? 'disable' : 'enable']();
9984 eventOptions: function(e){
9985 if(this.preventDefault){
9988 if(this.stopDefault){
9994 destroy : function() {
9996 Ext.destroy(this.el);
9997 this.purgeListeners();
10000 handleDblClick : function(e){
10001 clearTimeout(this.timer);
10004 this.fireEvent("mousedown", this, e);
10005 this.fireEvent("click", this, e);
10009 handleMouseDown : function(e){
10010 clearTimeout(this.timer);
10012 if(this.pressClass){
10013 this.el.addClass(this.pressClass);
10015 this.mousedownTime = new Date();
10017 Ext.getDoc().on("mouseup", this.handleMouseUp, this);
10018 this.el.on("mouseout", this.handleMouseOut, this);
10020 this.fireEvent("mousedown", this, e);
10021 this.fireEvent("click", this, e);
10024 if (this.accelerate) {
10027 this.timer = this.click.defer(this.delay || this.interval, this, [e]);
10031 click : function(e){
10032 this.fireEvent("click", this, e);
10033 this.timer = this.click.defer(this.accelerate ?
10034 this.easeOutExpo(this.mousedownTime.getElapsed(),
10038 this.interval, this, [e]);
10041 easeOutExpo : function (t, b, c, d) {
10042 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
10046 handleMouseOut : function(){
10047 clearTimeout(this.timer);
10048 if(this.pressClass){
10049 this.el.removeClass(this.pressClass);
10051 this.el.on("mouseover", this.handleMouseReturn, this);
10055 handleMouseReturn : function(){
10056 this.el.un("mouseover", this.handleMouseReturn, this);
10057 if(this.pressClass){
10058 this.el.addClass(this.pressClass);
10064 handleMouseUp : function(e){
10065 clearTimeout(this.timer);
10066 this.el.un("mouseover", this.handleMouseReturn, this);
10067 this.el.un("mouseout", this.handleMouseOut, this);
10068 Ext.getDoc().un("mouseup", this.handleMouseUp, this);
10069 this.el.removeClass(this.pressClass);
10070 this.fireEvent("mouseup", this, e);
10073 Ext.KeyNav = function(el, config){
10074 this.el = Ext.get(el);
10075 Ext.apply(this, config);
10076 if(!this.disabled){
10077 this.disabled = true;
10082 Ext.KeyNav.prototype = {
10086 defaultEventAction: "stopEvent",
10088 forceKeyDown : false,
10091 relay : function(e){
10092 var k = e.getKey(),
10093 h = this.keyToHandler[k];
10095 if(this.doRelay(e, this[h], h) !== true){
10096 e[this.defaultEventAction]();
10102 doRelay : function(e, h, hname){
10103 return h.call(this.scope || this, e, hname);
10136 stopKeyUp: function(e) {
10137 var k = e.getKey();
10139 if (k >= 37 && k <= 40) {
10147 destroy: function(){
10152 enable: function() {
10153 if (this.disabled) {
10154 if (Ext.isSafari2) {
10156 this.el.on('keyup', this.stopKeyUp, this);
10159 this.el.on(this.isKeydown()? 'keydown' : 'keypress', this.relay, this);
10160 this.disabled = false;
10165 disable: function() {
10166 if (!this.disabled) {
10167 if (Ext.isSafari2) {
10169 this.el.un('keyup', this.stopKeyUp, this);
10172 this.el.un(this.isKeydown()? 'keydown' : 'keypress', this.relay, this);
10173 this.disabled = true;
10178 setDisabled : function(disabled){
10179 this[disabled ? "disable" : "enable"]();
10183 isKeydown: function(){
10184 return this.forceKeyDown || Ext.EventManager.useKeydown;
10188 Ext.KeyMap = function(el, config, eventName){
10189 this.el = Ext.get(el);
10190 this.eventName = eventName || "keydown";
10191 this.bindings = [];
10193 this.addBinding(config);
10198 Ext.KeyMap.prototype = {
10203 addBinding : function(config){
10204 if(Ext.isArray(config)){
10205 Ext.each(config, function(c){
10206 this.addBinding(c);
10210 var keyCode = config.key,
10211 fn = config.fn || config.handler,
10212 scope = config.scope;
10214 if (config.stopEvent) {
10215 this.stopEvent = config.stopEvent;
10218 if(typeof keyCode == "string"){
10220 var keyString = keyCode.toUpperCase();
10221 for(var j = 0, len = keyString.length; j < len; j++){
10222 ks.push(keyString.charCodeAt(j));
10226 var keyArray = Ext.isArray(keyCode);
10228 var handler = function(e){
10229 if(this.checkModifiers(config, e)){
10230 var k = e.getKey();
10232 for(var i = 0, len = keyCode.length; i < len; i++){
10233 if(keyCode[i] == k){
10234 if(this.stopEvent){
10237 fn.call(scope || window, k, e);
10243 if(this.stopEvent){
10246 fn.call(scope || window, k, e);
10251 this.bindings.push(handler);
10255 checkModifiers: function(config, e){
10256 var val, key, keys = ['shift', 'ctrl', 'alt'];
10257 for (var i = 0, len = keys.length; i < len; ++i){
10260 if(!(val === undefined || (val === e[key + 'Key']))){
10268 on : function(key, fn, scope){
10269 var keyCode, shift, ctrl, alt;
10270 if(typeof key == "object" && !Ext.isArray(key)){
10289 handleKeyDown : function(e){
10291 var b = this.bindings;
10292 for(var i = 0, len = b.length; i < len; i++){
10293 b[i].call(this, e);
10299 isEnabled : function(){
10300 return this.enabled;
10304 enable: function(){
10306 this.el.on(this.eventName, this.handleKeyDown, this);
10307 this.enabled = true;
10312 disable: function(){
10314 this.el.removeListener(this.eventName, this.handleKeyDown, this);
10315 this.enabled = false;
10320 setDisabled : function(disabled){
10321 this[disabled ? "disable" : "enable"]();
10324 Ext.util.TextMetrics = function(){
10328 measure : function(el, text, fixedWidth){
10330 shared = Ext.util.TextMetrics.Instance(el, fixedWidth);
10333 shared.setFixedWidth(fixedWidth || 'auto');
10334 return shared.getSize(text);
10338 createInstance : function(el, fixedWidth){
10339 return Ext.util.TextMetrics.Instance(el, fixedWidth);
10344 Ext.util.TextMetrics.Instance = function(bindTo, fixedWidth){
10345 var ml = new Ext.Element(document.createElement('div'));
10346 document.body.appendChild(ml.dom);
10347 ml.position('absolute');
10348 ml.setLeftTop(-1000, -1000);
10352 ml.setWidth(fixedWidth);
10357 getSize : function(text){
10359 var s = ml.getSize();
10365 bind : function(el){
10367 Ext.fly(el).getStyles('font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing')
10372 setFixedWidth : function(width){
10373 ml.setWidth(width);
10377 getWidth : function(text){
10378 ml.dom.style.width = 'auto';
10379 return this.getSize(text).width;
10383 getHeight : function(text){
10384 return this.getSize(text).height;
10388 instance.bind(bindTo);
10393 Ext.Element.addMethods({
10395 getTextWidth : function(text, min, max){
10396 return (Ext.util.TextMetrics.measure(this.dom, Ext.value(text, this.dom.innerHTML, true)).width).constrain(min || 0, max || 1000000);
10400 Ext.util.Cookies = {
10402 set : function(name, value){
10403 var argv = arguments;
10404 var argc = arguments.length;
10405 var expires = (argc > 2) ? argv[2] : null;
10406 var path = (argc > 3) ? argv[3] : '/';
10407 var domain = (argc > 4) ? argv[4] : null;
10408 var secure = (argc > 5) ? argv[5] : false;
10409 document.cookie = name + "=" + escape(value) + ((expires === null) ? "" : ("; expires=" + expires.toGMTString())) + ((path === null) ? "" : ("; path=" + path)) + ((domain === null) ? "" : ("; domain=" + domain)) + ((secure === true) ? "; secure" : "");
10413 get : function(name){
10414 var arg = name + "=";
10415 var alen = arg.length;
10416 var clen = document.cookie.length;
10421 if(document.cookie.substring(i, j) == arg){
10422 return Ext.util.Cookies.getCookieVal(j);
10424 i = document.cookie.indexOf(" ", i) + 1;
10433 clear : function(name){
10434 if(Ext.util.Cookies.get(name)){
10435 document.cookie = name + "=" + "; expires=Thu, 01-Jan-70 00:00:01 GMT";
10439 getCookieVal : function(offset){
10440 var endstr = document.cookie.indexOf(";", offset);
10442 endstr = document.cookie.length;
10444 return unescape(document.cookie.substring(offset, endstr));
10447 Ext.handleError = function(e) {
10452 Ext.Error = function(message) {
10454 this.message = (this.lang[message]) ? this.lang[message] : message;
10457 Ext.Error.prototype = new Error();
10458 Ext.apply(Ext.Error.prototype, {
10464 getName : function() {
10468 getMessage : function() {
10469 return this.message;
10472 toJson : function() {
10473 return Ext.encode(this);
10477 Ext.ComponentMgr = function(){
10478 var all = new Ext.util.MixedCollection();
10484 register : function(c){
10489 unregister : function(c){
10494 get : function(id){
10495 return all.get(id);
10499 onAvailable : function(id, fn, scope){
10500 all.on("add", function(index, o){
10502 fn.call(scope || o, o);
10503 all.un("add", fn, scope);
10518 isRegistered : function(xtype){
10519 return types[xtype] !== undefined;
10523 isPluginRegistered : function(ptype){
10524 return ptypes[ptype] !== undefined;
10528 registerType : function(xtype, cls){
10529 types[xtype] = cls;
10534 create : function(config, defaultType){
10535 return config.render ? config : new types[config.xtype || defaultType](config);
10539 registerPlugin : function(ptype, cls){
10540 ptypes[ptype] = cls;
10545 createPlugin : function(config, defaultType){
10546 var PluginCls = ptypes[config.ptype || defaultType];
10547 if (PluginCls.init) {
10550 return new PluginCls(config);
10557 Ext.reg = Ext.ComponentMgr.registerType;
10559 Ext.preg = Ext.ComponentMgr.registerPlugin;
10561 Ext.create = Ext.ComponentMgr.create;
10562 Ext.Component = function(config){
10563 config = config || {};
10564 if(config.initialConfig){
10565 if(config.isAction){
10566 this.baseAction = config;
10568 config = config.initialConfig;
10569 }else if(config.tagName || config.dom || Ext.isString(config)){
10570 config = {applyTo: config, id: config.id || config};
10574 this.initialConfig = config;
10576 Ext.apply(this, config);
10605 'beforestaterestore',
10614 Ext.ComponentMgr.register(this);
10615 Ext.Component.superclass.constructor.call(this);
10617 if(this.baseAction){
10618 this.baseAction.addComponent(this);
10621 this.initComponent();
10624 if(Ext.isArray(this.plugins)){
10625 for(var i = 0, len = this.plugins.length; i < len; i++){
10626 this.plugins[i] = this.initPlugin(this.plugins[i]);
10629 this.plugins = this.initPlugin(this.plugins);
10633 if(this.stateful !== false){
10638 this.applyToMarkup(this.applyTo);
10639 delete this.applyTo;
10640 }else if(this.renderTo){
10641 this.render(this.renderTo);
10642 delete this.renderTo;
10647 Ext.Component.AUTO_ID = 1000;
10649 Ext.extend(Ext.Component, Ext.util.Observable, {
10680 disabledClass : 'x-item-disabled',
10682 allowDomMove : true,
10686 hideMode : 'display',
10688 hideParent : false,
10702 tplWriteMode : 'overwrite',
10711 ctype : 'Ext.Component',
10717 getActionEl : function(){
10718 return this[this.actionMode];
10721 initPlugin : function(p){
10722 if(p.ptype && !Ext.isFunction(p.init)){
10723 p = Ext.ComponentMgr.createPlugin(p);
10724 }else if(Ext.isString(p)){
10725 p = Ext.ComponentMgr.createPlugin({
10734 initComponent : function(){
10736 if(this.listeners){
10737 this.on(this.listeners);
10738 delete this.listeners;
10740 this.enableBubble(this.bubbleEvents);
10744 render : function(container, position){
10745 if(!this.rendered && this.fireEvent('beforerender', this) !== false){
10746 if(!container && this.el){
10747 this.el = Ext.get(this.el);
10748 container = this.el.dom.parentNode;
10749 this.allowDomMove = false;
10751 this.container = Ext.get(container);
10753 this.container.addClass(this.ctCls);
10755 this.rendered = true;
10756 if(position !== undefined){
10757 if(Ext.isNumber(position)){
10758 position = this.container.dom.childNodes[position];
10760 position = Ext.getDom(position);
10763 this.onRender(this.container, position || null);
10765 this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]);
10768 this.el.addClass(this.cls);
10772 this.el.applyStyles(this.style);
10776 this.el.addClassOnOver(this.overCls);
10778 this.fireEvent('render', this);
10783 var contentTarget = this.getContentTarget();
10785 contentTarget.update(Ext.DomHelper.markup(this.html));
10788 if (this.contentEl){
10789 var ce = Ext.getDom(this.contentEl);
10790 Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']);
10791 contentTarget.appendChild(ce);
10794 if (!this.tpl.compile) {
10795 this.tpl = new Ext.XTemplate(this.tpl);
10798 this.tpl[this.tplWriteMode](contentTarget, this.data);
10802 this.afterRender(this.container);
10811 this.disable(true);
10814 if(this.stateful !== false){
10815 this.initStateEvents();
10817 this.fireEvent('afterrender', this);
10824 update: function(htmlOrData, loadScripts, cb) {
10825 var contentTarget = this.getContentTarget();
10826 if (this.tpl && typeof htmlOrData !== "string") {
10827 this.tpl[this.tplWriteMode](contentTarget, htmlOrData || {});
10829 var html = Ext.isObject(htmlOrData) ? Ext.DomHelper.markup(htmlOrData) : htmlOrData;
10830 contentTarget.update(html, loadScripts, cb);
10836 onAdded : function(container, pos) {
10837 this.ownerCt = container;
10839 this.fireEvent('added', this, container, pos);
10843 onRemoved : function() {
10845 this.fireEvent('removed', this, this.ownerCt);
10846 delete this.ownerCt;
10850 initRef : function() {
10852 if(this.ref && !this.refOwner){
10853 var levels = this.ref.split('/'),
10854 last = levels.length,
10858 while(t && i < last){
10863 t[this.refName = levels[--i]] = this;
10870 removeRef : function() {
10871 if (this.refOwner && this.refName) {
10872 delete this.refOwner[this.refName];
10873 delete this.refOwner;
10878 initState : function(){
10879 if(Ext.state.Manager){
10880 var id = this.getStateId();
10882 var state = Ext.state.Manager.get(id);
10884 if(this.fireEvent('beforestaterestore', this, state) !== false){
10885 this.applyState(Ext.apply({}, state));
10886 this.fireEvent('staterestore', this, state);
10894 getStateId : function(){
10895 return this.stateId || ((/^(ext-comp-|ext-gen)/).test(String(this.id)) ? null : this.id);
10899 initStateEvents : function(){
10900 if(this.stateEvents){
10901 for(var i = 0, e; e = this.stateEvents[i]; i++){
10902 this.on(e, this.saveState, this, {delay:100});
10908 applyState : function(state){
10910 Ext.apply(this, state);
10915 getState : function(){
10920 saveState : function(){
10921 if(Ext.state.Manager && this.stateful !== false){
10922 var id = this.getStateId();
10924 var state = this.getState();
10925 if(this.fireEvent('beforestatesave', this, state) !== false){
10926 Ext.state.Manager.set(id, state);
10927 this.fireEvent('statesave', this, state);
10934 applyToMarkup : function(el){
10935 this.allowDomMove = false;
10936 this.el = Ext.get(el);
10937 this.render(this.el.dom.parentNode);
10941 addClass : function(cls){
10943 this.el.addClass(cls);
10945 this.cls = this.cls ? this.cls + ' ' + cls : cls;
10951 removeClass : function(cls){
10953 this.el.removeClass(cls);
10954 }else if(this.cls){
10955 this.cls = this.cls.split(' ').remove(cls).join(' ');
10962 onRender : function(ct, position){
10963 if(!this.el && this.autoEl){
10964 if(Ext.isString(this.autoEl)){
10965 this.el = document.createElement(this.autoEl);
10967 var div = document.createElement('div');
10968 Ext.DomHelper.overwrite(div, this.autoEl);
10969 this.el = div.firstChild;
10972 this.el.id = this.getId();
10976 this.el = Ext.get(this.el);
10977 if(this.allowDomMove !== false){
10978 ct.dom.insertBefore(this.el.dom, position);
10980 Ext.removeNode(div);
10988 getAutoCreate : function(){
10989 var cfg = Ext.isObject(this.autoCreate) ?
10990 this.autoCreate : Ext.apply({}, this.defaultAutoCreate);
10991 if(this.id && !cfg.id){
10998 afterRender : Ext.emptyFn,
11001 destroy : function(){
11002 if(!this.isDestroyed){
11003 if(this.fireEvent('beforedestroy', this) !== false){
11004 this.destroying = true;
11005 this.beforeDestroy();
11006 if(this.ownerCt && this.ownerCt.remove){
11007 this.ownerCt.remove(this, false);
11011 if(this.actionMode == 'container' || this.removeMode == 'container'){
11012 this.container.remove();
11016 if(this.focusTask && this.focusTask.cancel){
11017 this.focusTask.cancel();
11020 Ext.ComponentMgr.unregister(this);
11021 this.fireEvent('destroy', this);
11022 this.purgeListeners();
11023 this.destroying = false;
11024 this.isDestroyed = true;
11029 deleteMembers : function(){
11030 var args = arguments;
11031 for(var i = 0, len = args.length; i < len; ++i){
11032 delete this[args[i]];
11037 beforeDestroy : Ext.emptyFn,
11040 onDestroy : Ext.emptyFn,
11043 getEl : function(){
11048 getContentTarget : function(){
11053 getId : function(){
11054 return this.id || (this.id = 'ext-comp-' + (++Ext.Component.AUTO_ID));
11058 getItemId : function(){
11059 return this.itemId || this.getId();
11063 focus : function(selectText, delay){
11065 this.focusTask = new Ext.util.DelayedTask(this.focus, this, [selectText, false]);
11066 this.focusTask.delay(Ext.isNumber(delay) ? delay : 10);
11069 if(this.rendered && !this.isDestroyed){
11071 if(selectText === true){
11072 this.el.dom.select();
11087 disable : function( silent){
11091 this.disabled = true;
11092 if(silent !== true){
11093 this.fireEvent('disable', this);
11099 onDisable : function(){
11100 this.getActionEl().addClass(this.disabledClass);
11101 this.el.dom.disabled = true;
11105 enable : function(){
11109 this.disabled = false;
11110 this.fireEvent('enable', this);
11115 onEnable : function(){
11116 this.getActionEl().removeClass(this.disabledClass);
11117 this.el.dom.disabled = false;
11121 setDisabled : function(disabled){
11122 return this[disabled ? 'disable' : 'enable']();
11127 if(this.fireEvent('beforeshow', this) !== false){
11128 this.hidden = false;
11129 if(this.autoRender){
11130 this.render(Ext.isBoolean(this.autoRender) ? Ext.getBody() : this.autoRender);
11135 this.fireEvent('show', this);
11141 onShow : function(){
11142 this.getVisibilityEl().removeClass('x-hide-' + this.hideMode);
11147 if(this.fireEvent('beforehide', this) !== false){
11149 this.fireEvent('hide', this);
11155 doHide: function(){
11156 this.hidden = true;
11163 onHide : function(){
11164 this.getVisibilityEl().addClass('x-hide-' + this.hideMode);
11168 getVisibilityEl : function(){
11169 return this.hideParent ? this.container : this.getActionEl();
11173 setVisible : function(visible){
11174 return this[visible ? 'show' : 'hide']();
11178 isVisible : function(){
11179 return this.rendered && this.getVisibilityEl().isVisible();
11183 cloneConfig : function(overrides){
11184 overrides = overrides || {};
11185 var id = overrides.id || Ext.id();
11186 var cfg = Ext.applyIf(overrides, this.initialConfig);
11188 return new this.constructor(cfg);
11192 getXType : function(){
11193 return this.constructor.xtype;
11197 isXType : function(xtype, shallow){
11199 if (Ext.isFunction(xtype)){
11200 xtype = xtype.xtype;
11201 }else if (Ext.isObject(xtype)){
11202 xtype = xtype.constructor.xtype;
11205 return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 : this.constructor.xtype == xtype;
11209 getXTypes : function(){
11210 var tc = this.constructor;
11212 var c = [], sc = this;
11213 while(sc && sc.constructor.xtype){
11214 c.unshift(sc.constructor.xtype);
11215 sc = sc.constructor.superclass;
11218 tc.xtypes = c.join('/');
11224 findParentBy : function(fn) {
11225 for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt);
11230 findParentByType : function(xtype, shallow){
11231 return this.findParentBy(function(c){
11232 return c.isXType(xtype, shallow);
11237 bubble : function(fn, scope, args){
11240 if(fn.apply(scope || p, args || [p]) === false){
11249 getPositionEl : function(){
11250 return this.positionEl || this.el;
11254 purgeListeners : function(){
11255 Ext.Component.superclass.purgeListeners.call(this);
11257 this.on('beforedestroy', this.clearMons, this, {single: true});
11262 clearMons : function(){
11263 Ext.each(this.mons, function(m){
11264 m.item.un(m.ename, m.fn, m.scope);
11270 createMons: function(){
11273 this.on('beforedestroy', this.clearMons, this, {single: true});
11278 mon : function(item, ename, fn, scope, opt){
11280 if(Ext.isObject(ename)){
11281 var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
11285 if(propRe.test(e)){
11288 if(Ext.isFunction(o[e])){
11291 item: item, ename: e, fn: o[e], scope: o.scope
11293 item.on(e, o[e], o.scope, o);
11297 item: item, ename: e, fn: o[e], scope: o.scope
11306 item: item, ename: ename, fn: fn, scope: scope
11308 item.on(ename, fn, scope, opt);
11312 mun : function(item, ename, fn, scope){
11315 for(var i = 0, len = this.mons.length; i < len; ++i){
11316 mon = this.mons[i];
11317 if(item === mon.item && ename == mon.ename && fn === mon.fn && scope === mon.scope){
11318 this.mons.splice(i, 1);
11319 item.un(ename, fn, scope);
11328 nextSibling : function(){
11330 var index = this.ownerCt.items.indexOf(this);
11331 if(index != -1 && index+1 < this.ownerCt.items.getCount()){
11332 return this.ownerCt.items.itemAt(index+1);
11339 previousSibling : function(){
11341 var index = this.ownerCt.items.indexOf(this);
11343 return this.ownerCt.items.itemAt(index-1);
11350 getBubbleTarget : function(){
11351 return this.ownerCt;
11355 Ext.reg('component', Ext.Component);
11357 Ext.Action = Ext.extend(Object, {
11366 constructor : function(config){
11367 this.initialConfig = config;
11368 this.itemId = config.itemId = (config.itemId || config.id || Ext.id());
11376 setText : function(text){
11377 this.initialConfig.text = text;
11378 this.callEach('setText', [text]);
11382 getText : function(){
11383 return this.initialConfig.text;
11387 setIconClass : function(cls){
11388 this.initialConfig.iconCls = cls;
11389 this.callEach('setIconClass', [cls]);
11393 getIconClass : function(){
11394 return this.initialConfig.iconCls;
11398 setDisabled : function(v){
11399 this.initialConfig.disabled = v;
11400 this.callEach('setDisabled', [v]);
11404 enable : function(){
11405 this.setDisabled(false);
11409 disable : function(){
11410 this.setDisabled(true);
11414 isDisabled : function(){
11415 return this.initialConfig.disabled;
11419 setHidden : function(v){
11420 this.initialConfig.hidden = v;
11421 this.callEach('setVisible', [!v]);
11426 this.setHidden(false);
11431 this.setHidden(true);
11435 isHidden : function(){
11436 return this.initialConfig.hidden;
11440 setHandler : function(fn, scope){
11441 this.initialConfig.handler = fn;
11442 this.initialConfig.scope = scope;
11443 this.callEach('setHandler', [fn, scope]);
11447 each : function(fn, scope){
11448 Ext.each(this.items, fn, scope);
11452 callEach : function(fnName, args){
11453 var cs = this.items;
11454 for(var i = 0, len = cs.length; i < len; i++){
11455 cs[i][fnName].apply(cs[i], args);
11460 addComponent : function(comp){
11461 this.items.push(comp);
11462 comp.on('destroy', this.removeComponent, this);
11466 removeComponent : function(comp){
11467 this.items.remove(comp);
11471 execute : function(){
11472 this.initialConfig.handler.apply(this.initialConfig.scope || window, arguments);
11477 Ext.Layer = function(config, existingEl){
11478 config = config || {};
11479 var dh = Ext.DomHelper,
11480 cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body;
11483 this.dom = Ext.getDom(existingEl);
11486 var o = config.dh || {tag: 'div', cls: 'x-layer'};
11487 this.dom = dh.append(pel, o);
11490 this.addClass(config.cls);
11492 this.constrain = config.constrain !== false;
11493 this.setVisibilityMode(Ext.Element.VISIBILITY);
11495 this.id = this.dom.id = config.id;
11497 this.id = Ext.id(this.dom);
11499 this.zindex = config.zindex || this.getZIndex();
11500 this.position('absolute', this.zindex);
11502 this.shadowOffset = config.shadowOffset || 4;
11503 this.shadow = new Ext.Shadow({
11504 offset : this.shadowOffset,
11505 mode : config.shadow
11508 this.shadowOffset = 0;
11510 this.useShim = config.shim !== false && Ext.useShims;
11511 this.useDisplay = config.useDisplay;
11515 var supr = Ext.Element.prototype;
11520 Ext.extend(Ext.Layer, Ext.Element, {
11522 getZIndex : function(){
11523 return this.zindex || parseInt((this.getShim() || this).getStyle('z-index'), 10) || 11000;
11526 getShim : function(){
11533 var shim = shims.shift();
11535 shim = this.createShim();
11536 shim.enableDisplayMode('block');
11537 shim.dom.style.display = 'none';
11538 shim.dom.style.visibility = 'visible';
11540 var pn = this.dom.parentNode;
11541 if(shim.dom.parentNode != pn){
11542 pn.insertBefore(shim.dom, this.dom);
11544 shim.setStyle('z-index', this.getZIndex()-2);
11549 hideShim : function(){
11551 this.shim.setDisplayed(false);
11552 shims.push(this.shim);
11557 disableShadow : function(){
11559 this.shadowDisabled = true;
11560 this.shadow.hide();
11561 this.lastShadowOffset = this.shadowOffset;
11562 this.shadowOffset = 0;
11566 enableShadow : function(show){
11568 this.shadowDisabled = false;
11569 this.shadowOffset = this.lastShadowOffset;
11570 delete this.lastShadowOffset;
11580 sync : function(doShow){
11581 var shadow = this.shadow;
11582 if(!this.updating && this.isVisible() && (shadow || this.useShim)){
11583 var shim = this.getShim(),
11584 w = this.getWidth(),
11585 h = this.getHeight(),
11586 l = this.getLeft(true),
11587 t = this.getTop(true);
11589 if(shadow && !this.shadowDisabled){
11590 if(doShow && !shadow.isVisible()){
11593 shadow.realign(l, t, w, h);
11600 var shadowAdj = shadow.el.getXY(), shimStyle = shim.dom.style,
11601 shadowSize = shadow.el.getSize();
11602 shimStyle.left = (shadowAdj[0])+'px';
11603 shimStyle.top = (shadowAdj[1])+'px';
11604 shimStyle.width = (shadowSize.width)+'px';
11605 shimStyle.height = (shadowSize.height)+'px';
11611 shim.setSize(w, h);
11612 shim.setLeftTop(l, t);
11618 destroy : function(){
11621 this.shadow.hide();
11623 this.removeAllListeners();
11624 Ext.removeNode(this.dom);
11628 remove : function(){
11633 beginUpdate : function(){
11634 this.updating = true;
11638 endUpdate : function(){
11639 this.updating = false;
11644 hideUnders : function(negOffset){
11646 this.shadow.hide();
11652 constrainXY : function(){
11653 if(this.constrain){
11654 var vw = Ext.lib.Dom.getViewWidth(),
11655 vh = Ext.lib.Dom.getViewHeight();
11656 var s = Ext.getDoc().getScroll();
11658 var xy = this.getXY();
11659 var x = xy[0], y = xy[1];
11660 var so = this.shadowOffset;
11661 var w = this.dom.offsetWidth+so, h = this.dom.offsetHeight+so;
11665 if((x + w) > vw+s.left){
11669 if((y + h) > vh+s.top){
11684 var ay = this.avoidY;
11685 if(y <= ay && (y+h) >= ay){
11691 supr.setXY.call(this, xy);
11698 getConstrainOffset : function(){
11699 return this.shadowOffset;
11702 isVisible : function(){
11703 return this.visible;
11707 showAction : function(){
11708 this.visible = true;
11709 if(this.useDisplay === true){
11710 this.setDisplayed('');
11711 }else if(this.lastXY){
11712 supr.setXY.call(this, this.lastXY);
11713 }else if(this.lastLT){
11714 supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]);
11719 hideAction : function(){
11720 this.visible = false;
11721 if(this.useDisplay === true){
11722 this.setDisplayed(false);
11724 this.setLeftTop(-10000,-10000);
11729 setVisible : function(v, a, d, c, e){
11734 var cb = function(){
11739 }.createDelegate(this);
11740 supr.setVisible.call(this, true, true, d, cb, e);
11743 this.hideUnders(true);
11752 }.createDelegate(this);
11754 supr.setVisible.call(this, v, a, d, cb, e);
11764 storeXY : function(xy){
11765 delete this.lastLT;
11769 storeLeftTop : function(left, top){
11770 delete this.lastXY;
11771 this.lastLT = [left, top];
11775 beforeFx : function(){
11776 this.beforeAction();
11777 return Ext.Layer.superclass.beforeFx.apply(this, arguments);
11781 afterFx : function(){
11782 Ext.Layer.superclass.afterFx.apply(this, arguments);
11783 this.sync(this.isVisible());
11787 beforeAction : function(){
11788 if(!this.updating && this.shadow){
11789 this.shadow.hide();
11794 setLeft : function(left){
11795 this.storeLeftTop(left, this.getTop(true));
11796 supr.setLeft.apply(this, arguments);
11801 setTop : function(top){
11802 this.storeLeftTop(this.getLeft(true), top);
11803 supr.setTop.apply(this, arguments);
11808 setLeftTop : function(left, top){
11809 this.storeLeftTop(left, top);
11810 supr.setLeftTop.apply(this, arguments);
11815 setXY : function(xy, a, d, c, e){
11817 this.beforeAction();
11819 var cb = this.createCB(c);
11820 supr.setXY.call(this, xy, a, d, cb, e);
11828 createCB : function(c){
11840 setX : function(x, a, d, c, e){
11841 this.setXY([x, this.getY()], a, d, c, e);
11846 setY : function(y, a, d, c, e){
11847 this.setXY([this.getX(), y], a, d, c, e);
11852 setSize : function(w, h, a, d, c, e){
11853 this.beforeAction();
11854 var cb = this.createCB(c);
11855 supr.setSize.call(this, w, h, a, d, cb, e);
11863 setWidth : function(w, a, d, c, e){
11864 this.beforeAction();
11865 var cb = this.createCB(c);
11866 supr.setWidth.call(this, w, a, d, cb, e);
11874 setHeight : function(h, a, d, c, e){
11875 this.beforeAction();
11876 var cb = this.createCB(c);
11877 supr.setHeight.call(this, h, a, d, cb, e);
11885 setBounds : function(x, y, w, h, a, d, c, e){
11886 this.beforeAction();
11887 var cb = this.createCB(c);
11889 this.storeXY([x, y]);
11890 supr.setXY.call(this, [x, y]);
11891 supr.setSize.call(this, w, h, a, d, cb, e);
11894 supr.setBounds.call(this, x, y, w, h, a, d, cb, e);
11900 setZIndex : function(zindex){
11901 this.zindex = zindex;
11902 this.setStyle('z-index', zindex + 2);
11904 this.shadow.setZIndex(zindex + 1);
11907 this.shim.setStyle('z-index', zindex);
11914 Ext.Shadow = function(config) {
11915 Ext.apply(this, config);
11916 if (typeof this.mode != "string") {
11917 this.mode = this.defaultMode;
11919 var o = this.offset,
11923 rad = Math.floor(this.offset / 2);
11924 switch (this.mode.toLowerCase()) {
11931 a.l -= this.offset + rad;
11932 a.t -= this.offset + rad;
11943 a.l -= (this.offset - rad);
11944 a.t -= this.offset + rad;
11946 a.w -= (this.offset - rad) * 2;
11952 a.w = a.h = (o * 2);
11957 a.l -= (this.offset - rad);
11958 a.t -= (this.offset - rad);
11960 a.w -= (this.offset + rad + 1);
11961 a.h -= (this.offset + rad);
11970 Ext.Shadow.prototype = {
11976 defaultMode: "drop",
11979 show: function(target) {
11980 target = Ext.get(target);
11982 this.el = Ext.Shadow.Pool.pull();
11983 if (this.el.dom.nextSibling != target.dom) {
11984 this.el.insertBefore(target);
11987 this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10) - 1);
11989 this.el.dom.style.filter = "progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius=" + (this.offset) + ")";
11992 target.getLeft(true),
11993 target.getTop(true),
11997 this.el.dom.style.display = "block";
12001 isVisible: function() {
12002 return this.el ? true: false;
12006 realign: function(l, t, w, h) {
12010 var a = this.adjusts,
12020 s.left = (l + a.l) + "px";
12021 s.top = (t + a.t) + "px";
12022 if (s.width != sws || s.height != shs) {
12027 sww = Math.max(0, (sw - 12)) + "px";
12028 cn[0].childNodes[1].style.width = sww;
12029 cn[1].childNodes[1].style.width = sww;
12030 cn[2].childNodes[1].style.width = sww;
12031 cn[1].style.height = Math.max(0, (sh - 12)) + "px";
12039 this.el.dom.style.display = "none";
12040 Ext.Shadow.Pool.push(this.el);
12046 setZIndex: function(z) {
12049 this.el.setStyle("z-index", z);
12055 Ext.Shadow.Pool = function() {
12057 markup = Ext.isIE ?
12058 '<div class="x-ie-shadow"></div>':
12059 '<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>';
12062 var sh = p.shift();
12064 sh = Ext.get(Ext.DomHelper.insertHtml("beforeBegin", document.body.firstChild, markup));
12065 sh.autoBoxAdjust = false;
12070 push: function(sh) {
12075 Ext.BoxComponent = Ext.extend(Ext.Component, {
12104 initComponent : function(){
12105 Ext.BoxComponent.superclass.initComponent.call(this);
12117 deferHeight: false,
12120 setSize : function(w, h){
12123 if(typeof w == 'object'){
12127 if (Ext.isDefined(w) && Ext.isDefined(this.boxMinWidth) && (w < this.boxMinWidth)) {
12128 w = this.boxMinWidth;
12130 if (Ext.isDefined(h) && Ext.isDefined(this.boxMinHeight) && (h < this.boxMinHeight)) {
12131 h = this.boxMinHeight;
12133 if (Ext.isDefined(w) && Ext.isDefined(this.boxMaxWidth) && (w > this.boxMaxWidth)) {
12134 w = this.boxMaxWidth;
12136 if (Ext.isDefined(h) && Ext.isDefined(this.boxMaxHeight) && (h > this.boxMaxHeight)) {
12137 h = this.boxMaxHeight;
12140 if(!this.boxReady){
12147 if(this.cacheSizes !== false && this.lastSize && this.lastSize.width == w && this.lastSize.height == h){
12150 this.lastSize = {width: w, height: h};
12151 var adj = this.adjustSize(w, h),
12155 if(aw !== undefined || ah !== undefined){
12156 rz = this.getResizeEl();
12157 if(!this.deferHeight && aw !== undefined && ah !== undefined){
12158 rz.setSize(aw, ah);
12159 }else if(!this.deferHeight && ah !== undefined){
12161 }else if(aw !== undefined){
12164 this.onResize(aw, ah, w, h);
12165 this.fireEvent('resize', this, aw, ah, w, h);
12171 setWidth : function(width){
12172 return this.setSize(width);
12176 setHeight : function(height){
12177 return this.setSize(undefined, height);
12181 getSize : function(){
12182 return this.getResizeEl().getSize();
12186 getWidth : function(){
12187 return this.getResizeEl().getWidth();
12191 getHeight : function(){
12192 return this.getResizeEl().getHeight();
12196 getOuterSize : function(){
12197 var el = this.getResizeEl();
12198 return {width: el.getWidth() + el.getMargins('lr'),
12199 height: el.getHeight() + el.getMargins('tb')};
12203 getPosition : function(local){
12204 var el = this.getPositionEl();
12205 if(local === true){
12206 return [el.getLeft(true), el.getTop(true)];
12208 return this.xy || el.getXY();
12212 getBox : function(local){
12213 var pos = this.getPosition(local);
12214 var s = this.getSize();
12221 updateBox : function(box){
12222 this.setSize(box.width, box.height);
12223 this.setPagePosition(box.x, box.y);
12228 getResizeEl : function(){
12229 return this.resizeEl || this.el;
12233 setAutoScroll : function(scroll){
12235 this.getContentTarget().setOverflow(scroll ? 'auto' : '');
12237 this.autoScroll = scroll;
12242 setPosition : function(x, y){
12243 if(x && typeof x[1] == 'number'){
12249 if(!this.boxReady){
12252 var adj = this.adjustPosition(x, y);
12253 var ax = adj.x, ay = adj.y;
12255 var el = this.getPositionEl();
12256 if(ax !== undefined || ay !== undefined){
12257 if(ax !== undefined && ay !== undefined){
12258 el.setLeftTop(ax, ay);
12259 }else if(ax !== undefined){
12261 }else if(ay !== undefined){
12264 this.onPosition(ax, ay);
12265 this.fireEvent('move', this, ax, ay);
12271 setPagePosition : function(x, y){
12272 if(x && typeof x[1] == 'number'){
12278 if(!this.boxReady){
12281 if(x === undefined || y === undefined){
12284 var p = this.getPositionEl().translatePoints(x, y);
12285 this.setPosition(p.left, p.top);
12290 afterRender : function(){
12291 Ext.BoxComponent.superclass.afterRender.call(this);
12293 this.resizeEl = Ext.get(this.resizeEl);
12295 if(this.positionEl){
12296 this.positionEl = Ext.get(this.positionEl);
12298 this.boxReady = true;
12299 Ext.isDefined(this.autoScroll) && this.setAutoScroll(this.autoScroll);
12300 this.setSize(this.width, this.height);
12301 if(this.x || this.y){
12302 this.setPosition(this.x, this.y);
12303 }else if(this.pageX || this.pageY){
12304 this.setPagePosition(this.pageX, this.pageY);
12309 syncSize : function(){
12310 delete this.lastSize;
12311 this.setSize(this.autoWidth ? undefined : this.getResizeEl().getWidth(), this.autoHeight ? undefined : this.getResizeEl().getHeight());
12316 onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
12320 onPosition : function(x, y){
12325 adjustSize : function(w, h){
12326 if(this.autoWidth){
12329 if(this.autoHeight){
12332 return {width : w, height: h};
12336 adjustPosition : function(x, y){
12337 return {x : x, y: y};
12340 Ext.reg('box', Ext.BoxComponent);
12344 Ext.Spacer = Ext.extend(Ext.BoxComponent, {
12347 Ext.reg('spacer', Ext.Spacer);
12348 Ext.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){
12351 this.el = Ext.get(dragElement, true);
12352 this.el.dom.unselectable = "on";
12354 this.resizingEl = Ext.get(resizingElement, true);
12357 this.orientation = orientation || Ext.SplitBar.HORIZONTAL;
12364 this.maxSize = 2000;
12367 this.animate = false;
12370 this.useShim = false;
12375 if(!existingProxy){
12377 this.proxy = Ext.SplitBar.createProxy(this.orientation);
12379 this.proxy = Ext.get(existingProxy).dom;
12382 this.dd = new Ext.dd.DDProxy(this.el.dom.id, "XSplitBars", {dragElId : this.proxy.id});
12385 this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this);
12388 this.dd.endDrag = this.onEndProxyDrag.createDelegate(this);
12391 this.dragSpecs = {};
12394 this.adapter = new Ext.SplitBar.BasicLayoutAdapter();
12395 this.adapter.init(this);
12397 if(this.orientation == Ext.SplitBar.HORIZONTAL){
12399 this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? Ext.SplitBar.LEFT : Ext.SplitBar.RIGHT);
12400 this.el.addClass("x-splitbar-h");
12403 this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? Ext.SplitBar.TOP : Ext.SplitBar.BOTTOM);
12404 this.el.addClass("x-splitbar-v");
12418 Ext.SplitBar.superclass.constructor.call(this);
12421 Ext.extend(Ext.SplitBar, Ext.util.Observable, {
12422 onStartProxyDrag : function(x, y){
12423 this.fireEvent("beforeresize", this);
12424 this.overlay = Ext.DomHelper.append(document.body, {cls: "x-drag-overlay", html: " "}, true);
12425 this.overlay.unselectable();
12426 this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
12427 this.overlay.show();
12428 Ext.get(this.proxy).setDisplayed("block");
12429 var size = this.adapter.getElementSize(this);
12430 this.activeMinSize = this.getMinimumSize();
12431 this.activeMaxSize = this.getMaximumSize();
12432 var c1 = size - this.activeMinSize;
12433 var c2 = Math.max(this.activeMaxSize - size, 0);
12434 if(this.orientation == Ext.SplitBar.HORIZONTAL){
12435 this.dd.resetConstraints();
12436 this.dd.setXConstraint(
12437 this.placement == Ext.SplitBar.LEFT ? c1 : c2,
12438 this.placement == Ext.SplitBar.LEFT ? c2 : c1,
12441 this.dd.setYConstraint(0, 0);
12443 this.dd.resetConstraints();
12444 this.dd.setXConstraint(0, 0);
12445 this.dd.setYConstraint(
12446 this.placement == Ext.SplitBar.TOP ? c1 : c2,
12447 this.placement == Ext.SplitBar.TOP ? c2 : c1,
12451 this.dragSpecs.startSize = size;
12452 this.dragSpecs.startPoint = [x, y];
12453 Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd, x, y);
12457 onEndProxyDrag : function(e){
12458 Ext.get(this.proxy).setDisplayed(false);
12459 var endPoint = Ext.lib.Event.getXY(e);
12461 Ext.destroy(this.overlay);
12462 delete this.overlay;
12465 if(this.orientation == Ext.SplitBar.HORIZONTAL){
12466 newSize = this.dragSpecs.startSize +
12467 (this.placement == Ext.SplitBar.LEFT ?
12468 endPoint[0] - this.dragSpecs.startPoint[0] :
12469 this.dragSpecs.startPoint[0] - endPoint[0]
12472 newSize = this.dragSpecs.startSize +
12473 (this.placement == Ext.SplitBar.TOP ?
12474 endPoint[1] - this.dragSpecs.startPoint[1] :
12475 this.dragSpecs.startPoint[1] - endPoint[1]
12478 newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize);
12479 if(newSize != this.dragSpecs.startSize){
12480 if(this.fireEvent('beforeapply', this, newSize) !== false){
12481 this.adapter.setElementSize(this, newSize);
12482 this.fireEvent("moved", this, newSize);
12483 this.fireEvent("resize", this, newSize);
12489 getAdapter : function(){
12490 return this.adapter;
12494 setAdapter : function(adapter){
12495 this.adapter = adapter;
12496 this.adapter.init(this);
12500 getMinimumSize : function(){
12501 return this.minSize;
12505 setMinimumSize : function(minSize){
12506 this.minSize = minSize;
12510 getMaximumSize : function(){
12511 return this.maxSize;
12515 setMaximumSize : function(maxSize){
12516 this.maxSize = maxSize;
12520 setCurrentSize : function(size){
12521 var oldAnimate = this.animate;
12522 this.animate = false;
12523 this.adapter.setElementSize(this, size);
12524 this.animate = oldAnimate;
12528 destroy : function(removeEl){
12529 Ext.destroy(this.shim, Ext.get(this.proxy));
12534 this.purgeListeners();
12539 Ext.SplitBar.createProxy = function(dir){
12540 var proxy = new Ext.Element(document.createElement("div"));
12541 document.body.appendChild(proxy.dom);
12542 proxy.unselectable();
12543 var cls = 'x-splitbar-proxy';
12544 proxy.addClass(cls + ' ' + (dir == Ext.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v'));
12549 Ext.SplitBar.BasicLayoutAdapter = function(){
12552 Ext.SplitBar.BasicLayoutAdapter.prototype = {
12554 init : function(s){
12558 getElementSize : function(s){
12559 if(s.orientation == Ext.SplitBar.HORIZONTAL){
12560 return s.resizingEl.getWidth();
12562 return s.resizingEl.getHeight();
12567 setElementSize : function(s, newSize, onComplete){
12568 if(s.orientation == Ext.SplitBar.HORIZONTAL){
12570 s.resizingEl.setWidth(newSize);
12572 onComplete(s, newSize);
12575 s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut');
12580 s.resizingEl.setHeight(newSize);
12582 onComplete(s, newSize);
12585 s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut');
12592 Ext.SplitBar.AbsoluteLayoutAdapter = function(container){
12593 this.basic = new Ext.SplitBar.BasicLayoutAdapter();
12594 this.container = Ext.get(container);
12597 Ext.SplitBar.AbsoluteLayoutAdapter.prototype = {
12598 init : function(s){
12599 this.basic.init(s);
12602 getElementSize : function(s){
12603 return this.basic.getElementSize(s);
12606 setElementSize : function(s, newSize, onComplete){
12607 this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s]));
12610 moveSplitter : function(s){
12611 var yes = Ext.SplitBar;
12612 switch(s.placement){
12614 s.el.setX(s.resizingEl.getRight());
12617 s.el.setStyle("right", (this.container.getWidth() - s.resizingEl.getLeft()) + "px");
12620 s.el.setY(s.resizingEl.getBottom());
12623 s.el.setY(s.resizingEl.getTop() - s.el.getHeight());
12630 Ext.SplitBar.VERTICAL = 1;
12633 Ext.SplitBar.HORIZONTAL = 2;
12636 Ext.SplitBar.LEFT = 1;
12639 Ext.SplitBar.RIGHT = 2;
12642 Ext.SplitBar.TOP = 3;
12645 Ext.SplitBar.BOTTOM = 4;
12647 Ext.Container = Ext.extend(Ext.BoxComponent, {
12660 autoDestroy : true,
12663 forceLayout: false,
12667 defaultType : 'panel',
12670 resizeEvent: 'resize',
12673 bubbleEvents: ['add', 'remove'],
12676 initComponent : function(){
12677 Ext.Container.superclass.initComponent.call(this);
12693 var items = this.items;
12701 initItems : function(){
12703 this.items = new Ext.util.MixedCollection(false, this.getComponentId);
12709 setLayout : function(layout){
12710 if(this.layout && this.layout != layout){
12711 this.layout.setContainer(null);
12713 this.layout = layout;
12715 layout.setContainer(this);
12718 afterRender: function(){
12721 Ext.Container.superclass.afterRender.call(this);
12723 this.layout = 'auto';
12725 if(Ext.isObject(this.layout) && !this.layout.layout){
12726 this.layoutConfig = this.layout;
12727 this.layout = this.layoutConfig.type;
12729 if(Ext.isString(this.layout)){
12730 this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);
12732 this.setLayout(this.layout);
12735 if(this.activeItem !== undefined && this.layout.setActiveItem){
12736 var item = this.activeItem;
12737 delete this.activeItem;
12738 this.layout.setActiveItem(item);
12743 this.doLayout(false, true);
12748 if(this.monitorResize === true){
12749 Ext.EventManager.onWindowResize(this.doLayout, this, [false]);
12754 getLayoutTarget : function(){
12759 getComponentId : function(comp){
12760 return comp.getItemId();
12764 add : function(comp){
12766 var args = arguments.length > 1;
12767 if(args || Ext.isArray(comp)){
12769 Ext.each(args ? arguments : comp, function(c){
12770 result.push(this.add(c));
12774 var c = this.lookupComponent(this.applyDefaults(comp));
12775 var index = this.items.length;
12776 if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){
12779 c.onAdded(this, index);
12781 this.fireEvent('add', this, c, index);
12786 onAdd : function(c){
12791 onAdded : function(container, pos) {
12793 this.ownerCt = container;
12796 this.cascade(function(c){
12799 this.fireEvent('added', this, container, pos);
12803 insert : function(index, comp) {
12804 var args = arguments,
12805 length = args.length,
12812 for (i = length - 1; i >= 1; --i) {
12813 result.push(this.insert(index, args[i]));
12818 c = this.lookupComponent(this.applyDefaults(comp));
12819 index = Math.min(index, this.items.length);
12821 if (this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false) {
12822 if (c.ownerCt == this) {
12823 this.items.remove(c);
12825 this.items.insert(index, c);
12826 c.onAdded(this, index);
12828 this.fireEvent('add', this, c, index);
12835 applyDefaults : function(c){
12836 var d = this.defaults;
12838 if(Ext.isFunction(d)){
12839 d = d.call(this, c);
12841 if(Ext.isString(c)){
12842 c = Ext.ComponentMgr.get(c);
12844 }else if(!c.events){
12845 Ext.applyIf(c.isAction ? c.initialConfig : c, d);
12854 onBeforeAdd : function(item){
12856 item.ownerCt.remove(item, false);
12858 if(this.hideBorders === true){
12859 item.border = (item.border === true);
12864 remove : function(comp, autoDestroy){
12866 var c = this.getComponent(comp);
12867 if(c && this.fireEvent('beforeremove', this, c) !== false){
12868 this.doRemove(c, autoDestroy);
12869 this.fireEvent('remove', this, c);
12874 onRemove: function(c){
12879 doRemove: function(c, autoDestroy){
12880 var l = this.layout,
12881 hasLayout = l && this.rendered;
12886 this.items.remove(c);
12889 if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){
12898 removeAll: function(autoDestroy){
12900 var item, rem = [], items = [];
12901 this.items.each(function(i){
12904 for (var i = 0, len = rem.length; i < len; ++i){
12906 this.remove(item, autoDestroy);
12907 if(item.ownerCt !== this){
12915 getComponent : function(comp){
12916 if(Ext.isObject(comp)){
12917 comp = comp.getItemId();
12919 return this.items.get(comp);
12923 lookupComponent : function(comp){
12924 if(Ext.isString(comp)){
12925 return Ext.ComponentMgr.get(comp);
12926 }else if(!comp.events){
12927 return this.createComponent(comp);
12933 createComponent : function(config, defaultType){
12934 if (config.render) {
12939 var c = Ext.create(Ext.apply({
12941 }, config), defaultType || this.defaultType);
12942 delete c.initialConfig.ownerCt;
12948 canLayout : function() {
12949 var el = this.getVisibilityEl();
12950 return el && el.dom && !el.isStyle("display", "none");
12955 doLayout : function(shallow, force){
12956 var rendered = this.rendered,
12957 forceLayout = force || this.forceLayout;
12959 if(this.collapsed || !this.canLayout()){
12960 this.deferLayout = this.deferLayout || !shallow;
12964 shallow = shallow && !this.deferLayout;
12966 delete this.deferLayout;
12968 if(rendered && this.layout){
12969 this.layout.layout();
12971 if(shallow !== true && this.items){
12972 var cs = this.items.items;
12973 for(var i = 0, len = cs.length; i < len; i++){
12976 c.doLayout(false, forceLayout);
12981 this.onLayout(shallow, forceLayout);
12984 this.hasLayout = true;
12985 delete this.forceLayout;
12988 onLayout : Ext.emptyFn,
12991 shouldBufferLayout: function(){
12993 var hl = this.hasLayout;
12996 return hl ? !this.hasLayoutPending() : false;
13003 hasLayoutPending: function(){
13005 var pending = false;
13006 this.ownerCt.bubble(function(c){
13007 if(c.layoutPending){
13015 onShow : function(){
13017 Ext.Container.superclass.onShow.call(this);
13019 if(Ext.isDefined(this.deferLayout)){
13020 delete this.deferLayout;
13021 this.doLayout(true);
13026 getLayout : function(){
13028 var layout = new Ext.layout.AutoLayout(this.layoutConfig);
13029 this.setLayout(layout);
13031 return this.layout;
13035 beforeDestroy : function(){
13038 while(c = this.items.first()){
13039 this.doRemove(c, true);
13042 if(this.monitorResize){
13043 Ext.EventManager.removeResizeListener(this.doLayout, this);
13045 Ext.destroy(this.layout);
13046 Ext.Container.superclass.beforeDestroy.call(this);
13050 cascade : function(fn, scope, args){
13051 if(fn.apply(scope || this, args || [this]) !== false){
13053 var cs = this.items.items;
13054 for(var i = 0, len = cs.length; i < len; i++){
13056 cs[i].cascade(fn, scope, args);
13058 fn.apply(scope || cs[i], args || [cs[i]]);
13067 findById : function(id){
13070 this.cascade(function(c){
13071 if(ct != c && c.id === id){
13080 findByType : function(xtype, shallow){
13081 return this.findBy(function(c){
13082 return c.isXType(xtype, shallow);
13087 find : function(prop, value){
13088 return this.findBy(function(c){
13089 return c[prop] === value;
13094 findBy : function(fn, scope){
13095 var m = [], ct = this;
13096 this.cascade(function(c){
13097 if(ct != c && fn.call(scope || c, c, ct) === true){
13105 get : function(key){
13106 return this.getComponent(key);
13110 Ext.Container.LAYOUTS = {};
13111 Ext.reg('container', Ext.Container);
13113 Ext.layout.ContainerLayout = Ext.extend(Object, {
13120 monitorResize:false,
13124 constructor : function(config){
13125 this.id = Ext.id(null, 'ext-layout-');
13126 Ext.apply(this, config);
13132 IEMeasureHack : function(target, viewFlag) {
13133 var tChildren = target.dom.childNodes, tLen = tChildren.length, c, d = [], e, i, ret;
13134 for (i = 0 ; i < tLen ; i++) {
13138 d[i] = e.getStyle('display');
13139 e.setStyle({display: 'none'});
13142 ret = target ? target.getViewSize(viewFlag) : {};
13143 for (i = 0 ; i < tLen ; i++) {
13147 e.setStyle({display: d[i]});
13154 getLayoutTargetSize : Ext.EmptyFn,
13157 layout : function(){
13158 var ct = this.container, target = ct.getLayoutTarget();
13159 if(!(this.hasLayout || Ext.isEmpty(this.targetCls))){
13160 target.addClass(this.targetCls);
13162 this.onLayout(ct, target);
13163 ct.fireEvent('afterlayout', ct, this);
13167 onLayout : function(ct, target){
13168 this.renderAll(ct, target);
13172 isValidParent : function(c, target){
13173 return target && c.getPositionEl().dom.parentNode == (target.dom || target);
13177 renderAll : function(ct, target){
13178 var items = ct.items.items, i, c, len = items.length;
13179 for(i = 0; i < len; i++) {
13181 if(c && (!c.rendered || !this.isValidParent(c, target))){
13182 this.renderItem(c, i, target);
13188 renderItem : function(c, position, target){
13191 c.render(target, position);
13192 this.configureItem(c);
13193 } else if (!this.isValidParent(c, target)) {
13194 if (Ext.isNumber(position)) {
13195 position = target.dom.childNodes[position];
13198 target.dom.insertBefore(c.getPositionEl().dom, position || null);
13199 c.container = target;
13200 this.configureItem(c);
13207 getRenderedItems: function(ct){
13208 var t = ct.getLayoutTarget(), cti = ct.items.items, len = cti.length, i, c, items = [];
13209 for (i = 0; i < len; i++) {
13210 if((c = cti[i]).rendered && this.isValidParent(c, t) && c.shouldLayout !== false){
13218 configureItem: function(c){
13219 if (this.extraCls) {
13220 var t = c.getPositionEl ? c.getPositionEl() : c;
13221 t.addClass(this.extraCls);
13225 if (c.doLayout && this.forceLayout) {
13228 if (this.renderHidden && c != this.activeItem) {
13233 onRemove: function(c){
13234 if(this.activeItem == c){
13235 delete this.activeItem;
13237 if(c.rendered && this.extraCls){
13238 var t = c.getPositionEl ? c.getPositionEl() : c;
13239 t.removeClass(this.extraCls);
13243 afterRemove: function(c){
13244 if(c.removeRestore){
13245 c.removeMode = 'container';
13246 delete c.removeRestore;
13251 onResize: function(){
13252 var ct = this.container,
13257 if(b = ct.bufferResize && ct.shouldBufferLayout()){
13258 if(!this.resizeTask){
13259 this.resizeTask = new Ext.util.DelayedTask(this.runLayout, this);
13260 this.resizeBuffer = Ext.isNumber(b) ? b : 50;
13262 ct.layoutPending = true;
13263 this.resizeTask.delay(this.resizeBuffer);
13269 runLayout: function(){
13270 var ct = this.container;
13273 delete ct.layoutPending;
13277 setContainer : function(ct){
13279 if(this.monitorResize && ct != this.container){
13280 var old = this.container;
13282 old.un(old.resizeEvent, this.onResize, this);
13285 ct.on(ct.resizeEvent, this.onResize, this);
13288 this.container = ct;
13292 parseMargins : function(v){
13293 if (Ext.isNumber(v)) {
13296 var ms = v.split(' '),
13300 ms[1] = ms[2] = ms[3] = ms[0];
13301 } else if(len == 2) {
13304 } else if(len == 3) {
13309 top :parseInt(ms[0], 10) || 0,
13310 right :parseInt(ms[1], 10) || 0,
13311 bottom:parseInt(ms[2], 10) || 0,
13312 left :parseInt(ms[3], 10) || 0
13317 fieldTpl: (function() {
13318 var t = new Ext.Template(
13319 '<div class="x-form-item {itemCls}" tabIndex="-1">',
13320 '<label for="{id}" style="{labelStyle}" class="x-form-item-label">{label}{labelSeparator}</label>',
13321 '<div class="x-form-element" id="x-form-el-{id}" style="{elementStyle}">',
13322 '</div><div class="{clearCls}"></div>',
13325 t.disableFormats = true;
13326 return t.compile();
13330 destroy : function(){
13332 if(this.resizeTask && this.resizeTask.cancel){
13333 this.resizeTask.cancel();
13335 if(this.container) {
13336 this.container.un(this.container.resizeEvent, this.onResize, this);
13338 if(!Ext.isEmpty(this.targetCls)){
13339 var target = this.container.getLayoutTarget();
13341 target.removeClass(this.targetCls);
13346 Ext.layout.AutoLayout = Ext.extend(Ext.layout.ContainerLayout, {
13349 monitorResize: true,
13351 onLayout : function(ct, target){
13352 Ext.layout.AutoLayout.superclass.onLayout.call(this, ct, target);
13353 var cs = this.getRenderedItems(ct), len = cs.length, i, c;
13354 for(i = 0; i < len; i++){
13364 Ext.Container.LAYOUTS['auto'] = Ext.layout.AutoLayout;
13366 Ext.layout.FitLayout = Ext.extend(Ext.layout.ContainerLayout, {
13368 monitorResize:true,
13372 getLayoutTargetSize : function() {
13373 var target = this.container.getLayoutTarget();
13378 return target.getStyleSize();
13382 onLayout : function(ct, target){
13383 Ext.layout.FitLayout.superclass.onLayout.call(this, ct, target);
13385 this.setItemSize(this.activeItem || ct.items.itemAt(0), this.getLayoutTargetSize());
13390 setItemSize : function(item, size){
13391 if(item && size.height > 0){
13392 item.setSize(size);
13396 Ext.Container.LAYOUTS['fit'] = Ext.layout.FitLayout;
13397 Ext.layout.CardLayout = Ext.extend(Ext.layout.FitLayout, {
13399 deferredRender : false,
13402 layoutOnCardChange : false,
13406 renderHidden : true,
13411 setActiveItem : function(item){
13412 var ai = this.activeItem,
13413 ct = this.container;
13414 item = ct.getComponent(item);
13417 if(item && ai != item){
13422 if (ai.hidden !== true) {
13425 ai.fireEvent('deactivate', ai);
13428 var layout = item.doLayout && (this.layoutOnCardChange || !item.rendered);
13431 this.activeItem = item;
13435 delete item.deferLayout;
13445 item.fireEvent('activate', item);
13450 renderAll : function(ct, target){
13451 if(this.deferredRender){
13452 this.renderItem(this.activeItem, undefined, target);
13454 Ext.layout.CardLayout.superclass.renderAll.call(this, ct, target);
13458 Ext.Container.LAYOUTS['card'] = Ext.layout.CardLayout;
13460 Ext.layout.AnchorLayout = Ext.extend(Ext.layout.ContainerLayout, {
13464 monitorResize : true,
13469 defaultAnchor : '100%',
13471 parseAnchorRE : /^(r|right|b|bottom)$/i,
13474 getLayoutTargetSize : function() {
13475 var target = this.container.getLayoutTarget(), ret = {};
13477 ret = target.getViewSize();
13482 if (Ext.isIE && Ext.isStrict && ret.width == 0){
13483 ret = target.getStyleSize();
13485 ret.width -= target.getPadding('lr');
13486 ret.height -= target.getPadding('tb');
13492 onLayout : function(container, target) {
13493 Ext.layout.AnchorLayout.superclass.onLayout.call(this, container, target);
13495 var size = this.getLayoutTargetSize(),
13496 containerWidth = size.width,
13497 containerHeight = size.height,
13498 overflow = target.getStyle('overflow'),
13499 components = this.getRenderedItems(container),
13500 len = components.length,
13514 if(containerWidth < 20 && containerHeight < 20){
13519 if(container.anchorSize) {
13520 if(typeof container.anchorSize == 'number') {
13521 anchorWidth = container.anchorSize;
13523 anchorWidth = container.anchorSize.width;
13524 anchorHeight = container.anchorSize.height;
13527 anchorWidth = container.initialConfig.width;
13528 anchorHeight = container.initialConfig.height;
13531 for(i = 0; i < len; i++) {
13532 component = components[i];
13533 el = component.getPositionEl();
13536 if (!component.anchor && component.items && !Ext.isNumber(component.width) && !(Ext.isIE6 && Ext.isStrict)){
13537 component.anchor = this.defaultAnchor;
13540 if(component.anchor) {
13541 anchorSpec = component.anchorSpec;
13544 anchorsArray = component.anchor.split(' ');
13545 component.anchorSpec = anchorSpec = {
13546 right: this.parseAnchor(anchorsArray[0], component.initialConfig.width, anchorWidth),
13547 bottom: this.parseAnchor(anchorsArray[1], component.initialConfig.height, anchorHeight)
13550 calcWidth = anchorSpec.right ? this.adjustWidthAnchor(anchorSpec.right(containerWidth) - el.getMargins('lr'), component) : undefined;
13551 calcHeight = anchorSpec.bottom ? this.adjustHeightAnchor(anchorSpec.bottom(containerHeight) - el.getMargins('tb'), component) : undefined;
13553 if(calcWidth || calcHeight) {
13555 component: component,
13556 width: calcWidth || undefined,
13557 height: calcHeight || undefined
13562 for (i = 0, len = boxes.length; i < len; i++) {
13564 box.component.setSize(box.width, box.height);
13567 if (overflow && overflow != 'hidden' && !this.adjustmentPass) {
13568 var newTargetSize = this.getLayoutTargetSize();
13569 if (newTargetSize.width != size.width || newTargetSize.height != size.height){
13570 this.adjustmentPass = true;
13571 this.onLayout(container, target);
13575 delete this.adjustmentPass;
13579 parseAnchor : function(a, start, cstart) {
13580 if (a && a != 'none') {
13583 if (this.parseAnchorRE.test(a)) {
13584 var diff = cstart - start;
13585 return function(v){
13592 } else if(a.indexOf('%') != -1) {
13593 var ratio = parseFloat(a.replace('%', ''))*.01;
13594 return function(v){
13597 return Math.floor(v*ratio);
13602 a = parseInt(a, 10);
13604 return function(v) {
13617 adjustWidthAnchor : function(value, comp){
13622 adjustHeightAnchor : function(value, comp){
13628 Ext.Container.LAYOUTS['anchor'] = Ext.layout.AnchorLayout;
13630 Ext.layout.ColumnLayout = Ext.extend(Ext.layout.ContainerLayout, {
13632 monitorResize:true,
13636 extraCls: 'x-column',
13642 targetCls: 'x-column-layout-ct',
13644 isValidParent : function(c, target){
13645 return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom;
13648 getLayoutTargetSize : function() {
13649 var target = this.container.getLayoutTarget(), ret;
13651 ret = target.getViewSize();
13656 if (Ext.isIE && Ext.isStrict && ret.width == 0){
13657 ret = target.getStyleSize();
13660 ret.width -= target.getPadding('lr');
13661 ret.height -= target.getPadding('tb');
13666 renderAll : function(ct, target) {
13670 this.innerCt = target.createChild({cls:'x-column-inner'});
13671 this.innerCt.createChild({cls:'x-clear'});
13673 Ext.layout.ColumnLayout.superclass.renderAll.call(this, ct, this.innerCt);
13677 onLayout : function(ct, target){
13678 var cs = ct.items.items,
13685 this.renderAll(ct, target);
13687 var size = this.getLayoutTargetSize();
13689 if(size.width < 1 && size.height < 1){
13693 var w = size.width - this.scrollOffset,
13697 this.innerCt.setWidth(w);
13702 for(i = 0; i < len; i++){
13704 m = c.getPositionEl().getMargins('lr');
13706 if(!c.columnWidth){
13707 pw -= (c.getWidth() + m);
13711 pw = pw < 0 ? 0 : pw;
13713 for(i = 0; i < len; i++){
13717 c.setSize(Math.floor(c.columnWidth * pw) - m);
13724 if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) {
13725 var ts = this.getLayoutTargetSize();
13726 if (ts.width != size.width){
13727 this.adjustmentPass = true;
13728 this.onLayout(ct, target);
13732 delete this.adjustmentPass;
13738 Ext.Container.LAYOUTS['column'] = Ext.layout.ColumnLayout;
13740 Ext.layout.BorderLayout = Ext.extend(Ext.layout.ContainerLayout, {
13742 monitorResize:true,
13748 targetCls: 'x-border-layout-ct',
13750 getLayoutTargetSize : function() {
13751 var target = this.container.getLayoutTarget();
13752 return target ? target.getViewSize() : {};
13756 onLayout : function(ct, target){
13757 var collapsed, i, c, pos, items = ct.items.items, len = items.length;
13758 if(!this.rendered){
13760 for(i = 0; i < len; i++) {
13766 c.collapsed = false;
13768 c.render(target, i);
13769 c.getPositionEl().addClass('x-border-panel');
13771 this[pos] = pos != 'center' && c.split ?
13772 new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) :
13773 new Ext.layout.BorderLayout.Region(this, c.initialConfig, pos);
13774 this[pos].render(target, c);
13776 this.rendered = true;
13779 var size = this.getLayoutTargetSize();
13780 if(size.width < 20 || size.height < 20){
13782 this.restoreCollapsed = collapsed;
13785 }else if(this.restoreCollapsed){
13786 collapsed = this.restoreCollapsed;
13787 delete this.restoreCollapsed;
13790 var w = size.width, h = size.height,
13791 centerW = w, centerH = h, centerY = 0, centerX = 0,
13792 n = this.north, s = this.south, west = this.west, e = this.east, c = this.center,
13793 b, m, totalWidth, totalHeight;
13794 if(!c && Ext.layout.BorderLayout.WARN !== false){
13795 throw 'No center region defined in BorderLayout ' + ct.id;
13798 if(n && n.isVisible()){
13800 m = n.getMargins();
13801 b.width = w - (m.left+m.right);
13804 centerY = b.height + b.y + m.bottom;
13805 centerH -= centerY;
13808 if(s && s.isVisible()){
13810 m = s.getMargins();
13811 b.width = w - (m.left+m.right);
13813 totalHeight = (b.height + m.top + m.bottom);
13814 b.y = h - totalHeight + m.top;
13815 centerH -= totalHeight;
13818 if(west && west.isVisible()){
13819 b = west.getSize();
13820 m = west.getMargins();
13821 b.height = centerH - (m.top+m.bottom);
13823 b.y = centerY + m.top;
13824 totalWidth = (b.width + m.left + m.right);
13825 centerX += totalWidth;
13826 centerW -= totalWidth;
13827 west.applyLayout(b);
13829 if(e && e.isVisible()){
13831 m = e.getMargins();
13832 b.height = centerH - (m.top+m.bottom);
13833 totalWidth = (b.width + m.left + m.right);
13834 b.x = w - totalWidth + m.left;
13835 b.y = centerY + m.top;
13836 centerW -= totalWidth;
13840 m = c.getMargins();
13842 x: centerX + m.left,
13843 y: centerY + m.top,
13844 width: centerW - (m.left+m.right),
13845 height: centerH - (m.top+m.bottom)
13847 c.applyLayout(centerBox);
13850 for(i = 0, len = collapsed.length; i < len; i++){
13851 collapsed[i].collapse(false);
13854 if(Ext.isIE && Ext.isStrict){
13858 if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) {
13859 var ts = this.getLayoutTargetSize();
13860 if (ts.width != size.width || ts.height != size.height){
13861 this.adjustmentPass = true;
13862 this.onLayout(ct, target);
13865 delete this.adjustmentPass;
13868 destroy: function() {
13869 var r = ['north', 'south', 'east', 'west'], i, region;
13870 for (i = 0; i < r.length; i++) {
13871 region = this[r[i]];
13873 if(region.destroy){
13875 }else if (region.split){
13876 region.split.destroy(true);
13880 Ext.layout.BorderLayout.superclass.destroy.call(this);
13887 Ext.layout.BorderLayout.Region = function(layout, config, pos){
13888 Ext.apply(this, config);
13889 this.layout = layout;
13890 this.position = pos;
13892 if(typeof this.margins == 'string'){
13893 this.margins = this.layout.parseMargins(this.margins);
13895 this.margins = Ext.applyIf(this.margins || {}, this.defaultMargins);
13896 if(this.collapsible){
13897 if(typeof this.cmargins == 'string'){
13898 this.cmargins = this.layout.parseMargins(this.cmargins);
13900 if(this.collapseMode == 'mini' && !this.cmargins){
13901 this.cmargins = {left:0,top:0,right:0,bottom:0};
13903 this.cmargins = Ext.applyIf(this.cmargins || {},
13904 pos == 'north' || pos == 'south' ? this.defaultNSCMargins : this.defaultEWCMargins);
13909 Ext.layout.BorderLayout.Region.prototype = {
13916 collapsible : false,
13927 defaultMargins : {left:0,top:0,right:0,bottom:0},
13929 defaultNSCMargins : {left:5,top:5,right:5,bottom:5},
13931 defaultEWCMargins : {left:5,top:0,right:5,bottom:0},
13932 floatingZIndex: 100,
13935 isCollapsed : false,
13942 render : function(ct, p){
13944 p.el.enableDisplayMode();
13945 this.targetEl = ct;
13948 var gs = p.getState, ps = this.position;
13949 p.getState = function(){
13950 return Ext.apply(gs.call(p) || {}, this.state);
13951 }.createDelegate(this);
13953 if(ps != 'center'){
13954 p.allowQueuedExpand = false;
13956 beforecollapse: this.beforeCollapse,
13957 collapse: this.onCollapse,
13958 beforeexpand: this.beforeExpand,
13959 expand: this.onExpand,
13964 if(this.collapsible || this.floatable){
13965 p.collapseEl = 'el';
13966 p.slideAnchor = this.getSlideAnchor();
13968 if(p.tools && p.tools.toggle){
13969 p.tools.toggle.addClass('x-tool-collapse-'+ps);
13970 p.tools.toggle.addClassOnOver('x-tool-collapse-'+ps+'-over');
13976 getCollapsedEl : function(){
13977 if(!this.collapsedEl){
13978 if(!this.toolTemplate){
13979 var tt = new Ext.Template(
13980 '<div class="x-tool x-tool-{id}"> </div>'
13982 tt.disableFormats = true;
13984 Ext.layout.BorderLayout.Region.prototype.toolTemplate = tt;
13986 this.collapsedEl = this.targetEl.createChild({
13987 cls: "x-layout-collapsed x-layout-collapsed-"+this.position,
13988 id: this.panel.id + '-xcollapsed'
13990 this.collapsedEl.enableDisplayMode('block');
13992 if(this.collapseMode == 'mini'){
13993 this.collapsedEl.addClass('x-layout-cmini-'+this.position);
13994 this.miniCollapsedEl = this.collapsedEl.createChild({
13995 cls: "x-layout-mini x-layout-mini-"+this.position, html: " "
13997 this.miniCollapsedEl.addClassOnOver('x-layout-mini-over');
13998 this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
13999 this.collapsedEl.on('click', this.onExpandClick, this, {stopEvent:true});
14001 if(this.collapsible !== false && !this.hideCollapseTool) {
14002 var t = this.expandToolEl = this.toolTemplate.append(
14003 this.collapsedEl.dom,
14004 {id:'expand-'+this.position}, true);
14005 t.addClassOnOver('x-tool-expand-'+this.position+'-over');
14006 t.on('click', this.onExpandClick, this, {stopEvent:true});
14008 if(this.floatable !== false || this.titleCollapse){
14009 this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
14010 this.collapsedEl.on("click", this[this.floatable ? 'collapseClick' : 'onExpandClick'], this);
14014 return this.collapsedEl;
14018 onExpandClick : function(e){
14020 this.panel.expand(false);
14022 this.panel.expand();
14027 onCollapseClick : function(e){
14028 this.panel.collapse();
14032 beforeCollapse : function(p, animate){
14033 this.lastAnim = animate;
14035 this.splitEl.hide();
14037 this.getCollapsedEl().show();
14038 var el = this.panel.getEl();
14039 this.originalZIndex = el.getStyle('z-index');
14040 el.setStyle('z-index', 100);
14041 this.isCollapsed = true;
14042 this.layout.layout();
14046 onCollapse : function(animate){
14047 this.panel.el.setStyle('z-index', 1);
14048 if(this.lastAnim === false || this.panel.animCollapse === false){
14049 this.getCollapsedEl().dom.style.visibility = 'visible';
14051 this.getCollapsedEl().slideIn(this.panel.slideAnchor, {duration:.2});
14053 this.state.collapsed = true;
14054 this.panel.saveState();
14058 beforeExpand : function(animate){
14060 this.afterSlideIn();
14062 var c = this.getCollapsedEl();
14064 if(this.position == 'east' || this.position == 'west'){
14065 this.panel.setSize(undefined, c.getHeight());
14067 this.panel.setSize(c.getWidth(), undefined);
14070 c.dom.style.visibility = 'hidden';
14071 this.panel.el.setStyle('z-index', this.floatingZIndex);
14075 onExpand : function(){
14076 this.isCollapsed = false;
14078 this.splitEl.show();
14080 this.layout.layout();
14081 this.panel.el.setStyle('z-index', this.originalZIndex);
14082 this.state.collapsed = false;
14083 this.panel.saveState();
14087 collapseClick : function(e){
14089 e.stopPropagation();
14092 e.stopPropagation();
14098 onHide : function(){
14099 if(this.isCollapsed){
14100 this.getCollapsedEl().hide();
14101 }else if(this.splitEl){
14102 this.splitEl.hide();
14107 onShow : function(){
14108 if(this.isCollapsed){
14109 this.getCollapsedEl().show();
14110 }else if(this.splitEl){
14111 this.splitEl.show();
14116 isVisible : function(){
14117 return !this.panel.hidden;
14121 getMargins : function(){
14122 return this.isCollapsed && this.cmargins ? this.cmargins : this.margins;
14126 getSize : function(){
14127 return this.isCollapsed ? this.getCollapsedEl().getSize() : this.panel.getSize();
14131 setPanel : function(panel){
14132 this.panel = panel;
14136 getMinWidth: function(){
14137 return this.minWidth;
14141 getMinHeight: function(){
14142 return this.minHeight;
14146 applyLayoutCollapsed : function(box){
14147 var ce = this.getCollapsedEl();
14148 ce.setLeftTop(box.x, box.y);
14149 ce.setSize(box.width, box.height);
14153 applyLayout : function(box){
14154 if(this.isCollapsed){
14155 this.applyLayoutCollapsed(box);
14157 this.panel.setPosition(box.x, box.y);
14158 this.panel.setSize(box.width, box.height);
14163 beforeSlide: function(){
14164 this.panel.beforeEffect();
14168 afterSlide : function(){
14169 this.panel.afterEffect();
14173 initAutoHide : function(){
14174 if(this.autoHide !== false){
14175 if(!this.autoHideHd){
14176 this.autoHideSlideTask = new Ext.util.DelayedTask(this.slideIn, this);
14177 this.autoHideHd = {
14178 "mouseout": function(e){
14179 if(!e.within(this.el, true)){
14180 this.autoHideSlideTask.delay(500);
14183 "mouseover" : function(e){
14184 this.autoHideSlideTask.cancel();
14189 this.el.on(this.autoHideHd);
14190 this.collapsedEl.on(this.autoHideHd);
14195 clearAutoHide : function(){
14196 if(this.autoHide !== false){
14197 this.el.un("mouseout", this.autoHideHd.mouseout);
14198 this.el.un("mouseover", this.autoHideHd.mouseover);
14199 this.collapsedEl.un("mouseout", this.autoHideHd.mouseout);
14200 this.collapsedEl.un("mouseover", this.autoHideHd.mouseover);
14205 clearMonitor : function(){
14206 Ext.getDoc().un("click", this.slideInIf, this);
14210 slideOut : function(){
14211 if(this.isSlid || this.el.hasActiveFx()){
14214 this.isSlid = true;
14215 var ts = this.panel.tools, dh, pc;
14216 if(ts && ts.toggle){
14222 pc = this.panel.collapsed;
14223 this.panel.collapsed = false;
14225 if(this.position == 'east' || this.position == 'west'){
14227 dh = this.panel.deferHeight;
14228 this.panel.deferHeight = false;
14230 this.panel.setSize(undefined, this.collapsedEl.getHeight());
14233 this.panel.deferHeight = dh;
14235 this.panel.setSize(this.collapsedEl.getWidth(), undefined);
14239 this.panel.collapsed = pc;
14241 this.restoreLT = [this.el.dom.style.left, this.el.dom.style.top];
14242 this.el.alignTo(this.collapsedEl, this.getCollapseAnchor());
14243 this.el.setStyle("z-index", this.floatingZIndex+2);
14244 this.panel.el.replaceClass('x-panel-collapsed', 'x-panel-floating');
14245 if(this.animFloat !== false){
14246 this.beforeSlide();
14247 this.el.slideIn(this.getSlideAnchor(), {
14248 callback: function(){
14250 this.initAutoHide();
14251 Ext.getDoc().on("click", this.slideInIf, this);
14257 this.initAutoHide();
14258 Ext.getDoc().on("click", this.slideInIf, this);
14263 afterSlideIn : function(){
14264 this.clearAutoHide();
14265 this.isSlid = false;
14266 this.clearMonitor();
14267 this.el.setStyle("z-index", "");
14268 this.panel.el.replaceClass('x-panel-floating', 'x-panel-collapsed');
14269 this.el.dom.style.left = this.restoreLT[0];
14270 this.el.dom.style.top = this.restoreLT[1];
14272 var ts = this.panel.tools;
14273 if(ts && ts.toggle){
14279 slideIn : function(cb){
14280 if(!this.isSlid || this.el.hasActiveFx()){
14284 this.isSlid = false;
14285 if(this.animFloat !== false){
14286 this.beforeSlide();
14287 this.el.slideOut(this.getSlideAnchor(), {
14288 callback: function(){
14291 this.afterSlideIn();
14299 this.afterSlideIn();
14304 slideInIf : function(e){
14305 if(!e.within(this.el)){
14335 getAnchor : function(){
14336 return this.anchors[this.position];
14340 getCollapseAnchor : function(){
14341 return this.canchors[this.position];
14345 getSlideAnchor : function(){
14346 return this.sanchors[this.position];
14350 getAlignAdj : function(){
14351 var cm = this.cmargins;
14352 switch(this.position){
14369 getExpandAdj : function(){
14370 var c = this.collapsedEl, cm = this.cmargins;
14371 switch(this.position){
14373 return [-(cm.right+c.getWidth()+cm.left), 0];
14376 return [cm.right+c.getWidth()+cm.left, 0];
14379 return [0, -(cm.top+cm.bottom+c.getHeight())];
14382 return [0, cm.top+cm.bottom+c.getHeight()];
14387 destroy : function(){
14388 if (this.autoHideSlideTask && this.autoHideSlideTask.cancel){
14389 this.autoHideSlideTask.cancel();
14391 Ext.destroyMembers(this, 'miniCollapsedEl', 'collapsedEl', 'expandToolEl');
14396 Ext.layout.BorderLayout.SplitRegion = function(layout, config, pos){
14397 Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this, layout, config, pos);
14399 this.applyLayout = this.applyFns[pos];
14402 Ext.extend(Ext.layout.BorderLayout.SplitRegion, Ext.layout.BorderLayout.Region, {
14405 splitTip : "Drag to resize.",
14407 collapsibleSplitTip : "Drag to resize. Double click to hide.",
14409 useSplitTips : false,
14414 orientation: Ext.SplitBar.VERTICAL,
14415 placement: Ext.SplitBar.TOP,
14416 maxFn : 'getVMaxSize',
14417 minProp: 'minHeight',
14418 maxProp: 'maxHeight'
14421 orientation: Ext.SplitBar.VERTICAL,
14422 placement: Ext.SplitBar.BOTTOM,
14423 maxFn : 'getVMaxSize',
14424 minProp: 'minHeight',
14425 maxProp: 'maxHeight'
14428 orientation: Ext.SplitBar.HORIZONTAL,
14429 placement: Ext.SplitBar.RIGHT,
14430 maxFn : 'getHMaxSize',
14431 minProp: 'minWidth',
14432 maxProp: 'maxWidth'
14435 orientation: Ext.SplitBar.HORIZONTAL,
14436 placement: Ext.SplitBar.LEFT,
14437 maxFn : 'getHMaxSize',
14438 minProp: 'minWidth',
14439 maxProp: 'maxWidth'
14445 west : function(box){
14446 if(this.isCollapsed){
14447 return this.applyLayoutCollapsed(box);
14449 var sd = this.splitEl.dom, s = sd.style;
14450 this.panel.setPosition(box.x, box.y);
14451 var sw = sd.offsetWidth;
14452 s.left = (box.x+box.width-sw)+'px';
14453 s.top = (box.y)+'px';
14454 s.height = Math.max(0, box.height)+'px';
14455 this.panel.setSize(box.width-sw, box.height);
14457 east : function(box){
14458 if(this.isCollapsed){
14459 return this.applyLayoutCollapsed(box);
14461 var sd = this.splitEl.dom, s = sd.style;
14462 var sw = sd.offsetWidth;
14463 this.panel.setPosition(box.x+sw, box.y);
14464 s.left = (box.x)+'px';
14465 s.top = (box.y)+'px';
14466 s.height = Math.max(0, box.height)+'px';
14467 this.panel.setSize(box.width-sw, box.height);
14469 north : function(box){
14470 if(this.isCollapsed){
14471 return this.applyLayoutCollapsed(box);
14473 var sd = this.splitEl.dom, s = sd.style;
14474 var sh = sd.offsetHeight;
14475 this.panel.setPosition(box.x, box.y);
14476 s.left = (box.x)+'px';
14477 s.top = (box.y+box.height-sh)+'px';
14478 s.width = Math.max(0, box.width)+'px';
14479 this.panel.setSize(box.width, box.height-sh);
14481 south : function(box){
14482 if(this.isCollapsed){
14483 return this.applyLayoutCollapsed(box);
14485 var sd = this.splitEl.dom, s = sd.style;
14486 var sh = sd.offsetHeight;
14487 this.panel.setPosition(box.x, box.y+sh);
14488 s.left = (box.x)+'px';
14489 s.top = (box.y)+'px';
14490 s.width = Math.max(0, box.width)+'px';
14491 this.panel.setSize(box.width, box.height-sh);
14496 render : function(ct, p){
14497 Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p);
14499 var ps = this.position;
14501 this.splitEl = ct.createChild({
14502 cls: "x-layout-split x-layout-split-"+ps, html: " ",
14503 id: this.panel.id + '-xsplit'
14506 if(this.collapseMode == 'mini'){
14507 this.miniSplitEl = this.splitEl.createChild({
14508 cls: "x-layout-mini x-layout-mini-"+ps, html: " "
14510 this.miniSplitEl.addClassOnOver('x-layout-mini-over');
14511 this.miniSplitEl.on('click', this.onCollapseClick, this, {stopEvent:true});
14514 var s = this.splitSettings[ps];
14516 this.split = new Ext.SplitBar(this.splitEl.dom, p.el, s.orientation);
14517 this.split.tickSize = this.tickSize;
14518 this.split.placement = s.placement;
14519 this.split.getMaximumSize = this[s.maxFn].createDelegate(this);
14520 this.split.minSize = this.minSize || this[s.minProp];
14521 this.split.on("beforeapply", this.onSplitMove, this);
14522 this.split.useShim = this.useShim === true;
14523 this.maxSize = this.maxSize || this[s.maxProp];
14526 this.splitEl.hide();
14529 if(this.useSplitTips){
14530 this.splitEl.dom.title = this.collapsible ? this.collapsibleSplitTip : this.splitTip;
14532 if(this.collapsible){
14533 this.splitEl.on("dblclick", this.onCollapseClick, this);
14538 getSize : function(){
14539 if(this.isCollapsed){
14540 return this.collapsedEl.getSize();
14542 var s = this.panel.getSize();
14543 if(this.position == 'north' || this.position == 'south'){
14544 s.height += this.splitEl.dom.offsetHeight;
14546 s.width += this.splitEl.dom.offsetWidth;
14552 getHMaxSize : function(){
14553 var cmax = this.maxSize || 10000;
14554 var center = this.layout.center;
14555 return Math.min(cmax, (this.el.getWidth()+center.el.getWidth())-center.getMinWidth());
14559 getVMaxSize : function(){
14560 var cmax = this.maxSize || 10000;
14561 var center = this.layout.center;
14562 return Math.min(cmax, (this.el.getHeight()+center.el.getHeight())-center.getMinHeight());
14566 onSplitMove : function(split, newSize){
14567 var s = this.panel.getSize();
14568 this.lastSplitSize = newSize;
14569 if(this.position == 'north' || this.position == 'south'){
14570 this.panel.setSize(s.width, newSize);
14571 this.state.height = newSize;
14573 this.panel.setSize(newSize, s.height);
14574 this.state.width = newSize;
14576 this.layout.layout();
14577 this.panel.saveState();
14582 getSplitBar : function(){
14587 destroy : function() {
14588 Ext.destroy(this.miniSplitEl, this.split, this.splitEl);
14589 Ext.layout.BorderLayout.SplitRegion.superclass.destroy.call(this);
14593 Ext.Container.LAYOUTS['border'] = Ext.layout.BorderLayout;
14595 Ext.layout.FormLayout = Ext.extend(Ext.layout.AnchorLayout, {
14598 labelSeparator : ':',
14607 onRemove: function(c){
14608 Ext.layout.FormLayout.superclass.onRemove.call(this, c);
14609 if(this.trackLabels){
14610 c.un('show', this.onFieldShow, this);
14611 c.un('hide', this.onFieldHide, this);
14614 var el = c.getPositionEl(),
14615 ct = c.getItemCt && c.getItemCt();
14616 if (c.rendered && ct) {
14617 if (el && el.dom) {
14618 el.insertAfter(ct);
14621 Ext.destroyMembers(c, 'label', 'itemCt');
14622 if (c.customItemCt) {
14623 Ext.destroyMembers(c, 'getItemCt', 'customItemCt');
14629 setContainer : function(ct){
14630 Ext.layout.FormLayout.superclass.setContainer.call(this, ct);
14632 ct.addClass('x-form-label-'+ct.labelAlign);
14637 labelStyle: 'display:none',
14638 elementStyle: 'padding-left:0;',
14642 this.labelSeparator = Ext.isDefined(ct.labelSeparator) ? ct.labelSeparator : this.labelSeparator;
14643 ct.labelWidth = ct.labelWidth || 100;
14644 if(Ext.isNumber(ct.labelWidth)){
14645 var pad = Ext.isNumber(ct.labelPad) ? ct.labelPad : 5;
14647 labelAdjust: ct.labelWidth + pad,
14648 labelStyle: 'width:' + ct.labelWidth + 'px;',
14649 elementStyle: 'padding-left:' + (ct.labelWidth + pad) + 'px'
14652 if(ct.labelAlign == 'top'){
14654 labelStyle: 'width:auto;',
14656 elementStyle: 'padding-left:0;'
14663 isHide: function(c){
14664 return c.hideLabel || this.container.hideLabels;
14667 onFieldShow: function(c){
14668 c.getItemCt().removeClass('x-hide-' + c.hideMode);
14671 if (c.isComposite) {
14676 onFieldHide: function(c){
14677 c.getItemCt().addClass('x-hide-' + c.hideMode);
14681 getLabelStyle: function(s){
14682 var ls = '', items = [this.labelStyle, s];
14683 for (var i = 0, len = items.length; i < len; ++i){
14686 if (ls.substr(-1, 1) != ';'){
14697 renderItem : function(c, position, target){
14698 if(c && (c.isFormField || c.fieldLabel) && c.inputType != 'hidden'){
14699 var args = this.getTemplateArgs(c);
14700 if(Ext.isNumber(position)){
14701 position = target.dom.childNodes[position] || null;
14704 c.itemCt = this.fieldTpl.insertBefore(position, args, true);
14706 c.itemCt = this.fieldTpl.append(target, args, true);
14712 getItemCt: function(){
14718 c.label = c.getItemCt().child('label.x-form-item-label');
14720 c.render('x-form-el-' + c.id);
14721 }else if(!this.isValidParent(c, target)){
14722 Ext.fly('x-form-el-' + c.id).appendChild(c.getPositionEl());
14724 if(this.trackLabels){
14726 this.onFieldHide(c);
14730 show: this.onFieldShow,
14731 hide: this.onFieldHide
14734 this.configureItem(c);
14736 Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
14741 getTemplateArgs: function(field) {
14742 var noLabelSep = !field.fieldLabel || field.hideLabel;
14746 label : field.fieldLabel,
14747 itemCls : (field.itemCls || this.container.itemCls || '') + (field.hideLabel ? ' x-hide-label' : ''),
14748 clearCls : field.clearCls || 'x-form-clear-left',
14749 labelStyle : this.getLabelStyle(field.labelStyle),
14750 elementStyle : this.elementStyle || '',
14751 labelSeparator: noLabelSep ? '' : (Ext.isDefined(field.labelSeparator) ? field.labelSeparator : this.labelSeparator)
14756 adjustWidthAnchor: function(value, c){
14757 if(c.label && !this.isHide(c) && (this.container.labelAlign != 'top')){
14758 var adjust = Ext.isIE6 || (Ext.isIE && !Ext.isStrict);
14759 return value - this.labelAdjust + (adjust ? -3 : 0);
14764 adjustHeightAnchor : function(value, c){
14765 if(c.label && !this.isHide(c) && (this.container.labelAlign == 'top')){
14766 return value - c.label.getHeight();
14772 isValidParent : function(c, target){
14773 return target && this.container.getEl().contains(c.getPositionEl());
14779 Ext.Container.LAYOUTS['form'] = Ext.layout.FormLayout;
14781 Ext.layout.AccordionLayout = Ext.extend(Ext.layout.FitLayout, {
14787 titleCollapse : true,
14789 hideCollapseTool : false,
14791 collapseFirst : false,
14797 activeOnTop : false,
14801 renderItem : function(c){
14802 if(this.animate === false){
14803 c.animCollapse = false;
14805 c.collapsible = true;
14806 if(this.autoWidth){
14807 c.autoWidth = true;
14809 if(this.titleCollapse){
14810 c.titleCollapse = true;
14812 if(this.hideCollapseTool){
14813 c.hideCollapseTool = true;
14815 if(this.collapseFirst !== undefined){
14816 c.collapseFirst = this.collapseFirst;
14818 if(!this.activeItem && !c.collapsed){
14819 this.setActiveItem(c, true);
14820 }else if(this.activeItem && this.activeItem != c){
14821 c.collapsed = true;
14823 Ext.layout.AccordionLayout.superclass.renderItem.apply(this, arguments);
14824 c.header.addClass('x-accordion-hd');
14825 c.on('beforeexpand', this.beforeExpand, this);
14828 onRemove: function(c){
14829 Ext.layout.AccordionLayout.superclass.onRemove.call(this, c);
14831 c.header.removeClass('x-accordion-hd');
14833 c.un('beforeexpand', this.beforeExpand, this);
14837 beforeExpand : function(p, anim){
14838 var ai = this.activeItem;
14841 delete this.activeItem;
14842 if (!ai.collapsed){
14843 ai.collapse({callback:function(){
14844 p.expand(anim || true);
14849 ai.collapse(this.animate);
14853 if(this.activeOnTop){
14854 p.el.dom.parentNode.insertBefore(p.el.dom, p.el.dom.parentNode.firstChild);
14861 setItemSize : function(item, size){
14862 if(this.fill && item){
14863 var hh = 0, i, ct = this.getRenderedItems(this.container), len = ct.length, p;
14865 for (i = 0; i < len; i++) {
14866 if((p = ct[i]) != item && !p.hidden){
14867 hh += p.header.getHeight();
14874 item.setSize(size);
14879 setActiveItem : function(item){
14880 this.setActive(item, true);
14884 setActive : function(item, expand){
14885 var ai = this.activeItem;
14886 item = this.container.getComponent(item);
14888 if(item.rendered && item.collapsed && expand){
14892 ai.fireEvent('deactivate', ai);
14894 this.activeItem = item;
14895 item.fireEvent('activate', item);
14900 Ext.Container.LAYOUTS.accordion = Ext.layout.AccordionLayout;
14903 Ext.layout.Accordion = Ext.layout.AccordionLayout;
14904 Ext.layout.TableLayout = Ext.extend(Ext.layout.ContainerLayout, {
14908 monitorResize:false,
14912 targetCls: 'x-table-layout-ct',
14918 setContainer : function(ct){
14919 Ext.layout.TableLayout.superclass.setContainer.call(this, ct);
14921 this.currentRow = 0;
14922 this.currentColumn = 0;
14927 onLayout : function(ct, target){
14928 var cs = ct.items.items, len = cs.length, c, i;
14931 target.addClass('x-table-layout-ct');
14933 this.table = target.createChild(
14934 Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
14936 this.renderAll(ct, target);
14940 getRow : function(index){
14941 var row = this.table.tBodies[0].childNodes[index];
14943 row = document.createElement('tr');
14944 this.table.tBodies[0].appendChild(row);
14950 getNextCell : function(c){
14951 var cell = this.getNextNonSpan(this.currentColumn, this.currentRow);
14952 var curCol = this.currentColumn = cell[0], curRow = this.currentRow = cell[1];
14953 for(var rowIndex = curRow; rowIndex < curRow + (c.rowspan || 1); rowIndex++){
14954 if(!this.cells[rowIndex]){
14955 this.cells[rowIndex] = [];
14957 for(var colIndex = curCol; colIndex < curCol + (c.colspan || 1); colIndex++){
14958 this.cells[rowIndex][colIndex] = true;
14961 var td = document.createElement('td');
14965 var cls = 'x-table-layout-cell';
14967 cls += ' ' + c.cellCls;
14969 td.className = cls;
14971 td.colSpan = c.colspan;
14974 td.rowSpan = c.rowspan;
14976 this.getRow(curRow).appendChild(td);
14981 getNextNonSpan: function(colIndex, rowIndex){
14982 var cols = this.columns;
14983 while((cols && colIndex >= cols) || (this.cells[rowIndex] && this.cells[rowIndex][colIndex])) {
14984 if(cols && colIndex >= cols){
14991 return [colIndex, rowIndex];
14995 renderItem : function(c, position, target){
14998 this.table = target.createChild(
14999 Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
15001 if(c && !c.rendered){
15002 c.render(this.getNextCell(c));
15003 this.configureItem(c);
15004 }else if(c && !this.isValidParent(c, target)){
15005 var container = this.getNextCell(c);
15006 container.insertBefore(c.getPositionEl().dom, null);
15007 c.container = Ext.get(container);
15008 this.configureItem(c);
15013 isValidParent : function(c, target){
15014 return c.getPositionEl().up('table', 5).dom.parentNode === (target.dom || target);
15017 destroy: function(){
15019 Ext.layout.TableLayout.superclass.destroy.call(this);
15025 Ext.Container.LAYOUTS['table'] = Ext.layout.TableLayout;
15026 Ext.layout.AbsoluteLayout = Ext.extend(Ext.layout.AnchorLayout, {
15028 extraCls: 'x-abs-layout-item',
15032 onLayout : function(ct, target){
15034 this.paddingLeft = target.getPadding('l');
15035 this.paddingTop = target.getPadding('t');
15036 Ext.layout.AbsoluteLayout.superclass.onLayout.call(this, ct, target);
15040 adjustWidthAnchor : function(value, comp){
15041 return value ? value - comp.getPosition(true)[0] + this.paddingLeft : value;
15045 adjustHeightAnchor : function(value, comp){
15046 return value ? value - comp.getPosition(true)[1] + this.paddingTop : value;
15050 Ext.Container.LAYOUTS['absolute'] = Ext.layout.AbsoluteLayout;
15052 Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, {
15054 defaultMargins : {left:0,top:0,right:0,bottom:0},
15061 monitorResize : true,
15064 extraCls : 'x-box-item',
15065 targetCls : 'x-box-layout-ct',
15066 innerCls : 'x-box-inner',
15068 constructor : function(config){
15069 Ext.layout.BoxLayout.superclass.constructor.call(this, config);
15071 if (Ext.isString(this.defaultMargins)) {
15072 this.defaultMargins = this.parseMargins(this.defaultMargins);
15075 var handler = this.overflowHandler;
15077 if (typeof handler == 'string') {
15083 var handlerType = 'none';
15084 if (handler && handler.type != undefined) {
15085 handlerType = handler.type;
15088 var constructor = Ext.layout.boxOverflow[handlerType];
15089 if (constructor[this.type]) {
15090 constructor = constructor[this.type];
15093 this.overflowHandler = new constructor(this, handler);
15097 onLayout: function(container, target) {
15098 Ext.layout.BoxLayout.superclass.onLayout.call(this, container, target);
15100 var tSize = this.getLayoutTargetSize(),
15101 items = this.getVisibleItems(container),
15102 calcs = this.calculateChildBoxes(items, tSize),
15103 boxes = calcs.boxes,
15107 if (tSize.width > 0) {
15108 var handler = this.overflowHandler,
15109 method = meta.tooNarrow ? 'handleOverflow' : 'clearOverflow';
15111 var results = handler[method](calcs, tSize);
15114 if (results.targetSize) {
15115 tSize = results.targetSize;
15118 if (results.recalculate) {
15119 items = this.getVisibleItems(container);
15120 calcs = this.calculateChildBoxes(items, tSize);
15121 boxes = calcs.boxes;
15127 this.layoutTargetLastSize = tSize;
15130 this.childBoxCache = calcs;
15132 this.updateInnerCtSize(tSize, calcs);
15133 this.updateChildBoxes(boxes);
15136 this.handleTargetOverflow(tSize, container, target);
15140 updateChildBoxes: function(boxes) {
15141 for (var i = 0, length = boxes.length; i < length; i++) {
15142 var box = boxes[i],
15143 comp = box.component;
15145 if (box.dirtySize) {
15146 comp.setSize(box.width, box.height);
15149 if (isNaN(box.left) || isNaN(box.top)) {
15153 comp.setPosition(box.left, box.top);
15158 updateInnerCtSize: function(tSize, calcs) {
15159 var align = this.align,
15160 padding = this.padding,
15161 width = tSize.width,
15162 height = tSize.height;
15164 if (this.type == 'hbox') {
15165 var innerCtWidth = width,
15166 innerCtHeight = calcs.meta.maxHeight + padding.top + padding.bottom;
15168 if (align == 'stretch') {
15169 innerCtHeight = height;
15170 } else if (align == 'middle') {
15171 innerCtHeight = Math.max(height, innerCtHeight);
15174 var innerCtHeight = height,
15175 innerCtWidth = calcs.meta.maxWidth + padding.left + padding.right;
15177 if (align == 'stretch') {
15178 innerCtWidth = width;
15179 } else if (align == 'center') {
15180 innerCtWidth = Math.max(width, innerCtWidth);
15184 this.innerCt.setSize(innerCtWidth || undefined, innerCtHeight || undefined);
15188 handleTargetOverflow: function(previousTargetSize, container, target) {
15189 var overflow = target.getStyle('overflow');
15191 if (overflow && overflow != 'hidden' &&!this.adjustmentPass) {
15192 var newTargetSize = this.getLayoutTargetSize();
15193 if (newTargetSize.width != previousTargetSize.width || newTargetSize.height != previousTargetSize.height){
15194 this.adjustmentPass = true;
15195 this.onLayout(container, target);
15199 delete this.adjustmentPass;
15203 isValidParent : function(c, target) {
15204 return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom;
15208 getVisibleItems: function(ct) {
15209 var ct = ct || this.container,
15210 t = ct.getLayoutTarget(),
15211 cti = ct.items.items,
15216 for (i = 0; i < len; i++) {
15217 if((c = cti[i]).rendered && this.isValidParent(c, t) && c.hidden !== true && c.collapsed !== true && c.shouldLayout !== false){
15226 renderAll : function(ct, target) {
15227 if (!this.innerCt) {
15229 this.innerCt = target.createChild({cls:this.innerCls});
15230 this.padding = this.parseMargins(this.padding);
15232 Ext.layout.BoxLayout.superclass.renderAll.call(this, ct, this.innerCt);
15235 getLayoutTargetSize : function() {
15236 var target = this.container.getLayoutTarget(), ret;
15239 ret = target.getViewSize();
15244 if (Ext.isIE && Ext.isStrict && ret.width == 0){
15245 ret = target.getStyleSize();
15248 ret.width -= target.getPadding('lr');
15249 ret.height -= target.getPadding('tb');
15256 renderItem : function(c) {
15257 if(Ext.isString(c.margins)){
15258 c.margins = this.parseMargins(c.margins);
15259 }else if(!c.margins){
15260 c.margins = this.defaultMargins;
15262 Ext.layout.BoxLayout.superclass.renderItem.apply(this, arguments);
15266 destroy: function() {
15267 Ext.destroy(this.overflowHandler);
15269 Ext.layout.BoxLayout.superclass.destroy.apply(this, arguments);
15275 Ext.ns('Ext.layout.boxOverflow');
15279 Ext.layout.boxOverflow.None = Ext.extend(Object, {
15280 constructor: function(layout, config) {
15281 this.layout = layout;
15283 Ext.apply(this, config || {});
15286 handleOverflow: Ext.emptyFn,
15288 clearOverflow: Ext.emptyFn
15292 Ext.layout.boxOverflow.none = Ext.layout.boxOverflow.None;
15294 Ext.layout.boxOverflow.Menu = Ext.extend(Ext.layout.boxOverflow.None, {
15296 afterCls: 'x-strip-right',
15299 noItemsMenuText : '<div class="x-toolbar-no-items">(None)</div>',
15301 constructor: function(layout) {
15302 Ext.layout.boxOverflow.Menu.superclass.constructor.apply(this, arguments);
15305 this.menuItems = [];
15309 createInnerElements: function() {
15310 if (!this.afterCt) {
15311 this.afterCt = this.layout.innerCt.insertSibling({cls: this.afterCls}, 'before');
15316 clearOverflow: function(calculations, targetSize) {
15317 var newWidth = targetSize.width + (this.afterCt ? this.afterCt.getWidth() : 0),
15318 items = this.menuItems;
15320 this.hideTrigger();
15322 for (var index = 0, length = items.length; index < length; index++) {
15323 items.pop().component.show();
15328 height: targetSize.height,
15335 showTrigger: function() {
15337 this.menuTrigger.show();
15341 hideTrigger: function() {
15342 if (this.menuTrigger != undefined) {
15343 this.menuTrigger.hide();
15348 beforeMenuShow: function(menu) {
15349 var items = this.menuItems,
15350 len = items.length,
15354 var needsSep = function(group, item){
15355 return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator);
15361 for (var i = 0; i < len; i++) {
15362 item = items[i].component;
15364 if (prev && (needsSep(item, prev) || needsSep(prev, item))) {
15368 this.addComponentToMenu(menu, item);
15373 if (menu.items.length < 1) {
15374 menu.add(this.noItemsMenuText);
15379 createMenuConfig : function(component, hideOnClick){
15380 var config = Ext.apply({}, component.initialConfig),
15381 group = component.toggleGroup;
15383 Ext.copyTo(config, component, [
15384 'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu'
15387 Ext.apply(config, {
15388 text : component.overflowText || component.text,
15389 hideOnClick: hideOnClick
15392 if (group || component.enableToggle) {
15393 Ext.apply(config, {
15395 checked: component.pressed,
15397 checkchange: function(item, checked){
15398 component.toggle(checked);
15404 delete config.ownerCt;
15405 delete config.xtype;
15412 addComponentToMenu : function(menu, component) {
15413 if (component instanceof Ext.Toolbar.Separator) {
15416 } else if (Ext.isFunction(component.isXType)) {
15417 if (component.isXType('splitbutton')) {
15418 menu.add(this.createMenuConfig(component, true));
15420 } else if (component.isXType('button')) {
15421 menu.add(this.createMenuConfig(component, !component.menu));
15423 } else if (component.isXType('buttongroup')) {
15424 component.items.each(function(item){
15425 this.addComponentToMenu(menu, item);
15432 clearMenu : function(){
15433 var menu = this.moreMenu;
15434 if (menu && menu.items) {
15435 menu.items.each(function(item){
15442 createMenu: function() {
15443 if (!this.menuTrigger) {
15444 this.createInnerElements();
15447 this.menu = new Ext.menu.Menu({
15448 ownerCt : this.layout.container,
15451 beforeshow: this.beforeMenuShow
15456 this.menuTrigger = new Ext.Button({
15457 iconCls : 'x-toolbar-more-icon',
15458 cls : 'x-toolbar-more',
15460 renderTo: this.afterCt
15466 destroy: function() {
15467 Ext.destroy(this.menu, this.menuTrigger);
15471 Ext.layout.boxOverflow.menu = Ext.layout.boxOverflow.Menu;
15475 Ext.layout.boxOverflow.HorizontalMenu = Ext.extend(Ext.layout.boxOverflow.Menu, {
15477 constructor: function() {
15478 Ext.layout.boxOverflow.HorizontalMenu.superclass.constructor.apply(this, arguments);
15481 layout = me.layout,
15482 origFunction = layout.calculateChildBoxes;
15484 layout.calculateChildBoxes = function(visibleItems, targetSize) {
15485 var calcs = origFunction.apply(layout, arguments),
15487 items = me.menuItems;
15491 var hiddenWidth = 0;
15492 for (var index = 0, length = items.length; index < length; index++) {
15493 hiddenWidth += items[index].width;
15496 meta.minimumWidth += hiddenWidth;
15497 meta.tooNarrow = meta.minimumWidth > targetSize.width;
15503 handleOverflow: function(calculations, targetSize) {
15504 this.showTrigger();
15506 var newWidth = targetSize.width - this.afterCt.getWidth(),
15507 boxes = calculations.boxes,
15509 recalculate = false;
15512 for (var index = 0, length = boxes.length; index < length; index++) {
15513 usedWidth += boxes[index].width;
15516 var spareWidth = newWidth - usedWidth,
15520 for (var index = 0, length = this.menuItems.length; index < length; index++) {
15521 var hidden = this.menuItems[index],
15522 comp = hidden.component,
15523 width = hidden.width;
15525 if (width < spareWidth) {
15528 spareWidth -= width;
15530 recalculate = true;
15537 this.menuItems = this.menuItems.slice(showCount);
15539 for (var i = boxes.length - 1; i >= 0; i--) {
15540 var item = boxes[i].component,
15541 right = boxes[i].left + boxes[i].width;
15543 if (right >= newWidth) {
15544 this.menuItems.unshift({
15546 width : boxes[i].width
15556 if (this.menuItems.length == 0) {
15557 this.hideTrigger();
15562 height: targetSize.height,
15565 recalculate: recalculate
15570 Ext.layout.boxOverflow.menu.hbox = Ext.layout.boxOverflow.HorizontalMenu;
15571 Ext.layout.boxOverflow.Scroller = Ext.extend(Ext.layout.boxOverflow.None, {
15573 animateScroll: true,
15576 scrollIncrement: 100,
15582 scrollRepeatInterval: 400,
15585 scrollDuration: 0.4,
15588 beforeCls: 'x-strip-left',
15591 afterCls: 'x-strip-right',
15594 scrollerCls: 'x-strip-scroller',
15597 beforeScrollerCls: 'x-strip-scroller-left',
15600 afterScrollerCls: 'x-strip-scroller-right',
15603 createWheelListener: function() {
15604 this.layout.innerCt.on({
15606 mousewheel: function(e) {
15609 this.scrollBy(e.getWheelDelta() * this.wheelIncrement * -1, false);
15615 handleOverflow: function(calculations, targetSize) {
15616 this.createInnerElements();
15617 this.showScrollers();
15621 clearOverflow: function() {
15622 this.hideScrollers();
15626 showScrollers: function() {
15627 this.createScrollers();
15629 this.beforeScroller.show();
15630 this.afterScroller.show();
15632 this.updateScrollButtons();
15636 hideScrollers: function() {
15637 if (this.beforeScroller != undefined) {
15638 this.beforeScroller.hide();
15639 this.afterScroller.hide();
15644 createScrollers: function() {
15645 if (!this.beforeScroller && !this.afterScroller) {
15646 var before = this.beforeCt.createChild({
15647 cls: String.format("{0} {1} ", this.scrollerCls, this.beforeScrollerCls)
15650 var after = this.afterCt.createChild({
15651 cls: String.format("{0} {1}", this.scrollerCls, this.afterScrollerCls)
15654 before.addClassOnOver(this.beforeScrollerCls + '-hover');
15655 after.addClassOnOver(this.afterScrollerCls + '-hover');
15657 before.setVisibilityMode(Ext.Element.DISPLAY);
15658 after.setVisibilityMode(Ext.Element.DISPLAY);
15660 this.beforeRepeater = new Ext.util.ClickRepeater(before, {
15661 interval: this.scrollRepeatInterval,
15662 handler : this.scrollLeft,
15666 this.afterRepeater = new Ext.util.ClickRepeater(after, {
15667 interval: this.scrollRepeatInterval,
15668 handler : this.scrollRight,
15673 this.beforeScroller = before;
15676 this.afterScroller = after;
15681 destroy: function() {
15682 Ext.destroy(this.beforeScroller, this.afterScroller, this.beforeRepeater, this.afterRepeater, this.beforeCt, this.afterCt);
15686 scrollBy: function(delta, animate) {
15687 this.scrollTo(this.getScrollPosition() + delta, animate);
15691 getItem: function(item) {
15692 if (Ext.isString(item)) {
15693 item = Ext.getCmp(item);
15694 } else if (Ext.isNumber(item)) {
15695 item = this.items[item];
15702 getScrollAnim: function() {
15704 duration: this.scrollDuration,
15705 callback: this.updateScrollButtons,
15711 updateScrollButtons: function() {
15712 if (this.beforeScroller == undefined || this.afterScroller == undefined) {
15716 var beforeMeth = this.atExtremeBefore() ? 'addClass' : 'removeClass',
15717 afterMeth = this.atExtremeAfter() ? 'addClass' : 'removeClass',
15718 beforeCls = this.beforeScrollerCls + '-disabled',
15719 afterCls = this.afterScrollerCls + '-disabled';
15721 this.beforeScroller[beforeMeth](beforeCls);
15722 this.afterScroller[afterMeth](afterCls);
15723 this.scrolling = false;
15727 atExtremeBefore: function() {
15728 return this.getScrollPosition() === 0;
15732 scrollLeft: function(animate) {
15733 this.scrollBy(-this.scrollIncrement, animate);
15737 scrollRight: function(animate) {
15738 this.scrollBy(this.scrollIncrement, animate);
15742 scrollToItem: function(item, animate) {
15743 item = this.getItem(item);
15745 if (item != undefined) {
15746 var visibility = this.getItemVisibility(item);
15748 if (!visibility.fullyVisible) {
15749 var box = item.getBox(true, true),
15752 if (visibility.hiddenRight) {
15753 newX -= (this.layout.innerCt.getWidth() - box.width);
15756 this.scrollTo(newX, animate);
15762 getItemVisibility: function(item) {
15763 var box = this.getItem(item).getBox(true, true),
15765 itemRight = box.x + box.width,
15766 scrollLeft = this.getScrollPosition(),
15767 scrollRight = this.layout.innerCt.getWidth() + scrollLeft;
15770 hiddenLeft : itemLeft < scrollLeft,
15771 hiddenRight : itemRight > scrollRight,
15772 fullyVisible: itemLeft > scrollLeft && itemRight < scrollRight
15777 Ext.layout.boxOverflow.scroller = Ext.layout.boxOverflow.Scroller;
15781 Ext.layout.boxOverflow.VerticalScroller = Ext.extend(Ext.layout.boxOverflow.Scroller, {
15782 scrollIncrement: 75,
15783 wheelIncrement : 2,
15785 handleOverflow: function(calculations, targetSize) {
15786 Ext.layout.boxOverflow.VerticalScroller.superclass.handleOverflow.apply(this, arguments);
15790 height: targetSize.height - (this.beforeCt.getHeight() + this.afterCt.getHeight()),
15791 width : targetSize.width
15797 createInnerElements: function() {
15798 var target = this.layout.innerCt;
15802 if (!this.beforeCt) {
15803 this.beforeCt = target.insertSibling({cls: this.beforeCls}, 'before');
15804 this.afterCt = target.insertSibling({cls: this.afterCls}, 'after');
15806 this.createWheelListener();
15811 scrollTo: function(position, animate) {
15812 var oldPosition = this.getScrollPosition(),
15813 newPosition = position.constrain(0, this.getMaxScrollBottom());
15815 if (newPosition != oldPosition && !this.scrolling) {
15816 if (animate == undefined) {
15817 animate = this.animateScroll;
15820 this.layout.innerCt.scrollTo('top', newPosition, animate ? this.getScrollAnim() : false);
15823 this.scrolling = true;
15825 this.scrolling = false;
15826 this.updateScrollButtons();
15832 getScrollPosition: function(){
15833 return parseInt(this.layout.innerCt.dom.scrollTop, 10) || 0;
15837 getMaxScrollBottom: function() {
15838 return this.layout.innerCt.dom.scrollHeight - this.layout.innerCt.getHeight();
15842 atExtremeAfter: function() {
15843 return this.getScrollPosition() >= this.getMaxScrollBottom();
15847 Ext.layout.boxOverflow.scroller.vbox = Ext.layout.boxOverflow.VerticalScroller;
15851 Ext.layout.boxOverflow.HorizontalScroller = Ext.extend(Ext.layout.boxOverflow.Scroller, {
15852 handleOverflow: function(calculations, targetSize) {
15853 Ext.layout.boxOverflow.HorizontalScroller.superclass.handleOverflow.apply(this, arguments);
15857 height: targetSize.height,
15858 width : targetSize.width - (this.beforeCt.getWidth() + this.afterCt.getWidth())
15864 createInnerElements: function() {
15865 var target = this.layout.innerCt;
15869 if (!this.beforeCt) {
15870 this.afterCt = target.insertSibling({cls: this.afterCls}, 'before');
15871 this.beforeCt = target.insertSibling({cls: this.beforeCls}, 'before');
15873 this.createWheelListener();
15878 scrollTo: function(position, animate) {
15879 var oldPosition = this.getScrollPosition(),
15880 newPosition = position.constrain(0, this.getMaxScrollRight());
15882 if (newPosition != oldPosition && !this.scrolling) {
15883 if (animate == undefined) {
15884 animate = this.animateScroll;
15887 this.layout.innerCt.scrollTo('left', newPosition, animate ? this.getScrollAnim() : false);
15890 this.scrolling = true;
15892 this.scrolling = false;
15893 this.updateScrollButtons();
15899 getScrollPosition: function(){
15900 return parseInt(this.layout.innerCt.dom.scrollLeft, 10) || 0;
15904 getMaxScrollRight: function() {
15905 return this.layout.innerCt.dom.scrollWidth - this.layout.innerCt.getWidth();
15909 atExtremeAfter: function() {
15910 return this.getScrollPosition() >= this.getMaxScrollRight();
15914 Ext.layout.boxOverflow.scroller.hbox = Ext.layout.boxOverflow.HorizontalScroller;
15915 Ext.layout.HBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
15925 calculateChildBoxes: function(visibleItems, targetSize) {
15926 var visibleCount = visibleItems.length,
15928 padding = this.padding,
15929 topOffset = padding.top,
15930 leftOffset = padding.left,
15931 paddingVert = topOffset + padding.bottom,
15932 paddingHoriz = leftOffset + padding.right,
15934 width = targetSize.width - this.scrollOffset,
15935 height = targetSize.height,
15936 availHeight = Math.max(0, height - paddingVert),
15938 isStart = this.pack == 'start',
15939 isCenter = this.pack == 'center',
15940 isEnd = this.pack == 'end',
15952 child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedWidth,
15953 horizMargins, vertMargins, stretchHeight;
15956 for (i = 0; i < visibleCount; i++) {
15957 child = visibleItems[i];
15958 childHeight = child.height;
15959 childWidth = child.width;
15960 canLayout = !child.hasLayout && typeof child.doLayout == 'function';
15963 if (typeof childWidth != 'number') {
15966 if (child.flex && !childWidth) {
15967 totalFlex += child.flex;
15973 if (!childWidth && canLayout) {
15977 childSize = child.getSize();
15978 childWidth = childSize.width;
15979 childHeight = childSize.height;
15983 childMargins = child.margins;
15984 horizMargins = childMargins.left + childMargins.right;
15986 nonFlexWidth += horizMargins + (childWidth || 0);
15987 desiredWidth += horizMargins + (child.flex ? child.minWidth || 0 : childWidth);
15988 minimumWidth += horizMargins + (child.minWidth || childWidth || 0);
15991 if (typeof childHeight != 'number') {
15995 childHeight = child.getHeight();
15998 maxHeight = Math.max(maxHeight, childHeight + childMargins.top + childMargins.bottom);
16003 height : childHeight || undefined,
16004 width : childWidth || undefined
16008 var shortfall = desiredWidth - width,
16009 tooNarrow = minimumWidth > width;
16012 var availableWidth = Math.max(0, width - nonFlexWidth - paddingHoriz);
16015 for (i = 0; i < visibleCount; i++) {
16016 boxes[i].width = visibleItems[i].minWidth || visibleItems[i].width || boxes[i].width;
16021 if (shortfall > 0) {
16022 var minWidths = [];
16025 for (var index = 0, length = visibleCount; index < length; index++) {
16026 var item = visibleItems[index],
16027 minWidth = item.minWidth || 0;
16032 boxes[index].width = minWidth;
16035 minWidth : minWidth,
16036 available: boxes[index].width - minWidth,
16043 minWidths.sort(function(a, b) {
16044 return a.available > b.available ? 1 : -1;
16048 for (var i = 0, length = minWidths.length; i < length; i++) {
16049 var itemIndex = minWidths[i].index;
16051 if (itemIndex == undefined) {
16055 var item = visibleItems[itemIndex],
16056 box = boxes[itemIndex],
16057 oldWidth = box.width,
16058 minWidth = item.minWidth,
16059 newWidth = Math.max(minWidth, oldWidth - Math.ceil(shortfall / (length - i))),
16060 reduction = oldWidth - newWidth;
16062 boxes[itemIndex].width = newWidth;
16063 shortfall -= reduction;
16067 var remainingWidth = availableWidth,
16068 remainingFlex = totalFlex;
16071 for (i = 0; i < visibleCount; i++) {
16072 child = visibleItems[i];
16075 childMargins = child.margins;
16076 vertMargins = childMargins.top + childMargins.bottom;
16078 if (isStart && child.flex && !child.width) {
16079 flexedWidth = Math.ceil((child.flex / remainingFlex) * remainingWidth);
16080 remainingWidth -= flexedWidth;
16081 remainingFlex -= child.flex;
16083 calcs.width = flexedWidth;
16084 calcs.dirtySize = true;
16091 leftOffset += availableWidth / 2;
16092 } else if (isEnd) {
16093 leftOffset += availableWidth;
16097 for (i = 0; i < visibleCount; i++) {
16098 child = visibleItems[i];
16101 childMargins = child.margins;
16102 leftOffset += childMargins.left;
16103 vertMargins = childMargins.top + childMargins.bottom;
16105 calcs.left = leftOffset;
16106 calcs.top = topOffset + childMargins.top;
16108 switch (this.align) {
16110 stretchHeight = availHeight - vertMargins;
16111 calcs.height = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000);
16112 calcs.dirtySize = true;
16115 stretchHeight = maxHeight - vertMargins;
16116 calcs.height = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000);
16117 calcs.dirtySize = true;
16120 var diff = availHeight - calcs.height - vertMargins;
16122 calcs.top = topOffset + vertMargins + (diff / 2);
16126 leftOffset += calcs.width + childMargins.right;
16132 maxHeight : maxHeight,
16133 nonFlexWidth: nonFlexWidth,
16134 desiredWidth: desiredWidth,
16135 minimumWidth: minimumWidth,
16136 shortfall : desiredWidth - width,
16137 tooNarrow : tooNarrow
16143 Ext.Container.LAYOUTS.hbox = Ext.layout.HBoxLayout;
16144 Ext.layout.VBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
16154 calculateChildBoxes: function(visibleItems, targetSize) {
16155 var visibleCount = visibleItems.length,
16157 padding = this.padding,
16158 topOffset = padding.top,
16159 leftOffset = padding.left,
16160 paddingVert = topOffset + padding.bottom,
16161 paddingHoriz = leftOffset + padding.right,
16163 width = targetSize.width - this.scrollOffset,
16164 height = targetSize.height,
16165 availWidth = Math.max(0, width - paddingHoriz),
16167 isStart = this.pack == 'start',
16168 isCenter = this.pack == 'center',
16169 isEnd = this.pack == 'end',
16181 child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedWidth,
16182 horizMargins, vertMargins, stretchWidth;
16185 for (i = 0; i < visibleCount; i++) {
16186 child = visibleItems[i];
16187 childHeight = child.height;
16188 childWidth = child.width;
16189 canLayout = !child.hasLayout && typeof child.doLayout == 'function';
16192 if (typeof childHeight != 'number') {
16195 if (child.flex && !childHeight) {
16196 totalFlex += child.flex;
16202 if (!childHeight && canLayout) {
16206 childSize = child.getSize();
16207 childWidth = childSize.width;
16208 childHeight = childSize.height;
16212 childMargins = child.margins;
16213 vertMargins = childMargins.top + childMargins.bottom;
16215 nonFlexHeight += vertMargins + (childHeight || 0);
16216 desiredHeight += vertMargins + (child.flex ? child.minHeight || 0 : childHeight);
16217 minimumHeight += vertMargins + (child.minHeight || childHeight || 0);
16220 if (typeof childWidth != 'number') {
16224 childWidth = child.getWidth();
16227 maxWidth = Math.max(maxWidth, childWidth + childMargins.left + childMargins.right);
16232 height : childHeight || undefined,
16233 width : childWidth || undefined
16237 var shortfall = desiredHeight - height,
16238 tooNarrow = minimumHeight > height;
16241 var availableHeight = Math.max(0, (height - nonFlexHeight - paddingVert));
16244 for (i = 0, length = visibleCount; i < length; i++) {
16245 boxes[i].height = visibleItems[i].minHeight || visibleItems[i].height || boxes[i].height;
16250 if (shortfall > 0) {
16251 var minHeights = [];
16254 for (var index = 0, length = visibleCount; index < length; index++) {
16255 var item = visibleItems[index],
16256 minHeight = item.minHeight || 0;
16261 boxes[index].height = minHeight;
16264 minHeight: minHeight,
16265 available: boxes[index].height - minHeight,
16272 minHeights.sort(function(a, b) {
16273 return a.available > b.available ? 1 : -1;
16277 for (var i = 0, length = minHeights.length; i < length; i++) {
16278 var itemIndex = minHeights[i].index;
16280 if (itemIndex == undefined) {
16284 var item = visibleItems[itemIndex],
16285 box = boxes[itemIndex],
16286 oldHeight = box.height,
16287 minHeight = item.minHeight,
16288 newHeight = Math.max(minHeight, oldHeight - Math.ceil(shortfall / (length - i))),
16289 reduction = oldHeight - newHeight;
16291 boxes[itemIndex].height = newHeight;
16292 shortfall -= reduction;
16296 var remainingHeight = availableHeight,
16297 remainingFlex = totalFlex;
16300 for (i = 0; i < visibleCount; i++) {
16301 child = visibleItems[i];
16304 childMargins = child.margins;
16305 horizMargins = childMargins.left + childMargins.right;
16307 if (isStart && child.flex && !child.height) {
16308 flexedHeight = Math.ceil((child.flex / remainingFlex) * remainingHeight);
16309 remainingHeight -= flexedHeight;
16310 remainingFlex -= child.flex;
16312 calcs.height = flexedHeight;
16313 calcs.dirtySize = true;
16320 topOffset += availableHeight / 2;
16321 } else if (isEnd) {
16322 topOffset += availableHeight;
16326 for (i = 0; i < visibleCount; i++) {
16327 child = visibleItems[i];
16330 childMargins = child.margins;
16331 topOffset += childMargins.top;
16332 horizMargins = childMargins.left + childMargins.right;
16335 calcs.left = leftOffset + childMargins.left;
16336 calcs.top = topOffset;
16338 switch (this.align) {
16340 stretchWidth = availWidth - horizMargins;
16341 calcs.width = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000);
16342 calcs.dirtySize = true;
16345 stretchWidth = maxWidth - horizMargins;
16346 calcs.width = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000);
16347 calcs.dirtySize = true;
16350 var diff = availWidth - calcs.width - horizMargins;
16352 calcs.left = leftOffset + horizMargins + (diff / 2);
16356 topOffset += calcs.height + childMargins.bottom;
16362 maxWidth : maxWidth,
16363 nonFlexHeight: nonFlexHeight,
16364 desiredHeight: desiredHeight,
16365 minimumHeight: minimumHeight,
16366 shortfall : desiredHeight - height,
16367 tooNarrow : tooNarrow
16373 Ext.Container.LAYOUTS.vbox = Ext.layout.VBoxLayout;
16375 Ext.layout.ToolbarLayout = Ext.extend(Ext.layout.ContainerLayout, {
16376 monitorResize : true,
16384 noItemsMenuText : '<div class="x-toolbar-no-items">(None)</div>',
16387 lastOverflow: false,
16391 '<table cellspacing="0" class="x-toolbar-ct">',
16394 '<td class="x-toolbar-left" align="{0}">',
16395 '<table cellspacing="0">',
16397 '<tr class="x-toolbar-left-row"></tr>',
16401 '<td class="x-toolbar-right" align="right">',
16402 '<table cellspacing="0" class="x-toolbar-right-ct">',
16406 '<table cellspacing="0">',
16408 '<tr class="x-toolbar-right-row"></tr>',
16413 '<table cellspacing="0">',
16415 '<tr class="x-toolbar-extras-row"></tr>',
16429 onLayout : function(ct, target) {
16431 if (!this.leftTr) {
16432 var align = ct.buttonAlign == 'center' ? 'center' : 'left';
16434 target.addClass('x-toolbar-layout-ct');
16435 target.insertHtml('beforeEnd', String.format(this.tableHTML, align));
16437 this.leftTr = target.child('tr.x-toolbar-left-row', true);
16438 this.rightTr = target.child('tr.x-toolbar-right-row', true);
16439 this.extrasTr = target.child('tr.x-toolbar-extras-row', true);
16441 if (this.hiddenItem == undefined) {
16443 this.hiddenItems = [];
16447 var side = ct.buttonAlign == 'right' ? this.rightTr : this.leftTr,
16448 items = ct.items.items,
16452 for (var i = 0, len = items.length, c; i < len; i++, position++) {
16456 side = this.rightTr;
16458 } else if (!c.rendered) {
16459 c.render(this.insertCell(c, side, position));
16460 this.configureItem(c);
16462 if (!c.xtbHidden && !this.isValidParent(c, side.childNodes[position])) {
16463 var td = this.insertCell(c, side, position);
16464 td.appendChild(c.getPositionEl().dom);
16465 c.container = Ext.get(td);
16471 this.cleanup(this.leftTr);
16472 this.cleanup(this.rightTr);
16473 this.cleanup(this.extrasTr);
16474 this.fitToSize(target);
16478 cleanup : function(el) {
16479 var cn = el.childNodes, i, c;
16481 for (i = cn.length-1; i >= 0 && (c = cn[i]); i--) {
16482 if (!c.firstChild) {
16489 insertCell : function(c, target, position) {
16490 var td = document.createElement('td');
16491 td.className = 'x-toolbar-cell';
16493 target.insertBefore(td, target.childNodes[position] || null);
16499 hideItem : function(item) {
16500 this.hiddenItems.push(item);
16502 item.xtbHidden = true;
16503 item.xtbWidth = item.getPositionEl().dom.parentNode.offsetWidth;
16508 unhideItem : function(item) {
16510 item.xtbHidden = false;
16511 this.hiddenItems.remove(item);
16515 getItemWidth : function(c) {
16516 return c.hidden ? (c.xtbWidth || 0) : c.getPositionEl().dom.parentNode.offsetWidth;
16520 fitToSize : function(target) {
16521 if (this.container.enableOverflow === false) {
16525 var width = target.dom.clientWidth,
16526 tableWidth = target.dom.firstChild.offsetWidth,
16527 clipWidth = width - this.triggerWidth,
16528 lastWidth = this.lastWidth || 0,
16530 hiddenItems = this.hiddenItems,
16531 hasHiddens = hiddenItems.length != 0,
16532 isLarger = width >= lastWidth;
16534 this.lastWidth = width;
16536 if (tableWidth > width || (hasHiddens && isLarger)) {
16537 var items = this.container.items.items,
16538 len = items.length,
16542 for (var i = 0; i < len; i++) {
16545 if (!item.isFill) {
16546 loopWidth += this.getItemWidth(item);
16547 if (loopWidth > clipWidth) {
16548 if (!(item.hidden || item.xtbHidden)) {
16549 this.hideItem(item);
16551 } else if (item.xtbHidden) {
16552 this.unhideItem(item);
16559 hasHiddens = hiddenItems.length != 0;
16564 if (!this.lastOverflow) {
16565 this.container.fireEvent('overflowchange', this.container, true);
16566 this.lastOverflow = true;
16568 } else if (this.more) {
16570 this.more.destroy();
16573 if (this.lastOverflow) {
16574 this.container.fireEvent('overflowchange', this.container, false);
16575 this.lastOverflow = false;
16581 createMenuConfig : function(component, hideOnClick){
16582 var config = Ext.apply({}, component.initialConfig),
16583 group = component.toggleGroup;
16585 Ext.copyTo(config, component, [
16586 'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu'
16589 Ext.apply(config, {
16590 text : component.overflowText || component.text,
16591 hideOnClick: hideOnClick
16594 if (group || component.enableToggle) {
16595 Ext.apply(config, {
16597 checked: component.pressed,
16599 checkchange: function(item, checked){
16600 component.toggle(checked);
16606 delete config.ownerCt;
16607 delete config.xtype;
16614 addComponentToMenu : function(menu, component) {
16615 if (component instanceof Ext.Toolbar.Separator) {
16618 } else if (Ext.isFunction(component.isXType)) {
16619 if (component.isXType('splitbutton')) {
16620 menu.add(this.createMenuConfig(component, true));
16622 } else if (component.isXType('button')) {
16623 menu.add(this.createMenuConfig(component, !component.menu));
16625 } else if (component.isXType('buttongroup')) {
16626 component.items.each(function(item){
16627 this.addComponentToMenu(menu, item);
16634 clearMenu : function(){
16635 var menu = this.moreMenu;
16636 if (menu && menu.items) {
16637 menu.items.each(function(item){
16644 beforeMoreShow : function(menu) {
16645 var items = this.container.items.items,
16646 len = items.length,
16650 var needsSep = function(group, item){
16651 return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator);
16656 for (var i = 0; i < len; i++) {
16658 if (item.xtbHidden) {
16659 if (prev && (needsSep(item, prev) || needsSep(prev, item))) {
16662 this.addComponentToMenu(menu, item);
16668 if (menu.items.length < 1) {
16669 menu.add(this.noItemsMenuText);
16674 initMore : function(){
16677 this.moreMenu = new Ext.menu.Menu({
16678 ownerCt : this.container,
16680 beforeshow: this.beforeMoreShow,
16686 this.more = new Ext.Button({
16687 iconCls: 'x-toolbar-more-icon',
16688 cls : 'x-toolbar-more',
16689 menu : this.moreMenu,
16690 ownerCt: this.container
16693 var td = this.insertCell(this.more, this.extrasTr, 100);
16694 this.more.render(td);
16698 destroy : function(){
16699 Ext.destroy(this.more, this.moreMenu);
16700 delete this.leftTr;
16701 delete this.rightTr;
16702 delete this.extrasTr;
16703 Ext.layout.ToolbarLayout.superclass.destroy.call(this);
16707 Ext.Container.LAYOUTS.toolbar = Ext.layout.ToolbarLayout;
16709 Ext.layout.MenuLayout = Ext.extend(Ext.layout.ContainerLayout, {
16710 monitorResize : true,
16714 setContainer : function(ct){
16715 this.monitorResize = !ct.floating;
16718 ct.on('autosize', this.doAutoSize, this);
16719 Ext.layout.MenuLayout.superclass.setContainer.call(this, ct);
16722 renderItem : function(c, position, target){
16723 if (!this.itemTpl) {
16724 this.itemTpl = Ext.layout.MenuLayout.prototype.itemTpl = new Ext.XTemplate(
16725 '<li id="{itemId}" class="{itemCls}">',
16726 '<tpl if="needsIcon">',
16727 '<img alt="{altText}" src="{icon}" class="{iconCls}"/>',
16733 if(c && !c.rendered){
16734 if(Ext.isNumber(position)){
16735 position = target.dom.childNodes[position];
16737 var a = this.getItemArgs(c);
16740 c.render(c.positionEl = position ?
16741 this.itemTpl.insertBefore(position, a, true) :
16742 this.itemTpl.append(target, a, true));
16745 c.positionEl.menuItemId = c.getItemId();
16749 if (!a.isMenuItem && a.needsIcon) {
16750 c.positionEl.addClass('x-menu-list-item-indent');
16752 this.configureItem(c);
16753 }else if(c && !this.isValidParent(c, target)){
16754 if(Ext.isNumber(position)){
16755 position = target.dom.childNodes[position];
16757 target.dom.insertBefore(c.getActionEl().dom, position || null);
16761 getItemArgs : function(c) {
16762 var isMenuItem = c instanceof Ext.menu.Item,
16763 canHaveIcon = !(isMenuItem || c instanceof Ext.menu.Separator);
16766 isMenuItem: isMenuItem,
16767 needsIcon: canHaveIcon && (c.icon || c.iconCls),
16768 icon: c.icon || Ext.BLANK_IMAGE_URL,
16769 iconCls: 'x-menu-item-icon ' + (c.iconCls || ''),
16770 itemId: 'x-menu-el-' + c.id,
16771 itemCls: 'x-menu-list-item ',
16772 altText: c.altText || ''
16777 isValidParent : function(c, target) {
16778 return c.el.up('li.x-menu-list-item', 5).dom.parentNode === (target.dom || target);
16781 onLayout : function(ct, target){
16782 Ext.layout.MenuLayout.superclass.onLayout.call(this, ct, target);
16786 doAutoSize : function(){
16787 var ct = this.container, w = ct.width;
16791 }else if(Ext.isIE){
16792 ct.setWidth(Ext.isStrict && (Ext.isIE7 || Ext.isIE8) ? 'auto' : ct.minWidth);
16793 var el = ct.getEl(), t = el.dom.offsetWidth;
16794 ct.setWidth(ct.getLayoutTarget().getWidth() + el.getFrameWidth('lr'));
16799 Ext.Container.LAYOUTS['menu'] = Ext.layout.MenuLayout;
16801 Ext.Viewport = Ext.extend(Ext.Container, {
16815 initComponent : function() {
16816 Ext.Viewport.superclass.initComponent.call(this);
16817 document.getElementsByTagName('html')[0].className += ' x-viewport';
16818 this.el = Ext.getBody();
16819 this.el.setHeight = Ext.emptyFn;
16820 this.el.setWidth = Ext.emptyFn;
16821 this.el.setSize = Ext.emptyFn;
16822 this.el.dom.scroll = 'no';
16823 this.allowDomMove = false;
16824 this.autoWidth = true;
16825 this.autoHeight = true;
16826 Ext.EventManager.onWindowResize(this.fireResize, this);
16827 this.renderTo = this.el;
16830 fireResize : function(w, h){
16831 this.fireEvent('resize', this, w, h, w, h);
16834 Ext.reg('viewport', Ext.Viewport);
16836 Ext.Panel = Ext.extend(Ext.Container, {
16881 baseCls : 'x-panel',
16883 collapsedCls : 'x-panel-collapsed',
16885 maskDisabled : true,
16887 animCollapse : Ext.enableFx,
16889 headerAsText : true,
16891 buttonAlign : 'right',
16895 collapseFirst : true,
16897 minButtonWidth : 75,
16902 preventBodyReset : false,
16905 padding: undefined,
16908 resizeEvent: 'bodyresize',
16913 toolTarget : 'header',
16914 collapseEl : 'bwrap',
16916 disabledClass : '',
16919 deferHeight : true,
16925 collapseDefaults : {
16930 initComponent : function(){
16931 Ext.Panel.superclass.initComponent.call(this);
16959 this.baseCls = 'x-plain';
16963 this.toolbars = [];
16966 this.elements += ',tbar';
16967 this.topToolbar = this.createToolbar(this.tbar);
16972 this.elements += ',bbar';
16973 this.bottomToolbar = this.createToolbar(this.bbar);
16977 if(this.header === true){
16978 this.elements += ',header';
16979 this.header = null;
16980 }else if(this.headerCfg || (this.title && this.header !== false)){
16981 this.elements += ',header';
16984 if(this.footerCfg || this.footer === true){
16985 this.elements += ',footer';
16986 this.footer = null;
16990 this.fbar = this.buttons;
16991 this.buttons = null;
16994 this.createFbar(this.fbar);
16997 this.on('render', this.doAutoLoad, this, {delay:10});
17002 createFbar : function(fbar){
17003 var min = this.minButtonWidth;
17004 this.elements += ',footer';
17005 this.fbar = this.createToolbar(fbar, {
17006 buttonAlign: this.buttonAlign,
17007 toolbarCls: 'x-panel-fbar',
17008 enableOverflow: false,
17009 defaults: function(c){
17011 minWidth: c.minWidth || min
17018 this.fbar.items.each(function(c){
17019 c.minWidth = c.minWidth || this.minButtonWidth;
17021 this.buttons = this.fbar.items.items;
17025 createToolbar: function(tb, options){
17028 if(Ext.isArray(tb)){
17033 result = tb.events ? Ext.apply(tb, options) : this.createComponent(Ext.apply({}, tb, options), 'toolbar');
17034 this.toolbars.push(result);
17039 createElement : function(name, pnode){
17041 pnode.appendChild(this[name].dom);
17045 if(name === 'bwrap' || this.elements.indexOf(name) != -1){
17046 if(this[name+'Cfg']){
17047 this[name] = Ext.fly(pnode).createChild(this[name+'Cfg']);
17049 var el = document.createElement('div');
17050 el.className = this[name+'Cls'];
17051 this[name] = Ext.get(pnode.appendChild(el));
17053 if(this[name+'CssClass']){
17054 this[name].addClass(this[name+'CssClass']);
17056 if(this[name+'Style']){
17057 this[name].applyStyles(this[name+'Style']);
17063 onRender : function(ct, position){
17064 Ext.Panel.superclass.onRender.call(this, ct, position);
17065 this.createClasses();
17073 if(this.collapsible && !this.hideCollapseTool){
17074 this.tools = this.tools ? this.tools.slice(0) : [];
17075 this.tools[this.collapseFirst?'unshift':'push']({
17077 handler : this.toggleCollapse,
17084 this.elements += (this.header !== false) ? ',header' : '';
17088 el.addClass(this.baseCls);
17090 this.header = el.down('.'+this.headerCls);
17091 this.bwrap = el.down('.'+this.bwrapCls);
17092 var cp = this.bwrap ? this.bwrap : el;
17093 this.tbar = cp.down('.'+this.tbarCls);
17094 this.body = cp.down('.'+this.bodyCls);
17095 this.bbar = cp.down('.'+this.bbarCls);
17096 this.footer = cp.down('.'+this.footerCls);
17097 this.fromMarkup = true;
17099 if (this.preventBodyReset === true) {
17100 el.addClass('x-panel-reset');
17103 el.addClass(this.cls);
17107 this.elements += ',footer';
17114 el.insertHtml('afterBegin', String.format(Ext.Element.boxMarkup, this.baseCls));
17116 this.createElement('header', d.firstChild.firstChild.firstChild);
17117 this.createElement('bwrap', d);
17120 bw = this.bwrap.dom;
17121 var ml = d.childNodes[1], bl = d.childNodes[2];
17122 bw.appendChild(ml);
17123 bw.appendChild(bl);
17125 var mc = bw.firstChild.firstChild.firstChild;
17126 this.createElement('tbar', mc);
17127 this.createElement('body', mc);
17128 this.createElement('bbar', mc);
17129 this.createElement('footer', bw.lastChild.firstChild.firstChild);
17132 this.bwrap.dom.lastChild.className += ' x-panel-nofooter';
17135 this.ft = Ext.get(this.bwrap.dom.lastChild);
17136 this.mc = Ext.get(mc);
17138 this.createElement('header', d);
17139 this.createElement('bwrap', d);
17142 bw = this.bwrap.dom;
17143 this.createElement('tbar', bw);
17144 this.createElement('body', bw);
17145 this.createElement('bbar', bw);
17146 this.createElement('footer', bw);
17149 this.body.addClass(this.bodyCls + '-noheader');
17151 this.tbar.addClass(this.tbarCls + '-noheader');
17156 if(Ext.isDefined(this.padding)){
17157 this.body.setStyle('padding', this.body.addUnits(this.padding));
17160 if(this.border === false){
17161 this.el.addClass(this.baseCls + '-noborder');
17162 this.body.addClass(this.bodyCls + '-noborder');
17164 this.header.addClass(this.headerCls + '-noborder');
17167 this.footer.addClass(this.footerCls + '-noborder');
17170 this.tbar.addClass(this.tbarCls + '-noborder');
17173 this.bbar.addClass(this.bbarCls + '-noborder');
17177 if(this.bodyBorder === false){
17178 this.body.addClass(this.bodyCls + '-noborder');
17181 this.bwrap.enableDisplayMode('block');
17184 this.header.unselectable();
17187 if(this.headerAsText){
17188 this.header.dom.innerHTML =
17189 '<span class="' + this.headerTextCls + '">'+this.header.dom.innerHTML+'</span>';
17192 this.setIconClass(this.iconCls);
17198 this.makeFloating(this.floating);
17201 if(this.collapsible && this.titleCollapse && this.header){
17202 this.mon(this.header, 'click', this.toggleCollapse, this);
17203 this.header.setStyle('cursor', 'pointer');
17206 this.addTool.apply(this, ts);
17211 this.footer.addClass('x-panel-btns');
17212 this.fbar.ownerCt = this;
17213 this.fbar.render(this.footer);
17214 this.footer.createChild({cls:'x-clear'});
17216 if(this.tbar && this.topToolbar){
17217 this.topToolbar.ownerCt = this;
17218 this.topToolbar.render(this.tbar);
17220 if(this.bbar && this.bottomToolbar){
17221 this.bottomToolbar.ownerCt = this;
17222 this.bottomToolbar.render(this.bbar);
17227 setIconClass : function(cls){
17228 var old = this.iconCls;
17229 this.iconCls = cls;
17230 if(this.rendered && this.header){
17232 this.header.addClass('x-panel-icon');
17233 this.header.replaceClass(old, this.iconCls);
17235 var hd = this.header,
17236 img = hd.child('img.x-panel-inline-icon');
17238 Ext.fly(img).replaceClass(old, this.iconCls);
17240 var hdspan = hd.child('span.' + this.headerTextCls);
17242 Ext.DomHelper.insertBefore(hdspan.dom, {
17243 tag:'img', alt: '', src: Ext.BLANK_IMAGE_URL, cls:'x-panel-inline-icon '+this.iconCls
17249 this.fireEvent('iconchange', this, cls, old);
17253 makeFloating : function(cfg){
17254 this.floating = true;
17255 this.el = new Ext.Layer(Ext.apply({}, cfg, {
17256 shadow: Ext.isDefined(this.shadow) ? this.shadow : 'sides',
17257 shadowOffset: this.shadowOffset,
17259 shim: this.shim === false ? false : undefined
17264 getTopToolbar : function(){
17265 return this.topToolbar;
17269 getBottomToolbar : function(){
17270 return this.bottomToolbar;
17274 getFooterToolbar : function() {
17279 addButton : function(config, handler, scope){
17281 this.createFbar([]);
17284 if(Ext.isString(config)){
17285 config = {text: config};
17287 config = Ext.apply({
17292 return this.fbar.add(config);
17296 addTool : function(){
17297 if(!this.rendered){
17301 Ext.each(arguments, function(arg){
17302 this.tools.push(arg);
17307 if(!this[this.toolTarget]){
17310 if(!this.toolTemplate){
17312 var tt = new Ext.Template(
17313 '<div class="x-tool x-tool-{id}"> </div>'
17315 tt.disableFormats = true;
17317 Ext.Panel.prototype.toolTemplate = tt;
17319 for(var i = 0, a = arguments, len = a.length; i < len; i++) {
17321 if(!this.tools[tc.id]){
17322 var overCls = 'x-tool-'+tc.id+'-over';
17323 var t = this.toolTemplate.insertFirst(this[this.toolTarget], tc, true);
17324 this.tools[tc.id] = t;
17325 t.enableDisplayMode('block');
17326 this.mon(t, 'click', this.createToolHandler(t, tc, overCls, this));
17328 this.mon(t, tc.on);
17334 if(Ext.isObject(tc.qtip)){
17335 Ext.QuickTips.register(Ext.apply({
17339 t.dom.qtip = tc.qtip;
17342 t.addClassOnOver(overCls);
17347 onLayout : function(shallow, force){
17348 Ext.Panel.superclass.onLayout.apply(this, arguments);
17349 if(this.hasLayout && this.toolbars.length > 0){
17350 Ext.each(this.toolbars, function(tb){
17351 tb.doLayout(undefined, force);
17357 syncHeight : function(){
17358 var h = this.toolbarHeight,
17360 lsh = this.lastSize.height,
17363 if(this.autoHeight || !Ext.isDefined(lsh) || lsh == 'auto'){
17368 if(h != this.getToolbarHeight()){
17369 h = Math.max(0, lsh - this.getFrameHeight());
17372 this.toolbarHeight = this.getToolbarHeight();
17373 this.onBodyResize(sz.width, sz.height);
17378 onShow : function(){
17380 return this.el.show();
17382 Ext.Panel.superclass.onShow.call(this);
17386 onHide : function(){
17388 return this.el.hide();
17390 Ext.Panel.superclass.onHide.call(this);
17394 createToolHandler : function(t, tc, overCls, panel){
17395 return function(e){
17396 t.removeClass(overCls);
17397 if(tc.stopEvent !== false){
17401 tc.handler.call(tc.scope || t, e, t, panel, tc);
17407 afterRender : function(){
17408 if(this.floating && !this.hidden){
17412 this.setTitle(this.title);
17414 Ext.Panel.superclass.afterRender.call(this);
17415 if (this.collapsed) {
17416 this.collapsed = false;
17417 this.collapse(false);
17423 getKeyMap : function(){
17425 this.keyMap = new Ext.KeyMap(this.el, this.keys);
17427 return this.keyMap;
17431 initEvents : function(){
17435 if(this.draggable){
17436 this.initDraggable();
17438 if(this.toolbars.length > 0){
17439 Ext.each(this.toolbars, function(tb){
17443 afterlayout: this.syncHeight,
17444 remove: this.syncHeight
17453 initDraggable : function(){
17455 this.dd = new Ext.Panel.DD(this, Ext.isBoolean(this.draggable) ? null : this.draggable);
17459 beforeEffect : function(anim){
17461 this.el.beforeAction();
17463 if(anim !== false){
17464 this.el.addClass('x-panel-animated');
17469 afterEffect : function(anim){
17471 this.el.removeClass('x-panel-animated');
17475 createEffect : function(a, cb, scope){
17483 }else if(!a.callback){
17486 o.callback = function(){
17488 Ext.callback(a.callback, a.scope);
17491 return Ext.applyIf(o, a);
17495 collapse : function(animate){
17496 if(this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforecollapse', this, animate) === false){
17499 var doAnim = animate === true || (animate !== false && this.animCollapse);
17500 this.beforeEffect(doAnim);
17501 this.onCollapse(doAnim, animate);
17506 onCollapse : function(doAnim, animArg){
17508 this[this.collapseEl].slideOut(this.slideAnchor,
17509 Ext.apply(this.createEffect(animArg||true, this.afterCollapse, this),
17510 this.collapseDefaults));
17512 this[this.collapseEl].hide(this.hideMode);
17513 this.afterCollapse(false);
17518 afterCollapse : function(anim){
17519 this.collapsed = true;
17520 this.el.addClass(this.collapsedCls);
17521 if(anim !== false){
17522 this[this.collapseEl].hide(this.hideMode);
17524 this.afterEffect(anim);
17527 this.cascade(function(c) {
17529 c.lastSize = { width: undefined, height: undefined };
17532 this.fireEvent('collapse', this);
17536 expand : function(animate){
17537 if(!this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforeexpand', this, animate) === false){
17540 var doAnim = animate === true || (animate !== false && this.animCollapse);
17541 this.el.removeClass(this.collapsedCls);
17542 this.beforeEffect(doAnim);
17543 this.onExpand(doAnim, animate);
17548 onExpand : function(doAnim, animArg){
17550 this[this.collapseEl].slideIn(this.slideAnchor,
17551 Ext.apply(this.createEffect(animArg||true, this.afterExpand, this),
17552 this.expandDefaults));
17554 this[this.collapseEl].show(this.hideMode);
17555 this.afterExpand(false);
17560 afterExpand : function(anim){
17561 this.collapsed = false;
17562 if(anim !== false){
17563 this[this.collapseEl].show(this.hideMode);
17565 this.afterEffect(anim);
17566 if (this.deferLayout) {
17567 delete this.deferLayout;
17568 this.doLayout(true);
17570 this.fireEvent('expand', this);
17574 toggleCollapse : function(animate){
17575 this[this.collapsed ? 'expand' : 'collapse'](animate);
17580 onDisable : function(){
17581 if(this.rendered && this.maskDisabled){
17584 Ext.Panel.superclass.onDisable.call(this);
17588 onEnable : function(){
17589 if(this.rendered && this.maskDisabled){
17592 Ext.Panel.superclass.onEnable.call(this);
17596 onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
17600 if(Ext.isDefined(w) || Ext.isDefined(h)){
17601 if(!this.collapsed){
17606 if(Ext.isNumber(w)){
17607 this.body.setWidth(w = this.adjustBodyWidth(w - this.getFrameWidth()));
17608 } else if (w == 'auto') {
17609 w = this.body.setWidth('auto').dom.offsetWidth;
17611 w = this.body.dom.offsetWidth;
17615 this.tbar.setWidth(w);
17616 if(this.topToolbar){
17617 this.topToolbar.setSize(w);
17621 this.bbar.setWidth(w);
17622 if(this.bottomToolbar){
17623 this.bottomToolbar.setSize(w);
17626 this.bbar.setStyle('position', 'static');
17627 this.bbar.setStyle('position', '');
17632 this.footer.setWidth(w);
17634 this.fbar.setSize(Ext.isIE ? (w - this.footer.getFrameWidth('lr')) : 'auto');
17639 if(Ext.isNumber(h)){
17640 h = Math.max(0, h - this.getFrameHeight());
17642 this.body.setHeight(h);
17643 }else if(h == 'auto'){
17644 this.body.setHeight(h);
17647 if(this.disabled && this.el._mask){
17648 this.el._mask.setSize(this.el.dom.clientWidth, this.el.getHeight());
17652 this.queuedBodySize = {width: w, height: h};
17653 if(!this.queuedExpand && this.allowQueuedExpand !== false){
17654 this.queuedExpand = true;
17655 this.on('expand', function(){
17656 delete this.queuedExpand;
17657 this.onResize(this.queuedBodySize.width, this.queuedBodySize.height);
17658 }, this, {single:true});
17661 this.onBodyResize(w, h);
17664 Ext.Panel.superclass.onResize.call(this, adjWidth, adjHeight, rawWidth, rawHeight);
17669 onBodyResize: function(w, h){
17670 this.fireEvent('bodyresize', this, w, h);
17674 getToolbarHeight: function(){
17677 Ext.each(this.toolbars, function(tb){
17678 h += tb.getHeight();
17685 adjustBodyHeight : function(h){
17690 adjustBodyWidth : function(w){
17695 onPosition : function(){
17700 getFrameWidth : function(){
17701 var w = this.el.getFrameWidth('lr') + this.bwrap.getFrameWidth('lr');
17704 var l = this.bwrap.dom.firstChild;
17705 w += (Ext.fly(l).getFrameWidth('l') + Ext.fly(l.firstChild).getFrameWidth('r'));
17706 w += this.mc.getFrameWidth('lr');
17712 getFrameHeight : function() {
17713 var h = this.el.getFrameWidth('tb') + this.bwrap.getFrameWidth('tb');
17714 h += (this.tbar ? this.tbar.getHeight() : 0) +
17715 (this.bbar ? this.bbar.getHeight() : 0);
17718 h += this.el.dom.firstChild.offsetHeight + this.ft.dom.offsetHeight + this.mc.getFrameWidth('tb');
17720 h += (this.header ? this.header.getHeight() : 0) +
17721 (this.footer ? this.footer.getHeight() : 0);
17727 getInnerWidth : function(){
17728 return this.getSize().width - this.getFrameWidth();
17732 getInnerHeight : function(){
17733 return this.body.getHeight();
17738 syncShadow : function(){
17740 this.el.sync(true);
17745 getLayoutTarget : function(){
17750 getContentTarget : function(){
17755 setTitle : function(title, iconCls){
17756 this.title = title;
17757 if(this.header && this.headerAsText){
17758 this.header.child('span').update(title);
17761 this.setIconClass(iconCls);
17763 this.fireEvent('titlechange', this, title);
17768 getUpdater : function(){
17769 return this.body.getUpdater();
17774 var um = this.body.getUpdater();
17775 um.update.apply(um, arguments);
17780 beforeDestroy : function(){
17781 Ext.Panel.superclass.beforeDestroy.call(this);
17783 this.header.removeAllListeners();
17786 for(var k in this.tools){
17787 Ext.destroy(this.tools[k]);
17790 if(this.toolbars.length > 0){
17791 Ext.each(this.toolbars, function(tb){
17792 tb.un('afterlayout', this.syncHeight, this);
17793 tb.un('remove', this.syncHeight, this);
17796 if(Ext.isArray(this.buttons)){
17797 while(this.buttons.length) {
17798 Ext.destroy(this.buttons[0]);
17820 Ext.destroy(this.toolbars);
17824 createClasses : function(){
17825 this.headerCls = this.baseCls + '-header';
17826 this.headerTextCls = this.baseCls + '-header-text';
17827 this.bwrapCls = this.baseCls + '-bwrap';
17828 this.tbarCls = this.baseCls + '-tbar';
17829 this.bodyCls = this.baseCls + '-body';
17830 this.bbarCls = this.baseCls + '-bbar';
17831 this.footerCls = this.baseCls + '-footer';
17835 createGhost : function(cls, useShim, appendTo){
17836 var el = document.createElement('div');
17837 el.className = 'x-panel-ghost ' + (cls ? cls : '');
17839 el.appendChild(this.el.dom.firstChild.cloneNode(true));
17841 Ext.fly(el.appendChild(document.createElement('ul'))).setHeight(this.bwrap.getHeight());
17842 el.style.width = this.el.dom.offsetWidth + 'px';;
17844 this.container.dom.appendChild(el);
17846 Ext.getDom(appendTo).appendChild(el);
17848 if(useShim !== false && this.el.useShim !== false){
17849 var layer = new Ext.Layer({shadow:false, useDisplay:true, constrain:false}, el);
17853 return new Ext.Element(el);
17858 doAutoLoad : function(){
17859 var u = this.body.getUpdater();
17861 u.setRenderer(this.renderer);
17863 u.update(Ext.isObject(this.autoLoad) ? this.autoLoad : {url: this.autoLoad});
17867 getTool : function(id) {
17868 return this.tools[id];
17873 Ext.reg('panel', Ext.Panel);
17875 Ext.Editor = function(field, config){
17877 this.field = Ext.create(field.field, 'textfield');
17878 config = Ext.apply({}, field);
17879 delete config.field;
17881 this.field = field;
17883 Ext.Editor.superclass.constructor.call(this, config);
17886 Ext.extend(Ext.Editor, Ext.Component, {
17905 swallowKeys : true,
17907 completeOnEnter : true,
17909 cancelOnEsc : true,
17913 initComponent : function(){
17914 Ext.Editor.superclass.initComponent.call(this);
17932 onRender : function(ct, position){
17933 this.el = new Ext.Layer({
17934 shadow: this.shadow,
17938 shadowOffset: this.shadowOffset || 4,
17940 constrain: this.constrain
17943 this.el.setZIndex(this.zIndex);
17945 this.el.setStyle("overflow", Ext.isGecko ? "auto" : "hidden");
17946 if(this.field.msgTarget != 'title'){
17947 this.field.msgTarget = 'qtip';
17949 this.field.inEditor = true;
17950 this.mon(this.field, {
17953 specialkey: this.onSpecialKey
17955 if(this.field.grow){
17956 this.mon(this.field, "autosize", this.el.sync, this.el, {delay:1});
17958 this.field.render(this.el).show();
17959 this.field.getEl().dom.name = '';
17960 if(this.swallowKeys){
17961 this.field.el.swallowEvent([
17969 onSpecialKey : function(field, e){
17970 var key = e.getKey(),
17971 complete = this.completeOnEnter && key == e.ENTER,
17972 cancel = this.cancelOnEsc && key == e.ESC;
17973 if(complete || cancel){
17976 this.completeEdit();
17980 if(field.triggerBlur){
17981 field.triggerBlur();
17984 this.fireEvent('specialkey', field, e);
17988 startEdit : function(el, value){
17990 this.completeEdit();
17992 this.boundEl = Ext.get(el);
17993 var v = value !== undefined ? value : this.boundEl.dom.innerHTML;
17994 if(!this.rendered){
17995 this.render(this.parentEl || document.body);
17997 if(this.fireEvent("beforestartedit", this, this.boundEl, v) !== false){
17998 this.startValue = v;
17999 this.field.reset();
18000 this.field.setValue(v);
18001 this.realign(true);
18002 this.editing = true;
18008 doAutoSize : function(){
18010 var sz = this.boundEl.getSize(),
18011 fs = this.field.getSize();
18013 switch(this.autoSize){
18015 this.setSize(sz.width, fs.height);
18018 this.setSize(fs.width, sz.height);
18021 this.setSize(fs.width, fs.height);
18024 this.setSize(sz.width, sz.height);
18030 setSize : function(w, h){
18031 delete this.field.lastSize;
18032 this.field.setSize(w, h);
18035 if(Ext.isGecko2 || Ext.isOpera || (Ext.isIE7 && Ext.isStrict)){
18037 this.el.setSize(w, h);
18044 realign : function(autoSize){
18045 if(autoSize === true){
18048 this.el.alignTo(this.boundEl, this.alignment, this.offsets);
18052 completeEdit : function(remainVisible){
18057 if (this.field.assertValue) {
18058 this.field.assertValue();
18060 var v = this.getValue();
18061 if(!this.field.isValid()){
18062 if(this.revertInvalid !== false){
18063 this.cancelEdit(remainVisible);
18067 if(String(v) === String(this.startValue) && this.ignoreNoChange){
18068 this.hideEdit(remainVisible);
18071 if(this.fireEvent("beforecomplete", this, v, this.startValue) !== false){
18072 v = this.getValue();
18073 if(this.updateEl && this.boundEl){
18074 this.boundEl.update(v);
18076 this.hideEdit(remainVisible);
18077 this.fireEvent("complete", this, v, this.startValue);
18082 onShow : function(){
18084 if(this.hideEl !== false){
18085 this.boundEl.hide();
18087 this.field.show().focus(false, true);
18088 this.fireEvent("startedit", this.boundEl, this.startValue);
18092 cancelEdit : function(remainVisible){
18094 var v = this.getValue();
18095 this.setValue(this.startValue);
18096 this.hideEdit(remainVisible);
18097 this.fireEvent("canceledit", this, v, this.startValue);
18102 hideEdit: function(remainVisible){
18103 if(remainVisible !== true){
18104 this.editing = false;
18110 onBlur : function(){
18112 if(this.allowBlur === true && this.editing && this.selectSameEditor !== true){
18113 this.completeEdit();
18118 onHide : function(){
18120 this.completeEdit();
18124 if(this.field.collapse){
18125 this.field.collapse();
18128 if(this.hideEl !== false){
18129 this.boundEl.show();
18134 setValue : function(v){
18135 this.field.setValue(v);
18139 getValue : function(){
18140 return this.field.getValue();
18143 beforeDestroy : function(){
18144 Ext.destroyMembers(this, 'field');
18146 delete this.parentEl;
18147 delete this.boundEl;
18150 Ext.reg('editor', Ext.Editor);
18152 Ext.ColorPalette = Ext.extend(Ext.Component, {
18155 itemCls : 'x-color-palette',
18159 clickEvent :'click',
18161 ctype : 'Ext.ColorPalette',
18164 allowReselect : false,
18168 '000000', '993300', '333300', '003300', '003366', '000080', '333399', '333333',
18169 '800000', 'FF6600', '808000', '008000', '008080', '0000FF', '666699', '808080',
18170 'FF0000', 'FF9900', '99CC00', '339966', '33CCCC', '3366FF', '800080', '969696',
18171 'FF00FF', 'FFCC00', 'FFFF00', '00FF00', '00FFFF', '00CCFF', '993366', 'C0C0C0',
18172 'FF99CC', 'FFCC99', 'FFFF99', 'CCFFCC', 'CCFFFF', '99CCFF', 'CC99FF', 'FFFFFF'
18179 initComponent : function(){
18180 Ext.ColorPalette.superclass.initComponent.call(this);
18187 this.on('select', this.handler, this.scope, true);
18192 onRender : function(container, position){
18197 Ext.ColorPalette.superclass.onRender.call(this, container, position);
18198 var t = this.tpl || new Ext.XTemplate(
18199 '<tpl for="."><a href="#" class="color-{.}" hidefocus="on"><em><span style="background:#{.}" unselectable="on"> </span></em></a></tpl>'
18201 t.overwrite(this.el, this.colors);
18202 this.mon(this.el, this.clickEvent, this.handleClick, this, {delegate: 'a'});
18203 if(this.clickEvent != 'click'){
18204 this.mon(this.el, 'click', Ext.emptyFn, this, {delegate: 'a', preventDefault: true});
18209 afterRender : function(){
18210 Ext.ColorPalette.superclass.afterRender.call(this);
18212 var s = this.value;
18214 this.select(s, true);
18219 handleClick : function(e, t){
18220 e.preventDefault();
18221 if(!this.disabled){
18222 var c = t.className.match(/(?:^|\s)color-(.{6})(?:\s|$)/)[1];
18223 this.select(c.toUpperCase());
18228 select : function(color, suppressEvent){
18229 color = color.replace('#', '');
18230 if(color != this.value || this.allowReselect){
18233 el.child('a.color-'+this.value).removeClass('x-color-palette-sel');
18235 el.child('a.color-'+color).addClass('x-color-palette-sel');
18236 this.value = color;
18237 if(suppressEvent !== true){
18238 this.fireEvent('select', this, color);
18245 Ext.reg('colorpalette', Ext.ColorPalette);
18246 Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
18248 todayText : 'Today',
18250 okText : ' OK ',
18252 cancelText : 'Cancel',
18256 todayTip : '{0} (Spacebar)',
18258 minText : 'This date is before the minimum date',
18260 maxText : 'This date is after the maximum date',
18264 disabledDaysText : 'Disabled',
18266 disabledDatesText : 'Disabled',
18268 monthNames : Date.monthNames,
18270 dayNames : Date.dayNames,
18272 nextText : 'Next Month (Control+Right)',
18274 prevText : 'Previous Month (Control+Left)',
18276 monthYearText : 'Choose a month (Control+Up/Down to move years)',
18289 focusOnSelect: true,
18296 initComponent : function(){
18297 Ext.DatePicker.superclass.initComponent.call(this);
18299 this.value = this.value ?
18300 this.value.clearTime(true) : new Date().clearTime();
18308 this.on('select', this.handler, this.scope || this);
18311 this.initDisabledDays();
18315 initDisabledDays : function(){
18316 if(!this.disabledDatesRE && this.disabledDates){
18317 var dd = this.disabledDates,
18318 len = dd.length - 1,
18321 Ext.each(dd, function(d, i){
18322 re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i];
18327 this.disabledDatesRE = new RegExp(re + ')');
18332 setDisabledDates : function(dd){
18333 if(Ext.isArray(dd)){
18334 this.disabledDates = dd;
18335 this.disabledDatesRE = null;
18337 this.disabledDatesRE = dd;
18339 this.initDisabledDays();
18340 this.update(this.value, true);
18344 setDisabledDays : function(dd){
18345 this.disabledDays = dd;
18346 this.update(this.value, true);
18350 setMinDate : function(dt){
18352 this.update(this.value, true);
18356 setMaxDate : function(dt){
18358 this.update(this.value, true);
18362 setValue : function(value){
18363 this.value = value.clearTime(true);
18364 this.update(this.value);
18368 getValue : function(){
18373 focus : function(){
18374 this.update(this.activeDate);
18378 onEnable: function(initial){
18379 Ext.DatePicker.superclass.onEnable.call(this);
18380 this.doDisabled(false);
18381 this.update(initial ? this.value : this.activeDate);
18389 onDisable : function(){
18390 Ext.DatePicker.superclass.onDisable.call(this);
18391 this.doDisabled(true);
18392 if(Ext.isIE && !Ext.isIE8){
18394 Ext.each([].concat(this.textNodes, this.el.query('th span')), function(el){
18395 Ext.fly(el).repaint();
18401 doDisabled : function(disabled){
18402 this.keyNav.setDisabled(disabled);
18403 this.prevRepeater.setDisabled(disabled);
18404 this.nextRepeater.setDisabled(disabled);
18405 if(this.showToday){
18406 this.todayKeyListener.setDisabled(disabled);
18407 this.todayBtn.setDisabled(disabled);
18412 onRender : function(container, position){
18414 '<table cellspacing="0">',
18415 '<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>',
18416 '<tr><td colspan="3"><table class="x-date-inner" cellspacing="0"><thead><tr>'],
18417 dn = this.dayNames,
18419 for(i = 0; i < 7; i++){
18420 var d = this.startDay+i;
18424 m.push('<th><span>', dn[d].substr(0,1), '</span></th>');
18426 m[m.length] = '</tr></thead><tbody><tr>';
18427 for(i = 0; i < 42; i++) {
18428 if(i % 7 === 0 && i !== 0){
18429 m[m.length] = '</tr><tr>';
18431 m[m.length] = '<td><a href="#" hidefocus="on" class="x-date-date" tabIndex="1"><em><span></span></em></a></td>';
18433 m.push('</tr></tbody></table></td></tr>',
18434 this.showToday ? '<tr><td colspan="3" class="x-date-bottom" align="center"></td></tr>' : '',
18435 '</table><div class="x-date-mp"></div>');
18437 var el = document.createElement('div');
18438 el.className = 'x-date-picker';
18439 el.innerHTML = m.join('');
18441 container.dom.insertBefore(el, position);
18443 this.el = Ext.get(el);
18444 this.eventEl = Ext.get(el.firstChild);
18446 this.prevRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-left a'), {
18447 handler: this.showPrevMonth,
18449 preventDefault:true,
18453 this.nextRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-right a'), {
18454 handler: this.showNextMonth,
18456 preventDefault:true,
18460 this.monthPicker = this.el.down('div.x-date-mp');
18461 this.monthPicker.enableDisplayMode('block');
18463 this.keyNav = new Ext.KeyNav(this.eventEl, {
18464 'left' : function(e){
18466 this.showPrevMonth();
18468 this.update(this.activeDate.add('d', -1));
18472 'right' : function(e){
18474 this.showNextMonth();
18476 this.update(this.activeDate.add('d', 1));
18480 'up' : function(e){
18482 this.showNextYear();
18484 this.update(this.activeDate.add('d', -7));
18488 'down' : function(e){
18490 this.showPrevYear();
18492 this.update(this.activeDate.add('d', 7));
18496 'pageUp' : function(e){
18497 this.showNextMonth();
18500 'pageDown' : function(e){
18501 this.showPrevMonth();
18504 'enter' : function(e){
18505 e.stopPropagation();
18512 this.el.unselectable();
18514 this.cells = this.el.select('table.x-date-inner tbody td');
18515 this.textNodes = this.el.query('table.x-date-inner tbody span');
18517 this.mbtn = new Ext.Button({
18519 tooltip: this.monthYearText,
18520 renderTo: this.el.child('td.x-date-middle', true)
18522 this.mbtn.el.child('em').addClass('x-btn-arrow');
18524 if(this.showToday){
18525 this.todayKeyListener = this.eventEl.addKeyListener(Ext.EventObject.SPACE, this.selectToday, this);
18526 var today = (new Date()).dateFormat(this.format);
18527 this.todayBtn = new Ext.Button({
18528 renderTo: this.el.child('td.x-date-bottom', true),
18529 text: String.format(this.todayText, today),
18530 tooltip: String.format(this.todayTip, today),
18531 handler: this.selectToday,
18535 this.mon(this.eventEl, 'mousewheel', this.handleMouseWheel, this);
18536 this.mon(this.eventEl, 'click', this.handleDateClick, this, {delegate: 'a.x-date-date'});
18537 this.mon(this.mbtn, 'click', this.showMonthPicker, this);
18538 this.onEnable(true);
18542 createMonthPicker : function(){
18543 if(!this.monthPicker.dom.firstChild){
18544 var buf = ['<table border="0" cellspacing="0">'];
18545 for(var i = 0; i < 6; i++){
18547 '<tr><td class="x-date-mp-month"><a href="#">', Date.getShortMonthName(i), '</a></td>',
18548 '<td class="x-date-mp-month x-date-mp-sep"><a href="#">', Date.getShortMonthName(i + 6), '</a></td>',
18550 '<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>' :
18551 '<td class="x-date-mp-year"><a href="#"></a></td><td class="x-date-mp-year"><a href="#"></a></td></tr>'
18555 '<tr class="x-date-mp-btns"><td colspan="4"><button type="button" class="x-date-mp-ok">',
18557 '</button><button type="button" class="x-date-mp-cancel">',
18559 '</button></td></tr>',
18562 this.monthPicker.update(buf.join(''));
18564 this.mon(this.monthPicker, 'click', this.onMonthClick, this);
18565 this.mon(this.monthPicker, 'dblclick', this.onMonthDblClick, this);
18567 this.mpMonths = this.monthPicker.select('td.x-date-mp-month');
18568 this.mpYears = this.monthPicker.select('td.x-date-mp-year');
18570 this.mpMonths.each(function(m, a, i){
18573 m.dom.xmonth = 5 + Math.round(i * 0.5);
18575 m.dom.xmonth = Math.round((i-1) * 0.5);
18582 showMonthPicker : function(){
18583 if(!this.disabled){
18584 this.createMonthPicker();
18585 var size = this.el.getSize();
18586 this.monthPicker.setSize(size);
18587 this.monthPicker.child('table').setSize(size);
18589 this.mpSelMonth = (this.activeDate || this.value).getMonth();
18590 this.updateMPMonth(this.mpSelMonth);
18591 this.mpSelYear = (this.activeDate || this.value).getFullYear();
18592 this.updateMPYear(this.mpSelYear);
18594 this.monthPicker.slideIn('t', {duration:0.2});
18599 updateMPYear : function(y){
18601 var ys = this.mpYears.elements;
18602 for(var i = 1; i <= 10; i++){
18603 var td = ys[i-1], y2;
18605 y2 = y + Math.round(i * 0.5);
18606 td.firstChild.innerHTML = y2;
18609 y2 = y - (5-Math.round(i * 0.5));
18610 td.firstChild.innerHTML = y2;
18613 this.mpYears.item(i-1)[y2 == this.mpSelYear ? 'addClass' : 'removeClass']('x-date-mp-sel');
18618 updateMPMonth : function(sm){
18619 this.mpMonths.each(function(m, a, i){
18620 m[m.dom.xmonth == sm ? 'addClass' : 'removeClass']('x-date-mp-sel');
18625 selectMPMonth : function(m){
18630 onMonthClick : function(e, t){
18632 var el = new Ext.Element(t), pn;
18633 if(el.is('button.x-date-mp-cancel')){
18634 this.hideMonthPicker();
18636 else if(el.is('button.x-date-mp-ok')){
18637 var d = new Date(this.mpSelYear, this.mpSelMonth, (this.activeDate || this.value).getDate());
18638 if(d.getMonth() != this.mpSelMonth){
18640 d = new Date(this.mpSelYear, this.mpSelMonth, 1).getLastDateOfMonth();
18643 this.hideMonthPicker();
18645 else if((pn = el.up('td.x-date-mp-month', 2))){
18646 this.mpMonths.removeClass('x-date-mp-sel');
18647 pn.addClass('x-date-mp-sel');
18648 this.mpSelMonth = pn.dom.xmonth;
18650 else if((pn = el.up('td.x-date-mp-year', 2))){
18651 this.mpYears.removeClass('x-date-mp-sel');
18652 pn.addClass('x-date-mp-sel');
18653 this.mpSelYear = pn.dom.xyear;
18655 else if(el.is('a.x-date-mp-prev')){
18656 this.updateMPYear(this.mpyear-10);
18658 else if(el.is('a.x-date-mp-next')){
18659 this.updateMPYear(this.mpyear+10);
18664 onMonthDblClick : function(e, t){
18666 var el = new Ext.Element(t), pn;
18667 if((pn = el.up('td.x-date-mp-month', 2))){
18668 this.update(new Date(this.mpSelYear, pn.dom.xmonth, (this.activeDate || this.value).getDate()));
18669 this.hideMonthPicker();
18671 else if((pn = el.up('td.x-date-mp-year', 2))){
18672 this.update(new Date(pn.dom.xyear, this.mpSelMonth, (this.activeDate || this.value).getDate()));
18673 this.hideMonthPicker();
18678 hideMonthPicker : function(disableAnim){
18679 if(this.monthPicker){
18680 if(disableAnim === true){
18681 this.monthPicker.hide();
18683 this.monthPicker.slideOut('t', {duration:0.2});
18689 showPrevMonth : function(e){
18690 this.update(this.activeDate.add('mo', -1));
18694 showNextMonth : function(e){
18695 this.update(this.activeDate.add('mo', 1));
18699 showPrevYear : function(){
18700 this.update(this.activeDate.add('y', -1));
18704 showNextYear : function(){
18705 this.update(this.activeDate.add('y', 1));
18709 handleMouseWheel : function(e){
18711 if(!this.disabled){
18712 var delta = e.getWheelDelta();
18714 this.showPrevMonth();
18715 } else if(delta < 0){
18716 this.showNextMonth();
18722 handleDateClick : function(e, t){
18724 if(!this.disabled && t.dateValue && !Ext.fly(t.parentNode).hasClass('x-date-disabled')){
18725 this.cancelFocus = this.focusOnSelect === false;
18726 this.setValue(new Date(t.dateValue));
18727 delete this.cancelFocus;
18728 this.fireEvent('select', this, this.value);
18733 selectToday : function(){
18734 if(this.todayBtn && !this.todayBtn.disabled){
18735 this.setValue(new Date().clearTime());
18736 this.fireEvent('select', this, this.value);
18741 update : function(date, forceRefresh){
18743 var vd = this.activeDate, vis = this.isVisible();
18744 this.activeDate = date;
18745 if(!forceRefresh && vd && this.el){
18746 var t = date.getTime();
18747 if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){
18748 this.cells.removeClass('x-date-selected');
18749 this.cells.each(function(c){
18750 if(c.dom.firstChild.dateValue == t){
18751 c.addClass('x-date-selected');
18752 if(vis && !this.cancelFocus){
18753 Ext.fly(c.dom.firstChild).focus(50);
18761 var days = date.getDaysInMonth(),
18762 firstOfMonth = date.getFirstDateOfMonth(),
18763 startingPos = firstOfMonth.getDay()-this.startDay;
18765 if(startingPos < 0){
18768 days += startingPos;
18770 var pm = date.add('mo', -1),
18771 prevStart = pm.getDaysInMonth()-startingPos,
18772 cells = this.cells.elements,
18773 textEls = this.textNodes,
18775 d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart, this.initHour)),
18776 today = new Date().clearTime().getTime(),
18777 sel = date.clearTime(true).getTime(),
18778 min = this.minDate ? this.minDate.clearTime(true) : Number.NEGATIVE_INFINITY,
18779 max = this.maxDate ? this.maxDate.clearTime(true) : Number.POSITIVE_INFINITY,
18780 ddMatch = this.disabledDatesRE,
18781 ddText = this.disabledDatesText,
18782 ddays = this.disabledDays ? this.disabledDays.join('') : false,
18783 ddaysText = this.disabledDaysText,
18784 format = this.format;
18786 if(this.showToday){
18787 var td = new Date().clearTime(),
18788 disable = (td < min || td > max ||
18789 (ddMatch && format && ddMatch.test(td.dateFormat(format))) ||
18790 (ddays && ddays.indexOf(td.getDay()) != -1));
18792 if(!this.disabled){
18793 this.todayBtn.setDisabled(disable);
18794 this.todayKeyListener[disable ? 'disable' : 'enable']();
18798 var setCellClass = function(cal, cell){
18800 var t = d.clearTime(true).getTime();
18801 cell.firstChild.dateValue = t;
18803 cell.className += ' x-date-today';
18804 cell.title = cal.todayText;
18807 cell.className += ' x-date-selected';
18809 Ext.fly(cell.firstChild).focus(50);
18814 cell.className = ' x-date-disabled';
18815 cell.title = cal.minText;
18819 cell.className = ' x-date-disabled';
18820 cell.title = cal.maxText;
18824 if(ddays.indexOf(d.getDay()) != -1){
18825 cell.title = ddaysText;
18826 cell.className = ' x-date-disabled';
18829 if(ddMatch && format){
18830 var fvalue = d.dateFormat(format);
18831 if(ddMatch.test(fvalue)){
18832 cell.title = ddText.replace('%0', fvalue);
18833 cell.className = ' x-date-disabled';
18839 for(; i < startingPos; i++) {
18840 textEls[i].innerHTML = (++prevStart);
18841 d.setDate(d.getDate()+1);
18842 cells[i].className = 'x-date-prevday';
18843 setCellClass(this, cells[i]);
18845 for(; i < days; i++){
18846 var intDay = i - startingPos + 1;
18847 textEls[i].innerHTML = (intDay);
18848 d.setDate(d.getDate()+1);
18849 cells[i].className = 'x-date-active';
18850 setCellClass(this, cells[i]);
18853 for(; i < 42; i++) {
18854 textEls[i].innerHTML = (++extraDays);
18855 d.setDate(d.getDate()+1);
18856 cells[i].className = 'x-date-nextday';
18857 setCellClass(this, cells[i]);
18860 this.mbtn.setText(this.monthNames[date.getMonth()] + ' ' + date.getFullYear());
18862 if(!this.internalRender){
18863 var main = this.el.dom.firstChild,
18864 w = main.offsetWidth;
18865 this.el.setWidth(w + this.el.getBorderWidth('lr'));
18866 Ext.fly(main).setWidth(w);
18867 this.internalRender = true;
18871 if(Ext.isOpera && !this.secondPass){
18872 main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + 'px';
18873 this.secondPass = true;
18874 this.update.defer(10, this, [date]);
18881 beforeDestroy : function() {
18893 delete this.textNodes;
18894 delete this.cells.elements;
18901 Ext.reg('datepicker', Ext.DatePicker);
18903 Ext.LoadMask = function(el, config){
18904 this.el = Ext.get(el);
18905 Ext.apply(this, config);
18909 beforeload: this.onBeforeLoad,
18911 exception: this.onLoad
18913 this.removeMask = Ext.value(this.removeMask, false);
18915 var um = this.el.getUpdater();
18916 um.showLoadIndicator = false;
18919 beforeupdate: this.onBeforeLoad,
18920 update: this.onLoad,
18921 failure: this.onLoad
18923 this.removeMask = Ext.value(this.removeMask, true);
18927 Ext.LoadMask.prototype = {
18931 msg : 'Loading...',
18933 msgCls : 'x-mask-loading',
18939 disable : function(){
18940 this.disabled = true;
18944 enable : function(){
18945 this.disabled = false;
18949 onLoad : function(){
18950 this.el.unmask(this.removeMask);
18954 onBeforeLoad : function(){
18955 if(!this.disabled){
18956 this.el.mask(this.msg, this.msgCls);
18962 this.onBeforeLoad();
18971 destroy : function(){
18973 this.store.un('beforeload', this.onBeforeLoad, this);
18974 this.store.un('load', this.onLoad, this);
18975 this.store.un('exception', this.onLoad, this);
18977 var um = this.el.getUpdater();
18978 um.un('beforeupdate', this.onBeforeLoad, this);
18979 um.un('update', this.onLoad, this);
18980 um.un('failure', this.onLoad, this);
18983 };Ext.ns('Ext.slider');
18986 Ext.slider.Thumb = Ext.extend(Object, {
18992 constructor: function(config) {
18994 Ext.apply(this, config || {}, {
18995 cls: 'x-slider-thumb',
19001 Ext.slider.Thumb.superclass.constructor.call(this, config);
19003 if (this.slider.vertical) {
19004 Ext.apply(this, Ext.slider.Thumb.Vertical);
19009 render: function() {
19010 this.el = this.slider.innerEl.insertFirst({cls: this.cls});
19016 enable: function() {
19017 this.disabled = false;
19018 this.el.removeClass(this.slider.disabledClass);
19022 disable: function() {
19023 this.disabled = true;
19024 this.el.addClass(this.slider.disabledClass);
19028 initEvents: function() {
19031 el.addClassOnOver('x-slider-thumb-over');
19033 this.tracker = new Ext.dd.DragTracker({
19034 onBeforeStart: this.onBeforeDragStart.createDelegate(this),
19035 onStart : this.onDragStart.createDelegate(this),
19036 onDrag : this.onDrag.createDelegate(this),
19037 onEnd : this.onDragEnd.createDelegate(this),
19042 this.tracker.initEl(el);
19046 onBeforeDragStart : function(e) {
19047 if (this.disabled) {
19050 this.slider.promoteThumb(this);
19056 onDragStart: function(e){
19057 this.el.addClass('x-slider-thumb-drag');
19058 this.dragging = true;
19059 this.dragStartValue = this.value;
19061 this.slider.fireEvent('dragstart', this.slider, e, this);
19065 onDrag: function(e) {
19066 var slider = this.slider,
19067 index = this.index,
19068 newValue = this.getNewValue();
19070 if (this.constrain) {
19071 var above = slider.thumbs[index + 1],
19072 below = slider.thumbs[index - 1];
19074 if (below != undefined && newValue <= below.value) newValue = below.value;
19075 if (above != undefined && newValue >= above.value) newValue = above.value;
19078 slider.setValue(index, newValue, false);
19079 slider.fireEvent('drag', slider, e, this);
19082 getNewValue: function() {
19083 var slider = this.slider,
19084 pos = slider.innerEl.translatePoints(this.tracker.getXY());
19086 return Ext.util.Format.round(slider.reverseValue(pos.left), slider.decimalPrecision);
19090 onDragEnd: function(e) {
19091 var slider = this.slider,
19092 value = this.value;
19094 this.el.removeClass('x-slider-thumb-drag');
19096 this.dragging = false;
19097 slider.fireEvent('dragend', slider, e);
19099 if (this.dragStartValue != value) {
19100 slider.fireEvent('changecomplete', slider, value, this);
19105 destroy: function(){
19106 Ext.destroyMembers(this, 'tracker', 'el');
19111 Ext.slider.MultiSlider = Ext.extend(Ext.BoxComponent, {
19120 decimalPrecision: 0,
19127 clickRange: [5,15],
19130 clickToChange : true,
19134 constrainThumbs: true,
19137 topThumbZIndex: 10000,
19140 initComponent : function(){
19141 if(!Ext.isDefined(this.value)){
19142 this.value = this.minValue;
19148 Ext.slider.MultiSlider.superclass.initComponent.call(this);
19150 this.keyIncrement = Math.max(this.increment, this.keyIncrement);
19172 if (this.values == undefined || Ext.isEmpty(this.values)) this.values = [0];
19174 var values = this.values;
19176 for (var i=0; i < values.length; i++) {
19177 this.addThumb(values[i]);
19181 Ext.apply(this, Ext.slider.Vertical);
19186 addThumb: function(value) {
19187 var thumb = new Ext.slider.Thumb({
19190 index : this.thumbs.length,
19191 constrain: this.constrainThumbs
19193 this.thumbs.push(thumb);
19196 if (this.rendered) thumb.render();
19200 promoteThumb: function(topThumb) {
19201 var thumbs = this.thumbs,
19204 for (var i = 0, j = thumbs.length; i < j; i++) {
19207 if (thumb == topThumb) {
19208 zIndex = this.topThumbZIndex;
19213 thumb.el.setStyle('zIndex', zIndex);
19218 onRender : function() {
19220 cls: 'x-slider ' + (this.vertical ? 'x-slider-vert' : 'x-slider-horz'),
19222 cls: 'x-slider-end',
19224 cls:'x-slider-inner',
19225 cn : [{tag:'a', cls:'x-slider-focus', href:"#", tabIndex: '-1', hidefocus:'on'}]
19230 Ext.slider.MultiSlider.superclass.onRender.apply(this, arguments);
19232 this.endEl = this.el.first();
19233 this.innerEl = this.endEl.first();
19234 this.focusEl = this.innerEl.child('.x-slider-focus');
19237 for (var i=0; i < this.thumbs.length; i++) {
19238 this.thumbs[i].render();
19242 var thumb = this.innerEl.child('.x-slider-thumb');
19243 this.halfThumb = (this.vertical ? thumb.getHeight() : thumb.getWidth()) / 2;
19249 initEvents : function(){
19250 this.mon(this.el, {
19252 mousedown: this.onMouseDown,
19253 keydown : this.onKeyDown
19256 this.focusEl.swallowEvent("click", true);
19260 onMouseDown : function(e){
19266 var thumbClicked = false;
19267 for (var i=0; i < this.thumbs.length; i++) {
19268 thumbClicked = thumbClicked || e.target == this.thumbs[i].el.dom;
19271 if (this.clickToChange && !thumbClicked) {
19272 var local = this.innerEl.translatePoints(e.getXY());
19273 this.onClickChange(local);
19279 onClickChange : function(local) {
19280 if (local.top > this.clickRange[0] && local.top < this.clickRange[1]) {
19282 var thumb = this.getNearest(local, 'left'),
19283 index = thumb.index;
19285 this.setValue(index, Ext.util.Format.round(this.reverseValue(local.left), this.decimalPrecision), undefined, true);
19290 getNearest: function(local, prop) {
19291 var localValue = prop == 'top' ? this.innerEl.getHeight() - local[prop] : local[prop],
19292 clickValue = this.reverseValue(localValue),
19293 nearestDistance = (this.maxValue - this.minValue) + 5,
19297 for (var i=0; i < this.thumbs.length; i++) {
19298 var thumb = this.thumbs[i],
19299 value = thumb.value,
19300 dist = Math.abs(value - clickValue);
19302 if (Math.abs(dist <= nearestDistance)) {
19305 nearestDistance = dist;
19312 onKeyDown : function(e){
19314 if(this.disabled || this.thumbs.length !== 1){
19315 e.preventDefault();
19318 var k = e.getKey(),
19324 val = e.ctrlKey ? this.maxValue : this.getValue(0) + this.keyIncrement;
19325 this.setValue(0, val, undefined, true);
19330 val = e.ctrlKey ? this.minValue : this.getValue(0) - this.keyIncrement;
19331 this.setValue(0, val, undefined, true);
19334 e.preventDefault();
19339 doSnap : function(value){
19340 if (!(this.increment && value)) {
19343 var newValue = value,
19344 inc = this.increment,
19348 if (m * 2 >= inc) {
19350 } else if (m * 2 < -inc) {
19354 return newValue.constrain(this.minValue, this.maxValue);
19358 afterRender : function(){
19359 Ext.slider.MultiSlider.superclass.afterRender.apply(this, arguments);
19361 for (var i=0; i < this.thumbs.length; i++) {
19362 var thumb = this.thumbs[i];
19364 if (thumb.value !== undefined) {
19365 var v = this.normalizeValue(thumb.value);
19367 if (v !== thumb.value) {
19369 this.setValue(i, v, false);
19371 this.moveThumb(i, this.translateValue(v), false);
19378 getRatio : function(){
19379 var w = this.innerEl.getWidth(),
19380 v = this.maxValue - this.minValue;
19381 return v == 0 ? w : (w/v);
19385 normalizeValue : function(v){
19386 v = this.doSnap(v);
19387 v = Ext.util.Format.round(v, this.decimalPrecision);
19388 v = v.constrain(this.minValue, this.maxValue);
19393 setMinValue : function(val){
19394 this.minValue = val;
19396 thumbs = this.thumbs,
19397 len = thumbs.length,
19400 for(; i < len; ++i){
19402 t.value = t.value < val ? val : t.value;
19408 setMaxValue : function(val){
19409 this.maxValue = val;
19411 thumbs = this.thumbs,
19412 len = thumbs.length,
19415 for(; i < len; ++i){
19417 t.value = t.value > val ? val : t.value;
19423 setValue : function(index, v, animate, changeComplete) {
19424 var thumb = this.thumbs[index],
19427 v = this.normalizeValue(v);
19429 if (v !== thumb.value && this.fireEvent('beforechange', this, v, thumb.value, thumb) !== false) {
19432 this.moveThumb(index, this.translateValue(v), animate !== false);
19433 this.fireEvent('change', this, v, thumb);
19434 if(changeComplete){
19435 this.fireEvent('changecomplete', this, v, thumb);
19442 translateValue : function(v) {
19443 var ratio = this.getRatio();
19444 return (v * ratio) - (this.minValue * ratio) - this.halfThumb;
19448 reverseValue : function(pos){
19449 var ratio = this.getRatio();
19450 return (pos + (this.minValue * ratio)) / ratio;
19454 moveThumb: function(index, v, animate){
19455 var thumb = this.thumbs[index].el;
19457 if(!animate || this.animate === false){
19460 thumb.shift({left: v, stopFx: true, duration:.35});
19465 focus : function(){
19466 this.focusEl.focus(10);
19470 onResize : function(w, h){
19471 var thumbs = this.thumbs,
19472 len = thumbs.length,
19476 for(; i < len; ++i){
19477 thumbs[i].el.stopFx();
19480 if(Ext.isNumber(w)){
19481 this.innerEl.setWidth(w - (this.el.getPadding('l') + this.endEl.getPadding('r')));
19484 Ext.slider.MultiSlider.superclass.onResize.apply(this, arguments);
19488 onDisable: function(){
19489 Ext.slider.MultiSlider.superclass.onDisable.call(this);
19491 for (var i=0; i < this.thumbs.length; i++) {
19492 var thumb = this.thumbs[i],
19500 var xy = el.getXY();
19503 this.innerEl.addClass(this.disabledClass).dom.disabled = true;
19505 if (!this.thumbHolder) {
19506 this.thumbHolder = this.endEl.createChild({cls: 'x-slider-thumb ' + this.disabledClass});
19509 this.thumbHolder.show().setXY(xy);
19515 onEnable: function(){
19516 Ext.slider.MultiSlider.superclass.onEnable.call(this);
19518 for (var i=0; i < this.thumbs.length; i++) {
19519 var thumb = this.thumbs[i],
19525 this.innerEl.removeClass(this.disabledClass).dom.disabled = false;
19527 if (this.thumbHolder) this.thumbHolder.hide();
19536 syncThumb : function() {
19537 if (this.rendered) {
19538 for (var i=0; i < this.thumbs.length; i++) {
19539 this.moveThumb(i, this.translateValue(this.thumbs[i].value));
19545 getValue : function(index) {
19546 return this.thumbs[index].value;
19550 getValues: function() {
19553 for (var i=0; i < this.thumbs.length; i++) {
19554 values.push(this.thumbs[i].value);
19561 beforeDestroy : function(){
19562 var thumbs = this.thumbs;
19563 for(var i = 0, len = thumbs.length; i < len; ++i){
19564 thumbs[i].destroy();
19567 Ext.destroyMembers(this, 'endEl', 'innerEl', 'focusEl', 'thumbHolder');
19568 Ext.slider.MultiSlider.superclass.beforeDestroy.call(this);
19572 Ext.reg('multislider', Ext.slider.MultiSlider);
19575 Ext.slider.SingleSlider = Ext.extend(Ext.slider.MultiSlider, {
19576 constructor: function(config) {
19577 config = config || {};
19579 Ext.applyIf(config, {
19580 values: [config.value || 0]
19583 Ext.slider.SingleSlider.superclass.constructor.call(this, config);
19587 getValue: function() {
19589 return Ext.slider.SingleSlider.superclass.getValue.call(this, 0);
19593 setValue: function(value, animate) {
19594 var args = Ext.toArray(arguments),
19600 if (len == 1 || (len <= 3 && typeof arguments[1] != 'number')) {
19604 return Ext.slider.SingleSlider.superclass.setValue.apply(this, args);
19608 syncThumb : function() {
19609 return Ext.slider.SingleSlider.superclass.syncThumb.apply(this, [0].concat(arguments));
19613 getNearest : function(){
19615 return this.thumbs[0];
19620 Ext.Slider = Ext.slider.SingleSlider;
19622 Ext.reg('slider', Ext.slider.SingleSlider);
19625 Ext.slider.Vertical = {
19626 onResize : function(w, h){
19627 this.innerEl.setHeight(h - (this.el.getPadding('t') + this.endEl.getPadding('b')));
19631 getRatio : function(){
19632 var h = this.innerEl.getHeight(),
19633 v = this.maxValue - this.minValue;
19637 moveThumb: function(index, v, animate) {
19638 var thumb = this.thumbs[index],
19641 if (!animate || this.animate === false) {
19644 el.shift({bottom: v, stopFx: true, duration:.35});
19648 onClickChange : function(local) {
19649 if (local.left > this.clickRange[0] && local.left < this.clickRange[1]) {
19650 var thumb = this.getNearest(local, 'top'),
19651 index = thumb.index,
19652 value = this.minValue + this.reverseValue(this.innerEl.getHeight() - local.top);
19654 this.setValue(index, Ext.util.Format.round(value, this.decimalPrecision), undefined, true);
19660 Ext.slider.Thumb.Vertical = {
19661 getNewValue: function() {
19662 var slider = this.slider,
19663 innerEl = slider.innerEl,
19664 pos = innerEl.translatePoints(this.tracker.getXY()),
19665 bottom = innerEl.getHeight() - pos.top;
19667 return slider.minValue + Ext.util.Format.round(bottom / slider.getRatio(), slider.decimalPrecision);
19671 Ext.ProgressBar = Ext.extend(Ext.BoxComponent, {
19673 baseCls : 'x-progress',
19682 initComponent : function(){
19683 Ext.ProgressBar.superclass.initComponent.call(this);
19691 onRender : function(ct, position){
19692 var tpl = new Ext.Template(
19693 '<div class="{cls}-wrap">',
19694 '<div class="{cls}-inner">',
19695 '<div class="{cls}-bar">',
19696 '<div class="{cls}-text">',
19697 '<div> </div>',
19700 '<div class="{cls}-text {cls}-text-back">',
19701 '<div> </div>',
19707 this.el = position ? tpl.insertBefore(position, {cls: this.baseCls}, true)
19708 : tpl.append(ct, {cls: this.baseCls}, true);
19711 this.el.dom.id = this.id;
19713 var inner = this.el.dom.firstChild;
19714 this.progressBar = Ext.get(inner.firstChild);
19718 this.textEl = Ext.get(this.textEl);
19719 delete this.textTopEl;
19722 this.textTopEl = Ext.get(this.progressBar.dom.firstChild);
19723 var textBackEl = Ext.get(inner.childNodes[1]);
19724 this.textTopEl.setStyle("z-index", 99).addClass('x-hidden');
19725 this.textEl = new Ext.CompositeElement([this.textTopEl.dom.firstChild, textBackEl.dom.firstChild]);
19726 this.textEl.setWidth(inner.offsetWidth);
19728 this.progressBar.setHeight(inner.offsetHeight);
19732 afterRender : function(){
19733 Ext.ProgressBar.superclass.afterRender.call(this);
19735 this.updateProgress(this.value, this.text);
19737 this.updateText(this.text);
19742 updateProgress : function(value, text, animate){
19743 this.value = value || 0;
19745 this.updateText(text);
19747 if(this.rendered && !this.isDestroyed){
19748 var w = Math.floor(value*this.el.dom.firstChild.offsetWidth);
19749 this.progressBar.setWidth(w, animate === true || (animate !== false && this.animate));
19750 if(this.textTopEl){
19752 this.textTopEl.removeClass('x-hidden').setWidth(w);
19755 this.fireEvent('update', this, value, text);
19760 wait : function(o){
19761 if(!this.waitTimer){
19764 this.updateText(o.text);
19765 this.waitTimer = Ext.TaskMgr.start({
19767 var inc = o.increment || 10;
19769 this.updateProgress(((((i+inc)%inc)+1)*(100/inc))*0.01, null, o.animate);
19771 interval: o.interval || 1000,
19772 duration: o.duration,
19773 onStop: function(){
19775 o.fn.apply(o.scope || this);
19786 isWaiting : function(){
19787 return this.waitTimer !== null;
19791 updateText : function(text){
19792 this.text = text || ' ';
19794 this.textEl.update(this.text);
19800 syncProgressBar : function(){
19802 this.updateProgress(this.value, this.text);
19808 setSize : function(w, h){
19809 Ext.ProgressBar.superclass.setSize.call(this, w, h);
19810 if(this.textTopEl){
19811 var inner = this.el.dom.firstChild;
19812 this.textEl.setSize(inner.offsetWidth, inner.offsetHeight);
19814 this.syncProgressBar();
19819 reset : function(hide){
19820 this.updateProgress(0);
19821 if(this.textTopEl){
19822 this.textTopEl.addClass('x-hidden');
19832 clearTimer : function(){
19833 if(this.waitTimer){
19834 this.waitTimer.onStop = null;
19835 Ext.TaskMgr.stop(this.waitTimer);
19836 this.waitTimer = null;
19840 onDestroy: function(){
19843 if(this.textEl.isComposite){
19844 this.textEl.clear();
19846 Ext.destroyMembers(this, 'textEl', 'progressBar', 'textTopEl');
19848 Ext.ProgressBar.superclass.onDestroy.call(this);
19851 Ext.reg('progress', Ext.ProgressBar);
19855 var Event=Ext.EventManager;
19856 var Dom=Ext.lib.Dom;
19859 Ext.dd.DragDrop = function(id, sGroup, config) {
19861 this.init(id, sGroup, config);
19865 Ext.dd.DragDrop.prototype = {
19882 invalidHandleTypes: null,
19885 invalidHandleIds: null,
19888 invalidHandleClasses: null,
19904 this.locked = true;
19911 unlock: function() {
19912 this.locked = false;
19925 __ygDragDrop: true,
19946 maintainOffset: false,
19955 primaryButtonOnly: true,
19961 hasOuterHandles: false,
19964 b4StartDrag: function(x, y) { },
19967 startDrag: function(x, y) { },
19970 b4Drag: function(e) { },
19973 onDrag: function(e) { },
19976 onDragEnter: function(e, id) { },
19979 b4DragOver: function(e) { },
19982 onDragOver: function(e, id) { },
19985 b4DragOut: function(e) { },
19988 onDragOut: function(e, id) { },
19991 b4DragDrop: function(e) { },
19994 onDragDrop: function(e, id) { },
19997 onInvalidDrop: function(e) { },
20000 b4EndDrag: function(e) { },
20003 endDrag: function(e) { },
20006 b4MouseDown: function(e) { },
20009 onMouseDown: function(e) { },
20012 onMouseUp: function(e) { },
20015 onAvailable: function () {
20019 defaultPadding : {left:0, right:0, top:0, bottom:0},
20022 constrainTo : function(constrainTo, pad, inContent){
20023 if(Ext.isNumber(pad)){
20024 pad = {left: pad, right:pad, top:pad, bottom:pad};
20026 pad = pad || this.defaultPadding;
20027 var b = Ext.get(this.getEl()).getBox(),
20028 ce = Ext.get(constrainTo),
20029 s = ce.getScroll(),
20032 if(cd == document.body){
20033 c = { x: s.left, y: s.top, width: Ext.lib.Dom.getViewWidth(), height: Ext.lib.Dom.getViewHeight()};
20035 var xy = ce.getXY();
20036 c = {x : xy[0], y: xy[1], width: cd.clientWidth, height: cd.clientHeight};
20040 var topSpace = b.y - c.y,
20041 leftSpace = b.x - c.x;
20043 this.resetConstraints();
20044 this.setXConstraint(leftSpace - (pad.left||0),
20045 c.width - leftSpace - b.width - (pad.right||0),
20048 this.setYConstraint(topSpace - (pad.top||0),
20049 c.height - topSpace - b.height - (pad.bottom||0),
20055 getEl: function() {
20056 if (!this._domRef) {
20057 this._domRef = Ext.getDom(this.id);
20060 return this._domRef;
20064 getDragEl: function() {
20065 return Ext.getDom(this.dragElId);
20069 init: function(id, sGroup, config) {
20070 this.initTarget(id, sGroup, config);
20071 Event.on(this.id, "mousedown", this.handleMouseDown, this);
20076 initTarget: function(id, sGroup, config) {
20079 this.config = config || {};
20082 this.DDM = Ext.dd.DDM;
20088 if (typeof id !== "string") {
20096 this.addToGroup((sGroup) ? sGroup : "default");
20100 this.handleElId = id;
20103 this.setDragElId(id);
20106 this.invalidHandleTypes = { A: "A" };
20107 this.invalidHandleIds = {};
20108 this.invalidHandleClasses = [];
20110 this.applyConfig();
20112 this.handleOnAvailable();
20116 applyConfig: function() {
20120 this.padding = this.config.padding || [0, 0, 0, 0];
20121 this.isTarget = (this.config.isTarget !== false);
20122 this.maintainOffset = (this.config.maintainOffset);
20123 this.primaryButtonOnly = (this.config.primaryButtonOnly !== false);
20128 handleOnAvailable: function() {
20129 this.available = true;
20130 this.resetConstraints();
20131 this.onAvailable();
20135 setPadding: function(iTop, iRight, iBot, iLeft) {
20137 if (!iRight && 0 !== iRight) {
20138 this.padding = [iTop, iTop, iTop, iTop];
20139 } else if (!iBot && 0 !== iBot) {
20140 this.padding = [iTop, iRight, iTop, iRight];
20142 this.padding = [iTop, iRight, iBot, iLeft];
20147 setInitPosition: function(diffX, diffY) {
20148 var el = this.getEl();
20150 if (!this.DDM.verifyEl(el)) {
20154 var dx = diffX || 0;
20155 var dy = diffY || 0;
20157 var p = Dom.getXY( el );
20159 this.initPageX = p[0] - dx;
20160 this.initPageY = p[1] - dy;
20162 this.lastPageX = p[0];
20163 this.lastPageY = p[1];
20165 this.setStartPosition(p);
20169 setStartPosition: function(pos) {
20170 var p = pos || Dom.getXY( this.getEl() );
20171 this.deltaSetXY = null;
20173 this.startPageX = p[0];
20174 this.startPageY = p[1];
20178 addToGroup: function(sGroup) {
20179 this.groups[sGroup] = true;
20180 this.DDM.regDragDrop(this, sGroup);
20184 removeFromGroup: function(sGroup) {
20185 if (this.groups[sGroup]) {
20186 delete this.groups[sGroup];
20189 this.DDM.removeDDFromGroup(this, sGroup);
20193 setDragElId: function(id) {
20194 this.dragElId = id;
20198 setHandleElId: function(id) {
20199 if (typeof id !== "string") {
20202 this.handleElId = id;
20203 this.DDM.regHandle(this.id, id);
20207 setOuterHandleElId: function(id) {
20208 if (typeof id !== "string") {
20211 Event.on(id, "mousedown",
20212 this.handleMouseDown, this);
20213 this.setHandleElId(id);
20215 this.hasOuterHandles = true;
20219 unreg: function() {
20220 Event.un(this.id, "mousedown",
20221 this.handleMouseDown);
20222 this._domRef = null;
20223 this.DDM._remove(this);
20226 destroy : function(){
20231 isLocked: function() {
20232 return (this.DDM.isLocked() || this.locked);
20236 handleMouseDown: function(e, oDD){
20237 if (this.primaryButtonOnly && e.button != 0) {
20241 if (this.isLocked()) {
20245 this.DDM.refreshCache(this.groups);
20247 var pt = new Ext.lib.Point(Ext.lib.Event.getPageX(e), Ext.lib.Event.getPageY(e));
20248 if (!this.hasOuterHandles && !this.DDM.isOverTarget(pt, this) ) {
20250 if (this.clickValidator(e)) {
20253 this.setStartPosition();
20255 this.b4MouseDown(e);
20256 this.onMouseDown(e);
20258 this.DDM.handleMouseDown(e, this);
20260 this.DDM.stopEvent(e);
20268 clickValidator: function(e) {
20269 var target = e.getTarget();
20270 return ( this.isValidHandleChild(target) &&
20271 (this.id == this.handleElId ||
20272 this.DDM.handleWasClicked(target, this.id)) );
20276 addInvalidHandleType: function(tagName) {
20277 var type = tagName.toUpperCase();
20278 this.invalidHandleTypes[type] = type;
20282 addInvalidHandleId: function(id) {
20283 if (typeof id !== "string") {
20286 this.invalidHandleIds[id] = id;
20290 addInvalidHandleClass: function(cssClass) {
20291 this.invalidHandleClasses.push(cssClass);
20295 removeInvalidHandleType: function(tagName) {
20296 var type = tagName.toUpperCase();
20298 delete this.invalidHandleTypes[type];
20302 removeInvalidHandleId: function(id) {
20303 if (typeof id !== "string") {
20306 delete this.invalidHandleIds[id];
20310 removeInvalidHandleClass: function(cssClass) {
20311 for (var i=0, len=this.invalidHandleClasses.length; i<len; ++i) {
20312 if (this.invalidHandleClasses[i] == cssClass) {
20313 delete this.invalidHandleClasses[i];
20319 isValidHandleChild: function(node) {
20325 nodeName = node.nodeName.toUpperCase();
20327 nodeName = node.nodeName;
20329 valid = valid && !this.invalidHandleTypes[nodeName];
20330 valid = valid && !this.invalidHandleIds[node.id];
20332 for (var i=0, len=this.invalidHandleClasses.length; valid && i<len; ++i) {
20333 valid = !Ext.fly(node).hasClass(this.invalidHandleClasses[i]);
20342 setXTicks: function(iStartX, iTickSize) {
20344 this.xTickSize = iTickSize;
20348 for (var i = this.initPageX; i >= this.minX; i = i - iTickSize) {
20350 this.xTicks[this.xTicks.length] = i;
20355 for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) {
20357 this.xTicks[this.xTicks.length] = i;
20362 this.xTicks.sort(this.DDM.numericSort) ;
20366 setYTicks: function(iStartY, iTickSize) {
20368 this.yTickSize = iTickSize;
20372 for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) {
20374 this.yTicks[this.yTicks.length] = i;
20379 for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) {
20381 this.yTicks[this.yTicks.length] = i;
20386 this.yTicks.sort(this.DDM.numericSort) ;
20390 setXConstraint: function(iLeft, iRight, iTickSize) {
20391 this.leftConstraint = iLeft;
20392 this.rightConstraint = iRight;
20394 this.minX = this.initPageX - iLeft;
20395 this.maxX = this.initPageX + iRight;
20396 if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); }
20398 this.constrainX = true;
20402 clearConstraints: function() {
20403 this.constrainX = false;
20404 this.constrainY = false;
20409 clearTicks: function() {
20410 this.xTicks = null;
20411 this.yTicks = null;
20412 this.xTickSize = 0;
20413 this.yTickSize = 0;
20417 setYConstraint: function(iUp, iDown, iTickSize) {
20418 this.topConstraint = iUp;
20419 this.bottomConstraint = iDown;
20421 this.minY = this.initPageY - iUp;
20422 this.maxY = this.initPageY + iDown;
20423 if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); }
20425 this.constrainY = true;
20430 resetConstraints: function() {
20432 if (this.initPageX || this.initPageX === 0) {
20434 var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0;
20435 var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0;
20437 this.setInitPosition(dx, dy);
20441 this.setInitPosition();
20444 if (this.constrainX) {
20445 this.setXConstraint( this.leftConstraint,
20446 this.rightConstraint,
20450 if (this.constrainY) {
20451 this.setYConstraint( this.topConstraint,
20452 this.bottomConstraint,
20458 getTick: function(val, tickArray) {
20463 } else if (tickArray[0] >= val) {
20466 return tickArray[0];
20468 for (var i=0, len=tickArray.length; i<len; ++i) {
20470 if (tickArray[next] && tickArray[next] >= val) {
20471 var diff1 = val - tickArray[i];
20472 var diff2 = tickArray[next] - val;
20473 return (diff2 > diff1) ? tickArray[i] : tickArray[next];
20479 return tickArray[tickArray.length - 1];
20484 toString: function() {
20485 return ("DragDrop " + this.id);
20495 if (!Ext.dd.DragDropMgr) {
20498 Ext.dd.DragDropMgr = function() {
20500 var Event = Ext.EventManager;
20523 preventDefault: true,
20526 stopPropagation: true,
20529 initialized: false,
20536 this.initialized = true;
20549 _execOnAll: function(sMethod, args) {
20550 for (var i in this.ids) {
20551 for (var j in this.ids[i]) {
20552 var oDD = this.ids[i][j];
20553 if (! this.isTypeOfDD(oDD)) {
20556 oDD[sMethod].apply(oDD, args);
20562 _onLoad: function() {
20567 Event.on(document, "mouseup", this.handleMouseUp, this, true);
20568 Event.on(document, "mousemove", this.handleMouseMove, this, true);
20569 Event.on(window, "unload", this._onUnload, this, true);
20570 Event.on(window, "resize", this._onResize, this, true);
20576 _onResize: function(e) {
20577 this._execOnAll("resetConstraints", []);
20581 lock: function() { this.locked = true; },
20584 unlock: function() { this.locked = false; },
20587 isLocked: function() { return this.locked; },
20596 clickPixelThresh: 3,
20599 clickTimeThresh: 350,
20602 dragThreshMet: false,
20605 clickTimeout: null,
20614 regDragDrop: function(oDD, sGroup) {
20615 if (!this.initialized) { this.init(); }
20617 if (!this.ids[sGroup]) {
20618 this.ids[sGroup] = {};
20620 this.ids[sGroup][oDD.id] = oDD;
20624 removeDDFromGroup: function(oDD, sGroup) {
20625 if (!this.ids[sGroup]) {
20626 this.ids[sGroup] = {};
20629 var obj = this.ids[sGroup];
20630 if (obj && obj[oDD.id]) {
20631 delete obj[oDD.id];
20636 _remove: function(oDD) {
20637 for (var g in oDD.groups) {
20638 if (g && this.ids[g] && this.ids[g][oDD.id]) {
20639 delete this.ids[g][oDD.id];
20642 delete this.handleIds[oDD.id];
20646 regHandle: function(sDDId, sHandleId) {
20647 if (!this.handleIds[sDDId]) {
20648 this.handleIds[sDDId] = {};
20650 this.handleIds[sDDId][sHandleId] = sHandleId;
20654 isDragDrop: function(id) {
20655 return ( this.getDDById(id) ) ? true : false;
20659 getRelated: function(p_oDD, bTargetsOnly) {
20661 for (var i in p_oDD.groups) {
20662 for (var j in this.ids[i]) {
20663 var dd = this.ids[i][j];
20664 if (! this.isTypeOfDD(dd)) {
20667 if (!bTargetsOnly || dd.isTarget) {
20668 oDDs[oDDs.length] = dd;
20677 isLegalTarget: function (oDD, oTargetDD) {
20678 var targets = this.getRelated(oDD, true);
20679 for (var i=0, len=targets.length;i<len;++i) {
20680 if (targets[i].id == oTargetDD.id) {
20689 isTypeOfDD: function (oDD) {
20690 return (oDD && oDD.__ygDragDrop);
20694 isHandle: function(sDDId, sHandleId) {
20695 return ( this.handleIds[sDDId] &&
20696 this.handleIds[sDDId][sHandleId] );
20700 getDDById: function(id) {
20701 for (var i in this.ids) {
20702 if (this.ids[i][id]) {
20703 return this.ids[i][id];
20710 handleMouseDown: function(e, oDD) {
20712 Ext.QuickTips.ddDisable();
20714 if(this.dragCurrent){
20717 this.handleMouseUp(e);
20720 this.currentTarget = e.getTarget();
20721 this.dragCurrent = oDD;
20723 var el = oDD.getEl();
20726 this.startX = e.getPageX();
20727 this.startY = e.getPageY();
20729 this.deltaX = this.startX - el.offsetLeft;
20730 this.deltaY = this.startY - el.offsetTop;
20732 this.dragThreshMet = false;
20734 this.clickTimeout = setTimeout(
20736 var DDM = Ext.dd.DDM;
20737 DDM.startDrag(DDM.startX, DDM.startY);
20739 this.clickTimeThresh );
20743 startDrag: function(x, y) {
20744 clearTimeout(this.clickTimeout);
20745 if (this.dragCurrent) {
20746 this.dragCurrent.b4StartDrag(x, y);
20747 this.dragCurrent.startDrag(x, y);
20749 this.dragThreshMet = true;
20753 handleMouseUp: function(e) {
20756 Ext.QuickTips.ddEnable();
20758 if (! this.dragCurrent) {
20762 clearTimeout(this.clickTimeout);
20764 if (this.dragThreshMet) {
20765 this.fireEvents(e, true);
20775 stopEvent: function(e){
20776 if(this.stopPropagation) {
20777 e.stopPropagation();
20780 if (this.preventDefault) {
20781 e.preventDefault();
20786 stopDrag: function(e) {
20788 if (this.dragCurrent) {
20789 if (this.dragThreshMet) {
20790 this.dragCurrent.b4EndDrag(e);
20791 this.dragCurrent.endDrag(e);
20794 this.dragCurrent.onMouseUp(e);
20797 this.dragCurrent = null;
20798 this.dragOvers = {};
20802 handleMouseMove: function(e) {
20803 if (! this.dragCurrent) {
20809 if (Ext.isIE && (e.button !== 0 && e.button !== 1 && e.button !== 2)) {
20811 return this.handleMouseUp(e);
20814 if (!this.dragThreshMet) {
20815 var diffX = Math.abs(this.startX - e.getPageX());
20816 var diffY = Math.abs(this.startY - e.getPageY());
20817 if (diffX > this.clickPixelThresh ||
20818 diffY > this.clickPixelThresh) {
20819 this.startDrag(this.startX, this.startY);
20823 if (this.dragThreshMet) {
20824 this.dragCurrent.b4Drag(e);
20825 this.dragCurrent.onDrag(e);
20826 if(!this.dragCurrent.moveOnly){
20827 this.fireEvents(e, false);
20837 fireEvents: function(e, isDrop) {
20838 var dc = this.dragCurrent;
20842 if (!dc || dc.isLocked()) {
20846 var pt = e.getPoint();
20854 var enterEvts = [];
20858 for (var i in this.dragOvers) {
20860 var ddo = this.dragOvers[i];
20862 if (! this.isTypeOfDD(ddo)) {
20866 if (! this.isOverTarget(pt, ddo, this.mode)) {
20867 outEvts.push( ddo );
20870 oldOvers[i] = true;
20871 delete this.dragOvers[i];
20874 for (var sGroup in dc.groups) {
20876 if ("string" != typeof sGroup) {
20880 for (i in this.ids[sGroup]) {
20881 var oDD = this.ids[sGroup][i];
20882 if (! this.isTypeOfDD(oDD)) {
20886 if (oDD.isTarget && !oDD.isLocked() && ((oDD != dc) || (dc.ignoreSelf === false))) {
20887 if (this.isOverTarget(pt, oDD, this.mode)) {
20890 dropEvts.push( oDD );
20895 if (!oldOvers[oDD.id]) {
20896 enterEvts.push( oDD );
20899 overEvts.push( oDD );
20902 this.dragOvers[oDD.id] = oDD;
20910 if (outEvts.length) {
20911 dc.b4DragOut(e, outEvts);
20912 dc.onDragOut(e, outEvts);
20915 if (enterEvts.length) {
20916 dc.onDragEnter(e, enterEvts);
20919 if (overEvts.length) {
20920 dc.b4DragOver(e, overEvts);
20921 dc.onDragOver(e, overEvts);
20924 if (dropEvts.length) {
20925 dc.b4DragDrop(e, dropEvts);
20926 dc.onDragDrop(e, dropEvts);
20932 for (i=0, len=outEvts.length; i<len; ++i) {
20933 dc.b4DragOut(e, outEvts[i].id);
20934 dc.onDragOut(e, outEvts[i].id);
20938 for (i=0,len=enterEvts.length; i<len; ++i) {
20940 dc.onDragEnter(e, enterEvts[i].id);
20944 for (i=0,len=overEvts.length; i<len; ++i) {
20945 dc.b4DragOver(e, overEvts[i].id);
20946 dc.onDragOver(e, overEvts[i].id);
20950 for (i=0, len=dropEvts.length; i<len; ++i) {
20951 dc.b4DragDrop(e, dropEvts[i].id);
20952 dc.onDragDrop(e, dropEvts[i].id);
20958 if (isDrop && !dropEvts.length) {
20959 dc.onInvalidDrop(e);
20965 getBestMatch: function(dds) {
20973 var len = dds.length;
20979 for (var i=0; i<len; ++i) {
20984 if (dd.cursorIsOver) {
20990 winner.overlap.getArea() < dd.overlap.getArea()) {
21001 refreshCache: function(groups) {
21002 for (var sGroup in groups) {
21003 if ("string" != typeof sGroup) {
21006 for (var i in this.ids[sGroup]) {
21007 var oDD = this.ids[sGroup][i];
21009 if (this.isTypeOfDD(oDD)) {
21011 var loc = this.getLocation(oDD);
21013 this.locationCache[oDD.id] = loc;
21015 delete this.locationCache[oDD.id];
21026 verifyEl: function(el) {
21031 parent = el.offsetParent;
21034 parent = el.offsetParent;
21045 getLocation: function(oDD) {
21046 if (! this.isTypeOfDD(oDD)) {
21050 var el = oDD.getEl(), pos, x1, x2, y1, y2, t, r, b, l;
21053 pos= Ext.lib.Dom.getXY(el);
21061 x2 = x1 + el.offsetWidth;
21063 y2 = y1 + el.offsetHeight;
21065 t = y1 - oDD.padding[0];
21066 r = x2 + oDD.padding[1];
21067 b = y2 + oDD.padding[2];
21068 l = x1 - oDD.padding[3];
21070 return new Ext.lib.Region( t, r, b, l );
21074 isOverTarget: function(pt, oTarget, intersect) {
21076 var loc = this.locationCache[oTarget.id];
21077 if (!loc || !this.useCache) {
21078 loc = this.getLocation(oTarget);
21079 this.locationCache[oTarget.id] = loc;
21087 oTarget.cursorIsOver = loc.contains( pt );
21094 var dc = this.dragCurrent;
21095 if (!dc || !dc.getTargetCoord ||
21096 (!intersect && !dc.constrainX && !dc.constrainY)) {
21097 return oTarget.cursorIsOver;
21100 oTarget.overlap = null;
21106 var pos = dc.getTargetCoord(pt.x, pt.y);
21108 var el = dc.getDragEl();
21109 var curRegion = new Ext.lib.Region( pos.y,
21110 pos.x + el.offsetWidth,
21111 pos.y + el.offsetHeight,
21114 var overlap = curRegion.intersect(loc);
21117 oTarget.overlap = overlap;
21118 return (intersect) ? true : oTarget.cursorIsOver;
21125 _onUnload: function(e, me) {
21126 Ext.dd.DragDropMgr.unregAll();
21130 unregAll: function() {
21132 if (this.dragCurrent) {
21134 this.dragCurrent = null;
21137 this._execOnAll("unreg", []);
21139 for (var i in this.elementCache) {
21140 delete this.elementCache[i];
21143 this.elementCache = {};
21151 getElWrapper: function(id) {
21152 var oWrapper = this.elementCache[id];
21153 if (!oWrapper || !oWrapper.el) {
21154 oWrapper = this.elementCache[id] =
21155 new this.ElementWrapper(Ext.getDom(id));
21161 getElement: function(id) {
21162 return Ext.getDom(id);
21166 getCss: function(id) {
21167 var el = Ext.getDom(id);
21168 return (el) ? el.style : null;
21172 ElementWrapper: function(el) {
21174 this.el = el || null;
21176 this.id = this.el && el.id;
21178 this.css = this.el && el.style;
21182 getPosX: function(el) {
21183 return Ext.lib.Dom.getX(el);
21187 getPosY: function(el) {
21188 return Ext.lib.Dom.getY(el);
21192 swapNode: function(n1, n2) {
21196 var p = n2.parentNode;
21197 var s = n2.nextSibling;
21200 p.insertBefore(n1, n2);
21201 } else if (n2 == n1.nextSibling) {
21202 p.insertBefore(n2, n1);
21204 n1.parentNode.replaceChild(n2, n1);
21205 p.insertBefore(n1, s);
21211 getScroll: function () {
21212 var t, l, dde=document.documentElement, db=document.body;
21213 if (dde && (dde.scrollTop || dde.scrollLeft)) {
21215 l = dde.scrollLeft;
21222 return { top: t, left: l };
21226 getStyle: function(el, styleProp) {
21227 return Ext.fly(el).getStyle(styleProp);
21231 getScrollTop: function () {
21232 return this.getScroll().top;
21236 getScrollLeft: function () {
21237 return this.getScroll().left;
21241 moveToEl: function (moveEl, targetEl) {
21242 var aCoord = Ext.lib.Dom.getXY(targetEl);
21243 Ext.lib.Dom.setXY(moveEl, aCoord);
21247 numericSort: function(a, b) {
21255 _addListeners: function() {
21256 var DDM = Ext.dd.DDM;
21257 if ( Ext.lib.Event && document ) {
21260 if (DDM._timeoutCount > 2000) {
21262 setTimeout(DDM._addListeners, 10);
21263 if (document && document.body) {
21264 DDM._timeoutCount += 1;
21271 handleWasClicked: function(node, id) {
21272 if (this.isHandle(id, node.id)) {
21276 var p = node.parentNode;
21279 if (this.isHandle(id, p.id)) {
21295 Ext.dd.DDM = Ext.dd.DragDropMgr;
21296 Ext.dd.DDM._addListeners();
21301 Ext.dd.DD = function(id, sGroup, config) {
21303 this.init(id, sGroup, config);
21307 Ext.extend(Ext.dd.DD, Ext.dd.DragDrop, {
21313 autoOffset: function(iPageX, iPageY) {
21314 var x = iPageX - this.startPageX;
21315 var y = iPageY - this.startPageY;
21316 this.setDelta(x, y);
21320 setDelta: function(iDeltaX, iDeltaY) {
21321 this.deltaX = iDeltaX;
21322 this.deltaY = iDeltaY;
21326 setDragElPos: function(iPageX, iPageY) {
21330 var el = this.getDragEl();
21331 this.alignElWithMouse(el, iPageX, iPageY);
21335 alignElWithMouse: function(el, iPageX, iPageY) {
21336 var oCoord = this.getTargetCoord(iPageX, iPageY);
21337 var fly = el.dom ? el : Ext.fly(el, '_dd');
21338 if (!this.deltaSetXY) {
21339 var aCoord = [oCoord.x, oCoord.y];
21341 var newLeft = fly.getLeft(true);
21342 var newTop = fly.getTop(true);
21343 this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ];
21345 fly.setLeftTop(oCoord.x + this.deltaSetXY[0], oCoord.y + this.deltaSetXY[1]);
21348 this.cachePosition(oCoord.x, oCoord.y);
21349 this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
21354 cachePosition: function(iPageX, iPageY) {
21356 this.lastPageX = iPageX;
21357 this.lastPageY = iPageY;
21359 var aCoord = Ext.lib.Dom.getXY(this.getEl());
21360 this.lastPageX = aCoord[0];
21361 this.lastPageY = aCoord[1];
21366 autoScroll: function(x, y, h, w) {
21370 var clientH = Ext.lib.Dom.getViewHeight();
21373 var clientW = Ext.lib.Dom.getViewWidth();
21376 var st = this.DDM.getScrollTop();
21379 var sl = this.DDM.getScrollLeft();
21390 var toBot = (clientH + st - y - this.deltaY);
21393 var toRight = (clientW + sl - x - this.deltaX);
21403 var scrAmt = (document.all) ? 80 : 30;
21407 if ( bot > clientH && toBot < thresh ) {
21408 window.scrollTo(sl, st + scrAmt);
21413 if ( y < st && st > 0 && y - st < thresh ) {
21414 window.scrollTo(sl, st - scrAmt);
21419 if ( right > clientW && toRight < thresh ) {
21420 window.scrollTo(sl + scrAmt, st);
21425 if ( x < sl && sl > 0 && x - sl < thresh ) {
21426 window.scrollTo(sl - scrAmt, st);
21432 getTargetCoord: function(iPageX, iPageY) {
21433 var x = iPageX - this.deltaX;
21434 var y = iPageY - this.deltaY;
21436 if (this.constrainX) {
21437 if (x < this.minX) { x = this.minX; }
21438 if (x > this.maxX) { x = this.maxX; }
21441 if (this.constrainY) {
21442 if (y < this.minY) { y = this.minY; }
21443 if (y > this.maxY) { y = this.maxY; }
21446 x = this.getTick(x, this.xTicks);
21447 y = this.getTick(y, this.yTicks);
21454 applyConfig: function() {
21455 Ext.dd.DD.superclass.applyConfig.call(this);
21456 this.scroll = (this.config.scroll !== false);
21460 b4MouseDown: function(e) {
21462 this.autoOffset(e.getPageX(),
21467 b4Drag: function(e) {
21468 this.setDragElPos(e.getPageX(),
21472 toString: function() {
21473 return ("DD " + this.id);
21483 Ext.dd.DDProxy = function(id, sGroup, config) {
21485 this.init(id, sGroup, config);
21491 Ext.dd.DDProxy.dragElId = "ygddfdiv";
21493 Ext.extend(Ext.dd.DDProxy, Ext.dd.DD, {
21499 centerFrame: false,
21502 createFrame: function() {
21504 var body = document.body;
21506 if (!body || !body.firstChild) {
21507 setTimeout( function() { self.createFrame(); }, 50 );
21511 var div = this.getDragEl();
21514 div = document.createElement("div");
21515 div.id = this.dragElId;
21518 s.position = "absolute";
21519 s.visibility = "hidden";
21521 s.border = "2px solid #aaa";
21527 body.insertBefore(div, body.firstChild);
21532 initFrame: function() {
21533 this.createFrame();
21536 applyConfig: function() {
21537 Ext.dd.DDProxy.superclass.applyConfig.call(this);
21539 this.resizeFrame = (this.config.resizeFrame !== false);
21540 this.centerFrame = (this.config.centerFrame);
21541 this.setDragElId(this.config.dragElId || Ext.dd.DDProxy.dragElId);
21545 showFrame: function(iPageX, iPageY) {
21546 var el = this.getEl();
21547 var dragEl = this.getDragEl();
21548 var s = dragEl.style;
21550 this._resizeProxy();
21552 if (this.centerFrame) {
21553 this.setDelta( Math.round(parseInt(s.width, 10)/2),
21554 Math.round(parseInt(s.height, 10)/2) );
21557 this.setDragElPos(iPageX, iPageY);
21559 Ext.fly(dragEl).show();
21563 _resizeProxy: function() {
21564 if (this.resizeFrame) {
21565 var el = this.getEl();
21566 Ext.fly(this.getDragEl()).setSize(el.offsetWidth, el.offsetHeight);
21571 b4MouseDown: function(e) {
21572 var x = e.getPageX();
21573 var y = e.getPageY();
21574 this.autoOffset(x, y);
21575 this.setDragElPos(x, y);
21579 b4StartDrag: function(x, y) {
21581 this.showFrame(x, y);
21585 b4EndDrag: function(e) {
21586 Ext.fly(this.getDragEl()).hide();
21592 endDrag: function(e) {
21594 var lel = this.getEl();
21595 var del = this.getDragEl();
21598 del.style.visibility = "";
21603 lel.style.visibility = "hidden";
21604 Ext.dd.DDM.moveToEl(lel, del);
21605 del.style.visibility = "hidden";
21606 lel.style.visibility = "";
21611 beforeMove : function(){
21615 afterDrag : function(){
21619 toString: function() {
21620 return ("DDProxy " + this.id);
21625 Ext.dd.DDTarget = function(id, sGroup, config) {
21627 this.initTarget(id, sGroup, config);
21632 Ext.extend(Ext.dd.DDTarget, Ext.dd.DragDrop, {
21634 getDragEl: Ext.emptyFn,
21636 isValidHandleChild: Ext.emptyFn,
21638 startDrag: Ext.emptyFn,
21640 endDrag: Ext.emptyFn,
21642 onDrag: Ext.emptyFn,
21644 onDragDrop: Ext.emptyFn,
21646 onDragEnter: Ext.emptyFn,
21648 onDragOut: Ext.emptyFn,
21650 onDragOver: Ext.emptyFn,
21652 onInvalidDrop: Ext.emptyFn,
21654 onMouseDown: Ext.emptyFn,
21656 onMouseUp: Ext.emptyFn,
21658 setXConstraint: Ext.emptyFn,
21660 setYConstraint: Ext.emptyFn,
21662 resetConstraints: Ext.emptyFn,
21664 clearConstraints: Ext.emptyFn,
21666 clearTicks: Ext.emptyFn,
21668 setInitPosition: Ext.emptyFn,
21670 setDragElId: Ext.emptyFn,
21672 setHandleElId: Ext.emptyFn,
21674 setOuterHandleElId: Ext.emptyFn,
21676 addInvalidHandleClass: Ext.emptyFn,
21678 addInvalidHandleId: Ext.emptyFn,
21680 addInvalidHandleType: Ext.emptyFn,
21682 removeInvalidHandleClass: Ext.emptyFn,
21684 removeInvalidHandleId: Ext.emptyFn,
21686 removeInvalidHandleType: Ext.emptyFn,
21688 toString: function() {
21689 return ("DDTarget " + this.id);
21692 Ext.dd.DragTracker = Ext.extend(Ext.util.Observable, {
21700 constructor : function(config){
21701 Ext.apply(this, config);
21717 this.dragRegion = new Ext.lib.Region(0,0,0,0);
21720 this.initEl(this.el);
21722 Ext.dd.DragTracker.superclass.constructor.call(this, config);
21725 initEl: function(el){
21726 this.el = Ext.get(el);
21727 el.on('mousedown', this.onMouseDown, this,
21728 this.delegate ? {delegate: this.delegate} : undefined);
21731 destroy : function(){
21732 this.el.un('mousedown', this.onMouseDown, this);
21736 onMouseDown: function(e, target){
21737 if(this.fireEvent('mousedown', this, e) !== false && this.onBeforeStart(e) !== false){
21738 this.startXY = this.lastXY = e.getXY();
21739 this.dragTarget = this.delegate ? target : this.el.dom;
21740 if(this.preventDefault !== false){
21741 e.preventDefault();
21745 mouseup: this.onMouseUp,
21746 mousemove: this.onMouseMove,
21747 selectstart: this.stopSelect
21749 if(this.autoStart){
21750 this.timer = this.triggerStart.defer(this.autoStart === true ? 1000 : this.autoStart, this, [e]);
21755 onMouseMove: function(e, target){
21757 if(this.active && Ext.isIE && !e.browserEvent.button){
21758 e.preventDefault();
21763 e.preventDefault();
21764 var xy = e.getXY(), s = this.startXY;
21767 if(Math.abs(s[0]-xy[0]) > this.tolerance || Math.abs(s[1]-xy[1]) > this.tolerance){
21768 this.triggerStart(e);
21773 this.fireEvent('mousemove', this, e);
21775 this.fireEvent('drag', this, e);
21778 onMouseUp: function(e) {
21779 var doc = Ext.getDoc(),
21780 wasActive = this.active;
21782 doc.un('mousemove', this.onMouseMove, this);
21783 doc.un('mouseup', this.onMouseUp, this);
21784 doc.un('selectstart', this.stopSelect, this);
21785 e.preventDefault();
21787 this.active = false;
21788 delete this.elRegion;
21789 this.fireEvent('mouseup', this, e);
21792 this.fireEvent('dragend', this, e);
21796 triggerStart: function(e) {
21798 this.active = true;
21800 this.fireEvent('dragstart', this, e);
21803 clearStart : function() {
21805 clearTimeout(this.timer);
21810 stopSelect : function(e) {
21816 onBeforeStart : function(e) {
21821 onStart : function(xy) {
21826 onDrag : function(e) {
21831 onEnd : function(e) {
21836 getDragTarget : function(){
21837 return this.dragTarget;
21840 getDragCt : function(){
21844 getXY : function(constrain){
21846 this.constrainModes[constrain].call(this, this.lastXY) : this.lastXY;
21849 getOffset : function(constrain){
21850 var xy = this.getXY(constrain),
21852 return [s[0]-xy[0], s[1]-xy[1]];
21856 'point' : function(xy){
21858 if(!this.elRegion){
21859 this.elRegion = this.getDragCt().getRegion();
21862 var dr = this.dragRegion;
21869 dr.constrainTo(this.elRegion);
21871 return [dr.left, dr.top];
21875 Ext.dd.ScrollManager = function(){
21876 var ddm = Ext.dd.DragDropMgr;
21881 var onStop = function(e){
21886 var triggerRefresh = function(){
21887 if(ddm.dragCurrent){
21888 ddm.refreshCache(ddm.dragCurrent.groups);
21892 var doScroll = function(){
21893 if(ddm.dragCurrent){
21894 var dds = Ext.dd.ScrollManager;
21895 var inc = proc.el.ddScrollConfig ?
21896 proc.el.ddScrollConfig.increment : dds.increment;
21898 if(proc.el.scroll(proc.dir, inc)){
21902 proc.el.scroll(proc.dir, inc, true, dds.animDuration, triggerRefresh);
21907 var clearProc = function(){
21909 clearInterval(proc.id);
21916 var startProc = function(el, dir){
21920 var group = el.ddScrollConfig ? el.ddScrollConfig.ddGroup : undefined,
21921 freq = (el.ddScrollConfig && el.ddScrollConfig.frequency)
21922 ? el.ddScrollConfig.frequency
21923 : Ext.dd.ScrollManager.frequency;
21925 if (group === undefined || ddm.dragCurrent.ddGroup == group) {
21926 proc.id = setInterval(doScroll, freq);
21930 var onFire = function(e, isDrop){
21931 if(isDrop || !ddm.dragCurrent){ return; }
21932 var dds = Ext.dd.ScrollManager;
21933 if(!dragEl || dragEl != ddm.dragCurrent){
21934 dragEl = ddm.dragCurrent;
21936 dds.refreshCache();
21939 var xy = Ext.lib.Event.getXY(e);
21940 var pt = new Ext.lib.Point(xy[0], xy[1]);
21941 for(var id in els){
21942 var el = els[id], r = el._region;
21943 var c = el.ddScrollConfig ? el.ddScrollConfig : dds;
21944 if(r && r.contains(pt) && el.isScrollable()){
21945 if(r.bottom - pt.y <= c.vthresh){
21947 startProc(el, "down");
21950 }else if(r.right - pt.x <= c.hthresh){
21952 startProc(el, "left");
21955 }else if(pt.y - r.top <= c.vthresh){
21957 startProc(el, "up");
21960 }else if(pt.x - r.left <= c.hthresh){
21962 startProc(el, "right");
21971 ddm.fireEvents = ddm.fireEvents.createSequence(onFire, ddm);
21972 ddm.stopDrag = ddm.stopDrag.createSequence(onStop, ddm);
21976 register : function(el){
21977 if(Ext.isArray(el)){
21978 for(var i = 0, len = el.length; i < len; i++) {
21979 this.register(el[i]);
21988 unregister : function(el){
21989 if(Ext.isArray(el)){
21990 for(var i = 0, len = el.length; i < len; i++) {
21991 this.unregister(el[i]);
22017 ddGroup: undefined,
22020 refreshCache : function(){
22021 for(var id in els){
22022 if(typeof els[id] == 'object'){
22023 els[id]._region = els[id].getRegion();
22029 Ext.dd.Registry = function(){
22032 var autoIdSeed = 0;
22034 var getId = function(el, autogen){
22035 if(typeof el == "string"){
22039 if(!id && autogen !== false){
22040 id = "extdd-" + (++autoIdSeed);
22048 register : function(el, data){
22050 if(typeof el == "string"){
22051 el = document.getElementById(el);
22054 elements[getId(el)] = data;
22055 if(data.isHandle !== false){
22056 handles[data.ddel.id] = data;
22059 var hs = data.handles;
22060 for(var i = 0, len = hs.length; i < len; i++){
22061 handles[getId(hs[i])] = data;
22067 unregister : function(el){
22068 var id = getId(el, false);
22069 var data = elements[id];
22071 delete elements[id];
22073 var hs = data.handles;
22074 for(var i = 0, len = hs.length; i < len; i++){
22075 delete handles[getId(hs[i], false)];
22082 getHandle : function(id){
22083 if(typeof id != "string"){
22086 return handles[id];
22090 getHandleFromEvent : function(e){
22091 var t = Ext.lib.Event.getTarget(e);
22092 return t ? handles[t.id] : null;
22096 getTarget : function(id){
22097 if(typeof id != "string"){
22100 return elements[id];
22104 getTargetFromEvent : function(e){
22105 var t = Ext.lib.Event.getTarget(e);
22106 return t ? elements[t.id] || handles[t.id] : null;
22110 Ext.dd.StatusProxy = function(config){
22111 Ext.apply(this, config);
22112 this.id = this.id || Ext.id();
22113 this.el = new Ext.Layer({
22115 id: this.id, tag: "div", cls: "x-dd-drag-proxy "+this.dropNotAllowed, children: [
22116 {tag: "div", cls: "x-dd-drop-icon"},
22117 {tag: "div", cls: "x-dd-drag-ghost"}
22120 shadow: !config || config.shadow !== false
22122 this.ghost = Ext.get(this.el.dom.childNodes[1]);
22123 this.dropStatus = this.dropNotAllowed;
22126 Ext.dd.StatusProxy.prototype = {
22128 dropAllowed : "x-dd-drop-ok",
22130 dropNotAllowed : "x-dd-drop-nodrop",
22133 setStatus : function(cssClass){
22134 cssClass = cssClass || this.dropNotAllowed;
22135 if(this.dropStatus != cssClass){
22136 this.el.replaceClass(this.dropStatus, cssClass);
22137 this.dropStatus = cssClass;
22142 reset : function(clearGhost){
22143 this.el.dom.className = "x-dd-drag-proxy " + this.dropNotAllowed;
22144 this.dropStatus = this.dropNotAllowed;
22146 this.ghost.update("");
22151 update : function(html){
22152 if(typeof html == "string"){
22153 this.ghost.update(html);
22155 this.ghost.update("");
22156 html.style.margin = "0";
22157 this.ghost.dom.appendChild(html);
22159 var el = this.ghost.dom.firstChild;
22161 Ext.fly(el).setStyle('float', 'none');
22166 getEl : function(){
22171 getGhost : function(){
22176 hide : function(clear){
22185 if(this.anim && this.anim.isAnimated && this.anim.isAnimated()){
22201 repair : function(xy, callback, scope){
22202 this.callback = callback;
22203 this.scope = scope;
22204 if(xy && this.animRepair !== false){
22205 this.el.addClass("x-dd-drag-repair");
22206 this.el.hideUnders(true);
22207 this.anim = this.el.shift({
22208 duration: this.repairDuration || .5,
22212 callback: this.afterRepair,
22216 this.afterRepair();
22221 afterRepair : function(){
22223 if(typeof this.callback == "function"){
22224 this.callback.call(this.scope || this);
22226 this.callback = null;
22230 destroy: function(){
22231 Ext.destroy(this.ghost, this.el);
22234 Ext.dd.DragSource = function(el, config){
22235 this.el = Ext.get(el);
22236 if(!this.dragData){
22237 this.dragData = {};
22240 Ext.apply(this, config);
22243 this.proxy = new Ext.dd.StatusProxy();
22245 Ext.dd.DragSource.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group,
22246 {dragElId : this.proxy.id, resizeFrame: false, isTarget: false, scroll: this.scroll === true});
22248 this.dragging = false;
22251 Ext.extend(Ext.dd.DragSource, Ext.dd.DDProxy, {
22254 dropAllowed : "x-dd-drop-ok",
22256 dropNotAllowed : "x-dd-drop-nodrop",
22259 getDragData : function(e){
22260 return this.dragData;
22264 onDragEnter : function(e, id){
22265 var target = Ext.dd.DragDropMgr.getDDById(id);
22266 this.cachedTarget = target;
22267 if(this.beforeDragEnter(target, e, id) !== false){
22268 if(target.isNotifyTarget){
22269 var status = target.notifyEnter(this, e, this.dragData);
22270 this.proxy.setStatus(status);
22272 this.proxy.setStatus(this.dropAllowed);
22275 if(this.afterDragEnter){
22277 this.afterDragEnter(target, e, id);
22283 beforeDragEnter : function(target, e, id){
22288 alignElWithMouse: function() {
22289 Ext.dd.DragSource.superclass.alignElWithMouse.apply(this, arguments);
22294 onDragOver : function(e, id){
22295 var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
22296 if(this.beforeDragOver(target, e, id) !== false){
22297 if(target.isNotifyTarget){
22298 var status = target.notifyOver(this, e, this.dragData);
22299 this.proxy.setStatus(status);
22302 if(this.afterDragOver){
22304 this.afterDragOver(target, e, id);
22310 beforeDragOver : function(target, e, id){
22315 onDragOut : function(e, id){
22316 var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
22317 if(this.beforeDragOut(target, e, id) !== false){
22318 if(target.isNotifyTarget){
22319 target.notifyOut(this, e, this.dragData);
22321 this.proxy.reset();
22322 if(this.afterDragOut){
22324 this.afterDragOut(target, e, id);
22327 this.cachedTarget = null;
22331 beforeDragOut : function(target, e, id){
22336 onDragDrop : function(e, id){
22337 var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
22338 if(this.beforeDragDrop(target, e, id) !== false){
22339 if(target.isNotifyTarget){
22340 if(target.notifyDrop(this, e, this.dragData)){
22341 this.onValidDrop(target, e, id);
22343 this.onInvalidDrop(target, e, id);
22346 this.onValidDrop(target, e, id);
22349 if(this.afterDragDrop){
22351 this.afterDragDrop(target, e, id);
22354 delete this.cachedTarget;
22358 beforeDragDrop : function(target, e, id){
22363 onValidDrop : function(target, e, id){
22365 if(this.afterValidDrop){
22367 this.afterValidDrop(target, e, id);
22372 getRepairXY : function(e, data){
22373 return this.el.getXY();
22377 onInvalidDrop : function(target, e, id){
22378 this.beforeInvalidDrop(target, e, id);
22379 if(this.cachedTarget){
22380 if(this.cachedTarget.isNotifyTarget){
22381 this.cachedTarget.notifyOut(this, e, this.dragData);
22383 this.cacheTarget = null;
22385 this.proxy.repair(this.getRepairXY(e, this.dragData), this.afterRepair, this);
22387 if(this.afterInvalidDrop){
22389 this.afterInvalidDrop(e, id);
22394 afterRepair : function(){
22396 this.el.highlight(this.hlColor || "c3daf9");
22398 this.dragging = false;
22402 beforeInvalidDrop : function(target, e, id){
22407 handleMouseDown : function(e){
22408 if(this.dragging) {
22411 var data = this.getDragData(e);
22412 if(data && this.onBeforeDrag(data, e) !== false){
22413 this.dragData = data;
22415 Ext.dd.DragSource.superclass.handleMouseDown.apply(this, arguments);
22420 onBeforeDrag : function(data, e){
22425 onStartDrag : Ext.emptyFn,
22428 startDrag : function(x, y){
22429 this.proxy.reset();
22430 this.dragging = true;
22431 this.proxy.update("");
22432 this.onInitDrag(x, y);
22437 onInitDrag : function(x, y){
22438 var clone = this.el.dom.cloneNode(true);
22439 clone.id = Ext.id();
22440 this.proxy.update(clone);
22441 this.onStartDrag(x, y);
22446 getProxy : function(){
22451 hideProxy : function(){
22453 this.proxy.reset(true);
22454 this.dragging = false;
22458 triggerCacheRefresh : function(){
22459 Ext.dd.DDM.refreshCache(this.groups);
22463 b4EndDrag: function(e) {
22467 endDrag : function(e){
22468 this.onEndDrag(this.dragData, e);
22472 onEndDrag : function(data, e){
22476 autoOffset : function(x, y) {
22477 this.setDelta(-12, -20);
22480 destroy: function(){
22481 Ext.dd.DragSource.superclass.destroy.call(this);
22482 Ext.destroy(this.proxy);
22485 Ext.dd.DropTarget = Ext.extend(Ext.dd.DDTarget, {
22487 constructor : function(el, config){
22488 this.el = Ext.get(el);
22490 Ext.apply(this, config);
22492 if(this.containerScroll){
22493 Ext.dd.ScrollManager.register(this.el);
22496 Ext.dd.DropTarget.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group,
22503 dropAllowed : "x-dd-drop-ok",
22505 dropNotAllowed : "x-dd-drop-nodrop",
22511 isNotifyTarget : true,
22514 notifyEnter : function(dd, e, data){
22515 if(this.overClass){
22516 this.el.addClass(this.overClass);
22518 return this.dropAllowed;
22522 notifyOver : function(dd, e, data){
22523 return this.dropAllowed;
22527 notifyOut : function(dd, e, data){
22528 if(this.overClass){
22529 this.el.removeClass(this.overClass);
22534 notifyDrop : function(dd, e, data){
22538 destroy : function(){
22539 Ext.dd.DropTarget.superclass.destroy.call(this);
22540 if(this.containerScroll){
22541 Ext.dd.ScrollManager.unregister(this.el);
22545 Ext.dd.DragZone = Ext.extend(Ext.dd.DragSource, {
22547 constructor : function(el, config){
22548 Ext.dd.DragZone.superclass.constructor.call(this, el, config);
22549 if(this.containerScroll){
22550 Ext.dd.ScrollManager.register(this.el);
22559 getDragData : function(e){
22560 return Ext.dd.Registry.getHandleFromEvent(e);
22564 onInitDrag : function(x, y){
22565 this.proxy.update(this.dragData.ddel.cloneNode(true));
22566 this.onStartDrag(x, y);
22571 afterRepair : function(){
22573 Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9");
22575 this.dragging = false;
22579 getRepairXY : function(e){
22580 return Ext.Element.fly(this.dragData.ddel).getXY();
22583 destroy : function(){
22584 Ext.dd.DragZone.superclass.destroy.call(this);
22585 if(this.containerScroll){
22586 Ext.dd.ScrollManager.unregister(this.el);
22590 Ext.dd.DropZone = function(el, config){
22591 Ext.dd.DropZone.superclass.constructor.call(this, el, config);
22594 Ext.extend(Ext.dd.DropZone, Ext.dd.DropTarget, {
22596 getTargetFromEvent : function(e){
22597 return Ext.dd.Registry.getTargetFromEvent(e);
22601 onNodeEnter : function(n, dd, e, data){
22606 onNodeOver : function(n, dd, e, data){
22607 return this.dropAllowed;
22611 onNodeOut : function(n, dd, e, data){
22616 onNodeDrop : function(n, dd, e, data){
22621 onContainerOver : function(dd, e, data){
22622 return this.dropNotAllowed;
22626 onContainerDrop : function(dd, e, data){
22631 notifyEnter : function(dd, e, data){
22632 return this.dropNotAllowed;
22636 notifyOver : function(dd, e, data){
22637 var n = this.getTargetFromEvent(e);
22639 if(this.lastOverNode){
22640 this.onNodeOut(this.lastOverNode, dd, e, data);
22641 this.lastOverNode = null;
22643 return this.onContainerOver(dd, e, data);
22645 if(this.lastOverNode != n){
22646 if(this.lastOverNode){
22647 this.onNodeOut(this.lastOverNode, dd, e, data);
22649 this.onNodeEnter(n, dd, e, data);
22650 this.lastOverNode = n;
22652 return this.onNodeOver(n, dd, e, data);
22656 notifyOut : function(dd, e, data){
22657 if(this.lastOverNode){
22658 this.onNodeOut(this.lastOverNode, dd, e, data);
22659 this.lastOverNode = null;
22664 notifyDrop : function(dd, e, data){
22665 if(this.lastOverNode){
22666 this.onNodeOut(this.lastOverNode, dd, e, data);
22667 this.lastOverNode = null;
22669 var n = this.getTargetFromEvent(e);
22671 this.onNodeDrop(n, dd, e, data) :
22672 this.onContainerDrop(dd, e, data);
22676 triggerCacheRefresh : function(){
22677 Ext.dd.DDM.refreshCache(this.groups);
22680 Ext.Element.addMethods({
22682 initDD : function(group, config, overrides){
22683 var dd = new Ext.dd.DD(Ext.id(this.dom), group, config);
22684 return Ext.apply(dd, overrides);
22688 initDDProxy : function(group, config, overrides){
22689 var dd = new Ext.dd.DDProxy(Ext.id(this.dom), group, config);
22690 return Ext.apply(dd, overrides);
22694 initDDTarget : function(group, config, overrides){
22695 var dd = new Ext.dd.DDTarget(Ext.id(this.dom), group, config);
22696 return Ext.apply(dd, overrides);
22700 Ext.data.Api = (function() {
22706 var validActions = {};
22714 destroy : 'destroy'
22726 isAction : function(action) {
22727 return (Ext.data.Api.actions[action]) ? true : false;
22731 getVerb : function(name) {
22732 if (validActions[name]) {
22733 return validActions[name];
22735 for (var verb in this.actions) {
22736 if (this.actions[verb] === name) {
22737 validActions[name] = verb;
22741 return (validActions[name] !== undefined) ? validActions[name] : null;
22745 isValid : function(api){
22747 var crud = this.actions;
22748 for (var action in api) {
22749 if (!(action in crud)) {
22750 invalid.push(action);
22753 return (!invalid.length) ? true : invalid;
22757 hasUniqueUrl : function(proxy, verb) {
22758 var url = (proxy.api[verb]) ? proxy.api[verb].url : null;
22760 for (var action in proxy.api) {
22761 if ((unique = (action === verb) ? true : (proxy.api[action].url != url) ? true : false) === false) {
22769 prepare : function(proxy) {
22773 for (var verb in this.actions) {
22774 var action = this.actions[verb];
22775 proxy.api[action] = proxy.api[action] || proxy.url || proxy.directFn;
22776 if (typeof(proxy.api[action]) == 'string') {
22777 proxy.api[action] = {
22778 url: proxy.api[action],
22779 method: (proxy.restful === true) ? Ext.data.Api.restActions[action] : undefined
22786 restify : function(proxy) {
22787 proxy.restful = true;
22788 for (var verb in this.restActions) {
22789 proxy.api[this.actions[verb]].method ||
22790 (proxy.api[this.actions[verb]].method = this.restActions[verb]);
22794 proxy.onWrite = proxy.onWrite.createInterceptor(function(action, o, response, rs) {
22795 var reader = o.reader;
22796 var res = new Ext.data.Response({
22801 switch (response.status) {
22806 if (Ext.isEmpty(res.raw.responseText)) {
22807 res.success = true;
22814 res.success = true;
22821 if (res.success === true) {
22822 this.fireEvent("write", this, action, res.data, res, rs, o.request.arg);
22824 this.fireEvent('exception', this, 'remote', action, o, res, rs);
22826 o.request.callback.call(o.request.scope, res.data, res, res.success);
22835 Ext.data.Response = function(params, response) {
22836 Ext.apply(this, params, {
22840 Ext.data.Response.prototype = {
22847 getMessage : function() {
22848 return this.message;
22850 getSuccess : function() {
22851 return this.success;
22853 getStatus : function() {
22854 return this.status;
22856 getRoot : function() {
22859 getRawResponse : function() {
22865 Ext.data.Api.Error = Ext.extend(Ext.Error, {
22866 constructor : function(message, arg) {
22868 Ext.Error.call(this, message);
22870 name: 'Ext.data.Api'
22872 Ext.apply(Ext.data.Api.Error.prototype, {
22874 '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.',
22875 'invalid': 'received an invalid API-configuration. Please ensure your proxy API-configuration contains only the actions defined in Ext.data.Api.actions',
22876 'invalid-url': 'Invalid url. Please review your proxy configuration.',
22877 'execute': 'Attempted to execute an unknown action. Valid API actions are defined in Ext.data.Api.actions"'
22884 Ext.data.SortTypes = {
22886 none : function(s){
22891 stripTagsRE : /<\/?[^>]+>/gi,
22894 asText : function(s){
22895 return String(s).replace(this.stripTagsRE, "");
22899 asUCText : function(s){
22900 return String(s).toUpperCase().replace(this.stripTagsRE, "");
22904 asUCString : function(s) {
22905 return String(s).toUpperCase();
22909 asDate : function(s) {
22914 return s.getTime();
22916 return Date.parse(String(s));
22920 asFloat : function(s) {
22921 var val = parseFloat(String(s).replace(/,/g, ""));
22922 return isNaN(val) ? 0 : val;
22926 asInt : function(s) {
22927 var val = parseInt(String(s).replace(/,/g, ""), 10);
22928 return isNaN(val) ? 0 : val;
22931 Ext.data.Record = function(data, id){
22933 this.id = (id || id === 0) ? id : Ext.data.Record.id(this);
22934 this.data = data || {};
22938 Ext.data.Record.create = function(o){
22939 var f = Ext.extend(Ext.data.Record, {});
22940 var p = f.prototype;
22941 p.fields = new Ext.util.MixedCollection(false, function(field){
22944 for(var i = 0, len = o.length; i < len; i++){
22945 p.fields.add(new Ext.data.Field(o[i]));
22947 f.getField = function(name){
22948 return p.fields.get(name);
22953 Ext.data.Record.PREFIX = 'ext-record';
22954 Ext.data.Record.AUTO_ID = 1;
22955 Ext.data.Record.EDIT = 'edit';
22956 Ext.data.Record.REJECT = 'reject';
22957 Ext.data.Record.COMMIT = 'commit';
22961 Ext.data.Record.id = function(rec) {
22962 rec.phantom = true;
22963 return [Ext.data.Record.PREFIX, '-', Ext.data.Record.AUTO_ID++].join('');
22966 Ext.data.Record.prototype = {
22982 join : function(store){
22984 this.store = store;
22988 set : function(name, value){
22989 var encode = Ext.isPrimitive(value) ? String : Ext.encode;
22990 if(encode(this.data[name]) == encode(value)) {
22994 if(!this.modified){
22995 this.modified = {};
22997 if(this.modified[name] === undefined){
22998 this.modified[name] = this.data[name];
23000 this.data[name] = value;
23007 afterEdit : function(){
23008 if (this.store != undefined && typeof this.store.afterEdit == "function") {
23009 this.store.afterEdit(this);
23014 afterReject : function(){
23016 this.store.afterReject(this);
23021 afterCommit : function(){
23023 this.store.afterCommit(this);
23028 get : function(name){
23029 return this.data[name];
23033 beginEdit : function(){
23034 this.editing = true;
23035 this.modified = this.modified || {};
23039 cancelEdit : function(){
23040 this.editing = false;
23041 delete this.modified;
23045 endEdit : function(){
23046 this.editing = false;
23053 reject : function(silent){
23054 var m = this.modified;
23056 if(typeof m[n] != "function"){
23057 this.data[n] = m[n];
23060 this.dirty = false;
23061 delete this.modified;
23062 this.editing = false;
23063 if(silent !== true){
23064 this.afterReject();
23069 commit : function(silent){
23070 this.dirty = false;
23071 delete this.modified;
23072 this.editing = false;
23073 if(silent !== true){
23074 this.afterCommit();
23079 getChanges : function(){
23080 var m = this.modified, cs = {};
23082 if(m.hasOwnProperty(n)){
23083 cs[n] = this.data[n];
23090 hasError : function(){
23091 return this.error !== null;
23095 clearError : function(){
23100 copy : function(newId) {
23101 return new this.constructor(Ext.apply({}, this.data), newId || this.id);
23105 isModified : function(fieldName){
23106 return !!(this.modified && this.modified.hasOwnProperty(fieldName));
23110 isValid : function() {
23111 return this.fields.find(function(f) {
23112 return (f.allowBlank === false && Ext.isEmpty(this.data[f.name])) ? true : false;
23113 },this) ? false : true;
23117 markDirty : function(){
23119 if(!this.modified){
23120 this.modified = {};
23122 this.fields.each(function(f) {
23123 this.modified[f.name] = this.data[f.name];
23128 Ext.StoreMgr = Ext.apply(new Ext.util.MixedCollection(), {
23132 register : function(){
23133 for(var i = 0, s; (s = arguments[i]); i++){
23139 unregister : function(){
23140 for(var i = 0, s; (s = arguments[i]); i++){
23141 this.remove(this.lookup(s));
23146 lookup : function(id){
23147 if(Ext.isArray(id)){
23148 var fields = ['field1'], expand = !Ext.isArray(id[0]);
23150 for(var i = 2, len = id[0].length; i <= len; ++i){
23151 fields.push('field' + i);
23154 return new Ext.data.ArrayStore({
23157 expandData: expand,
23163 return Ext.isObject(id) ? (id.events ? id : Ext.create(id, 'store')) : this.get(id);
23167 getKey : function(o){
23171 Ext.data.Store = Ext.extend(Ext.util.Observable, {
23179 writer : undefined,
23183 remoteSort : false,
23186 autoDestroy : false,
23189 pruneModifiedRecords : false,
23192 lastOptions : null,
23204 paramNames : undefined,
23207 defaultParamNames : {
23214 isDestroyed: false,
23215 hasMultiSort: false,
23218 batchKey : '_ext_batch_',
23220 constructor : function(config){
23225 this.data = new Ext.util.MixedCollection(false);
23226 this.data.getKey = function(o){
23234 if(config && config.data){
23235 this.inlineData = config.data;
23236 delete config.data;
23239 Ext.apply(this, config);
23242 this.baseParams = Ext.isObject(this.baseParams) ? this.baseParams : {};
23244 this.paramNames = Ext.applyIf(this.paramNames || {}, this.defaultParamNames);
23246 if((this.url || this.api) && !this.proxy){
23247 this.proxy = new Ext.data.HttpProxy({url: this.url, api: this.api});
23250 if (this.restful === true && this.proxy) {
23253 this.batch = false;
23254 Ext.data.Api.restify(this.proxy);
23258 if(!this.recordType){
23259 this.recordType = this.reader.recordType;
23261 if(this.reader.onMetaChange){
23262 this.reader.onMetaChange = this.reader.onMetaChange.createSequence(this.onMetaChange, this);
23265 if (this.writer instanceof(Ext.data.DataWriter) === false) {
23266 this.writer = this.buildWriter(this.writer);
23268 this.writer.meta = this.reader.meta;
23269 this.pruneModifiedRecords = true;
23275 if(this.recordType){
23277 this.fields = this.recordType.prototype.fields;
23279 this.modified = [];
23315 this.relayEvents(this.proxy, ['loadexception', 'exception']);
23321 add: this.createRecords,
23322 remove: this.destroyRecord,
23323 update: this.updateRecord,
23324 clear: this.onClear
23328 this.sortToggle = {};
23329 if(this.sortField){
23330 this.setDefaultSort(this.sortField, this.sortDir);
23331 }else if(this.sortInfo){
23332 this.setDefaultSort(this.sortInfo.field, this.sortInfo.direction);
23335 Ext.data.Store.superclass.constructor.call(this);
23338 this.storeId = this.id;
23342 Ext.StoreMgr.register(this);
23344 if(this.inlineData){
23345 this.loadData(this.inlineData);
23346 delete this.inlineData;
23347 }else if(this.autoLoad){
23348 this.load.defer(10, this, [
23349 typeof this.autoLoad == 'object' ?
23350 this.autoLoad : undefined]);
23353 this.batchCounter = 0;
23358 buildWriter : function(config) {
23359 var klass = undefined,
23360 type = (config.format || 'json').toLowerCase();
23363 klass = Ext.data.JsonWriter;
23366 klass = Ext.data.XmlWriter;
23369 klass = Ext.data.JsonWriter;
23371 return new klass(config);
23375 destroy : function(){
23376 if(!this.isDestroyed){
23378 Ext.StoreMgr.unregister(this);
23382 Ext.destroy(this.proxy);
23383 this.reader = this.writer = null;
23384 this.purgeListeners();
23385 this.isDestroyed = true;
23390 add : function(records) {
23391 var i, len, record, index;
23393 records = [].concat(records);
23394 if (records.length < 1) {
23398 for (i = 0, len = records.length; i < len; i++) {
23399 record = records[i];
23403 if (record.dirty || record.phantom) {
23404 this.modified.push(record);
23408 index = this.data.length;
23409 this.data.addAll(records);
23411 if (this.snapshot) {
23412 this.snapshot.addAll(records);
23415 this.fireEvent('add', this, records, index);
23419 addSorted : function(record){
23420 var index = this.findInsertIndex(record);
23421 this.insert(index, record);
23425 doUpdate : function(rec){
23426 this.data.replace(rec.id, rec);
23428 this.snapshot.replace(rec.id, rec);
23430 this.fireEvent('update', this, rec, Ext.data.Record.COMMIT);
23434 remove : function(record){
23435 if(Ext.isArray(record)){
23436 Ext.each(record, function(r){
23441 var index = this.data.indexOf(record);
23444 this.data.removeAt(index);
23446 if(this.pruneModifiedRecords){
23447 this.modified.remove(record);
23450 this.snapshot.remove(record);
23453 this.fireEvent('remove', this, record, index);
23458 removeAt : function(index){
23459 this.remove(this.getAt(index));
23463 removeAll : function(silent){
23465 this.each(function(rec){
23470 this.snapshot.clear();
23472 if(this.pruneModifiedRecords){
23473 this.modified = [];
23475 if (silent !== true) {
23476 this.fireEvent('clear', this, items);
23481 onClear: function(store, records){
23482 Ext.each(records, function(rec, index){
23483 this.destroyRecord(this, rec, index);
23488 insert : function(index, records) {
23489 var i, len, record;
23491 records = [].concat(records);
23492 for (i = 0, len = records.length; i < len; i++) {
23493 record = records[i];
23495 this.data.insert(index + i, record);
23498 if (record.dirty || record.phantom) {
23499 this.modified.push(record);
23503 if (this.snapshot) {
23504 this.snapshot.addAll(records);
23507 this.fireEvent('add', this, records, index);
23511 indexOf : function(record){
23512 return this.data.indexOf(record);
23516 indexOfId : function(id){
23517 return this.data.indexOfKey(id);
23521 getById : function(id){
23522 return (this.snapshot || this.data).key(id);
23526 getAt : function(index){
23527 return this.data.itemAt(index);
23531 getRange : function(start, end){
23532 return this.data.getRange(start, end);
23536 storeOptions : function(o){
23537 o = Ext.apply({}, o);
23540 this.lastOptions = o;
23544 clearData: function(){
23545 this.data.each(function(rec) {
23552 load : function(options) {
23553 options = Ext.apply({}, options);
23554 this.storeOptions(options);
23555 if(this.sortInfo && this.remoteSort){
23556 var pn = this.paramNames;
23557 options.params = Ext.apply({}, options.params);
23558 options.params[pn.sort] = this.sortInfo.field;
23559 options.params[pn.dir] = this.sortInfo.direction;
23562 return this.execute('read', null, options);
23564 this.handleException(e);
23570 updateRecord : function(store, record, action) {
23571 if (action == Ext.data.Record.EDIT && this.autoSave === true && (!record.phantom || (record.phantom && record.isValid()))) {
23577 createRecords : function(store, records, index) {
23578 var modified = this.modified,
23579 length = records.length,
23582 for (i = 0; i < length; i++) {
23583 record = records[i];
23585 if (record.phantom && record.isValid()) {
23586 record.markDirty();
23588 if (modified.indexOf(record) == -1) {
23589 modified.push(record);
23593 if (this.autoSave === true) {
23599 destroyRecord : function(store, record, index) {
23600 if (this.modified.indexOf(record) != -1) {
23601 this.modified.remove(record);
23603 if (!record.phantom) {
23604 this.removed.push(record);
23609 record.lastIndex = index;
23611 if (this.autoSave === true) {
23618 execute : function(action, rs, options, batch) {
23620 if (!Ext.data.Api.isAction(action)) {
23621 throw new Ext.data.Api.Error('execute', action);
23624 options = Ext.applyIf(options||{}, {
23627 if(batch !== undefined){
23628 this.addToBatch(batch);
23632 var doRequest = true;
23634 if (action === 'read') {
23635 doRequest = this.fireEvent('beforeload', this, options);
23636 Ext.applyIf(options.params, this.baseParams);
23641 if (this.writer.listful === true && this.restful !== true) {
23642 rs = (Ext.isArray(rs)) ? rs : [rs];
23645 else if (Ext.isArray(rs) && rs.length == 1) {
23649 if ((doRequest = this.fireEvent('beforewrite', this, action, rs, options)) !== false) {
23650 this.writer.apply(options.params, this.baseParams, action, rs);
23653 if (doRequest !== false) {
23655 if (this.writer && this.proxy.url && !this.proxy.restful && !Ext.data.Api.hasUniqueUrl(this.proxy, action)) {
23656 options.params.xaction = action;
23663 this.proxy.request(Ext.data.Api.actions[action], rs, options.params, this.reader, this.createCallback(action, rs, batch), this, options);
23669 save : function() {
23670 if (!this.writer) {
23671 throw new Ext.data.Store.Error('writer-undefined');
23681 if(this.removed.length){
23682 queue.push(['destroy', this.removed]);
23686 var rs = [].concat(this.getModifiedRecords());
23690 for(i = rs.length-1; i >= 0; i--){
23691 if(rs[i].phantom === true){
23692 var rec = rs.splice(i, 1).shift();
23694 phantoms.push(rec);
23696 }else if(!rs[i].isValid()){
23701 if(phantoms.length){
23702 queue.push(['create', phantoms]);
23707 queue.push(['update', rs]);
23710 len = queue.length;
23712 batch = ++this.batchCounter;
23713 for(i = 0; i < len; ++i){
23715 data[trans[0]] = trans[1];
23717 if(this.fireEvent('beforesave', this, data) !== false){
23718 for(i = 0; i < len; ++i){
23720 this.doTransaction(trans[0], trans[1], batch);
23729 doTransaction : function(action, rs, batch) {
23730 function transaction(records) {
23732 this.execute(action, records, undefined, batch);
23734 this.handleException(e);
23737 if(this.batch === false){
23738 for(var i = 0, len = rs.length; i < len; i++){
23739 transaction.call(this, rs[i]);
23742 transaction.call(this, rs);
23747 addToBatch : function(batch){
23748 var b = this.batches,
23749 key = this.batchKey + batch,
23762 removeFromBatch : function(batch, action, data){
23763 var b = this.batches,
23764 key = this.batchKey + batch,
23770 arr = o.data[action] || [];
23771 o.data[action] = arr.concat(data);
23775 this.fireEvent('save', this, batch, data);
23784 createCallback : function(action, rs, batch) {
23785 var actions = Ext.data.Api.actions;
23786 return (action == 'read') ? this.loadRecords : function(data, response, success) {
23788 this['on' + Ext.util.Format.capitalize(action) + 'Records'](success, rs, [].concat(data));
23790 if (success === true) {
23791 this.fireEvent('write', this, action, data, response, rs);
23793 this.removeFromBatch(batch, action, data);
23800 clearModified : function(rs) {
23801 if (Ext.isArray(rs)) {
23802 for (var n=rs.length-1;n>=0;n--) {
23803 this.modified.splice(this.modified.indexOf(rs[n]), 1);
23806 this.modified.splice(this.modified.indexOf(rs), 1);
23811 reMap : function(record) {
23812 if (Ext.isArray(record)) {
23813 for (var i = 0, len = record.length; i < len; i++) {
23814 this.reMap(record[i]);
23817 delete this.data.map[record._phid];
23818 this.data.map[record.id] = record;
23819 var index = this.data.keys.indexOf(record._phid);
23820 this.data.keys.splice(index, 1, record.id);
23821 delete record._phid;
23826 onCreateRecords : function(success, rs, data) {
23827 if (success === true) {
23829 this.reader.realize(rs, data);
23833 this.handleException(e);
23834 if (Ext.isArray(rs)) {
23836 this.onCreateRecords(success, rs, data);
23843 onUpdateRecords : function(success, rs, data) {
23844 if (success === true) {
23846 this.reader.update(rs, data);
23848 this.handleException(e);
23849 if (Ext.isArray(rs)) {
23851 this.onUpdateRecords(success, rs, data);
23858 onDestroyRecords : function(success, rs, data) {
23860 rs = (rs instanceof Ext.data.Record) ? [rs] : [].concat(rs);
23861 for (var i=0,len=rs.length;i<len;i++) {
23862 this.removed.splice(this.removed.indexOf(rs[i]), 1);
23864 if (success === false) {
23867 for (i=rs.length-1;i>=0;i--) {
23868 this.insert(rs[i].lastIndex, rs[i]);
23874 handleException : function(e) {
23876 Ext.handleError(e);
23880 reload : function(options){
23881 this.load(Ext.applyIf(options||{}, this.lastOptions));
23886 loadRecords : function(o, options, success){
23889 if (this.isDestroyed === true) {
23892 if(!o || success === false){
23893 if(success !== false){
23894 this.fireEvent('load', this, [], options);
23896 if(options.callback){
23897 options.callback.call(options.scope || this, [], options, false, o);
23901 var r = o.records, t = o.totalRecords || r.length;
23902 if(!options || options.add !== true){
23903 if(this.pruneModifiedRecords){
23904 this.modified = [];
23906 for(i = 0, len = r.length; i < len; i++){
23910 this.data = this.snapshot;
23911 delete this.snapshot;
23914 this.data.addAll(r);
23915 this.totalLength = t;
23917 this.fireEvent('datachanged', this);
23922 for(i = 0, len = r.length; i < len; ++i){
23924 if(this.indexOfId(rec.id) > -1){
23925 this.doUpdate(rec);
23931 this.totalLength = Math.max(t, this.data.length + cnt);
23934 this.fireEvent('load', this, r, options);
23935 if(options.callback){
23936 options.callback.call(options.scope || this, r, options, true);
23941 loadData : function(o, append){
23942 var r = this.reader.readRecords(o);
23943 this.loadRecords(r, {add: append}, true);
23947 getCount : function(){
23948 return this.data.length || 0;
23952 getTotalCount : function(){
23953 return this.totalLength || 0;
23957 getSortState : function(){
23958 return this.sortInfo;
23962 applySort : function(){
23963 if ((this.sortInfo || this.multiSortInfo) && !this.remoteSort) {
23969 sortData : function() {
23970 var sortInfo = this.hasMultiSort ? this.multiSortInfo : this.sortInfo,
23971 direction = sortInfo.direction || "ASC",
23972 sorters = sortInfo.sorters,
23976 if (!this.hasMultiSort) {
23977 sorters = [{direction: direction, field: sortInfo.field}];
23981 for (var i=0, j = sorters.length; i < j; i++) {
23982 sortFns.push(this.createSortFunction(sorters[i].field, sorters[i].direction));
23985 if (sortFns.length == 0) {
23991 var directionModifier = direction.toUpperCase() == "DESC" ? -1 : 1;
23994 var fn = function(r1, r2) {
23995 var result = sortFns[0].call(this, r1, r2);
23998 if (sortFns.length > 1) {
23999 for (var i=1, j = sortFns.length; i < j; i++) {
24000 result = result || sortFns[i].call(this, r1, r2);
24004 return directionModifier * result;
24008 this.data.sort(direction, fn);
24009 if (this.snapshot && this.snapshot != this.data) {
24010 this.snapshot.sort(direction, fn);
24015 createSortFunction: function(field, direction) {
24016 direction = direction || "ASC";
24017 var directionModifier = direction.toUpperCase() == "DESC" ? -1 : 1;
24019 var sortType = this.fields.get(field).sortType;
24023 return function(r1, r2) {
24024 var v1 = sortType(r1.data[field]),
24025 v2 = sortType(r2.data[field]);
24027 return directionModifier * (v1 > v2 ? 1 : (v1 < v2 ? -1 : 0));
24032 setDefaultSort : function(field, dir) {
24033 dir = dir ? dir.toUpperCase() : 'ASC';
24034 this.sortInfo = {field: field, direction: dir};
24035 this.sortToggle[field] = dir;
24039 sort : function(fieldName, dir) {
24040 if (Ext.isArray(arguments[0])) {
24041 return this.multiSort.call(this, fieldName, dir);
24043 return this.singleSort(fieldName, dir);
24048 singleSort: function(fieldName, dir) {
24049 var field = this.fields.get(fieldName);
24054 var name = field.name,
24055 sortInfo = this.sortInfo || null,
24056 sortToggle = this.sortToggle ? this.sortToggle[name] : null;
24059 if (sortInfo && sortInfo.field == name) {
24060 dir = (this.sortToggle[name] || 'ASC').toggle('ASC', 'DESC');
24062 dir = field.sortDir;
24066 this.sortToggle[name] = dir;
24067 this.sortInfo = {field: name, direction: dir};
24068 this.hasMultiSort = false;
24070 if (this.remoteSort) {
24071 if (!this.load(this.lastOptions)) {
24073 this.sortToggle[name] = sortToggle;
24076 this.sortInfo = sortInfo;
24081 this.fireEvent('datachanged', this);
24087 multiSort: function(sorters, direction) {
24088 this.hasMultiSort = true;
24089 direction = direction || "ASC";
24092 if (this.multiSortInfo && direction == this.multiSortInfo.direction) {
24093 direction = direction.toggle("ASC", "DESC");
24097 this.multiSortInfo = {
24099 direction: direction
24102 if (this.remoteSort) {
24103 this.singleSort(sorters[0].field, sorters[0].direction);
24107 this.fireEvent('datachanged', this);
24112 each : function(fn, scope){
24113 this.data.each(fn, scope);
24117 getModifiedRecords : function(){
24118 return this.modified;
24122 sum : function(property, start, end){
24123 var rs = this.data.items, v = 0;
24124 start = start || 0;
24125 end = (end || end === 0) ? end : rs.length-1;
24127 for(var i = start; i <= end; i++){
24128 v += (rs[i].data[property] || 0);
24134 createFilterFn : function(property, value, anyMatch, caseSensitive, exactMatch){
24135 if(Ext.isEmpty(value, false)){
24138 value = this.data.createValueMatcher(value, anyMatch, caseSensitive, exactMatch);
24139 return function(r) {
24140 return value.test(r.data[property]);
24145 createMultipleFilterFn: function(filters) {
24146 return function(record) {
24147 var isMatch = true;
24149 for (var i=0, j = filters.length; i < j; i++) {
24150 var filter = filters[i],
24152 scope = filter.scope;
24154 isMatch = isMatch && fn.call(scope, record);
24162 filter : function(property, value, anyMatch, caseSensitive, exactMatch){
24165 if (Ext.isObject(property)) {
24166 property = [property];
24169 if (Ext.isArray(property)) {
24173 for (var i=0, j = property.length; i < j; i++) {
24174 var filter = property[i],
24176 scope = filter.scope || this;
24179 if (!Ext.isFunction(func)) {
24180 func = this.createFilterFn(filter.property, filter.value, filter.anyMatch, filter.caseSensitive, filter.exactMatch);
24183 filters.push({fn: func, scope: scope});
24186 fn = this.createMultipleFilterFn(filters);
24189 fn = this.createFilterFn(property, value, anyMatch, caseSensitive, exactMatch);
24192 return fn ? this.filterBy(fn) : this.clearFilter();
24196 filterBy : function(fn, scope){
24197 this.snapshot = this.snapshot || this.data;
24198 this.data = this.queryBy(fn, scope || this);
24199 this.fireEvent('datachanged', this);
24203 clearFilter : function(suppressEvent){
24204 if(this.isFiltered()){
24205 this.data = this.snapshot;
24206 delete this.snapshot;
24207 if(suppressEvent !== true){
24208 this.fireEvent('datachanged', this);
24214 isFiltered : function(){
24215 return !!this.snapshot && this.snapshot != this.data;
24219 query : function(property, value, anyMatch, caseSensitive){
24220 var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
24221 return fn ? this.queryBy(fn) : this.data.clone();
24225 queryBy : function(fn, scope){
24226 var data = this.snapshot || this.data;
24227 return data.filterBy(fn, scope||this);
24231 find : function(property, value, start, anyMatch, caseSensitive){
24232 var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
24233 return fn ? this.data.findIndexBy(fn, null, start) : -1;
24237 findExact: function(property, value, start){
24238 return this.data.findIndexBy(function(rec){
24239 return rec.get(property) === value;
24244 findBy : function(fn, scope, start){
24245 return this.data.findIndexBy(fn, scope, start);
24249 collect : function(dataIndex, allowNull, bypassFilter){
24250 var d = (bypassFilter === true && this.snapshot) ?
24251 this.snapshot.items : this.data.items;
24252 var v, sv, r = [], l = {};
24253 for(var i = 0, len = d.length; i < len; i++){
24254 v = d[i].data[dataIndex];
24256 if((allowNull || !Ext.isEmpty(v)) && !l[sv]){
24265 afterEdit : function(record){
24266 if(this.modified.indexOf(record) == -1){
24267 this.modified.push(record);
24269 this.fireEvent('update', this, record, Ext.data.Record.EDIT);
24273 afterReject : function(record){
24274 this.modified.remove(record);
24275 this.fireEvent('update', this, record, Ext.data.Record.REJECT);
24279 afterCommit : function(record){
24280 this.modified.remove(record);
24281 this.fireEvent('update', this, record, Ext.data.Record.COMMIT);
24285 commitChanges : function(){
24286 var modified = this.modified.slice(0),
24287 length = modified.length,
24290 for (i = 0; i < length; i++){
24291 modified[i].commit();
24294 this.modified = [];
24299 rejectChanges : function() {
24300 var modified = this.modified.slice(0),
24301 removed = this.removed.slice(0).reverse(),
24302 mLength = modified.length,
24303 rLength = removed.length,
24306 for (i = 0; i < mLength; i++) {
24307 modified[i].reject();
24310 for (i = 0; i < rLength; i++) {
24311 this.insert(removed[i].lastIndex || 0, removed[i]);
24312 removed[i].reject();
24315 this.modified = [];
24320 onMetaChange : function(meta){
24321 this.recordType = this.reader.recordType;
24322 this.fields = this.recordType.prototype.fields;
24323 delete this.snapshot;
24324 if(this.reader.meta.sortInfo){
24325 this.sortInfo = this.reader.meta.sortInfo;
24326 }else if(this.sortInfo && !this.fields.get(this.sortInfo.field)){
24327 delete this.sortInfo;
24330 this.writer.meta = this.reader.meta;
24332 this.modified = [];
24333 this.fireEvent('metachange', this, this.reader.meta);
24337 findInsertIndex : function(record){
24338 this.suspendEvents();
24339 var data = this.data.clone();
24340 this.data.add(record);
24342 var index = this.data.indexOf(record);
24344 this.resumeEvents();
24349 setBaseParam : function (name, value){
24350 this.baseParams = this.baseParams || {};
24351 this.baseParams[name] = value;
24355 Ext.reg('store', Ext.data.Store);
24358 Ext.data.Store.Error = Ext.extend(Ext.Error, {
24359 name: 'Ext.data.Store'
24361 Ext.apply(Ext.data.Store.Error.prototype, {
24363 'writer-undefined' : 'Attempted to execute a write-action without a DataWriter installed.'
24367 Ext.data.Field = Ext.extend(Object, {
24369 constructor : function(config){
24370 if(Ext.isString(config)){
24371 config = {name: config};
24373 Ext.apply(this, config);
24375 var types = Ext.data.Types,
24376 st = this.sortType,
24380 if(Ext.isString(this.type)){
24381 this.type = Ext.data.Types[this.type.toUpperCase()] || types.AUTO;
24384 this.type = types.AUTO;
24388 if(Ext.isString(st)){
24389 this.sortType = Ext.data.SortTypes[st];
24390 }else if(Ext.isEmpty(st)){
24391 this.sortType = this.type.sortType;
24395 this.convert = this.type.convert;
24420 Ext.data.DataReader = function(meta, recordType){
24424 this.recordType = Ext.isArray(recordType) ?
24425 Ext.data.Record.create(recordType) : recordType;
24428 if (this.recordType){
24429 this.buildExtractors();
24433 Ext.data.DataReader.prototype = {
24436 getTotal: Ext.emptyFn,
24438 getRoot: Ext.emptyFn,
24440 getMessage: Ext.emptyFn,
24442 getSuccess: Ext.emptyFn,
24444 getId: Ext.emptyFn,
24446 buildExtractors : Ext.emptyFn,
24448 extractValues : Ext.emptyFn,
24451 realize: function(rs, data){
24452 if (Ext.isArray(rs)) {
24453 for (var i = rs.length - 1; i >= 0; i--) {
24455 if (Ext.isArray(data)) {
24456 this.realize(rs.splice(i,1).shift(), data.splice(i,1).shift());
24461 this.realize(rs.splice(i,1).shift(), data);
24467 if (Ext.isArray(data) && data.length == 1) {
24468 data = data.shift();
24470 if (!this.isData(data)) {
24473 throw new Ext.data.DataReader.Error('realize', rs);
24475 rs.phantom = false;
24477 rs.id = this.getId(data);
24485 update : function(rs, data) {
24486 if (Ext.isArray(rs)) {
24487 for (var i=rs.length-1; i >= 0; i--) {
24488 if (Ext.isArray(data)) {
24489 this.update(rs.splice(i,1).shift(), data.splice(i,1).shift());
24494 this.update(rs.splice(i,1).shift(), data);
24500 if (Ext.isArray(data) && data.length == 1) {
24501 data = data.shift();
24503 if (this.isData(data)) {
24504 rs.data = Ext.apply(rs.data, data);
24511 extractData : function(root, returnRecords) {
24513 var rawName = (this instanceof Ext.data.JsonReader) ? 'json' : 'node';
24519 if (this.isData(root) && !(this instanceof Ext.data.XmlReader)) {
24522 var f = this.recordType.prototype.fields,
24526 if (returnRecords === true) {
24527 var Record = this.recordType;
24528 for (var i = 0; i < root.length; i++) {
24530 var record = new Record(this.extractValues(n, fi, fl), this.getId(n));
24531 record[rawName] = n;
24536 for (var i = 0; i < root.length; i++) {
24537 var data = this.extractValues(root[i], fi, fl);
24538 data[this.meta.idProperty] = this.getId(root[i]);
24546 isData : function(data) {
24547 return (data && Ext.isObject(data) && !Ext.isEmpty(this.getId(data))) ? true : false;
24551 onMetaChange : function(meta){
24554 this.recordType = Ext.data.Record.create(meta.fields);
24555 this.buildExtractors();
24560 Ext.data.DataReader.Error = Ext.extend(Ext.Error, {
24561 constructor : function(message, arg) {
24563 Ext.Error.call(this, message);
24565 name: 'Ext.data.DataReader'
24567 Ext.apply(Ext.data.DataReader.Error.prototype, {
24569 'update': "#update received invalid data from server. Please see docs for DataReader#update and review your DataReader configuration.",
24570 'realize': "#realize was called with invalid remote-data. Please see the docs for DataReader#realize and review your DataReader configuration.",
24571 'invalid-response': "#readResponse received an invalid response from the server."
24575 Ext.data.DataWriter = function(config){
24576 Ext.apply(this, config);
24578 Ext.data.DataWriter.prototype = {
24581 writeAllFields : false,
24586 apply : function(params, baseParams, action, rs) {
24588 renderer = action + 'Record';
24590 if (Ext.isArray(rs)) {
24591 Ext.each(rs, function(rec){
24592 data.push(this[renderer](rec));
24595 else if (rs instanceof Ext.data.Record) {
24596 data = this[renderer](rs);
24598 this.render(params, baseParams, data);
24602 render : Ext.emptyFn,
24605 updateRecord : Ext.emptyFn,
24608 createRecord : Ext.emptyFn,
24611 destroyRecord : Ext.emptyFn,
24614 toHash : function(rec, config) {
24615 var map = rec.fields.map,
24617 raw = (this.writeAllFields === false && rec.phantom === false) ? rec.getChanges() : rec.data,
24619 Ext.iterate(raw, function(prop, value){
24620 if((m = map[prop])){
24621 data[m.mapping ? m.mapping : m.name] = value;
24628 if (rec.fields.containsKey(this.meta.idProperty) && Ext.isEmpty(rec.data[this.meta.idProperty])) {
24629 delete data[this.meta.idProperty];
24632 data[this.meta.idProperty] = rec.id;
24638 toArray : function(data) {
24640 Ext.iterate(data, function(k, v) {fields.push({name: k, value: v});},this);
24644 Ext.data.DataProxy = function(conn){
24653 this.api = conn.api;
24654 this.url = conn.url;
24655 this.restful = conn.restful;
24656 this.listeners = conn.listeners;
24659 this.prettyUrls = conn.prettyUrls;
24677 Ext.data.DataProxy.superclass.constructor.call(this);
24681 Ext.data.Api.prepare(this);
24683 if (e instanceof Ext.data.Api.Error) {
24688 Ext.data.DataProxy.relayEvents(this, ['beforewrite', 'write', 'exception']);
24691 Ext.extend(Ext.data.DataProxy, Ext.util.Observable, {
24696 setApi : function() {
24697 if (arguments.length == 1) {
24698 var valid = Ext.data.Api.isValid(arguments[0]);
24699 if (valid === true) {
24700 this.api = arguments[0];
24703 throw new Ext.data.Api.Error('invalid', valid);
24706 else if (arguments.length == 2) {
24707 if (!Ext.data.Api.isAction(arguments[0])) {
24708 throw new Ext.data.Api.Error('invalid', arguments[0]);
24710 this.api[arguments[0]] = arguments[1];
24712 Ext.data.Api.prepare(this);
24716 isApiAction : function(action) {
24717 return (this.api[action]) ? true : false;
24721 request : function(action, rs, params, reader, callback, scope, options) {
24722 if (!this.api[action] && !this.load) {
24723 throw new Ext.data.DataProxy.Error('action-undefined', action);
24725 params = params || {};
24726 if ((action === Ext.data.Api.actions.read) ? this.fireEvent("beforeload", this, params) : this.fireEvent("beforewrite", this, action, rs, params) !== false) {
24727 this.doRequest.apply(this, arguments);
24730 callback.call(scope || this, null, options, false);
24739 doRequest : function(action, rs, params, reader, callback, scope, options) {
24743 this.load(params, reader, callback, scope, options);
24747 onRead : Ext.emptyFn,
24749 onWrite : Ext.emptyFn,
24751 buildUrl : function(action, record) {
24752 record = record || null;
24757 var url = (this.conn && this.conn.url) ? this.conn.url : (this.api[action]) ? this.api[action].url : this.url;
24759 throw new Ext.data.Api.Error('invalid-url', action);
24768 var provides = null;
24769 var m = url.match(/(.*)(\.json|\.xml|\.html)$/);
24775 if ((this.restful === true || this.prettyUrls === true) && record instanceof Ext.data.Record && !record.phantom) {
24776 url += '/' + record.id;
24778 return (provides === null) ? url : url + provides;
24782 destroy: function(){
24783 this.purgeListeners();
24789 Ext.apply(Ext.data.DataProxy, Ext.util.Observable.prototype);
24790 Ext.util.Observable.call(Ext.data.DataProxy);
24793 Ext.data.DataProxy.Error = Ext.extend(Ext.Error, {
24794 constructor : function(message, arg) {
24796 Ext.Error.call(this, message);
24798 name: 'Ext.data.DataProxy'
24800 Ext.apply(Ext.data.DataProxy.Error.prototype, {
24802 'action-undefined': "DataProxy attempted to execute an API-action but found an undefined url / function. Please review your Proxy url/api-configuration.",
24803 'api-invalid': 'Recieved an invalid API-configuration. Please ensure your proxy API-configuration contains only the actions from Ext.data.Api.actions.'
24809 Ext.data.Request = function(params) {
24810 Ext.apply(this, params);
24812 Ext.data.Request.prototype = {
24814 action : undefined,
24820 callback : Ext.emptyFn,
24827 Ext.data.Response = function(params) {
24828 Ext.apply(this, params);
24830 Ext.data.Response.prototype = {
24834 success : undefined,
24836 message : undefined,
24845 Ext.data.ScriptTagProxy = function(config){
24846 Ext.apply(this, config);
24848 Ext.data.ScriptTagProxy.superclass.constructor.call(this, config);
24850 this.head = document.getElementsByTagName("head")[0];
24855 Ext.data.ScriptTagProxy.TRANS_ID = 1000;
24857 Ext.extend(Ext.data.ScriptTagProxy, Ext.data.DataProxy, {
24862 callbackParam : "callback",
24867 doRequest : function(action, rs, params, reader, callback, scope, arg) {
24868 var p = Ext.urlEncode(Ext.apply(params, this.extraParams));
24870 var url = this.buildUrl(action, rs);
24872 throw new Ext.data.Api.Error('invalid-url', url);
24874 url = Ext.urlAppend(url, p);
24877 url = Ext.urlAppend(url, '_dc=' + (new Date().getTime()));
24879 var transId = ++Ext.data.ScriptTagProxy.TRANS_ID;
24883 cb : "stcCallback"+transId,
24884 scriptId : "stcScript"+transId,
24888 callback : callback,
24892 window[trans.cb] = this.createCallback(action, rs, trans);
24893 url += String.format("&{0}={1}", this.callbackParam, trans.cb);
24894 if(this.autoAbort !== false){
24898 trans.timeoutId = this.handleFailure.defer(this.timeout, this, [trans]);
24900 var script = document.createElement("script");
24901 script.setAttribute("src", url);
24902 script.setAttribute("type", "text/javascript");
24903 script.setAttribute("id", trans.scriptId);
24904 this.head.appendChild(script);
24906 this.trans = trans;
24910 createCallback : function(action, rs, trans) {
24912 return function(res) {
24913 self.trans = false;
24914 self.destroyTrans(trans, true);
24915 if (action === Ext.data.Api.actions.read) {
24916 self.onRead.call(self, action, trans, res);
24918 self.onWrite.call(self, action, trans, res, rs);
24923 onRead : function(action, trans, res) {
24926 result = trans.reader.readRecords(res);
24929 this.fireEvent("loadexception", this, trans, res, e);
24931 this.fireEvent('exception', this, 'response', action, trans, res, e);
24932 trans.callback.call(trans.scope||window, null, trans.arg, false);
24935 if (result.success === false) {
24937 this.fireEvent('loadexception', this, trans, res);
24939 this.fireEvent('exception', this, 'remote', action, trans, res, null);
24941 this.fireEvent("load", this, res, trans.arg);
24943 trans.callback.call(trans.scope||window, result, trans.arg, result.success);
24946 onWrite : function(action, trans, response, rs) {
24947 var reader = trans.reader;
24950 var res = reader.readResponse(action, response);
24952 this.fireEvent('exception', this, 'response', action, trans, res, e);
24953 trans.callback.call(trans.scope||window, null, res, false);
24956 if(!res.success === true){
24957 this.fireEvent('exception', this, 'remote', action, trans, res, rs);
24958 trans.callback.call(trans.scope||window, null, res, false);
24961 this.fireEvent("write", this, action, res.data, res, rs, trans.arg );
24962 trans.callback.call(trans.scope||window, res.data, res, true);
24966 isLoading : function(){
24967 return this.trans ? true : false;
24971 abort : function(){
24972 if(this.isLoading()){
24973 this.destroyTrans(this.trans);
24978 destroyTrans : function(trans, isLoaded){
24979 this.head.removeChild(document.getElementById(trans.scriptId));
24980 clearTimeout(trans.timeoutId);
24982 window[trans.cb] = undefined;
24984 delete window[trans.cb];
24988 window[trans.cb] = function(){
24989 window[trans.cb] = undefined;
24991 delete window[trans.cb];
24998 handleFailure : function(trans){
24999 this.trans = false;
25000 this.destroyTrans(trans, false);
25001 if (trans.action === Ext.data.Api.actions.read) {
25003 this.fireEvent("loadexception", this, null, trans.arg);
25006 this.fireEvent('exception', this, 'response', trans.action, {
25010 trans.callback.call(trans.scope||window, null, trans.arg, false);
25014 destroy: function(){
25016 Ext.data.ScriptTagProxy.superclass.destroy.call(this);
25019 Ext.data.HttpProxy = function(conn){
25020 Ext.data.HttpProxy.superclass.constructor.call(this, conn);
25029 this.conn.url = null;
25031 this.useAjax = !conn || !conn.events;
25034 var actions = Ext.data.Api.actions;
25035 this.activeRequest = {};
25036 for (var verb in actions) {
25037 this.activeRequest[actions[verb]] = undefined;
25041 Ext.extend(Ext.data.HttpProxy, Ext.data.DataProxy, {
25043 getConnection : function() {
25044 return this.useAjax ? Ext.Ajax : this.conn;
25048 setUrl : function(url, makePermanent) {
25049 this.conn.url = url;
25050 if (makePermanent === true) {
25053 Ext.data.Api.prepare(this);
25058 doRequest : function(action, rs, params, reader, cb, scope, arg) {
25060 method: (this.api[action]) ? this.api[action]['method'] : undefined,
25067 callback : this.createCallback(action, rs),
25073 if (params.jsonData) {
25074 o.jsonData = params.jsonData;
25075 } else if (params.xmlData) {
25076 o.xmlData = params.xmlData;
25078 o.params = params || {};
25083 this.conn.url = this.buildUrl(action, rs);
25087 Ext.applyIf(o, this.conn);
25090 if (this.activeRequest[action]) {
25097 this.activeRequest[action] = Ext.Ajax.request(o);
25099 this.conn.request(o);
25102 this.conn.url = null;
25106 createCallback : function(action, rs) {
25107 return function(o, success, response) {
25108 this.activeRequest[action] = undefined;
25110 if (action === Ext.data.Api.actions.read) {
25113 this.fireEvent('loadexception', this, o, response);
25115 this.fireEvent('exception', this, 'response', action, o, response);
25116 o.request.callback.call(o.request.scope, null, o.request.arg, false);
25119 if (action === Ext.data.Api.actions.read) {
25120 this.onRead(action, o, response);
25122 this.onWrite(action, o, response, rs);
25128 onRead : function(action, o, response) {
25131 result = o.reader.read(response);
25135 this.fireEvent('loadexception', this, o, response, e);
25137 this.fireEvent('exception', this, 'response', action, o, response, e);
25138 o.request.callback.call(o.request.scope, null, o.request.arg, false);
25141 if (result.success === false) {
25144 this.fireEvent('loadexception', this, o, response);
25147 var res = o.reader.readResponse(action, response);
25148 this.fireEvent('exception', this, 'remote', action, o, res, null);
25151 this.fireEvent('load', this, o, o.request.arg);
25156 o.request.callback.call(o.request.scope, result, o.request.arg, result.success);
25159 onWrite : function(action, o, response, rs) {
25160 var reader = o.reader;
25163 res = reader.readResponse(action, response);
25165 this.fireEvent('exception', this, 'response', action, o, response, e);
25166 o.request.callback.call(o.request.scope, null, o.request.arg, false);
25169 if (res.success === true) {
25170 this.fireEvent('write', this, action, res.data, res, rs, o.request.arg);
25172 this.fireEvent('exception', this, 'remote', action, o, res, rs);
25177 o.request.callback.call(o.request.scope, res.data, res, res.success);
25181 destroy: function(){
25184 }else if(this.activeRequest){
25185 var actions = Ext.data.Api.actions;
25186 for (var verb in actions) {
25187 if(this.activeRequest[actions[verb]]){
25188 Ext.Ajax.abort(this.activeRequest[actions[verb]]);
25192 Ext.data.HttpProxy.superclass.destroy.call(this);
25195 Ext.data.MemoryProxy = function(data){
25198 api[Ext.data.Api.actions.read] = true;
25199 Ext.data.MemoryProxy.superclass.constructor.call(this, {
25205 Ext.extend(Ext.data.MemoryProxy, Ext.data.DataProxy, {
25209 doRequest : function(action, rs, params, reader, callback, scope, arg) {
25211 params = params || {};
25214 result = reader.readRecords(this.data);
25217 this.fireEvent("loadexception", this, null, arg, e);
25219 this.fireEvent('exception', this, 'response', action, arg, null, e);
25220 callback.call(scope, null, arg, false);
25223 callback.call(scope, result, arg, true);
25226 Ext.data.Types = new function(){
25227 var st = Ext.data.SortTypes;
25230 stripRe: /[\$,%]/g,
25234 convert: function(v){ return v; },
25241 convert: function(v){ return (v === undefined || v === null) ? '' : String(v); },
25242 sortType: st.asUCString,
25248 convert: function(v){
25249 return v !== undefined && v !== null && v !== '' ?
25250 parseInt(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0);
25258 convert: function(v){
25259 return v !== undefined && v !== null && v !== '' ?
25260 parseFloat(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0);
25268 convert: function(v){ return v === true || v === 'true' || v == 1; },
25275 convert: function(v){
25276 var df = this.dateFormat;
25284 if(df == 'timestamp'){
25285 return new Date(v*1000);
25288 return new Date(parseInt(v, 10));
25290 return Date.parseDate(v, df);
25292 var parsed = Date.parse(v);
25293 return parsed ? new Date(parsed) : null;
25295 sortType: st.asDate,
25302 BOOLEAN: this.BOOL,
25309 Ext.data.JsonWriter = Ext.extend(Ext.data.DataWriter, {
25313 encodeDelete: false,
25315 constructor : function(config){
25316 Ext.data.JsonWriter.superclass.constructor.call(this, config);
25320 render : function(params, baseParams, data) {
25321 if (this.encode === true) {
25323 Ext.apply(params, baseParams);
25324 params[this.meta.root] = Ext.encode(data);
25327 var jdata = Ext.apply({}, baseParams);
25328 jdata[this.meta.root] = data;
25329 params.jsonData = jdata;
25333 createRecord : function(rec) {
25334 return this.toHash(rec);
25337 updateRecord : function(rec) {
25338 return this.toHash(rec);
25342 destroyRecord : function(rec){
25343 if(this.encodeDelete){
25345 data[this.meta.idProperty] = rec.id;
25352 Ext.data.JsonReader = function(meta, recordType){
25358 Ext.applyIf(meta, {
25360 successProperty: 'success',
25361 totalProperty: 'total'
25364 Ext.data.JsonReader.superclass.constructor.call(this, meta, recordType || meta.fields);
25366 Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
25369 read : function(response){
25370 var json = response.responseText;
25371 var o = Ext.decode(json);
25373 throw {message: 'JsonReader.read: Json object not found'};
25375 return this.readRecords(o);
25380 readResponse : function(action, response) {
25381 var o = (response.responseText !== undefined) ? Ext.decode(response.responseText) : response;
25383 throw new Ext.data.JsonReader.Error('response');
25386 var root = this.getRoot(o);
25387 if (action === Ext.data.Api.actions.create) {
25388 var def = Ext.isDefined(root);
25389 if (def && Ext.isEmpty(root)) {
25390 throw new Ext.data.JsonReader.Error('root-empty', this.meta.root);
25393 throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root);
25398 var res = new Ext.data.Response({
25400 success: this.getSuccess(o),
25401 data: (root) ? this.extractData(root, false) : [],
25402 message: this.getMessage(o),
25407 if (Ext.isEmpty(res.success)) {
25408 throw new Ext.data.JsonReader.Error('successProperty-response', this.meta.successProperty);
25414 readRecords : function(o){
25418 this.onMetaChange(o.metaData);
25420 var s = this.meta, Record = this.recordType,
25421 f = Record.prototype.fields, fi = f.items, fl = f.length, v;
25423 var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;
25424 if(s.totalProperty){
25425 v = parseInt(this.getTotal(o), 10);
25430 if(s.successProperty){
25431 v = this.getSuccess(o);
25432 if(v === false || v === 'false'){
25440 records : this.extractData(root, true),
25441 totalRecords : totalRecords
25446 buildExtractors : function() {
25450 var s = this.meta, Record = this.recordType,
25451 f = Record.prototype.fields, fi = f.items, fl = f.length;
25453 if(s.totalProperty) {
25454 this.getTotal = this.createAccessor(s.totalProperty);
25456 if(s.successProperty) {
25457 this.getSuccess = this.createAccessor(s.successProperty);
25459 if (s.messageProperty) {
25460 this.getMessage = this.createAccessor(s.messageProperty);
25462 this.getRoot = s.root ? this.createAccessor(s.root) : function(p){return p;};
25463 if (s.id || s.idProperty) {
25464 var g = this.createAccessor(s.id || s.idProperty);
25465 this.getId = function(rec) {
25467 return (r === undefined || r === '') ? null : r;
25470 this.getId = function(){return null;};
25473 for(var i = 0; i < fl; i++){
25475 var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
25476 ef.push(this.createAccessor(map));
25482 simpleAccess : function(obj, subsc) {
25487 createAccessor : function(){
25489 return function(expr) {
25490 if(Ext.isEmpty(expr)){
25491 return Ext.emptyFn;
25493 if(Ext.isFunction(expr)){
25496 var i = String(expr).search(re);
25498 return new Function('obj', 'return obj' + (i > 0 ? '.' : '') + expr);
25500 return function(obj){
25508 extractValues : function(data, items, len) {
25509 var f, values = {};
25510 for(var j = 0; j < len; j++){
25512 var v = this.ef[j](data);
25513 values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
25520 Ext.data.JsonReader.Error = Ext.extend(Ext.Error, {
25521 constructor : function(message, arg) {
25523 Ext.Error.call(this, message);
25525 name : 'Ext.data.JsonReader'
25527 Ext.apply(Ext.data.JsonReader.Error.prototype, {
25529 'response': 'An error occurred while json-decoding your server response',
25530 '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.',
25531 '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.',
25532 '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.',
25533 '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.'
25537 Ext.data.ArrayReader = Ext.extend(Ext.data.JsonReader, {
25542 readRecords : function(o){
25543 this.arrayData = o;
25545 sid = s ? Ext.num(s.idIndex, s.id) : null,
25546 recordType = this.recordType,
25547 fields = recordType.prototype.fields,
25552 var root = this.getRoot(o);
25554 for(var i = 0, len = root.length; i < len; i++) {
25557 id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);
25558 for(var j = 0, jlen = fields.length; j < jlen; j++) {
25559 var f = fields.items[j],
25560 k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;
25561 v = n[k] !== undefined ? n[k] : f.defaultValue;
25562 v = f.convert(v, n);
25563 values[f.name] = v;
25565 var record = new recordType(values, id);
25567 records[records.length] = record;
25570 var totalRecords = records.length;
25572 if(s.totalProperty) {
25573 v = parseInt(this.getTotal(o), 10);
25578 if(s.successProperty){
25579 v = this.getSuccess(o);
25580 if(v === false || v === 'false'){
25588 totalRecords : totalRecords
25592 Ext.data.ArrayStore = Ext.extend(Ext.data.Store, {
25594 constructor: function(config){
25595 Ext.data.ArrayStore.superclass.constructor.call(this, Ext.apply(config, {
25596 reader: new Ext.data.ArrayReader(config)
25600 loadData : function(data, append){
25601 if(this.expandData === true){
25603 for(var i = 0, len = data.length; i < len; i++){
25604 r[r.length] = [data[i]];
25608 Ext.data.ArrayStore.superclass.loadData.call(this, data, append);
25611 Ext.reg('arraystore', Ext.data.ArrayStore);
25614 Ext.data.SimpleStore = Ext.data.ArrayStore;
25615 Ext.reg('simplestore', Ext.data.SimpleStore);
25616 Ext.data.JsonStore = Ext.extend(Ext.data.Store, {
25618 constructor: function(config){
25619 Ext.data.JsonStore.superclass.constructor.call(this, Ext.apply(config, {
25620 reader: new Ext.data.JsonReader(config)
25624 Ext.reg('jsonstore', Ext.data.JsonStore);
25625 Ext.data.XmlWriter = function(params) {
25626 Ext.data.XmlWriter.superclass.constructor.apply(this, arguments);
25628 this.tpl = (typeof(this.tpl) === 'string') ? new Ext.XTemplate(this.tpl).compile() : this.tpl.compile();
25630 Ext.extend(Ext.data.XmlWriter, Ext.data.DataWriter, {
25632 documentRoot: 'xrequest',
25634 forceDocumentRoot: false,
25638 xmlVersion : '1.0',
25640 xmlEncoding: 'ISO-8859-15',
25643 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>',
25647 render : function(params, baseParams, data) {
25648 baseParams = this.toArray(baseParams);
25649 params.xmlData = this.tpl.applyTemplate({
25650 version: this.xmlVersion,
25651 encoding: this.xmlEncoding,
25652 documentRoot: (baseParams.length > 0 || this.forceDocumentRoot === true) ? this.documentRoot : false,
25653 record: this.meta.record,
25655 baseParams: baseParams,
25656 records: (Ext.isArray(data[0])) ? data : [data]
25661 createRecord : function(rec) {
25662 return this.toArray(this.toHash(rec));
25666 updateRecord : function(rec) {
25667 return this.toArray(this.toHash(rec));
25671 destroyRecord : function(rec) {
25673 data[this.meta.idProperty] = rec.id;
25674 return this.toArray(data);
25678 Ext.data.XmlReader = function(meta, recordType){
25682 Ext.applyIf(meta, {
25683 idProperty: meta.idProperty || meta.idPath || meta.id,
25684 successProperty: meta.successProperty || meta.success
25687 Ext.data.XmlReader.superclass.constructor.call(this, meta, recordType || meta.fields);
25689 Ext.extend(Ext.data.XmlReader, Ext.data.DataReader, {
25691 read : function(response){
25692 var doc = response.responseXML;
25694 throw {message: "XmlReader.read: XML Document not available"};
25696 return this.readRecords(doc);
25700 readRecords : function(doc){
25702 this.xmlData = doc;
25704 var root = doc.documentElement || doc,
25709 if(this.meta.totalProperty){
25710 totalRecords = this.getTotal(root, 0);
25712 if(this.meta.successProperty){
25713 success = this.getSuccess(root);
25716 var records = this.extractData(q.select(this.meta.record, root), true);
25722 totalRecords : totalRecords || records.length
25727 readResponse : function(action, response) {
25728 var q = Ext.DomQuery,
25729 doc = response.responseXML,
25730 root = doc.documentElement || doc;
25733 var res = new Ext.data.Response({
25735 success : this.getSuccess(root),
25736 message: this.getMessage(root),
25737 data: this.extractData(q.select(this.meta.record, root) || q.select(this.meta.root, root), false),
25741 if (Ext.isEmpty(res.success)) {
25742 throw new Ext.data.DataReader.Error('successProperty-response', this.meta.successProperty);
25746 if (action === Ext.data.Api.actions.create) {
25747 var def = Ext.isDefined(res.data);
25748 if (def && Ext.isEmpty(res.data)) {
25749 throw new Ext.data.JsonReader.Error('root-empty', this.meta.root);
25752 throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root);
25758 getSuccess : function() {
25763 buildExtractors : function() {
25768 Record = this.recordType,
25769 f = Record.prototype.fields,
25773 if(s.totalProperty) {
25774 this.getTotal = this.createAccessor(s.totalProperty);
25776 if(s.successProperty) {
25777 this.getSuccess = this.createAccessor(s.successProperty);
25779 if (s.messageProperty) {
25780 this.getMessage = this.createAccessor(s.messageProperty);
25782 this.getRoot = function(res) {
25783 return (!Ext.isEmpty(res[this.meta.record])) ? res[this.meta.record] : res[this.meta.root];
25785 if (s.idPath || s.idProperty) {
25786 var g = this.createAccessor(s.idPath || s.idProperty);
25787 this.getId = function(rec) {
25788 var id = g(rec) || rec.id;
25789 return (id === undefined || id === '') ? null : id;
25792 this.getId = function(){return null;};
25795 for(var i = 0; i < fl; i++){
25797 var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
25798 ef.push(this.createAccessor(map));
25804 createAccessor : function(){
25805 var q = Ext.DomQuery;
25806 return function(key) {
25807 if (Ext.isFunction(key)) {
25811 case this.meta.totalProperty:
25812 return function(root, def){
25813 return q.selectNumber(key, root, def);
25816 case this.meta.successProperty:
25817 return function(root, def) {
25818 var sv = q.selectValue(key, root, true);
25819 var success = sv !== false && sv !== 'false';
25824 return function(root, def) {
25825 return q.selectValue(key, root, def);
25833 extractValues : function(data, items, len) {
25834 var f, values = {};
25835 for(var j = 0; j < len; j++){
25837 var v = this.ef[j](data);
25838 values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
25843 Ext.data.XmlStore = Ext.extend(Ext.data.Store, {
25845 constructor: function(config){
25846 Ext.data.XmlStore.superclass.constructor.call(this, Ext.apply(config, {
25847 reader: new Ext.data.XmlReader(config)
25851 Ext.reg('xmlstore', Ext.data.XmlStore);
25852 Ext.data.GroupingStore = Ext.extend(Ext.data.Store, {
25855 constructor: function(config) {
25856 config = config || {};
25862 this.hasMultiSort = true;
25863 this.multiSortInfo = this.multiSortInfo || {sorters: []};
25865 var sorters = this.multiSortInfo.sorters,
25866 groupField = config.groupField || this.groupField,
25867 sortInfo = config.sortInfo || this.sortInfo,
25868 groupDir = config.groupDir || this.groupDir;
25873 field : groupField,
25874 direction: groupDir
25880 sorters.push(sortInfo);
25883 Ext.data.GroupingStore.superclass.constructor.call(this, config);
25890 this.applyGroupField();
25895 remoteGroup : false,
25903 clearGrouping : function(){
25904 this.groupField = false;
25906 if(this.remoteGroup){
25907 if(this.baseParams){
25908 delete this.baseParams.groupBy;
25909 delete this.baseParams.groupDir;
25911 var lo = this.lastOptions;
25912 if(lo && lo.params){
25913 delete lo.params.groupBy;
25914 delete lo.params.groupDir;
25920 this.fireEvent('datachanged', this);
25925 groupBy : function(field, forceRegroup, direction) {
25926 direction = direction ? (String(direction).toUpperCase() == 'DESC' ? 'DESC' : 'ASC') : this.groupDir;
25928 if (this.groupField == field && this.groupDir == direction && !forceRegroup) {
25934 var sorters = this.multiSortInfo.sorters;
25935 if (sorters.length > 0 && sorters[0].field == this.groupField) {
25939 this.groupField = field;
25940 this.groupDir = direction;
25941 this.applyGroupField();
25943 var fireGroupEvent = function() {
25944 this.fireEvent('groupchange', this, this.getGroupState());
25947 if (this.groupOnSort) {
25948 this.sort(field, direction);
25949 fireGroupEvent.call(this);
25953 if (this.remoteGroup) {
25954 this.on('load', fireGroupEvent, this, {single: true});
25957 this.sort(sorters);
25958 fireGroupEvent.call(this);
25964 sort : function(fieldName, dir) {
25965 if (this.remoteSort) {
25966 return Ext.data.GroupingStore.superclass.sort.call(this, fieldName, dir);
25972 if (Ext.isArray(arguments[0])) {
25973 sorters = arguments[0];
25974 } else if (fieldName == undefined) {
25977 sorters = this.sortInfo ? [this.sortInfo] : [];
25981 var field = this.fields.get(fieldName);
25982 if (!field) return false;
25984 var name = field.name,
25985 sortInfo = this.sortInfo || null,
25986 sortToggle = this.sortToggle ? this.sortToggle[name] : null;
25989 if (sortInfo && sortInfo.field == name) {
25990 dir = (this.sortToggle[name] || 'ASC').toggle('ASC', 'DESC');
25992 dir = field.sortDir;
25996 this.sortToggle[name] = dir;
25997 this.sortInfo = {field: name, direction: dir};
25999 sorters = [this.sortInfo];
26003 if (this.groupField) {
26004 sorters.unshift({direction: this.groupDir, field: this.groupField});
26007 return this.multiSort.call(this, sorters, dir);
26011 applyGroupField: function(){
26012 if (this.remoteGroup) {
26013 if(!this.baseParams){
26014 this.baseParams = {};
26017 Ext.apply(this.baseParams, {
26018 groupBy : this.groupField,
26019 groupDir: this.groupDir
26022 var lo = this.lastOptions;
26023 if (lo && lo.params) {
26024 lo.params.groupDir = this.groupDir;
26027 delete lo.params.groupBy;
26033 applyGrouping : function(alwaysFireChange){
26034 if(this.groupField !== false){
26035 this.groupBy(this.groupField, true, this.groupDir);
26038 if(alwaysFireChange === true){
26039 this.fireEvent('datachanged', this);
26046 getGroupState : function(){
26047 return this.groupOnSort && this.groupField !== false ?
26048 (this.sortInfo ? this.sortInfo.field : undefined) : this.groupField;
26051 Ext.reg('groupingstore', Ext.data.GroupingStore);
26053 Ext.data.DirectProxy = function(config){
26054 Ext.apply(this, config);
26055 if(typeof this.paramOrder == 'string'){
26056 this.paramOrder = this.paramOrder.split(/[\s,|]/);
26058 Ext.data.DirectProxy.superclass.constructor.call(this, config);
26061 Ext.extend(Ext.data.DirectProxy, Ext.data.DataProxy, {
26063 paramOrder: undefined,
26066 paramsAsHash: true,
26069 directFn : undefined,
26072 doRequest : function(action, rs, params, reader, callback, scope, options) {
26074 directFn = this.api[action] || this.directFn;
26077 case Ext.data.Api.actions.create:
26078 args.push(params.jsonData);
26080 case Ext.data.Api.actions.read:
26082 if(directFn.directCfg.method.len > 0){
26083 if(this.paramOrder){
26084 for(var i = 0, len = this.paramOrder.length; i < len; i++){
26085 args.push(params[this.paramOrder[i]]);
26087 }else if(this.paramsAsHash){
26092 case Ext.data.Api.actions.update:
26093 args.push(params.jsonData);
26095 case Ext.data.Api.actions.destroy:
26096 args.push(params.jsonData);
26101 params : params || {},
26103 callback : callback,
26110 args.push(this.createCallback(action, rs, trans), this);
26111 directFn.apply(window, args);
26115 createCallback : function(action, rs, trans) {
26117 return function(result, res) {
26120 if (action === Ext.data.Api.actions.read) {
26121 me.fireEvent("loadexception", me, trans, res, null);
26123 me.fireEvent('exception', me, 'remote', action, trans, res, null);
26124 trans.request.callback.call(trans.request.scope, null, trans.request.arg, false);
26127 if (action === Ext.data.Api.actions.read) {
26128 me.onRead(action, trans, result, res);
26130 me.onWrite(action, trans, result, res, rs);
26136 onRead : function(action, trans, result, res) {
26139 records = trans.reader.readRecords(result);
26143 this.fireEvent("loadexception", this, trans, res, ex);
26145 this.fireEvent('exception', this, 'response', action, trans, res, ex);
26146 trans.request.callback.call(trans.request.scope, null, trans.request.arg, false);
26149 this.fireEvent("load", this, res, trans.request.arg);
26150 trans.request.callback.call(trans.request.scope, records, trans.request.arg, true);
26153 onWrite : function(action, trans, result, res, rs) {
26154 var data = trans.reader.extractData(trans.reader.getRoot(result), false);
26155 var success = trans.reader.getSuccess(result);
26156 success = (success !== false);
26158 this.fireEvent("write", this, action, data, res, rs, trans.request.arg);
26160 this.fireEvent('exception', this, 'remote', action, trans, result, rs);
26162 trans.request.callback.call(trans.request.scope, data, res, success);
26166 Ext.data.DirectStore = Ext.extend(Ext.data.Store, {
26167 constructor : function(config){
26169 var c = Ext.apply({}, {
26170 batchTransactions: false
26172 Ext.data.DirectStore.superclass.constructor.call(this, Ext.apply(c, {
26173 proxy: Ext.isDefined(c.proxy) ? c.proxy : new Ext.data.DirectProxy(Ext.copyTo({}, c, 'paramOrder,paramsAsHash,directFn,api')),
26174 reader: (!Ext.isDefined(c.reader) && c.fields) ? new Ext.data.JsonReader(Ext.copyTo({}, c, 'totalProperty,root,idProperty'), c.fields) : c.reader
26178 Ext.reg('directstore', Ext.data.DirectStore);
26180 Ext.Direct = Ext.extend(Ext.util.Observable, {
26188 SERVER: 'exception'
26192 constructor: function(){
26199 this.transactions = {};
26200 this.providers = {};
26204 addProvider : function(provider){
26207 for(var i = 0, len = a.length; i < len; i++){
26208 this.addProvider(a[i]);
26214 if(!provider.events){
26215 provider = new Ext.Direct.PROVIDERS[provider.type](provider);
26217 provider.id = provider.id || Ext.id();
26218 this.providers[provider.id] = provider;
26220 provider.on('data', this.onProviderData, this);
26221 provider.on('exception', this.onProviderException, this);
26224 if(!provider.isConnected()){
26225 provider.connect();
26232 getProvider : function(id){
26233 return this.providers[id];
26236 removeProvider : function(id){
26237 var provider = id.id ? id : this.providers[id];
26238 provider.un('data', this.onProviderData, this);
26239 provider.un('exception', this.onProviderException, this);
26240 delete this.providers[provider.id];
26244 addTransaction: function(t){
26245 this.transactions[t.tid] = t;
26249 removeTransaction: function(t){
26250 delete this.transactions[t.tid || t];
26254 getTransaction: function(tid){
26255 return this.transactions[tid.tid || tid];
26258 onProviderData : function(provider, e){
26259 if(Ext.isArray(e)){
26260 for(var i = 0, len = e.length; i < len; i++){
26261 this.onProviderData(provider, e[i]);
26265 if(e.name && e.name != 'event' && e.name != 'exception'){
26266 this.fireEvent(e.name, e);
26267 }else if(e.type == 'exception'){
26268 this.fireEvent('exception', e);
26270 this.fireEvent('event', e, provider);
26273 createEvent : function(response, extraProps){
26274 return new Ext.Direct.eventTypes[response.type](Ext.apply(response, extraProps));
26278 Ext.Direct = new Ext.Direct();
26280 Ext.Direct.TID = 1;
26281 Ext.Direct.PROVIDERS = {};
26282 Ext.Direct.Transaction = function(config){
26283 Ext.apply(this, config);
26284 this.tid = ++Ext.Direct.TID;
26285 this.retryCount = 0;
26287 Ext.Direct.Transaction.prototype = {
26289 this.provider.queueTransaction(this);
26297 getProvider: function(){
26298 return this.provider;
26300 };Ext.Direct.Event = function(config){
26301 Ext.apply(this, config);
26304 Ext.Direct.Event.prototype = {
26306 getData: function(){
26311 Ext.Direct.RemotingEvent = Ext.extend(Ext.Direct.Event, {
26313 getTransaction: function(){
26314 return this.transaction || Ext.Direct.getTransaction(this.tid);
26318 Ext.Direct.ExceptionEvent = Ext.extend(Ext.Direct.RemotingEvent, {
26323 Ext.Direct.eventTypes = {
26324 'rpc': Ext.Direct.RemotingEvent,
26325 'event': Ext.Direct.Event,
26326 'exception': Ext.Direct.ExceptionEvent
26329 Ext.direct.Provider = Ext.extend(Ext.util.Observable, {
26338 constructor : function(config){
26339 Ext.apply(this, config);
26350 Ext.direct.Provider.superclass.constructor.call(this, config);
26354 isConnected: function(){
26359 connect: Ext.emptyFn,
26362 disconnect: Ext.emptyFn
26365 Ext.direct.JsonProvider = Ext.extend(Ext.direct.Provider, {
26366 parseResponse: function(xhr){
26367 if(!Ext.isEmpty(xhr.responseText)){
26368 if(typeof xhr.responseText == 'object'){
26369 return xhr.responseText;
26371 return Ext.decode(xhr.responseText);
26376 getEvents: function(xhr){
26379 data = this.parseResponse(xhr);
26381 var event = new Ext.Direct.ExceptionEvent({
26384 code: Ext.Direct.exceptions.PARSE,
26385 message: 'Error parsing json response: \n\n ' + data
26390 if(Ext.isArray(data)){
26391 for(var i = 0, len = data.length; i < len; i++){
26392 events.push(Ext.Direct.createEvent(data[i]));
26395 events.push(Ext.Direct.createEvent(data));
26400 Ext.direct.PollingProvider = Ext.extend(Ext.direct.JsonProvider, {
26413 constructor : function(config){
26414 Ext.direct.PollingProvider.superclass.constructor.call(this, config);
26424 isConnected: function(){
26425 return !!this.pollTask;
26429 connect: function(){
26430 if(this.url && !this.pollTask){
26431 this.pollTask = Ext.TaskMgr.start({
26433 if(this.fireEvent('beforepoll', this) !== false){
26434 if(typeof this.url == 'function'){
26435 this.url(this.baseParams);
26439 callback: this.onData,
26441 params: this.baseParams
26446 interval: this.interval,
26449 this.fireEvent('connect', this);
26450 }else if(!this.url){
26451 throw 'Error initializing PollingProvider, no url configured.';
26456 disconnect: function(){
26458 Ext.TaskMgr.stop(this.pollTask);
26459 delete this.pollTask;
26460 this.fireEvent('disconnect', this);
26465 onData: function(opt, success, xhr){
26467 var events = this.getEvents(xhr);
26468 for(var i = 0, len = events.length; i < len; i++){
26470 this.fireEvent('data', this, e);
26473 var e = new Ext.Direct.ExceptionEvent({
26475 code: Ext.Direct.exceptions.TRANSPORT,
26476 message: 'Unable to connect to the server.',
26479 this.fireEvent('data', this, e);
26484 Ext.Direct.PROVIDERS['polling'] = Ext.direct.PollingProvider;
26485 Ext.direct.RemotingProvider = Ext.extend(Ext.direct.JsonProvider, {
26501 timeout: undefined,
26503 constructor : function(config){
26504 Ext.direct.RemotingProvider.superclass.constructor.call(this, config);
26511 this.namespace = (Ext.isString(this.namespace)) ? Ext.ns(this.namespace) : this.namespace || window;
26512 this.transactions = {};
26513 this.callBuffer = [];
26517 initAPI : function(){
26518 var o = this.actions;
26520 var cls = this.namespace[c] || (this.namespace[c] = {}),
26522 for(var i = 0, len = ms.length; i < len; i++){
26524 cls[m.name] = this.createMethod(c, m);
26530 isConnected: function(){
26531 return !!this.connected;
26534 connect: function(){
26537 this.connected = true;
26538 this.fireEvent('connect', this);
26539 }else if(!this.url){
26540 throw 'Error initializing RemotingProvider, no url configured.';
26544 disconnect: function(){
26545 if(this.connected){
26546 this.connected = false;
26547 this.fireEvent('disconnect', this);
26551 onData: function(opt, success, xhr){
26553 var events = this.getEvents(xhr);
26554 for(var i = 0, len = events.length; i < len; i++){
26556 t = this.getTransaction(e);
26557 this.fireEvent('data', this, e);
26559 this.doCallback(t, e, true);
26560 Ext.Direct.removeTransaction(t);
26564 var ts = [].concat(opt.ts);
26565 for(var i = 0, len = ts.length; i < len; i++){
26566 var t = this.getTransaction(ts[i]);
26567 if(t && t.retryCount < this.maxRetries){
26570 var e = new Ext.Direct.ExceptionEvent({
26573 code: Ext.Direct.exceptions.TRANSPORT,
26574 message: 'Unable to connect to the server.',
26577 this.fireEvent('data', this, e);
26579 this.doCallback(t, e, false);
26580 Ext.Direct.removeTransaction(t);
26587 getCallData: function(t){
26597 doSend : function(data){
26600 callback: this.onData,
26603 timeout: this.timeout
26606 if(Ext.isArray(data)){
26608 for(var i = 0, len = data.length; i < len; i++){
26609 callData.push(this.getCallData(data[i]));
26612 callData = this.getCallData(data);
26615 if(this.enableUrlEncode){
26617 params[Ext.isString(this.enableUrlEncode) ? this.enableUrlEncode : 'data'] = Ext.encode(callData);
26620 o.jsonData = callData;
26622 Ext.Ajax.request(o);
26625 combineAndSend : function(){
26626 var len = this.callBuffer.length;
26628 this.doSend(len == 1 ? this.callBuffer[0] : this.callBuffer);
26629 this.callBuffer = [];
26633 queueTransaction: function(t){
26635 this.processForm(t);
26638 this.callBuffer.push(t);
26639 if(this.enableBuffer){
26640 if(!this.callTask){
26641 this.callTask = new Ext.util.DelayedTask(this.combineAndSend, this);
26643 this.callTask.delay(Ext.isNumber(this.enableBuffer) ? this.enableBuffer : 10);
26645 this.combineAndSend();
26649 doCall : function(c, m, args){
26650 var data = null, hs = args[m.len], scope = args[m.len+1];
26653 data = args.slice(0, m.len);
26656 var t = new Ext.Direct.Transaction({
26662 cb: scope && Ext.isFunction(hs) ? hs.createDelegate(scope) : hs
26665 if(this.fireEvent('beforecall', this, t, m) !== false){
26666 Ext.Direct.addTransaction(t);
26667 this.queueTransaction(t);
26668 this.fireEvent('call', this, t, m);
26672 doForm : function(c, m, form, callback, scope){
26673 var t = new Ext.Direct.Transaction({
26677 args:[form, callback, scope],
26678 cb: scope && Ext.isFunction(callback) ? callback.createDelegate(scope) : callback,
26682 if(this.fireEvent('beforecall', this, t, m) !== false){
26683 Ext.Direct.addTransaction(t);
26684 var isUpload = String(form.getAttribute("enctype")).toLowerCase() == 'multipart/form-data',
26690 extUpload: String(isUpload)
26696 form: Ext.getDom(form),
26697 isUpload: isUpload,
26698 params: callback && Ext.isObject(callback.params) ? Ext.apply(params, callback.params) : params
26700 this.fireEvent('call', this, t, m);
26701 this.processForm(t);
26705 processForm: function(t){
26709 callback: this.onData,
26712 isUpload: t.isUpload,
26717 createMethod : function(c, m){
26719 if(!m.formHandler){
26721 this.doCall(c, m, Array.prototype.slice.call(arguments, 0));
26722 }.createDelegate(this);
26724 f = function(form, callback, scope){
26725 this.doForm(c, m, form, callback, scope);
26726 }.createDelegate(this);
26735 getTransaction: function(opt){
26736 return opt && opt.tid ? Ext.Direct.getTransaction(opt.tid) : null;
26739 doCallback: function(t, e){
26740 var fn = e.status ? 'success' : 'failure';
26743 result = Ext.isDefined(e.result) ? e.result : e.data;
26744 if(Ext.isFunction(hs)){
26747 Ext.callback(hs[fn], hs.scope, [result, e]);
26748 Ext.callback(hs.callback, hs.scope, [result, e]);
26753 Ext.Direct.PROVIDERS['remoting'] = Ext.direct.RemotingProvider;
26754 Ext.Resizable = Ext.extend(Ext.util.Observable, {
26756 constructor: function(el, config){
26757 this.el = Ext.get(el);
26758 if(config && config.wrap){
26759 config.resizeChild = this.el;
26760 this.el = this.el.wrap(typeof config.wrap == 'object' ? config.wrap : {cls:'xresizable-wrap'});
26761 this.el.id = this.el.dom.id = config.resizeChild.id + '-rzwrap';
26762 this.el.setStyle('overflow', 'hidden');
26763 this.el.setPositioning(config.resizeChild.getPositioning());
26764 config.resizeChild.clearPositioning();
26765 if(!config.width || !config.height){
26766 var csize = config.resizeChild.getSize();
26767 this.el.setSize(csize.width, csize.height);
26769 if(config.pinned && !config.adjustments){
26770 config.adjustments = 'auto';
26775 this.proxy = this.el.createProxy({tag: 'div', cls: 'x-resizable-proxy', id: this.el.id + '-rzproxy'}, Ext.getBody());
26776 this.proxy.unselectable();
26777 this.proxy.enableDisplayMode('block');
26779 Ext.apply(this, config);
26782 this.disableTrackOver = true;
26783 this.el.addClass('x-resizable-pinned');
26786 var position = this.el.getStyle('position');
26787 if(position != 'absolute' && position != 'fixed'){
26788 this.el.setStyle('position', 'relative');
26791 this.handles = 's,e,se';
26792 if(this.multiDirectional){
26793 this.handles += ',n,w';
26796 if(this.handles == 'all'){
26797 this.handles = 'n s e w ne nw se sw';
26799 var hs = this.handles.split(/\s*?[,;]\s*?| /);
26800 var ps = Ext.Resizable.positions;
26801 for(var i = 0, len = hs.length; i < len; i++){
26802 if(hs[i] && ps[hs[i]]){
26803 var pos = ps[hs[i]];
26804 this[pos] = new Ext.Resizable.Handle(this, pos, this.disableTrackOver, this.transparent, this.handleCls);
26808 this.corner = this.southeast;
26810 if(this.handles.indexOf('n') != -1 || this.handles.indexOf('w') != -1){
26811 this.updateBox = true;
26814 this.activeHandle = null;
26816 if(this.resizeChild){
26817 if(typeof this.resizeChild == 'boolean'){
26818 this.resizeChild = Ext.get(this.el.dom.firstChild, true);
26820 this.resizeChild = Ext.get(this.resizeChild, true);
26824 if(this.adjustments == 'auto'){
26825 var rc = this.resizeChild;
26826 var hw = this.west, he = this.east, hn = this.north, hs = this.south;
26827 if(rc && (hw || hn)){
26828 rc.position('relative');
26829 rc.setLeft(hw ? hw.el.getWidth() : 0);
26830 rc.setTop(hn ? hn.el.getHeight() : 0);
26832 this.adjustments = [
26833 (he ? -he.el.getWidth() : 0) + (hw ? -hw.el.getWidth() : 0),
26834 (hn ? -hn.el.getHeight() : 0) + (hs ? -hs.el.getHeight() : 0) -1
26838 if(this.draggable){
26839 this.dd = this.dynamic ?
26840 this.el.initDD(null) : this.el.initDDProxy(null, {dragElId: this.proxy.id});
26841 this.dd.setHandleElId(this.resizeChild ? this.resizeChild.id : this.el.id);
26842 if(this.constrainTo){
26843 this.dd.constrainTo(this.constrainTo);
26854 if(this.width !== null && this.height !== null){
26855 this.resizeTo(this.width, this.height);
26857 this.updateChildSize();
26860 this.el.dom.style.zoom = 1;
26862 Ext.Resizable.superclass.constructor.call(this);
26866 adjustments : [0, 0],
26871 disableTrackOver : false,
26879 easing : 'easeOutStrong',
26886 multiDirectional : false,
26892 heightIncrement : 0,
26894 widthIncrement : 0,
26910 preserveRatio : false,
26912 resizeChild : false,
26914 transparent: false,
26921 resizeTo : function(width, height){
26922 this.el.setSize(width, height);
26923 this.updateChildSize();
26924 this.fireEvent('resize', this, width, height, null);
26928 startSizing : function(e, handle){
26929 this.fireEvent('beforeresize', this, e);
26933 this.overlay = this.el.createProxy({tag: 'div', cls: 'x-resizable-overlay', html: ' '}, Ext.getBody());
26934 this.overlay.unselectable();
26935 this.overlay.enableDisplayMode('block');
26938 mousemove: this.onMouseMove,
26939 mouseup: this.onMouseUp
26942 this.overlay.setStyle('cursor', handle.el.getStyle('cursor'));
26944 this.resizing = true;
26945 this.startBox = this.el.getBox();
26946 this.startPoint = e.getXY();
26947 this.offsets = [(this.startBox.x + this.startBox.width) - this.startPoint[0],
26948 (this.startBox.y + this.startBox.height) - this.startPoint[1]];
26950 this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
26951 this.overlay.show();
26953 if(this.constrainTo) {
26954 var ct = Ext.get(this.constrainTo);
26955 this.resizeRegion = ct.getRegion().adjust(
26956 ct.getFrameWidth('t'),
26957 ct.getFrameWidth('l'),
26958 -ct.getFrameWidth('b'),
26959 -ct.getFrameWidth('r')
26963 this.proxy.setStyle('visibility', 'hidden');
26965 this.proxy.setBox(this.startBox);
26967 this.proxy.setStyle('visibility', 'visible');
26973 onMouseDown : function(handle, e){
26976 this.activeHandle = handle;
26977 this.startSizing(e, handle);
26982 onMouseUp : function(e){
26983 this.activeHandle = null;
26984 var size = this.resizeElement();
26985 this.resizing = false;
26987 this.overlay.hide();
26989 this.fireEvent('resize', this, size.width, size.height, e);
26993 updateChildSize : function(){
26994 if(this.resizeChild){
26996 var child = this.resizeChild;
26997 var adj = this.adjustments;
26998 if(el.dom.offsetWidth){
26999 var b = el.getSize(true);
27000 child.setSize(b.width+adj[0], b.height+adj[1]);
27007 setTimeout(function(){
27008 if(el.dom.offsetWidth){
27009 var b = el.getSize(true);
27010 child.setSize(b.width+adj[0], b.height+adj[1]);
27018 snap : function(value, inc, min){
27019 if(!inc || !value){
27022 var newValue = value;
27023 var m = value % inc;
27026 newValue = value + (inc-m);
27028 newValue = value - m;
27031 return Math.max(min, newValue);
27035 resizeElement : function(){
27036 var box = this.proxy.getBox();
27037 if(this.updateBox){
27038 this.el.setBox(box, false, this.animate, this.duration, null, this.easing);
27040 this.el.setSize(box.width, box.height, this.animate, this.duration, null, this.easing);
27042 this.updateChildSize();
27046 if(this.draggable && this.constrainTo){
27047 this.dd.resetConstraints();
27048 this.dd.constrainTo(this.constrainTo);
27054 constrain : function(v, diff, m, mx){
27057 }else if(v - diff > mx){
27064 onMouseMove : function(e){
27065 if(this.enabled && this.activeHandle){
27068 if(this.resizeRegion && !this.resizeRegion.contains(e.getPoint())) {
27073 var curSize = this.curSize || this.startBox,
27074 x = this.startBox.x, y = this.startBox.y,
27078 h = curSize.height,
27081 mw = this.minWidth,
27082 mh = this.minHeight,
27083 mxw = this.maxWidth,
27084 mxh = this.maxHeight,
27085 wi = this.widthIncrement,
27086 hi = this.heightIncrement,
27087 eventXY = e.getXY(),
27088 diffX = -(this.startPoint[0] - Math.max(this.minX, eventXY[0])),
27089 diffY = -(this.startPoint[1] - Math.max(this.minY, eventXY[1])),
27090 pos = this.activeHandle.position,
27097 w = Math.min(Math.max(mw, w), mxw);
27101 h = Math.min(Math.max(mh, h), mxh);
27106 w = Math.min(Math.max(mw, w), mxw);
27107 h = Math.min(Math.max(mh, h), mxh);
27110 diffY = this.constrain(h, diffY, mh, mxh);
27115 diffX = this.constrain(w, diffX, mw, mxw);
27121 w = Math.min(Math.max(mw, w), mxw);
27122 diffY = this.constrain(h, diffY, mh, mxh);
27127 diffX = this.constrain(w, diffX, mw, mxw);
27128 diffY = this.constrain(h, diffY, mh, mxh);
27135 diffX = this.constrain(w, diffX, mw, mxw);
27137 h = Math.min(Math.max(mh, h), mxh);
27143 var sw = this.snap(w, wi, mw);
27144 var sh = this.snap(h, hi, mh);
27145 if(sw != w || sh != h){
27168 if(this.preserveRatio){
27173 h = Math.min(Math.max(mh, h), mxh);
27178 w = Math.min(Math.max(mw, w), mxw);
27183 w = Math.min(Math.max(mw, w), mxw);
27189 w = Math.min(Math.max(mw, w), mxw);
27195 h = Math.min(Math.max(mh, h), mxh);
27203 h = Math.min(Math.max(mh, h), mxh);
27213 h = Math.min(Math.max(mh, h), mxh);
27221 this.proxy.setBounds(x, y, w, h);
27223 this.resizeElement();
27230 handleOver : function(){
27232 this.el.addClass('x-resizable-over');
27237 handleOut : function(){
27238 if(!this.resizing){
27239 this.el.removeClass('x-resizable-over');
27244 getEl : function(){
27249 getResizeChild : function(){
27250 return this.resizeChild;
27254 destroy : function(removeEl){
27255 Ext.destroy(this.dd, this.overlay, this.proxy);
27256 this.overlay = null;
27259 var ps = Ext.Resizable.positions;
27261 if(typeof ps[k] != 'function' && this[ps[k]]){
27262 this[ps[k]].destroy();
27266 this.el.update('');
27267 Ext.destroy(this.el);
27270 this.purgeListeners();
27273 syncHandleHeight : function(){
27274 var h = this.el.getHeight(true);
27276 this.west.el.setHeight(h);
27279 this.east.el.setHeight(h);
27286 Ext.Resizable.positions = {
27287 n: 'north', s: 'south', e: 'east', w: 'west', se: 'southeast', sw: 'southwest', nw: 'northwest', ne: 'northeast'
27290 Ext.Resizable.Handle = Ext.extend(Object, {
27291 constructor : function(rz, pos, disableTrackOver, transparent, cls){
27294 var tpl = Ext.DomHelper.createTemplate(
27295 {tag: 'div', cls: 'x-resizable-handle x-resizable-handle-{0}'}
27298 Ext.Resizable.Handle.prototype.tpl = tpl;
27300 this.position = pos;
27302 this.el = this.tpl.append(rz.el.dom, [this.position], true);
27303 this.el.unselectable();
27305 this.el.setOpacity(0);
27307 if(!Ext.isEmpty(cls)){
27308 this.el.addClass(cls);
27310 this.el.on('mousedown', this.onMouseDown, this);
27311 if(!disableTrackOver){
27314 mouseover: this.onMouseOver,
27315 mouseout: this.onMouseOut
27321 afterResize : function(rz){
27325 onMouseDown : function(e){
27326 this.rz.onMouseDown(this, e);
27329 onMouseOver : function(e){
27330 this.rz.handleOver(this, e);
27333 onMouseOut : function(e){
27334 this.rz.handleOut(this, e);
27337 destroy : function(){
27338 Ext.destroy(this.el);
27343 Ext.Window = Ext.extend(Ext.Panel, {
27356 baseCls : 'x-window',
27364 closeAction : 'close',
27368 constrainHeader : false,
27372 minimizable : false,
27374 maximizable : false,
27380 expandOnShow : true,
27383 showAnimDuration: 0.25,
27386 hideAnimDuration: 0.25,
27389 collapsible : false,
27392 initHidden : undefined,
27402 elements : 'header,body',
27409 initComponent : function(){
27411 Ext.Window.superclass.initComponent.call(this);
27425 if(Ext.isDefined(this.initHidden)){
27426 this.hidden = this.initHidden;
27428 if(this.hidden === false){
27429 this.hidden = true;
27435 getState : function(){
27436 return Ext.apply(Ext.Window.superclass.getState.call(this) || {}, this.getBox(true));
27440 onRender : function(ct, position){
27441 Ext.Window.superclass.onRender.call(this, ct, position);
27444 this.el.addClass('x-window-plain');
27448 this.focusEl = this.el.createChild({
27449 tag: 'a', href:'#', cls:'x-dlg-focus',
27450 tabIndex:'-1', html: ' '});
27451 this.focusEl.swallowEvent('click', true);
27453 this.proxy = this.el.createProxy('x-window-proxy');
27454 this.proxy.enableDisplayMode('block');
27457 this.mask = this.container.createChild({cls:'ext-el-mask'}, this.el.dom);
27458 this.mask.enableDisplayMode('block');
27460 this.mon(this.mask, 'click', this.focus, this);
27462 if(this.maximizable){
27463 this.mon(this.header, 'dblclick', this.toggleMaximize, this);
27468 initEvents : function(){
27469 Ext.Window.superclass.initEvents.call(this);
27470 if(this.animateTarget){
27471 this.setAnimateTarget(this.animateTarget);
27474 if(this.resizable){
27475 this.resizer = new Ext.Resizable(this.el, {
27476 minWidth: this.minWidth,
27477 minHeight:this.minHeight,
27478 handles: this.resizeHandles || 'all',
27480 resizeElement : this.resizerAction,
27481 handleCls: 'x-window-handle'
27483 this.resizer.window = this;
27484 this.mon(this.resizer, 'beforeresize', this.beforeResize, this);
27487 if(this.draggable){
27488 this.header.addClass('x-window-draggable');
27490 this.mon(this.el, 'mousedown', this.toFront, this);
27491 this.manager = this.manager || Ext.WindowMgr;
27492 this.manager.register(this);
27493 if(this.maximized){
27494 this.maximized = false;
27498 var km = this.getKeyMap();
27499 km.on(27, this.onEsc, this);
27504 initDraggable : function(){
27506 this.dd = new Ext.Window.DD(this);
27510 onEsc : function(k, e){
27512 this[this.closeAction]();
27516 beforeDestroy : function(){
27519 this.clearAnchor();
27528 Ext.Window.superclass.beforeDestroy.call(this);
27532 onDestroy : function(){
27534 this.manager.unregister(this);
27536 Ext.Window.superclass.onDestroy.call(this);
27540 initTools : function(){
27541 if(this.minimizable){
27544 handler: this.minimize.createDelegate(this, [])
27547 if(this.maximizable){
27550 handler: this.maximize.createDelegate(this, [])
27554 handler: this.restore.createDelegate(this, []),
27561 handler: this[this.closeAction].createDelegate(this, [])
27567 resizerAction : function(){
27568 var box = this.proxy.getBox();
27570 this.window.handleResize(box);
27575 beforeResize : function(){
27576 this.resizer.minHeight = Math.max(this.minHeight, this.getFrameHeight() + 40);
27577 this.resizer.minWidth = Math.max(this.minWidth, this.getFrameWidth() + 40);
27578 this.resizeBox = this.el.getBox();
27582 updateHandles : function(){
27583 if(Ext.isIE && this.resizer){
27584 this.resizer.syncHandleHeight();
27590 handleResize : function(box){
27591 var rz = this.resizeBox;
27592 if(rz.x != box.x || rz.y != box.y){
27593 this.updateBox(box);
27596 if (Ext.isIE6 && Ext.isStrict) {
27601 this.updateHandles();
27606 focus : function(){
27607 var f = this.focusEl,
27608 db = this.defaultButton,
27612 if(Ext.isDefined(db)){
27613 if(Ext.isNumber(db) && this.fbar){
27614 f = this.fbar.items.get(db);
27615 }else if(Ext.isString(db)){
27616 f = Ext.getCmp(db);
27621 ct = Ext.getDom(this.container);
27623 if (ct != document.body && !Ext.lib.Region.getRegion(ct).contains(Ext.lib.Region.getRegion(el.dom))){
27628 f = f || this.focusEl;
27629 f.focus.defer(10, f);
27633 setAnimateTarget : function(el){
27635 this.animateTarget = el;
27639 beforeShow : function(){
27640 delete this.el.lastXY;
27641 delete this.el.lastLT;
27642 if(this.x === undefined || this.y === undefined){
27643 var xy = this.el.getAlignToXY(this.container, 'c-c');
27644 var pos = this.el.translatePoints(xy[0], xy[1]);
27645 this.x = this.x === undefined? pos.left : this.x;
27646 this.y = this.y === undefined? pos.top : this.y;
27648 this.el.setLeftTop(this.x, this.y);
27650 if(this.expandOnShow){
27651 this.expand(false);
27655 Ext.getBody().addClass('x-body-masked');
27656 this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
27662 show : function(animateTarget, cb, scope){
27663 if(!this.rendered){
27664 this.render(Ext.getBody());
27666 if(this.hidden === false){
27670 if(this.fireEvent('beforeshow', this) === false){
27674 this.on('show', cb, scope, {single:true});
27676 this.hidden = false;
27677 if(Ext.isDefined(animateTarget)){
27678 this.setAnimateTarget(animateTarget);
27681 if(this.animateTarget){
27690 afterShow : function(isAnim){
27691 if (this.isDestroyed){
27695 this.el.setStyle('display', 'block');
27697 if(this.maximized){
27698 this.fitContainer();
27700 if(Ext.isMac && Ext.isGecko2){
27701 this.cascade(this.setAutoScroll);
27704 if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
27705 Ext.EventManager.onWindowResize(this.onWindowResize, this);
27707 this.doConstrain();
27710 this.keyMap.enable();
27713 this.updateHandles();
27714 if(isAnim && (Ext.isIE || Ext.isWebKit)){
27715 var sz = this.getSize();
27716 this.onResize(sz.width, sz.height);
27719 this.fireEvent('show', this);
27723 animShow : function(){
27725 this.proxy.setBox(this.animateTarget.getBox());
27726 this.proxy.setOpacity(0);
27727 var b = this.getBox();
27728 this.el.setStyle('display', 'none');
27729 this.proxy.shift(Ext.apply(b, {
27730 callback: this.afterShow.createDelegate(this, [true], false),
27732 easing: 'easeNone',
27733 duration: this.showAnimDuration,
27739 hide : function(animateTarget, cb, scope){
27740 if(this.hidden || this.fireEvent('beforehide', this) === false){
27744 this.on('hide', cb, scope, {single:true});
27746 this.hidden = true;
27747 if(animateTarget !== undefined){
27748 this.setAnimateTarget(animateTarget);
27752 Ext.getBody().removeClass('x-body-masked');
27754 if(this.animateTarget){
27764 afterHide : function(){
27766 if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
27767 Ext.EventManager.removeResizeListener(this.onWindowResize, this);
27770 this.keyMap.disable();
27773 this.fireEvent('hide', this);
27777 animHide : function(){
27778 this.proxy.setOpacity(0.5);
27780 var tb = this.getBox(false);
27781 this.proxy.setBox(tb);
27783 this.proxy.shift(Ext.apply(this.animateTarget.getBox(), {
27784 callback: this.afterHide,
27786 duration: this.hideAnimDuration,
27787 easing: 'easeNone',
27793 onShow : Ext.emptyFn,
27796 onHide : Ext.emptyFn,
27799 onWindowResize : function(){
27800 if(this.maximized){
27801 this.fitContainer();
27804 this.mask.setSize('100%', '100%');
27805 var force = this.mask.dom.offsetHeight;
27806 this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
27808 this.doConstrain();
27812 doConstrain : function(){
27813 if(this.constrain || this.constrainHeader){
27815 if(this.constrain){
27817 right:this.el.shadowOffset,
27818 left:this.el.shadowOffset,
27819 bottom:this.el.shadowOffset
27822 var s = this.getSize();
27824 right:-(s.width - 100),
27825 bottom:-(s.height - 25)
27829 var xy = this.el.getConstrainToXY(this.container, true, offsets);
27831 this.setPosition(xy[0], xy[1]);
27837 ghost : function(cls){
27838 var ghost = this.createGhost(cls);
27839 var box = this.getBox(true);
27840 ghost.setLeftTop(box.x, box.y);
27841 ghost.setWidth(box.width);
27843 this.activeGhost = ghost;
27848 unghost : function(show, matchPosition){
27849 if(!this.activeGhost) {
27852 if(show !== false){
27854 this.focus.defer(10, this);
27855 if(Ext.isMac && Ext.isGecko2){
27856 this.cascade(this.setAutoScroll);
27859 if(matchPosition !== false){
27860 this.setPosition(this.activeGhost.getLeft(true), this.activeGhost.getTop(true));
27862 this.activeGhost.hide();
27863 this.activeGhost.remove();
27864 delete this.activeGhost;
27868 minimize : function(){
27869 this.fireEvent('minimize', this);
27874 close : function(){
27875 if(this.fireEvent('beforeclose', this) !== false){
27879 this.hide(null, this.doClose, this);
27885 doClose : function(){
27886 this.fireEvent('close', this);
27891 maximize : function(){
27892 if(!this.maximized){
27893 this.expand(false);
27894 this.restoreSize = this.getSize();
27895 this.restorePos = this.getPosition(true);
27896 if (this.maximizable){
27897 this.tools.maximize.hide();
27898 this.tools.restore.show();
27900 this.maximized = true;
27901 this.el.disableShadow();
27906 if(this.collapsible){
27907 this.tools.toggle.hide();
27909 this.el.addClass('x-window-maximized');
27910 this.container.addClass('x-window-maximized-ct');
27912 this.setPosition(0, 0);
27913 this.fitContainer();
27914 this.fireEvent('maximize', this);
27920 restore : function(){
27921 if(this.maximized){
27922 var t = this.tools;
27923 this.el.removeClass('x-window-maximized');
27930 this.setPosition(this.restorePos[0], this.restorePos[1]);
27931 this.setSize(this.restoreSize.width, this.restoreSize.height);
27932 delete this.restorePos;
27933 delete this.restoreSize;
27934 this.maximized = false;
27935 this.el.enableShadow(true);
27940 if(this.collapsible && t.toggle){
27943 this.container.removeClass('x-window-maximized-ct');
27945 this.doConstrain();
27946 this.fireEvent('restore', this);
27952 toggleMaximize : function(){
27953 return this[this.maximized ? 'restore' : 'maximize']();
27957 fitContainer : function(){
27958 var vs = this.container.getViewSize(false);
27959 this.setSize(vs.width, vs.height);
27964 setZIndex : function(index){
27966 this.mask.setStyle('z-index', index);
27968 this.el.setZIndex(++index);
27972 this.resizer.proxy.setStyle('z-index', ++index);
27975 this.lastZIndex = index;
27979 alignTo : function(element, position, offsets){
27980 var xy = this.el.getAlignToXY(element, position, offsets);
27981 this.setPagePosition(xy[0], xy[1]);
27986 anchorTo : function(el, alignment, offsets, monitorScroll){
27987 this.clearAnchor();
27988 this.anchorTarget = {
27990 alignment: alignment,
27994 Ext.EventManager.onWindowResize(this.doAnchor, this);
27995 var tm = typeof monitorScroll;
27996 if(tm != 'undefined'){
27997 Ext.EventManager.on(window, 'scroll', this.doAnchor, this,
27998 {buffer: tm == 'number' ? monitorScroll : 50});
28000 return this.doAnchor();
28004 doAnchor : function(){
28005 var o = this.anchorTarget;
28006 this.alignTo(o.el, o.alignment, o.offsets);
28011 clearAnchor : function(){
28012 if(this.anchorTarget){
28013 Ext.EventManager.removeResizeListener(this.doAnchor, this);
28014 Ext.EventManager.un(window, 'scroll', this.doAnchor, this);
28015 delete this.anchorTarget;
28021 toFront : function(e){
28022 if(this.manager.bringToFront(this)){
28023 if(!e || !e.getTarget().focus){
28031 setActive : function(active){
28033 if(!this.maximized){
28034 this.el.enableShadow(true);
28036 this.fireEvent('activate', this);
28038 this.el.disableShadow();
28039 this.fireEvent('deactivate', this);
28044 toBack : function(){
28045 this.manager.sendToBack(this);
28050 center : function(){
28051 var xy = this.el.getAlignToXY(this.container, 'c-c');
28052 this.setPagePosition(xy[0], xy[1]);
28058 Ext.reg('window', Ext.Window);
28061 Ext.Window.DD = Ext.extend(Ext.dd.DD, {
28063 constructor : function(win){
28065 Ext.Window.DD.superclass.constructor.call(this, win.el.id, 'WindowDD-'+win.id);
28066 this.setHandleElId(win.header.id);
28067 this.scroll = false;
28071 headerOffsets:[100, 25],
28072 startDrag : function(){
28074 this.proxy = w.ghost(w.initialConfig.cls);
28075 if(w.constrain !== false){
28076 var so = w.el.shadowOffset;
28077 this.constrainTo(w.container, {right: so, left: so, bottom: so});
28078 }else if(w.constrainHeader !== false){
28079 var s = this.proxy.getSize();
28080 this.constrainTo(w.container, {right: -(s.width-this.headerOffsets[0]), bottom: -(s.height-this.headerOffsets[1])});
28083 b4Drag : Ext.emptyFn,
28085 onDrag : function(e){
28086 this.alignElWithMouse(this.proxy, e.getPageX(), e.getPageY());
28089 endDrag : function(e){
28090 this.win.unghost();
28091 this.win.saveState();
28095 Ext.WindowGroup = function(){
28097 var accessList = [];
28101 var sortWindows = function(d1, d2){
28102 return (!d1._lastAccess || d1._lastAccess < d2._lastAccess) ? -1 : 1;
28106 var orderWindows = function(){
28107 var a = accessList, len = a.length;
28109 a.sort(sortWindows);
28110 var seed = a[0].manager.zseed;
28111 for(var i = 0; i < len; i++){
28113 if(win && !win.hidden){
28114 win.setZIndex(seed + (i*10));
28122 var setActiveWin = function(win){
28125 front.setActive(false);
28129 win.setActive(true);
28135 var activateLast = function(){
28136 for(var i = accessList.length-1; i >=0; --i) {
28137 if(!accessList[i].hidden){
28138 setActiveWin(accessList[i]);
28143 setActiveWin(null);
28151 register : function(win){
28153 win.manager.unregister(win);
28155 win.manager = this;
28157 list[win.id] = win;
28158 accessList.push(win);
28159 win.on('hide', activateLast);
28163 unregister : function(win){
28164 delete win.manager;
28165 delete list[win.id];
28166 win.un('hide', activateLast);
28167 accessList.remove(win);
28171 get : function(id){
28172 return typeof id == "object" ? id : list[id];
28176 bringToFront : function(win){
28177 win = this.get(win);
28179 win._lastAccess = new Date().getTime();
28187 sendToBack : function(win){
28188 win = this.get(win);
28189 win._lastAccess = -(new Date().getTime());
28195 hideAll : function(){
28196 for(var id in list){
28197 if(list[id] && typeof list[id] != "function" && list[id].isVisible()){
28204 getActive : function(){
28209 getBy : function(fn, scope){
28211 for(var i = accessList.length-1; i >=0; --i) {
28212 var win = accessList[i];
28213 if(fn.call(scope||win, win) !== false){
28221 each : function(fn, scope){
28222 for(var id in list){
28223 if(list[id] && typeof list[id] != "function"){
28224 if(fn.call(scope || list[id], list[id]) === false){
28235 Ext.WindowMgr = new Ext.WindowGroup();
28236 Ext.MessageBox = function(){
28237 var dlg, opt, mask, waitTimer,
28238 bodyEl, msgEl, textboxEl, textareaEl, progressBar, pp, iconEl, spacerEl,
28239 buttons, activeTextEl, bwidth, bufferIcon = '', iconCls = '',
28240 buttonNames = ['ok', 'yes', 'no', 'cancel'];
28243 var handleButton = function(button){
28244 buttons[button].blur();
28245 if(dlg.isVisible()){
28248 Ext.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value, opt], 1);
28253 var handleHide = function(){
28254 if(opt && opt.cls){
28255 dlg.el.removeClass(opt.cls);
28257 progressBar.reset();
28261 var handleEsc = function(d, k, e){
28262 if(opt && opt.closable !== false){
28272 var updateButtons = function(b){
28276 Ext.each(buttonNames, function(name){
28277 buttons[name].hide();
28281 dlg.footer.dom.style.display = '';
28282 Ext.iterate(buttons, function(name, btn){
28286 btn.setText(Ext.isString(cfg) ? cfg : Ext.MessageBox.buttonText[name]);
28287 width += btn.getEl().getWidth() + 15;
28297 getDialog : function(titleText){
28302 Ext.each(buttonNames, function(name){
28303 btns.push(buttons[name] = new Ext.Button({
28304 text: this.buttonText[name],
28305 handler: handleButton.createCallback(name),
28306 hideMode: 'offsets'
28309 dlg = new Ext.Window({
28314 constrainHeader:true,
28315 minimizable : false,
28316 maximizable : false,
28320 buttonAlign:"center",
28327 close : function(){
28328 if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){
28329 handleButton("no");
28331 handleButton("cancel");
28334 fbar: new Ext.Toolbar({
28336 enableOverflow: false
28339 dlg.render(document.body);
28340 dlg.getEl().addClass('x-window-dlg');
28342 bodyEl = dlg.body.createChild({
28343 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>'
28345 iconEl = Ext.get(bodyEl.dom.firstChild);
28346 var contentEl = bodyEl.dom.childNodes[1];
28347 msgEl = Ext.get(contentEl.firstChild);
28348 textboxEl = Ext.get(contentEl.childNodes[2].firstChild);
28349 textboxEl.enableDisplayMode();
28350 textboxEl.addKeyListener([10,13], function(){
28351 if(dlg.isVisible() && opt && opt.buttons){
28352 if(opt.buttons.ok){
28353 handleButton("ok");
28354 }else if(opt.buttons.yes){
28355 handleButton("yes");
28359 textareaEl = Ext.get(contentEl.childNodes[2].childNodes[1]);
28360 textareaEl.enableDisplayMode();
28361 progressBar = new Ext.ProgressBar({
28364 bodyEl.createChild({cls:'x-clear'});
28370 updateText : function(text){
28371 if(!dlg.isVisible() && !opt.width){
28372 dlg.setSize(this.maxWidth, 100);
28375 msgEl.update(text ? text + ' ' : ' ');
28377 var iw = iconCls != '' ? (iconEl.getWidth() + iconEl.getMargins('lr')) : 0,
28378 mw = msgEl.getWidth() + msgEl.getMargins('lr'),
28379 fw = dlg.getFrameWidth('lr'),
28380 bw = dlg.body.getFrameWidth('lr'),
28383 w = Math.max(Math.min(opt.width || iw+mw+fw+bw, opt.maxWidth || this.maxWidth),
28384 Math.max(opt.minWidth || this.minWidth, bwidth || 0));
28386 if(opt.prompt === true){
28387 activeTextEl.setWidth(w-iw-fw-bw);
28389 if(opt.progress === true || opt.wait === true){
28390 progressBar.setSize(w-iw-fw-bw);
28392 if(Ext.isIE && w == bwidth){
28395 msgEl.update(text || ' ');
28396 dlg.setSize(w, 'auto').center();
28401 updateProgress : function(value, progressText, msg){
28402 progressBar.updateProgress(value, progressText);
28404 this.updateText(msg);
28410 isVisible : function(){
28411 return dlg && dlg.isVisible();
28416 var proxy = dlg ? dlg.activeGhost : null;
28417 if(this.isVisible() || proxy){
28423 dlg.unghost(false, false);
28430 show : function(options){
28431 if(this.isVisible()){
28435 var d = this.getDialog(opt.title || " ");
28437 d.setTitle(opt.title || " ");
28438 var allowClose = (opt.closable !== false && opt.progress !== true && opt.wait !== true);
28439 d.tools.close.setDisplayed(allowClose);
28440 activeTextEl = textboxEl;
28441 opt.prompt = opt.prompt || (opt.multiline ? true : false);
28446 textareaEl.setHeight(Ext.isNumber(opt.multiline) ? opt.multiline : this.defaultTextHeight);
28447 activeTextEl = textareaEl;
28456 activeTextEl.dom.value = opt.value || "";
28458 d.focusEl = activeTextEl;
28460 var bs = opt.buttons;
28463 db = buttons["ok"];
28464 }else if(bs && bs.yes){
28465 db = buttons["yes"];
28471 if(Ext.isDefined(opt.iconCls)){
28472 d.setIconClass(opt.iconCls);
28474 this.setIcon(Ext.isDefined(opt.icon) ? opt.icon : bufferIcon);
28475 bwidth = updateButtons(opt.buttons);
28476 progressBar.setVisible(opt.progress === true || opt.wait === true);
28477 this.updateProgress(0, opt.progressText);
28478 this.updateText(opt.msg);
28480 d.el.addClass(opt.cls);
28482 d.proxyDrag = opt.proxyDrag === true;
28483 d.modal = opt.modal !== false;
28484 d.mask = opt.modal !== false ? mask : false;
28485 if(!d.isVisible()){
28487 document.body.appendChild(dlg.el.dom);
28488 d.setAnimateTarget(opt.animEl);
28490 d.on('show', function(){
28491 if(allowClose === true){
28494 d.keyMap.disable();
28496 }, this, {single:true});
28497 d.show(opt.animEl);
28499 if(opt.wait === true){
28500 progressBar.wait(opt.waitConfig);
28506 setIcon : function(icon){
28511 bufferIcon = undefined;
28512 if(icon && icon != ''){
28513 iconEl.removeClass('x-hidden');
28514 iconEl.replaceClass(iconCls, icon);
28515 bodyEl.addClass('x-dlg-icon');
28518 iconEl.replaceClass(iconCls, 'x-hidden');
28519 bodyEl.removeClass('x-dlg-icon');
28526 progress : function(title, msg, progressText){
28533 minWidth: this.minProgressWidth,
28534 progressText: progressText
28540 wait : function(msg, title, config){
28548 minWidth: this.minProgressWidth,
28555 alert : function(title, msg, fn, scope){
28562 minWidth: this.minWidth
28568 confirm : function(title, msg, fn, scope){
28572 buttons: this.YESNO,
28575 icon: this.QUESTION,
28576 minWidth: this.minWidth
28582 prompt : function(title, msg, fn, scope, multiline, value){
28586 buttons: this.OKCANCEL,
28588 minWidth: this.minPromptWidth,
28591 multiline: multiline,
28600 CANCEL : {cancel:true},
28602 OKCANCEL : {ok:true, cancel:true},
28604 YESNO : {yes:true, no:true},
28606 YESNOCANCEL : {yes:true, no:true, cancel:true},
28608 INFO : 'ext-mb-info',
28610 WARNING : 'ext-mb-warning',
28612 QUESTION : 'ext-mb-question',
28614 ERROR : 'ext-mb-error',
28617 defaultTextHeight : 75,
28623 minProgressWidth : 250,
28625 minPromptWidth: 250,
28637 Ext.Msg = Ext.MessageBox;
28638 Ext.dd.PanelProxy = Ext.extend(Object, {
28640 constructor : function(panel, config){
28641 this.panel = panel;
28642 this.id = this.panel.id +'-ddproxy';
28643 Ext.apply(this, config);
28647 insertProxy : true,
28650 setStatus : Ext.emptyFn,
28651 reset : Ext.emptyFn,
28652 update : Ext.emptyFn,
28653 stop : Ext.emptyFn,
28657 getEl : function(){
28662 getGhost : function(){
28667 getProxy : function(){
28675 this.proxy.remove();
28678 this.panel.el.dom.style.display = '';
28679 this.ghost.remove();
28687 this.ghost = this.panel.createGhost(this.panel.initialConfig.cls, undefined, Ext.getBody());
28688 this.ghost.setXY(this.panel.el.getXY());
28689 if(this.insertProxy){
28690 this.proxy = this.panel.el.insertSibling({cls:'x-panel-dd-spacer'});
28691 this.proxy.setSize(this.panel.getSize());
28693 this.panel.el.dom.style.display = 'none';
28698 repair : function(xy, callback, scope){
28700 if(typeof callback == "function"){
28701 callback.call(scope || this);
28706 moveProxy : function(parentNode, before){
28708 parentNode.insertBefore(this.proxy.dom, before);
28714 Ext.Panel.DD = Ext.extend(Ext.dd.DragSource, {
28716 constructor : function(panel, cfg){
28717 this.panel = panel;
28718 this.dragData = {panel: panel};
28719 this.proxy = new Ext.dd.PanelProxy(panel, cfg);
28720 Ext.Panel.DD.superclass.constructor.call(this, panel.el, cfg);
28721 var h = panel.header,
28724 this.setHandleElId(h.id);
28727 el.setStyle('cursor', 'move');
28728 this.scroll = false;
28731 showFrame: Ext.emptyFn,
28732 startDrag: Ext.emptyFn,
28733 b4StartDrag: function(x, y) {
28736 b4MouseDown: function(e) {
28737 var x = e.getPageX(),
28739 this.autoOffset(x, y);
28741 onInitDrag : function(x, y){
28742 this.onStartDrag(x, y);
28745 createFrame : Ext.emptyFn,
28746 getDragEl : function(e){
28747 return this.proxy.ghost.dom;
28749 endDrag : function(e){
28751 this.panel.saveState();
28754 autoOffset : function(x, y) {
28755 x -= this.startPageX;
28756 y -= this.startPageY;
28757 this.setDelta(x, y);
28760 Ext.state.Provider = Ext.extend(Ext.util.Observable, {
28762 constructor : function(){
28764 this.addEvents("statechange");
28766 Ext.state.Provider.superclass.constructor.call(this);
28770 get : function(name, defaultValue){
28771 return typeof this.state[name] == "undefined" ?
28772 defaultValue : this.state[name];
28776 clear : function(name){
28777 delete this.state[name];
28778 this.fireEvent("statechange", this, name, null);
28782 set : function(name, value){
28783 this.state[name] = value;
28784 this.fireEvent("statechange", this, name, value);
28788 decodeValue : function(cookie){
28790 var re = /^(a|n|d|b|s|o|e)\:(.*)$/,
28791 matches = re.exec(unescape(cookie)),
28796 if(!matches || !matches[1]){
28805 return parseFloat(v);
28807 return new Date(Date.parse(v));
28813 Ext.each(v.split('^'), function(val){
28814 all.push(this.decodeValue(val));
28821 Ext.each(v.split('^'), function(val){
28822 kv = val.split('=');
28823 all[kv[0]] = this.decodeValue(kv[1]);
28833 encodeValue : function(v){
28841 }else if(typeof v == 'number'){
28843 }else if(typeof v == 'boolean'){
28844 enc = 'b:' + (v ? '1' : '0');
28845 }else if(Ext.isDate(v)){
28846 enc = 'd:' + v.toGMTString();
28847 }else if(Ext.isArray(v)){
28848 for(len = v.length; i < len; i++){
28849 flat += this.encodeValue(v[i]);
28855 }else if(typeof v == 'object'){
28857 if(typeof v[key] != 'function' && v[key] !== undefined){
28858 flat += key + '=' + this.encodeValue(v[key]) + '^';
28861 enc = 'o:' + flat.substring(0, flat.length-1);
28865 return escape(enc);
28869 Ext.state.Manager = function(){
28870 var provider = new Ext.state.Provider();
28874 setProvider : function(stateProvider){
28875 provider = stateProvider;
28879 get : function(key, defaultValue){
28880 return provider.get(key, defaultValue);
28884 set : function(key, value){
28885 provider.set(key, value);
28889 clear : function(key){
28890 provider.clear(key);
28894 getProvider : function(){
28900 Ext.state.CookieProvider = Ext.extend(Ext.state.Provider, {
28902 constructor : function(config){
28903 Ext.state.CookieProvider.superclass.constructor.call(this);
28905 this.expires = new Date(new Date().getTime()+(1000*60*60*24*7));
28906 this.domain = null;
28907 this.secure = false;
28908 Ext.apply(this, config);
28909 this.state = this.readCookies();
28913 set : function(name, value){
28914 if(typeof value == "undefined" || value === null){
28918 this.setCookie(name, value);
28919 Ext.state.CookieProvider.superclass.set.call(this, name, value);
28923 clear : function(name){
28924 this.clearCookie(name);
28925 Ext.state.CookieProvider.superclass.clear.call(this, name);
28929 readCookies : function(){
28931 c = document.cookie + ";",
28932 re = /\s?(.*?)=(.*?);/g,
28936 while((matches = re.exec(c)) != null){
28938 value = matches[2];
28939 if(name && name.substring(0,3) == "ys-"){
28940 cookies[name.substr(3)] = this.decodeValue(value);
28947 setCookie : function(name, value){
28948 document.cookie = "ys-"+ name + "=" + this.encodeValue(value) +
28949 ((this.expires == null) ? "" : ("; expires=" + this.expires.toGMTString())) +
28950 ((this.path == null) ? "" : ("; path=" + this.path)) +
28951 ((this.domain == null) ? "" : ("; domain=" + this.domain)) +
28952 ((this.secure == true) ? "; secure" : "");
28956 clearCookie : function(name){
28957 document.cookie = "ys-" + name + "=null; expires=Thu, 01-Jan-70 00:00:01 GMT" +
28958 ((this.path == null) ? "" : ("; path=" + this.path)) +
28959 ((this.domain == null) ? "" : ("; domain=" + this.domain)) +
28960 ((this.secure == true) ? "; secure" : "");
28963 Ext.DataView = Ext.extend(Ext.BoxComponent, {
28973 selectedClass : "x-view-selected",
28978 deferEmptyText: true,
28983 blockRefresh: false,
28989 initComponent : function(){
28990 Ext.DataView.superclass.initComponent.call(this);
28991 if(Ext.isString(this.tpl) || Ext.isArray(this.tpl)){
28992 this.tpl = new Ext.XTemplate(this.tpl);
29011 "containercontextmenu",
29019 this.store = Ext.StoreMgr.lookup(this.store);
29020 this.all = new Ext.CompositeElementLite();
29021 this.selected = new Ext.CompositeElementLite();
29025 afterRender : function(){
29026 Ext.DataView.superclass.afterRender.call(this);
29028 this.mon(this.getTemplateTarget(), {
29029 "click": this.onClick,
29030 "dblclick": this.onDblClick,
29031 "contextmenu": this.onContextMenu,
29035 if(this.overClass || this.trackOver){
29036 this.mon(this.getTemplateTarget(), {
29037 "mouseover": this.onMouseOver,
29038 "mouseout": this.onMouseOut,
29044 this.bindStore(this.store, true);
29049 refresh : function() {
29050 this.clearSelections(false, true);
29051 var el = this.getTemplateTarget(),
29052 records = this.store.getRange();
29055 if(records.length < 1){
29056 if(!this.deferEmptyText || this.hasSkippedEmptyText){
29057 el.update(this.emptyText);
29061 this.tpl.overwrite(el, this.collectData(records, 0));
29062 this.all.fill(Ext.query(this.itemSelector, el.dom));
29063 this.updateIndexes(0);
29065 this.hasSkippedEmptyText = true;
29068 getTemplateTarget: function(){
29073 prepareData : function(data){
29078 collectData : function(records, startIndex){
29081 len = records.length;
29082 for(; i < len; i++){
29083 r[r.length] = this.prepareData(records[i].data, startIndex + i, records[i]);
29089 bufferRender : function(records, index){
29090 var div = document.createElement('div');
29091 this.tpl.overwrite(div, this.collectData(records, index));
29092 return Ext.query(this.itemSelector, div);
29096 onUpdate : function(ds, record){
29097 var index = this.store.indexOf(record);
29099 var sel = this.isSelected(index),
29100 original = this.all.elements[index],
29101 node = this.bufferRender([record], index)[0];
29103 this.all.replaceElement(index, node, true);
29105 this.selected.replaceElement(original, node);
29106 this.all.item(index).addClass(this.selectedClass);
29108 this.updateIndexes(index, index);
29113 onAdd : function(ds, records, index){
29114 if(this.all.getCount() === 0){
29118 var nodes = this.bufferRender(records, index), n, a = this.all.elements;
29119 if(index < this.all.getCount()){
29120 n = this.all.item(index).insertSibling(nodes, 'before', true);
29121 a.splice.apply(a, [index, 0].concat(nodes));
29123 n = this.all.last().insertSibling(nodes, 'after', true);
29124 a.push.apply(a, nodes);
29126 this.updateIndexes(index);
29130 onRemove : function(ds, record, index){
29131 this.deselect(index);
29132 this.all.removeElement(index, true);
29133 this.updateIndexes(index);
29134 if (this.store.getCount() === 0){
29140 refreshNode : function(index){
29141 this.onUpdate(this.store, this.store.getAt(index));
29145 updateIndexes : function(startIndex, endIndex){
29146 var ns = this.all.elements;
29147 startIndex = startIndex || 0;
29148 endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length - 1));
29149 for(var i = startIndex; i <= endIndex; i++){
29150 ns[i].viewIndex = i;
29155 getStore : function(){
29160 bindStore : function(store, initial){
29161 if(!initial && this.store){
29162 if(store !== this.store && this.store.autoDestroy){
29163 this.store.destroy();
29165 this.store.un("beforeload", this.onBeforeLoad, this);
29166 this.store.un("datachanged", this.onDataChanged, this);
29167 this.store.un("add", this.onAdd, this);
29168 this.store.un("remove", this.onRemove, this);
29169 this.store.un("update", this.onUpdate, this);
29170 this.store.un("clear", this.refresh, this);
29177 store = Ext.StoreMgr.lookup(store);
29180 beforeload: this.onBeforeLoad,
29181 datachanged: this.onDataChanged,
29183 remove: this.onRemove,
29184 update: this.onUpdate,
29185 clear: this.refresh
29188 this.store = store;
29195 onDataChanged: function() {
29196 if (this.blockRefresh !== true) {
29197 this.refresh.apply(this, arguments);
29202 findItemFromChild : function(node){
29203 return Ext.fly(node).findParent(this.itemSelector, this.getTemplateTarget());
29207 onClick : function(e){
29208 var item = e.getTarget(this.itemSelector, this.getTemplateTarget()),
29211 index = this.indexOf(item);
29212 if(this.onItemClick(item, index, e) !== false){
29213 this.fireEvent("click", this, index, item, e);
29216 if(this.fireEvent("containerclick", this, e) !== false){
29217 this.onContainerClick(e);
29222 onContainerClick : function(e){
29223 this.clearSelections();
29227 onContextMenu : function(e){
29228 var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
29230 this.fireEvent("contextmenu", this, this.indexOf(item), item, e);
29232 this.fireEvent("containercontextmenu", this, e);
29237 onDblClick : function(e){
29238 var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
29240 this.fireEvent("dblclick", this, this.indexOf(item), item, e);
29245 onMouseOver : function(e){
29246 var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
29247 if(item && item !== this.lastItem){
29248 this.lastItem = item;
29249 Ext.fly(item).addClass(this.overClass);
29250 this.fireEvent("mouseenter", this, this.indexOf(item), item, e);
29255 onMouseOut : function(e){
29257 if(!e.within(this.lastItem, true, true)){
29258 Ext.fly(this.lastItem).removeClass(this.overClass);
29259 this.fireEvent("mouseleave", this, this.indexOf(this.lastItem), this.lastItem, e);
29260 delete this.lastItem;
29266 onItemClick : function(item, index, e){
29267 if(this.fireEvent("beforeclick", this, index, item, e) === false){
29270 if(this.multiSelect){
29271 this.doMultiSelection(item, index, e);
29272 e.preventDefault();
29273 }else if(this.singleSelect){
29274 this.doSingleSelection(item, index, e);
29275 e.preventDefault();
29281 doSingleSelection : function(item, index, e){
29282 if(e.ctrlKey && this.isSelected(index)){
29283 this.deselect(index);
29285 this.select(index, false);
29290 doMultiSelection : function(item, index, e){
29291 if(e.shiftKey && this.last !== false){
29292 var last = this.last;
29293 this.selectRange(last, index, e.ctrlKey);
29296 if((e.ctrlKey||this.simpleSelect) && this.isSelected(index)){
29297 this.deselect(index);
29299 this.select(index, e.ctrlKey || e.shiftKey || this.simpleSelect);
29305 getSelectionCount : function(){
29306 return this.selected.getCount();
29310 getSelectedNodes : function(){
29311 return this.selected.elements;
29315 getSelectedIndexes : function(){
29317 selected = this.selected.elements,
29319 len = selected.length;
29321 for(; i < len; i++){
29322 indexes.push(selected[i].viewIndex);
29328 getSelectedRecords : function(){
29329 return this.getRecords(this.selected.elements);
29333 getRecords : function(nodes){
29336 len = nodes.length;
29338 for(; i < len; i++){
29339 records[records.length] = this.store.getAt(nodes[i].viewIndex);
29345 getRecord : function(node){
29346 return this.store.getAt(node.viewIndex);
29350 clearSelections : function(suppressEvent, skipUpdate){
29351 if((this.multiSelect || this.singleSelect) && this.selected.getCount() > 0){
29353 this.selected.removeClass(this.selectedClass);
29355 this.selected.clear();
29357 if(!suppressEvent){
29358 this.fireEvent("selectionchange", this, this.selected.elements);
29364 isSelected : function(node){
29365 return this.selected.contains(this.getNode(node));
29369 deselect : function(node){
29370 if(this.isSelected(node)){
29371 node = this.getNode(node);
29372 this.selected.removeElement(node);
29373 if(this.last == node.viewIndex){
29376 Ext.fly(node).removeClass(this.selectedClass);
29377 this.fireEvent("selectionchange", this, this.selected.elements);
29382 select : function(nodeInfo, keepExisting, suppressEvent){
29383 if(Ext.isArray(nodeInfo)){
29385 this.clearSelections(true);
29387 for(var i = 0, len = nodeInfo.length; i < len; i++){
29388 this.select(nodeInfo[i], true, true);
29390 if(!suppressEvent){
29391 this.fireEvent("selectionchange", this, this.selected.elements);
29394 var node = this.getNode(nodeInfo);
29396 this.clearSelections(true);
29398 if(node && !this.isSelected(node)){
29399 if(this.fireEvent("beforeselect", this, node, this.selected.elements) !== false){
29400 Ext.fly(node).addClass(this.selectedClass);
29401 this.selected.add(node);
29402 this.last = node.viewIndex;
29403 if(!suppressEvent){
29404 this.fireEvent("selectionchange", this, this.selected.elements);
29412 selectRange : function(start, end, keepExisting){
29414 this.clearSelections(true);
29416 this.select(this.getNodes(start, end), true);
29420 getNode : function(nodeInfo){
29421 if(Ext.isString(nodeInfo)){
29422 return document.getElementById(nodeInfo);
29423 }else if(Ext.isNumber(nodeInfo)){
29424 return this.all.elements[nodeInfo];
29425 }else if(nodeInfo instanceof Ext.data.Record){
29426 var idx = this.store.indexOf(nodeInfo);
29427 return this.all.elements[idx];
29433 getNodes : function(start, end){
29434 var ns = this.all.elements,
29438 start = start || 0;
29439 end = !Ext.isDefined(end) ? Math.max(ns.length - 1, 0) : end;
29441 for(i = start; i <= end && ns[i]; i++){
29445 for(i = start; i >= end && ns[i]; i--){
29453 indexOf : function(node){
29454 node = this.getNode(node);
29455 if(Ext.isNumber(node.viewIndex)){
29456 return node.viewIndex;
29458 return this.all.indexOf(node);
29462 onBeforeLoad : function(){
29463 if(this.loadingText){
29464 this.clearSelections(false, true);
29465 this.getTemplateTarget().update('<div class="loading-indicator">'+this.loadingText+'</div>');
29470 onDestroy : function(){
29472 this.selected.clear();
29473 Ext.DataView.superclass.onDestroy.call(this);
29474 this.bindStore(null);
29479 Ext.DataView.prototype.setStore = Ext.DataView.prototype.bindStore;
29481 Ext.reg('dataview', Ext.DataView);
29483 Ext.list.ListView = Ext.extend(Ext.DataView, {
29487 itemSelector: 'dl',
29489 selectedClass:'x-list-selected',
29491 overClass:'x-list-over',
29494 scrollOffset : undefined,
29496 columnResize: true,
29503 maxColumnWidth: Ext.isIE ? 99 : 100,
29505 initComponent : function(){
29506 if(this.columnResize){
29507 this.colResizer = new Ext.list.ColumnResizer(this.colResizer);
29508 this.colResizer.init(this);
29510 if(this.columnSort){
29511 this.colSorter = new Ext.list.Sorter(this.columnSort);
29512 this.colSorter.init(this);
29514 if(!this.internalTpl){
29515 this.internalTpl = new Ext.XTemplate(
29516 '<div class="x-list-header"><div class="x-list-header-inner">',
29517 '<tpl for="columns">',
29518 '<div style="width:{[values.width*100]}%;text-align:{align};"><em unselectable="on" id="',this.id, '-xlhd-{#}">',
29522 '<div class="x-clear"></div>',
29524 '<div class="x-list-body"><div class="x-list-body-inner">',
29529 this.tpl = new Ext.XTemplate(
29530 '<tpl for="rows">',
29532 '<tpl for="parent.columns">',
29533 '<dt style="width:{[values.width*100]}%;text-align:{align};">',
29534 '<em unselectable="on"<tpl if="cls"> class="{cls}</tpl>">',
29535 '{[values.tpl.apply(parent)]}',
29538 '<div class="x-clear"></div>',
29544 var cs = this.columns,
29545 allocatedWidth = 0,
29550 for(var i = 0; i < len; i++){
29553 c.xtype = c.xtype ? (/^lv/.test(c.xtype) ? c.xtype : 'lv' + c.xtype) : 'lvcolumn';
29557 allocatedWidth += c.width*100;
29558 if(allocatedWidth > this.maxColumnWidth){
29559 c.width -= (allocatedWidth - this.maxColumnWidth) / 100;
29566 cs = this.columns = columns;
29569 if(colsWithWidth < len){
29570 var remaining = len - colsWithWidth;
29571 if(allocatedWidth < this.maxColumnWidth){
29572 var perCol = ((this.maxColumnWidth-allocatedWidth) / remaining)/100;
29573 for(var j = 0; j < len; j++){
29581 Ext.list.ListView.superclass.initComponent.call(this);
29584 onRender : function(){
29588 Ext.list.ListView.superclass.onRender.apply(this, arguments);
29590 this.internalTpl.overwrite(this.el, {columns: this.columns});
29592 this.innerBody = Ext.get(this.el.dom.childNodes[1].firstChild);
29593 this.innerHd = Ext.get(this.el.dom.firstChild.firstChild);
29595 if(this.hideHeaders){
29596 this.el.dom.firstChild.style.display = 'none';
29600 getTemplateTarget : function(){
29601 return this.innerBody;
29605 collectData : function(){
29606 var rs = Ext.list.ListView.superclass.collectData.apply(this, arguments);
29608 columns: this.columns,
29613 verifyInternalSize : function(){
29615 this.onResize(this.lastSize.width, this.lastSize.height);
29620 onResize : function(w, h){
29621 var body = this.innerBody.dom,
29622 header = this.innerHd.dom,
29623 scrollWidth = w - Ext.num(this.scrollOffset, Ext.getScrollBarWidth()) + 'px',
29629 parentNode = body.parentNode;
29630 if(Ext.isNumber(w)){
29631 if(this.reserveScrollOffset || ((parentNode.offsetWidth - parentNode.clientWidth) > 10)){
29632 body.style.width = scrollWidth;
29633 header.style.width = scrollWidth;
29635 body.style.width = w + 'px';
29636 header.style.width = w + 'px';
29637 setTimeout(function(){
29638 if((parentNode.offsetWidth - parentNode.clientWidth) > 10){
29639 body.style.width = scrollWidth;
29640 header.style.width = scrollWidth;
29645 if(Ext.isNumber(h)){
29646 parentNode.style.height = Math.max(0, h - header.parentNode.offsetHeight) + 'px';
29650 updateIndexes : function(){
29651 Ext.list.ListView.superclass.updateIndexes.apply(this, arguments);
29652 this.verifyInternalSize();
29655 findHeaderIndex : function(header){
29656 header = header.dom || header;
29657 var parentNode = header.parentNode,
29658 children = parentNode.parentNode.childNodes,
29661 for(; c = children[i]; i++){
29662 if(c == parentNode){
29669 setHdWidths : function(){
29670 var els = this.innerHd.dom.getElementsByTagName('div'),
29672 columns = this.columns,
29673 len = columns.length;
29675 for(; i < len; i++){
29676 els[i].style.width = (columns[i].width*100) + '%';
29681 Ext.reg('listview', Ext.list.ListView);
29684 Ext.ListView = Ext.list.ListView;
29685 Ext.list.Column = Ext.extend(Object, {
29704 constructor : function(c){
29706 c.tpl = new Ext.XTemplate('{' + c.dataIndex + '}');
29708 else if(Ext.isString(c.tpl)){
29709 c.tpl = new Ext.XTemplate(c.tpl);
29712 Ext.apply(this, c);
29716 Ext.reg('lvcolumn', Ext.list.Column);
29719 Ext.list.NumberColumn = Ext.extend(Ext.list.Column, {
29721 format: '0,000.00',
29723 constructor : function(c) {
29724 c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':number("' + (c.format || this.format) + '")}');
29725 Ext.list.NumberColumn.superclass.constructor.call(this, c);
29729 Ext.reg('lvnumbercolumn', Ext.list.NumberColumn);
29732 Ext.list.DateColumn = Ext.extend(Ext.list.Column, {
29734 constructor : function(c) {
29735 c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':date("' + (c.format || this.format) + '")}');
29736 Ext.list.DateColumn.superclass.constructor.call(this, c);
29739 Ext.reg('lvdatecolumn', Ext.list.DateColumn);
29742 Ext.list.BooleanColumn = Ext.extend(Ext.list.Column, {
29746 falseText: 'false',
29748 undefinedText: ' ',
29750 constructor : function(c) {
29751 c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':this.format}');
29753 var t = this.trueText, f = this.falseText, u = this.undefinedText;
29754 c.tpl.format = function(v){
29755 if(v === undefined){
29758 if(!v || v === 'false'){
29764 Ext.list.DateColumn.superclass.constructor.call(this, c);
29768 Ext.reg('lvbooleancolumn', Ext.list.BooleanColumn);
29769 Ext.list.ColumnResizer = Ext.extend(Ext.util.Observable, {
29773 constructor: function(config){
29774 Ext.apply(this, config);
29775 Ext.list.ColumnResizer.superclass.constructor.call(this);
29777 init : function(listView){
29778 this.view = listView;
29779 listView.on('render', this.initEvents, this);
29782 initEvents : function(view){
29783 view.mon(view.innerHd, 'mousemove', this.handleHdMove, this);
29784 this.tracker = new Ext.dd.DragTracker({
29785 onBeforeStart: this.onBeforeStart.createDelegate(this),
29786 onStart: this.onStart.createDelegate(this),
29787 onDrag: this.onDrag.createDelegate(this),
29788 onEnd: this.onEnd.createDelegate(this),
29792 this.tracker.initEl(view.innerHd);
29793 view.on('beforedestroy', this.tracker.destroy, this.tracker);
29796 handleHdMove : function(e, t){
29797 var handleWidth = 5,
29799 header = e.getTarget('em', 3, true);
29801 var region = header.getRegion(),
29802 style = header.dom.style,
29803 parentNode = header.dom.parentNode;
29805 if(x - region.left <= handleWidth && parentNode != parentNode.parentNode.firstChild){
29806 this.activeHd = Ext.get(parentNode.previousSibling.firstChild);
29807 style.cursor = Ext.isWebKit ? 'e-resize' : 'col-resize';
29808 } else if(region.right - x <= handleWidth && parentNode != parentNode.parentNode.lastChild.previousSibling){
29809 this.activeHd = header;
29810 style.cursor = Ext.isWebKit ? 'w-resize' : 'col-resize';
29812 delete this.activeHd;
29818 onBeforeStart : function(e){
29819 this.dragHd = this.activeHd;
29820 return !!this.dragHd;
29823 onStart: function(e){
29827 dragHeader = me.dragHd,
29828 x = me.tracker.getXY()[0];
29830 me.proxy = view.el.createChild({cls:'x-list-resizer'});
29831 me.dragX = dragHeader.getX();
29832 me.headerIndex = view.findHeaderIndex(dragHeader);
29834 me.headersDisabled = view.disableHeaders;
29835 view.disableHeaders = true;
29837 me.proxy.setHeight(view.el.getHeight());
29838 me.proxy.setX(me.dragX);
29839 me.proxy.setWidth(x - me.dragX);
29841 this.setBoundaries();
29846 setBoundaries: function(relativeX){
29847 var view = this.view,
29848 headerIndex = this.headerIndex,
29849 width = view.innerHd.getWidth(),
29850 relativeX = view.innerHd.getX(),
29851 minWidth = Math.ceil(width * this.minPct),
29852 maxWidth = width - minWidth,
29853 numColumns = view.columns.length,
29854 headers = view.innerHd.select('em', true),
29855 minX = minWidth + relativeX,
29856 maxX = maxWidth + relativeX,
29859 if (numColumns == 2) {
29863 header = headers.item(headerIndex + 2);
29864 this.minX = headers.item(headerIndex).getX() + minWidth;
29865 this.maxX = header ? header.getX() - minWidth : maxX;
29866 if (headerIndex == 0) {
29869 } else if (headerIndex == numColumns - 2) {
29876 onDrag: function(e){
29878 cursorX = me.tracker.getXY()[0].constrain(me.minX, me.maxX);
29880 me.proxy.setWidth(cursorX - this.dragX);
29883 onEnd: function(e){
29885 var newWidth = this.proxy.getWidth(),
29886 index = this.headerIndex,
29888 columns = view.columns,
29889 width = view.innerHd.getWidth(),
29890 newPercent = Math.ceil(newWidth * view.maxColumnWidth / width) / 100,
29891 disabled = this.headersDisabled,
29892 headerCol = columns[index],
29893 otherCol = columns[index + 1],
29894 totalPercent = headerCol.width + otherCol.width;
29896 this.proxy.remove();
29898 headerCol.width = newPercent;
29899 otherCol.width = totalPercent - newPercent;
29901 delete this.dragHd;
29902 view.setHdWidths();
29905 setTimeout(function(){
29906 view.disableHeaders = disabled;
29912 Ext.ListView.ColumnResizer = Ext.list.ColumnResizer;
29913 Ext.list.Sorter = Ext.extend(Ext.util.Observable, {
29915 sortClasses : ["sort-asc", "sort-desc"],
29917 constructor: function(config){
29918 Ext.apply(this, config);
29919 Ext.list.Sorter.superclass.constructor.call(this);
29922 init : function(listView){
29923 this.view = listView;
29924 listView.on('render', this.initEvents, this);
29927 initEvents : function(view){
29928 view.mon(view.innerHd, 'click', this.onHdClick, this);
29929 view.innerHd.setStyle('cursor', 'pointer');
29930 view.mon(view.store, 'datachanged', this.updateSortState, this);
29931 this.updateSortState.defer(10, this, [view.store]);
29934 updateSortState : function(store){
29935 var state = store.getSortState();
29939 this.sortState = state;
29940 var cs = this.view.columns, sortColumn = -1;
29941 for(var i = 0, len = cs.length; i < len; i++){
29942 if(cs[i].dataIndex == state.field){
29947 if(sortColumn != -1){
29948 var sortDir = state.direction;
29949 this.updateSortIcon(sortColumn, sortDir);
29953 updateSortIcon : function(col, dir){
29954 var sc = this.sortClasses;
29955 var hds = this.view.innerHd.select('em').removeClass(sc);
29956 hds.item(col).addClass(sc[dir == "DESC" ? 1 : 0]);
29959 onHdClick : function(e){
29960 var hd = e.getTarget('em', 3);
29961 if(hd && !this.view.disableHeaders){
29962 var index = this.view.findHeaderIndex(hd);
29963 this.view.store.sort(this.view.columns[index].dataIndex);
29969 Ext.ListView.Sorter = Ext.list.Sorter;
29970 Ext.TabPanel = Ext.extend(Ext.Panel, {
29974 deferredRender : true,
29980 resizeTabs : false,
29982 enableTabScroll : false,
29984 scrollIncrement : 0,
29986 scrollRepeatInterval : 400,
29988 scrollDuration : 0.35,
29992 tabPosition : 'top',
29994 baseCls : 'x-tab-panel',
29998 autoTabSelector : 'div.x-tab',
30000 activeTab : undefined,
30006 wheelIncrement : 20,
30009 idDelimiter : '__',
30012 itemCls : 'x-tab-item',
30016 headerAsText : false,
30021 initComponent : function(){
30022 this.frame = false;
30023 Ext.TabPanel.superclass.initComponent.call(this);
30033 this.setLayout(new Ext.layout.CardLayout(Ext.apply({
30034 layoutOnCardChange: this.layoutOnTabChange,
30035 deferredRender: this.deferredRender
30036 }, this.layoutConfig)));
30038 if(this.tabPosition == 'top'){
30039 this.elements += ',header';
30040 this.stripTarget = 'header';
30042 this.elements += ',footer';
30043 this.stripTarget = 'footer';
30046 this.stack = Ext.TabPanel.AccessStack();
30052 onRender : function(ct, position){
30053 Ext.TabPanel.superclass.onRender.call(this, ct, position);
30056 var pos = this.tabPosition == 'top' ? 'header' : 'footer';
30057 this[pos].addClass('x-tab-panel-'+pos+'-plain');
30060 var st = this[this.stripTarget];
30062 this.stripWrap = st.createChild({cls:'x-tab-strip-wrap', cn:{
30063 tag:'ul', cls:'x-tab-strip x-tab-strip-'+this.tabPosition}});
30065 var beforeEl = (this.tabPosition=='bottom' ? this.stripWrap : null);
30066 st.createChild({cls:'x-tab-strip-spacer'}, beforeEl);
30067 this.strip = new Ext.Element(this.stripWrap.dom.firstChild);
30070 this.edge = this.strip.createChild({tag:'li', cls:'x-tab-edge', cn: [{tag: 'span', cls: 'x-tab-strip-text', cn: ' '}]});
30071 this.strip.createChild({cls:'x-clear'});
30073 this.body.addClass('x-tab-panel-body-'+this.tabPosition);
30077 var tt = new Ext.Template(
30078 '<li class="{cls}" id="{id}"><a class="x-tab-strip-close"></a>',
30079 '<a class="x-tab-right" href="#"><em class="x-tab-left">',
30080 '<span class="x-tab-strip-inner"><span class="x-tab-strip-text {iconCls}">{text}</span></span>',
30083 tt.disableFormats = true;
30085 Ext.TabPanel.prototype.itemTpl = tt;
30088 this.items.each(this.initTab, this);
30092 afterRender : function(){
30093 Ext.TabPanel.superclass.afterRender.call(this);
30095 this.readTabs(false);
30097 if(this.activeTab !== undefined){
30098 var item = Ext.isObject(this.activeTab) ? this.activeTab : this.items.get(this.activeTab);
30099 delete this.activeTab;
30100 this.setActiveTab(item);
30105 initEvents : function(){
30106 Ext.TabPanel.superclass.initEvents.call(this);
30107 this.mon(this.strip, {
30109 mousedown: this.onStripMouseDown,
30110 contextmenu: this.onStripContextMenu
30112 if(this.enableTabScroll){
30113 this.mon(this.strip, 'mousewheel', this.onWheel, this);
30118 findTargets : function(e){
30120 itemEl = e.getTarget('li:not(.x-tab-edge)', this.strip);
30123 item = this.getComponent(itemEl.id.split(this.idDelimiter)[1]);
30133 close : e.getTarget('.x-tab-strip-close', this.strip),
30140 onStripMouseDown : function(e){
30141 if(e.button !== 0){
30144 e.preventDefault();
30145 var t = this.findTargets(e);
30147 if (t.item.fireEvent('beforeclose', t.item) !== false) {
30148 t.item.fireEvent('close', t.item);
30149 this.remove(t.item);
30153 if(t.item && t.item != this.activeTab){
30154 this.setActiveTab(t.item);
30159 onStripContextMenu : function(e){
30160 e.preventDefault();
30161 var t = this.findTargets(e);
30163 this.fireEvent('contextmenu', this, t.item, e);
30168 readTabs : function(removeExisting){
30169 if(removeExisting === true){
30170 this.items.each(function(item){
30174 var tabs = this.el.query(this.autoTabSelector);
30175 for(var i = 0, len = tabs.length; i < len; i++){
30177 title = tab.getAttribute('title');
30178 tab.removeAttribute('title');
30187 initTab : function(item, index){
30188 var before = this.strip.dom.childNodes[index],
30189 p = this.getTemplateArgs(item),
30191 this.itemTpl.insertBefore(before, p) :
30192 this.itemTpl.append(this.strip, p),
30193 cls = 'x-tab-strip-over',
30194 tabEl = Ext.get(el);
30196 tabEl.hover(function(){
30197 if(!item.disabled){
30198 tabEl.addClass(cls);
30201 tabEl.removeClass(cls);
30205 tabEl.child('span.x-tab-strip-text', true).qtip = item.tabTip;
30210 tabEl.select('a').on('click', function(e){
30212 this.onStripMouseDown(e);
30214 }, this, {preventDefault: true});
30218 disable: this.onItemDisabled,
30219 enable: this.onItemEnabled,
30220 titlechange: this.onItemTitleChanged,
30221 iconchange: this.onItemIconChanged,
30222 beforeshow: this.onBeforeShowItem
30229 getTemplateArgs : function(item) {
30230 var cls = item.closable ? 'x-tab-strip-closable' : '';
30232 cls += ' x-item-disabled';
30235 cls += ' x-tab-with-icon';
30238 cls += ' ' + item.tabCls;
30242 id: this.id + this.idDelimiter + item.getItemId(),
30245 iconCls: item.iconCls || ''
30250 onAdd : function(c){
30251 Ext.TabPanel.superclass.onAdd.call(this, c);
30253 var items = this.items;
30254 this.initTab(c, items.indexOf(c));
30255 this.delegateUpdates();
30260 onBeforeAdd : function(item){
30261 var existing = item.events ? (this.items.containsKey(item.getItemId()) ? item : null) : this.items.get(item);
30263 this.setActiveTab(item);
30266 Ext.TabPanel.superclass.onBeforeAdd.apply(this, arguments);
30267 var es = item.elements;
30268 item.elements = es ? es.replace(',header', '') : es;
30269 item.border = (item.border === true);
30273 onRemove : function(c){
30274 var te = Ext.get(c.tabEl);
30277 te.select('a').removeAllListeners();
30280 Ext.TabPanel.superclass.onRemove.call(this, c);
30281 this.stack.remove(c);
30283 c.un('disable', this.onItemDisabled, this);
30284 c.un('enable', this.onItemEnabled, this);
30285 c.un('titlechange', this.onItemTitleChanged, this);
30286 c.un('iconchange', this.onItemIconChanged, this);
30287 c.un('beforeshow', this.onBeforeShowItem, this);
30288 if(c == this.activeTab){
30289 var next = this.stack.next();
30291 this.setActiveTab(next);
30292 }else if(this.items.getCount() > 0){
30293 this.setActiveTab(0);
30295 this.setActiveTab(null);
30298 if(!this.destroying){
30299 this.delegateUpdates();
30304 onBeforeShowItem : function(item){
30305 if(item != this.activeTab){
30306 this.setActiveTab(item);
30312 onItemDisabled : function(item){
30313 var el = this.getTabEl(item);
30315 Ext.fly(el).addClass('x-item-disabled');
30317 this.stack.remove(item);
30321 onItemEnabled : function(item){
30322 var el = this.getTabEl(item);
30324 Ext.fly(el).removeClass('x-item-disabled');
30329 onItemTitleChanged : function(item){
30330 var el = this.getTabEl(item);
30332 Ext.fly(el).child('span.x-tab-strip-text', true).innerHTML = item.title;
30337 onItemIconChanged : function(item, iconCls, oldCls){
30338 var el = this.getTabEl(item);
30341 el.child('span.x-tab-strip-text').replaceClass(oldCls, iconCls);
30342 el[Ext.isEmpty(iconCls) ? 'removeClass' : 'addClass']('x-tab-with-icon');
30347 getTabEl : function(item){
30348 var c = this.getComponent(item);
30349 return c ? c.tabEl : null;
30353 onResize : function(){
30354 Ext.TabPanel.superclass.onResize.apply(this, arguments);
30355 this.delegateUpdates();
30359 beginUpdate : function(){
30360 this.suspendUpdates = true;
30364 endUpdate : function(){
30365 this.suspendUpdates = false;
30366 this.delegateUpdates();
30370 hideTabStripItem : function(item){
30371 item = this.getComponent(item);
30372 var el = this.getTabEl(item);
30374 el.style.display = 'none';
30375 this.delegateUpdates();
30377 this.stack.remove(item);
30381 unhideTabStripItem : function(item){
30382 item = this.getComponent(item);
30383 var el = this.getTabEl(item);
30385 el.style.display = '';
30386 this.delegateUpdates();
30391 delegateUpdates : function(){
30392 var rendered = this.rendered;
30393 if(this.suspendUpdates){
30396 if(this.resizeTabs && rendered){
30397 this.autoSizeTabs();
30399 if(this.enableTabScroll && rendered){
30400 this.autoScrollTabs();
30405 autoSizeTabs : function(){
30406 var count = this.items.length,
30407 ce = this.tabPosition != 'bottom' ? 'header' : 'footer',
30408 ow = this[ce].dom.offsetWidth,
30409 aw = this[ce].dom.clientWidth;
30411 if(!this.resizeTabs || count < 1 || !aw){
30415 var each = Math.max(Math.min(Math.floor((aw-4) / count) - this.tabMargin, this.tabWidth), this.minTabWidth);
30416 this.lastTabWidth = each;
30417 var lis = this.strip.query('li:not(.x-tab-edge)');
30418 for(var i = 0, len = lis.length; i < len; i++) {
30420 inner = Ext.fly(li).child('.x-tab-strip-inner', true),
30421 tw = li.offsetWidth,
30422 iw = inner.offsetWidth;
30423 inner.style.width = (each - (tw-iw)) + 'px';
30428 adjustBodyWidth : function(w){
30430 this.header.setWidth(w);
30433 this.footer.setWidth(w);
30439 setActiveTab : function(item){
30440 item = this.getComponent(item);
30441 if(this.fireEvent('beforetabchange', this, item, this.activeTab) === false){
30444 if(!this.rendered){
30445 this.activeTab = item;
30448 if(this.activeTab != item){
30449 if(this.activeTab){
30450 var oldEl = this.getTabEl(this.activeTab);
30452 Ext.fly(oldEl).removeClass('x-tab-strip-active');
30455 this.activeTab = item;
30457 var el = this.getTabEl(item);
30458 Ext.fly(el).addClass('x-tab-strip-active');
30459 this.stack.add(item);
30461 this.layout.setActiveItem(item);
30463 this.delegateUpdates();
30464 if(this.scrolling){
30465 this.scrollToTab(item, this.animScroll);
30468 this.fireEvent('tabchange', this, item);
30473 getActiveTab : function(){
30474 return this.activeTab || null;
30478 getItem : function(item){
30479 return this.getComponent(item);
30483 autoScrollTabs : function(){
30484 this.pos = this.tabPosition=='bottom' ? this.footer : this.header;
30485 var count = this.items.length,
30486 ow = this.pos.dom.offsetWidth,
30487 tw = this.pos.dom.clientWidth,
30488 wrap = this.stripWrap,
30490 cw = wd.offsetWidth,
30491 pos = this.getScrollPos(),
30492 l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos;
30494 if(!this.enableTabScroll || cw < 20){
30497 if(count == 0 || l <= tw){
30501 if(this.scrolling){
30502 this.scrolling = false;
30503 this.pos.removeClass('x-tab-scrolling');
30504 this.scrollLeft.hide();
30505 this.scrollRight.hide();
30507 if(Ext.isAir || Ext.isWebKit){
30508 wd.style.marginLeft = '';
30509 wd.style.marginRight = '';
30513 if(!this.scrolling){
30514 this.pos.addClass('x-tab-scrolling');
30516 if(Ext.isAir || Ext.isWebKit){
30517 wd.style.marginLeft = '18px';
30518 wd.style.marginRight = '18px';
30521 tw -= wrap.getMargins('lr');
30522 wrap.setWidth(tw > 20 ? tw : 20);
30523 if(!this.scrolling){
30524 if(!this.scrollLeft){
30525 this.createScrollers();
30527 this.scrollLeft.show();
30528 this.scrollRight.show();
30531 this.scrolling = true;
30533 wd.scrollLeft = l-tw;
30535 this.scrollToTab(this.activeTab, false);
30537 this.updateScrollButtons();
30542 createScrollers : function(){
30543 this.pos.addClass('x-tab-scrolling-' + this.tabPosition);
30544 var h = this.stripWrap.dom.offsetHeight;
30547 var sl = this.pos.insertFirst({
30548 cls:'x-tab-scroller-left'
30551 sl.addClassOnOver('x-tab-scroller-left-over');
30552 this.leftRepeater = new Ext.util.ClickRepeater(sl, {
30553 interval : this.scrollRepeatInterval,
30554 handler: this.onScrollLeft,
30557 this.scrollLeft = sl;
30560 var sr = this.pos.insertFirst({
30561 cls:'x-tab-scroller-right'
30564 sr.addClassOnOver('x-tab-scroller-right-over');
30565 this.rightRepeater = new Ext.util.ClickRepeater(sr, {
30566 interval : this.scrollRepeatInterval,
30567 handler: this.onScrollRight,
30570 this.scrollRight = sr;
30574 getScrollWidth : function(){
30575 return this.edge.getOffsetsTo(this.stripWrap)[0] + this.getScrollPos();
30579 getScrollPos : function(){
30580 return parseInt(this.stripWrap.dom.scrollLeft, 10) || 0;
30584 getScrollArea : function(){
30585 return parseInt(this.stripWrap.dom.clientWidth, 10) || 0;
30589 getScrollAnim : function(){
30590 return {duration:this.scrollDuration, callback: this.updateScrollButtons, scope: this};
30594 getScrollIncrement : function(){
30595 return this.scrollIncrement || (this.resizeTabs ? this.lastTabWidth+2 : 100);
30600 scrollToTab : function(item, animate){
30604 var el = this.getTabEl(item),
30605 pos = this.getScrollPos(),
30606 area = this.getScrollArea(),
30607 left = Ext.fly(el).getOffsetsTo(this.stripWrap)[0] + pos,
30608 right = left + el.offsetWidth;
30610 this.scrollTo(left, animate);
30611 }else if(right > (pos + area)){
30612 this.scrollTo(right - area, animate);
30617 scrollTo : function(pos, animate){
30618 this.stripWrap.scrollTo('left', pos, animate ? this.getScrollAnim() : false);
30620 this.updateScrollButtons();
30624 onWheel : function(e){
30625 var d = e.getWheelDelta()*this.wheelIncrement*-1;
30628 var pos = this.getScrollPos(),
30630 sw = this.getScrollWidth()-this.getScrollArea();
30632 var s = Math.max(0, Math.min(sw, newpos));
30634 this.scrollTo(s, false);
30639 onScrollRight : function(){
30640 var sw = this.getScrollWidth()-this.getScrollArea(),
30641 pos = this.getScrollPos(),
30642 s = Math.min(sw, pos + this.getScrollIncrement());
30644 this.scrollTo(s, this.animScroll);
30649 onScrollLeft : function(){
30650 var pos = this.getScrollPos(),
30651 s = Math.max(0, pos - this.getScrollIncrement());
30653 this.scrollTo(s, this.animScroll);
30658 updateScrollButtons : function(){
30659 var pos = this.getScrollPos();
30660 this.scrollLeft[pos === 0 ? 'addClass' : 'removeClass']('x-tab-scroller-left-disabled');
30661 this.scrollRight[pos >= (this.getScrollWidth()-this.getScrollArea()) ? 'addClass' : 'removeClass']('x-tab-scroller-right-disabled');
30665 beforeDestroy : function() {
30666 Ext.destroy(this.leftRepeater, this.rightRepeater);
30667 this.deleteMembers('strip', 'edge', 'scrollLeft', 'scrollRight', 'stripWrap');
30668 this.activeTab = null;
30669 Ext.TabPanel.superclass.beforeDestroy.apply(this);
30685 Ext.reg('tabpanel', Ext.TabPanel);
30688 Ext.TabPanel.prototype.activate = Ext.TabPanel.prototype.setActiveTab;
30691 Ext.TabPanel.AccessStack = function(){
30694 add : function(item){
30696 if(items.length > 10){
30701 remove : function(item){
30703 for(var i = 0, len = items.length; i < len; i++) {
30704 if(items[i] != item){
30712 return items.pop();
30717 Ext.Button = Ext.extend(Ext.BoxComponent, {
30730 enableToggle : false,
30734 menuAlign : 'tl-bl?',
30742 menuClassTarget : 'tr:nth(2)',
30745 clickEvent : 'click',
30748 handleMouseEvents : true,
30751 tooltipType : 'qtip',
30754 buttonSelector : 'button:first-child',
30762 iconAlign : 'left',
30765 arrowAlign : 'right',
30772 initComponent : function(){
30774 this.menu = Ext.menu.MenuMgr.get(this.menu);
30775 this.menu.ownerCt = this;
30778 Ext.Button.superclass.initComponent.call(this);
30800 this.menu.ownerCt = undefined;
30802 if(Ext.isString(this.toggleGroup)){
30803 this.enableToggle = true;
30808 getTemplateArgs : function(){
30809 return [this.type, 'x-btn-' + this.scale + ' x-btn-icon-' + this.scale + '-' + this.iconAlign, this.getMenuClass(), this.cls, this.id];
30813 setButtonClass : function(){
30814 if(this.useSetClass){
30815 if(!Ext.isEmpty(this.oldCls)){
30816 this.el.removeClass([this.oldCls, 'x-btn-pressed']);
30818 this.oldCls = (this.iconCls || this.icon) ? (this.text ? 'x-btn-text-icon' : 'x-btn-icon') : 'x-btn-noicon';
30819 this.el.addClass([this.oldCls, this.pressed ? 'x-btn-pressed' : null]);
30824 getMenuClass : function(){
30825 return this.menu ? (this.arrowAlign != 'bottom' ? 'x-btn-arrow' : 'x-btn-arrow-bottom') : '';
30829 onRender : function(ct, position){
30830 if(!this.template){
30831 if(!Ext.Button.buttonTemplate){
30833 Ext.Button.buttonTemplate = new Ext.Template(
30834 '<table id="{4}" cellspacing="0" class="x-btn {3}"><tbody class="{1}">',
30835 '<tr><td class="x-btn-tl"><i> </i></td><td class="x-btn-tc"></td><td class="x-btn-tr"><i> </i></td></tr>',
30836 '<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>',
30837 '<tr><td class="x-btn-bl"><i> </i></td><td class="x-btn-bc"></td><td class="x-btn-br"><i> </i></td></tr>',
30838 '</tbody></table>');
30839 Ext.Button.buttonTemplate.compile();
30841 this.template = Ext.Button.buttonTemplate;
30844 var btn, targs = this.getTemplateArgs();
30847 btn = this.template.insertBefore(position, targs, true);
30849 btn = this.template.append(ct, targs, true);
30852 this.btnEl = btn.child(this.buttonSelector);
30853 this.mon(this.btnEl, {
30855 focus: this.onFocus,
30859 this.initButtonEl(btn, this.btnEl);
30861 Ext.ButtonToggleMgr.register(this);
30865 initButtonEl : function(btn, btnEl){
30867 this.setIcon(this.icon);
30868 this.setText(this.text);
30869 this.setIconClass(this.iconCls);
30870 if(Ext.isDefined(this.tabIndex)){
30871 btnEl.dom.tabIndex = this.tabIndex;
30874 this.setTooltip(this.tooltip, true);
30877 if(this.handleMouseEvents){
30880 mouseover: this.onMouseOver,
30881 mousedown: this.onMouseDown
30889 this.mon(this.menu, {
30891 show: this.onMenuShow,
30892 hide: this.onMenuHide
30897 var repeater = new Ext.util.ClickRepeater(btn, Ext.isObject(this.repeat) ? this.repeat : {});
30898 this.mon(repeater, 'click', this.onRepeatClick, this);
30900 this.mon(btn, this.clickEvent, this.onClick, this);
30905 afterRender : function(){
30906 Ext.Button.superclass.afterRender.call(this);
30907 this.useSetClass = true;
30908 this.setButtonClass();
30909 this.doc = Ext.getDoc();
30910 this.doAutoWidth();
30914 setIconClass : function(cls){
30915 this.iconCls = cls;
30917 this.btnEl.dom.className = '';
30918 this.btnEl.addClass(['x-btn-text', cls || '']);
30919 this.setButtonClass();
30925 setTooltip : function(tooltip, initial){
30930 if(Ext.isObject(tooltip)){
30931 Ext.QuickTips.register(Ext.apply({
30932 target: this.btnEl.id
30934 this.tooltip = tooltip;
30936 this.btnEl.dom[this.tooltipType] = tooltip;
30939 this.tooltip = tooltip;
30945 clearTip : function(){
30946 if(Ext.isObject(this.tooltip)){
30947 Ext.QuickTips.unregister(this.btnEl);
30952 beforeDestroy : function(){
30956 if(this.menu && this.destroyMenu !== false) {
30957 Ext.destroy(this.btnEl, this.menu);
30959 Ext.destroy(this.repeater);
30963 onDestroy : function(){
30965 this.doc.un('mouseover', this.monitorMouseOver, this);
30966 this.doc.un('mouseup', this.onMouseUp, this);
30969 Ext.ButtonToggleMgr.unregister(this);
30971 Ext.Button.superclass.onDestroy.call(this);
30975 doAutoWidth : function(){
30976 if(this.autoWidth !== false && this.el && this.text && this.width === undefined){
30977 this.el.setWidth('auto');
30978 if(Ext.isIE7 && Ext.isStrict){
30979 var ib = this.btnEl;
30980 if(ib && ib.getWidth() > 20){
30982 ib.setWidth(Ext.util.TextMetrics.measure(ib, this.text).width+ib.getFrameWidth('lr'));
30986 if(this.el.getWidth() < this.minWidth){
30987 this.el.setWidth(this.minWidth);
30994 setHandler : function(handler, scope){
30995 this.handler = handler;
30996 this.scope = scope;
31001 setText : function(text){
31004 this.btnEl.update(text || ' ');
31005 this.setButtonClass();
31007 this.doAutoWidth();
31012 setIcon : function(icon){
31015 this.btnEl.setStyle('background-image', icon ? 'url(' + icon + ')' : '');
31016 this.setButtonClass();
31022 getText : function(){
31027 toggle : function(state, suppressEvent){
31028 state = state === undefined ? !this.pressed : !!state;
31029 if(state != this.pressed){
31031 this.el[state ? 'addClass' : 'removeClass']('x-btn-pressed');
31033 this.pressed = state;
31034 if(!suppressEvent){
31035 this.fireEvent('toggle', this, state);
31036 if(this.toggleHandler){
31037 this.toggleHandler.call(this.scope || this, this, state);
31045 onDisable : function(){
31046 this.onDisableChange(true);
31050 onEnable : function(){
31051 this.onDisableChange(false);
31054 onDisableChange : function(disabled){
31056 if(!Ext.isIE6 || !this.text){
31057 this.el[disabled ? 'addClass' : 'removeClass'](this.disabledClass);
31059 this.el.dom.disabled = disabled;
31061 this.disabled = disabled;
31065 showMenu : function(){
31066 if(this.rendered && this.menu){
31068 Ext.QuickTips.getQuickTip().cancelShow(this.btnEl);
31070 if(this.menu.isVisible()){
31073 this.menu.ownerCt = this;
31074 this.menu.show(this.el, this.menuAlign);
31080 hideMenu : function(){
31081 if(this.hasVisibleMenu()){
31088 hasVisibleMenu : function(){
31089 return this.menu && this.menu.ownerCt == this && this.menu.isVisible();
31093 onRepeatClick : function(repeat, e){
31098 onClick : function(e){
31100 e.preventDefault();
31102 if(e.button !== 0){
31105 if(!this.disabled){
31107 if(this.menu && !this.hasVisibleMenu() && !this.ignoreNextClick){
31110 this.fireEvent('click', this, e);
31113 this.handler.call(this.scope || this, this, e);
31119 doToggle: function(){
31120 if (this.enableToggle && (this.allowDepress !== false || !this.pressed)) {
31126 isMenuTriggerOver : function(e, internal){
31127 return this.menu && !internal;
31131 isMenuTriggerOut : function(e, internal){
31132 return this.menu && !internal;
31136 onMouseOver : function(e){
31137 if(!this.disabled){
31138 var internal = e.within(this.el, true);
31140 this.el.addClass('x-btn-over');
31141 if(!this.monitoringMouseOver){
31142 this.doc.on('mouseover', this.monitorMouseOver, this);
31143 this.monitoringMouseOver = true;
31145 this.fireEvent('mouseover', this, e);
31147 if(this.isMenuTriggerOver(e, internal)){
31148 this.fireEvent('menutriggerover', this, this.menu, e);
31154 monitorMouseOver : function(e){
31155 if(e.target != this.el.dom && !e.within(this.el)){
31156 if(this.monitoringMouseOver){
31157 this.doc.un('mouseover', this.monitorMouseOver, this);
31158 this.monitoringMouseOver = false;
31160 this.onMouseOut(e);
31165 onMouseOut : function(e){
31166 var internal = e.within(this.el) && e.target != this.el.dom;
31167 this.el.removeClass('x-btn-over');
31168 this.fireEvent('mouseout', this, e);
31169 if(this.isMenuTriggerOut(e, internal)){
31170 this.fireEvent('menutriggerout', this, this.menu, e);
31174 focus : function() {
31175 this.btnEl.focus();
31178 blur : function() {
31183 onFocus : function(e){
31184 if(!this.disabled){
31185 this.el.addClass('x-btn-focus');
31189 onBlur : function(e){
31190 this.el.removeClass('x-btn-focus');
31194 getClickEl : function(e, isUp){
31199 onMouseDown : function(e){
31200 if(!this.disabled && e.button === 0){
31201 this.getClickEl(e).addClass('x-btn-click');
31202 this.doc.on('mouseup', this.onMouseUp, this);
31206 onMouseUp : function(e){
31207 if(e.button === 0){
31208 this.getClickEl(e, true).removeClass('x-btn-click');
31209 this.doc.un('mouseup', this.onMouseUp, this);
31213 onMenuShow : function(e){
31214 if(this.menu.ownerCt == this){
31215 this.menu.ownerCt = this;
31216 this.ignoreNextClick = 0;
31217 this.el.addClass('x-btn-menu-active');
31218 this.fireEvent('menushow', this, this.menu);
31222 onMenuHide : function(e){
31223 if(this.menu.ownerCt == this){
31224 this.el.removeClass('x-btn-menu-active');
31225 this.ignoreNextClick = this.restoreClick.defer(250, this);
31226 this.fireEvent('menuhide', this, this.menu);
31227 delete this.menu.ownerCt;
31232 restoreClick : function(){
31233 this.ignoreNextClick = 0;
31243 Ext.reg('button', Ext.Button);
31246 Ext.ButtonToggleMgr = function(){
31249 function toggleGroup(btn, state){
31251 var g = groups[btn.toggleGroup];
31252 for(var i = 0, l = g.length; i < l; i++){
31254 g[i].toggle(false);
31261 register : function(btn){
31262 if(!btn.toggleGroup){
31265 var g = groups[btn.toggleGroup];
31267 g = groups[btn.toggleGroup] = [];
31270 btn.on('toggle', toggleGroup);
31273 unregister : function(btn){
31274 if(!btn.toggleGroup){
31277 var g = groups[btn.toggleGroup];
31280 btn.un('toggle', toggleGroup);
31285 getPressed : function(group){
31286 var g = groups[group];
31288 for(var i = 0, len = g.length; i < len; i++){
31289 if(g[i].pressed === true){
31299 Ext.SplitButton = Ext.extend(Ext.Button, {
31301 arrowSelector : 'em',
31305 initComponent : function(){
31306 Ext.SplitButton.superclass.initComponent.call(this);
31308 this.addEvents("arrowclick");
31312 onRender : function(){
31313 Ext.SplitButton.superclass.onRender.apply(this, arguments);
31314 if(this.arrowTooltip){
31315 this.el.child(this.arrowSelector).dom[this.tooltipType] = this.arrowTooltip;
31320 setArrowHandler : function(handler, scope){
31321 this.arrowHandler = handler;
31322 this.scope = scope;
31325 getMenuClass : function(){
31326 return 'x-btn-split' + (this.arrowAlign == 'bottom' ? '-bottom' : '');
31329 isClickOnArrow : function(e){
31330 if (this.arrowAlign != 'bottom') {
31331 var visBtn = this.el.child('em.x-btn-split');
31332 var right = visBtn.getRegion().right - visBtn.getPadding('r');
31333 return e.getPageX() > right;
31335 return e.getPageY() > this.btnEl.getRegion().bottom;
31340 onClick : function(e, t){
31341 e.preventDefault();
31342 if(!this.disabled){
31343 if(this.isClickOnArrow(e)){
31344 if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
31347 this.fireEvent("arrowclick", this, e);
31348 if(this.arrowHandler){
31349 this.arrowHandler.call(this.scope || this, this, e);
31353 this.fireEvent("click", this, e);
31355 this.handler.call(this.scope || this, this, e);
31362 isMenuTriggerOver : function(e){
31363 return this.menu && e.target.tagName == this.arrowSelector;
31367 isMenuTriggerOut : function(e, internal){
31368 return this.menu && e.target.tagName != this.arrowSelector;
31372 Ext.reg('splitbutton', Ext.SplitButton);
31373 Ext.CycleButton = Ext.extend(Ext.SplitButton, {
31382 getItemText : function(item){
31383 if(item && this.showText === true){
31385 if(this.prependText){
31386 text += this.prependText;
31395 setActiveItem : function(item, suppressEvent){
31396 if(!Ext.isObject(item)){
31397 item = this.menu.getComponent(item);
31400 if(!this.rendered){
31401 this.text = this.getItemText(item);
31402 this.iconCls = item.iconCls;
31404 var t = this.getItemText(item);
31408 this.setIconClass(item.iconCls);
31410 this.activeItem = item;
31412 item.setChecked(true, false);
31414 if(this.forceIcon){
31415 this.setIconClass(this.forceIcon);
31417 if(!suppressEvent){
31418 this.fireEvent('change', this, item);
31424 getActiveItem : function(){
31425 return this.activeItem;
31429 initComponent : function(){
31435 if(this.changeHandler){
31436 this.on('change', this.changeHandler, this.scope||this);
31437 delete this.changeHandler;
31440 this.itemCount = this.items.length;
31442 this.menu = {cls:'x-cycle-menu', items:[]};
31444 Ext.each(this.items, function(item, i){
31446 group: item.group || this.id,
31448 checkHandler: this.checkHandler,
31450 checked: item.checked || false
31452 this.menu.items.push(item);
31457 Ext.CycleButton.superclass.initComponent.call(this);
31458 this.on('click', this.toggleSelected, this);
31459 this.setActiveItem(checked, true);
31463 checkHandler : function(item, pressed){
31465 this.setActiveItem(item);
31470 toggleSelected : function(){
31478 var nextIdx, checkItem;
31479 for (var i = 1; i < this.itemCount; i++) {
31480 nextIdx = (this.activeItem.itemIndex + i) % this.itemCount;
31482 checkItem = m.items.itemAt(nextIdx);
31484 if (!checkItem.disabled) {
31485 checkItem.setChecked(true);
31491 Ext.reg('cycle', Ext.CycleButton);
31492 Ext.Toolbar = function(config){
31493 if(Ext.isArray(config)){
31494 config = {items: config, layout: 'toolbar'};
31496 config = Ext.apply({
31499 if(config.buttons) {
31500 config.items = config.buttons;
31503 Ext.Toolbar.superclass.constructor.call(this, config);
31508 var T = Ext.Toolbar;
31510 Ext.extend(T, Ext.Container, {
31512 defaultType: 'button',
31516 enableOverflow : false,
31522 internalDefaults: {removeMode: 'container', hideParent: true},
31523 toolbarCls: 'x-toolbar',
31525 initComponent : function(){
31526 T.superclass.initComponent.call(this);
31529 this.addEvents('overflowchange');
31533 onRender : function(ct, position){
31535 if(!this.autoCreate){
31536 this.autoCreate = {
31537 cls: this.toolbarCls + ' x-small-editor'
31540 this.el = ct.createChild(Ext.apply({ id: this.id },this.autoCreate), position);
31541 Ext.Toolbar.superclass.onRender.apply(this, arguments);
31548 lookupComponent : function(c){
31549 if(Ext.isString(c)){
31551 c = new T.Separator();
31552 }else if(c == ' '){
31553 c = new T.Spacer();
31554 }else if(c == '->'){
31557 c = new T.TextItem(c);
31559 this.applyDefaults(c);
31561 if(c.isFormField || c.render){
31562 c = this.createComponent(c);
31564 c = new T.Item({autoEl: c});
31565 }else if(c.tagName){
31566 c = new T.Item({el:c});
31567 }else if(Ext.isObject(c)){
31568 c = c.xtype ? this.createComponent(c) : this.constructButton(c);
31575 applyDefaults : function(c){
31576 if(!Ext.isString(c)){
31577 c = Ext.Toolbar.superclass.applyDefaults.call(this, c);
31578 var d = this.internalDefaults;
31580 Ext.applyIf(c.initialConfig, d);
31590 addSeparator : function(){
31591 return this.add(new T.Separator());
31595 addSpacer : function(){
31596 return this.add(new T.Spacer());
31600 addFill : function(){
31601 this.add(new T.Fill());
31605 addElement : function(el){
31606 return this.addItem(new T.Item({el:el}));
31610 addItem : function(item){
31611 return this.add.apply(this, arguments);
31615 addButton : function(config){
31616 if(Ext.isArray(config)){
31618 for(var i = 0, len = config.length; i < len; i++) {
31619 buttons.push(this.addButton(config[i]));
31623 return this.add(this.constructButton(config));
31627 addText : function(text){
31628 return this.addItem(new T.TextItem(text));
31632 addDom : function(config){
31633 return this.add(new T.Item({autoEl: config}));
31637 addField : function(field){
31638 return this.add(field);
31642 insertButton : function(index, item){
31643 if(Ext.isArray(item)){
31645 for(var i = 0, len = item.length; i < len; i++) {
31646 buttons.push(this.insertButton(index + i, item[i]));
31650 return Ext.Toolbar.superclass.insert.call(this, index, item);
31654 trackMenu : function(item, remove){
31655 if(this.trackMenus && item.menu){
31656 var method = remove ? 'mun' : 'mon';
31657 this[method](item, 'menutriggerover', this.onButtonTriggerOver, this);
31658 this[method](item, 'menushow', this.onButtonMenuShow, this);
31659 this[method](item, 'menuhide', this.onButtonMenuHide, this);
31664 constructButton : function(item){
31665 var b = item.events ? item : this.createComponent(item, item.split ? 'splitbutton' : this.defaultType);
31670 onAdd : function(c){
31671 Ext.Toolbar.superclass.onAdd.call(this);
31679 onRemove : function(c){
31680 Ext.Toolbar.superclass.onRemove.call(this);
31681 if (c == this.activeMenuBtn) {
31682 delete this.activeMenuBtn;
31684 this.trackMenu(c, true);
31688 onDisable : function(){
31689 this.items.each(function(item){
31697 onEnable : function(){
31698 this.items.each(function(item){
31706 onButtonTriggerOver : function(btn){
31707 if(this.activeMenuBtn && this.activeMenuBtn != btn){
31708 this.activeMenuBtn.hideMenu();
31710 this.activeMenuBtn = btn;
31715 onButtonMenuShow : function(btn){
31716 this.activeMenuBtn = btn;
31720 onButtonMenuHide : function(btn){
31721 delete this.activeMenuBtn;
31724 Ext.reg('toolbar', Ext.Toolbar);
31727 T.Item = Ext.extend(Ext.BoxComponent, {
31729 enable:Ext.emptyFn,
31730 disable:Ext.emptyFn,
31734 Ext.reg('tbitem', T.Item);
31737 T.Separator = Ext.extend(T.Item, {
31738 onRender : function(ct, position){
31739 this.el = ct.createChild({tag:'span', cls:'xtb-sep'}, position);
31742 Ext.reg('tbseparator', T.Separator);
31745 T.Spacer = Ext.extend(T.Item, {
31748 onRender : function(ct, position){
31749 this.el = ct.createChild({tag:'div', cls:'xtb-spacer', style: this.width?'width:'+this.width+'px':''}, position);
31752 Ext.reg('tbspacer', T.Spacer);
31755 T.Fill = Ext.extend(T.Item, {
31757 render : Ext.emptyFn,
31760 Ext.reg('tbfill', T.Fill);
31763 T.TextItem = Ext.extend(T.Item, {
31766 constructor: function(config){
31767 T.TextItem.superclass.constructor.call(this, Ext.isString(config) ? {text: config} : config);
31771 onRender : function(ct, position) {
31772 this.autoEl = {cls: 'xtb-text', html: this.text || ''};
31773 T.TextItem.superclass.onRender.call(this, ct, position);
31777 setText : function(t) {
31785 Ext.reg('tbtext', T.TextItem);
31788 T.Button = Ext.extend(Ext.Button, {});
31789 T.SplitButton = Ext.extend(Ext.SplitButton, {});
31790 Ext.reg('tbbutton', T.Button);
31791 Ext.reg('tbsplit', T.SplitButton);
31795 Ext.ButtonGroup = Ext.extend(Ext.Panel, {
31798 baseCls: 'x-btn-group',
31801 defaultType: 'button',
31804 internalDefaults: {removeMode: 'container', hideParent: true},
31806 initComponent : function(){
31807 this.layoutConfig = this.layoutConfig || {};
31808 Ext.applyIf(this.layoutConfig, {
31809 columns : this.columns
31812 this.addClass('x-btn-group-notitle');
31814 this.on('afterlayout', this.onAfterLayout, this);
31815 Ext.ButtonGroup.superclass.initComponent.call(this);
31818 applyDefaults : function(c){
31819 c = Ext.ButtonGroup.superclass.applyDefaults.call(this, c);
31820 var d = this.internalDefaults;
31822 Ext.applyIf(c.initialConfig, d);
31830 onAfterLayout : function(){
31831 var bodyWidth = this.body.getFrameWidth('lr') + this.body.dom.firstChild.offsetWidth;
31832 this.body.setWidth(bodyWidth);
31833 this.el.setWidth(bodyWidth + this.getFrameWidth());
31838 Ext.reg('buttongroup', Ext.ButtonGroup);
31842 var T = Ext.Toolbar;
31844 Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {
31851 displayMsg : 'Displaying {0} - {1} of {2}',
31853 emptyMsg : 'No data to display',
31855 beforePageText : 'Page',
31857 afterPageText : 'of {0}',
31859 firstText : 'First Page',
31861 prevText : 'Previous Page',
31863 nextText : 'Next Page',
31865 lastText : 'Last Page',
31867 refreshText : 'Refresh',
31875 initComponent : function(){
31876 var pagingItems = [this.first = new T.Button({
31877 tooltip: this.firstText,
31878 overflowText: this.firstText,
31879 iconCls: 'x-tbar-page-first',
31881 handler: this.moveFirst,
31883 }), this.prev = new T.Button({
31884 tooltip: this.prevText,
31885 overflowText: this.prevText,
31886 iconCls: 'x-tbar-page-prev',
31888 handler: this.movePrevious,
31890 }), '-', this.beforePageText,
31891 this.inputItem = new Ext.form.NumberField({
31892 cls: 'x-tbar-page-number',
31893 allowDecimals: false,
31894 allowNegative: false,
31895 enableKeyEvents: true,
31896 selectOnFocus: true,
31897 submitValue: false,
31900 keydown: this.onPagingKeyDown,
31901 blur: this.onPagingBlur
31903 }), this.afterTextItem = new T.TextItem({
31904 text: String.format(this.afterPageText, 1)
31905 }), '-', this.next = new T.Button({
31906 tooltip: this.nextText,
31907 overflowText: this.nextText,
31908 iconCls: 'x-tbar-page-next',
31910 handler: this.moveNext,
31912 }), this.last = new T.Button({
31913 tooltip: this.lastText,
31914 overflowText: this.lastText,
31915 iconCls: 'x-tbar-page-last',
31917 handler: this.moveLast,
31919 }), '-', this.refresh = new T.Button({
31920 tooltip: this.refreshText,
31921 overflowText: this.refreshText,
31922 iconCls: 'x-tbar-loading',
31923 handler: this.doRefresh,
31928 var userItems = this.items || this.buttons || [];
31929 if (this.prependButtons) {
31930 this.items = userItems.concat(pagingItems);
31932 this.items = pagingItems.concat(userItems);
31934 delete this.buttons;
31935 if(this.displayInfo){
31936 this.items.push('->');
31937 this.items.push(this.displayItem = new T.TextItem({}));
31939 Ext.PagingToolbar.superclass.initComponent.call(this);
31946 this.on('afterlayout', this.onFirstLayout, this, {single: true});
31948 this.bindStore(this.store, true);
31952 onFirstLayout : function(){
31954 this.onLoad.apply(this, this.dsLoaded);
31959 updateInfo : function(){
31960 if(this.displayItem){
31961 var count = this.store.getCount();
31962 var msg = count == 0 ?
31966 this.cursor+1, this.cursor+count, this.store.getTotalCount()
31968 this.displayItem.setText(msg);
31973 onLoad : function(store, r, o){
31974 if(!this.rendered){
31975 this.dsLoaded = [store, r, o];
31978 var p = this.getParams();
31979 this.cursor = (o.params && o.params[p.start]) ? o.params[p.start] : 0;
31980 var d = this.getPageData(), ap = d.activePage, ps = d.pages;
31982 this.afterTextItem.setText(String.format(this.afterPageText, d.pages));
31983 this.inputItem.setValue(ap);
31984 this.first.setDisabled(ap == 1);
31985 this.prev.setDisabled(ap == 1);
31986 this.next.setDisabled(ap == ps);
31987 this.last.setDisabled(ap == ps);
31988 this.refresh.enable();
31990 this.fireEvent('change', this, d);
31994 getPageData : function(){
31995 var total = this.store.getTotalCount();
31998 activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize),
31999 pages : total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)
32004 changePage : function(page){
32005 this.doLoad(((page-1) * this.pageSize).constrain(0, this.store.getTotalCount()));
32009 onLoadError : function(){
32010 if(!this.rendered){
32013 this.refresh.enable();
32017 readPage : function(d){
32018 var v = this.inputItem.getValue(), pageNum;
32019 if (!v || isNaN(pageNum = parseInt(v, 10))) {
32020 this.inputItem.setValue(d.activePage);
32026 onPagingFocus : function(){
32027 this.inputItem.select();
32031 onPagingBlur : function(e){
32032 this.inputItem.setValue(this.getPageData().activePage);
32036 onPagingKeyDown : function(field, e){
32037 var k = e.getKey(), d = this.getPageData(), pageNum;
32038 if (k == e.RETURN) {
32040 pageNum = this.readPage(d);
32041 if(pageNum !== false){
32042 pageNum = Math.min(Math.max(1, pageNum), d.pages) - 1;
32043 this.doLoad(pageNum * this.pageSize);
32045 }else if (k == e.HOME || k == e.END){
32047 pageNum = k == e.HOME ? 1 : d.pages;
32048 field.setValue(pageNum);
32049 }else if (k == e.UP || k == e.PAGEUP || k == e.DOWN || k == e.PAGEDOWN){
32051 if((pageNum = this.readPage(d))){
32052 var increment = e.shiftKey ? 10 : 1;
32053 if(k == e.DOWN || k == e.PAGEDOWN){
32056 pageNum += increment;
32057 if(pageNum >= 1 & pageNum <= d.pages){
32058 field.setValue(pageNum);
32065 getParams : function(){
32067 return this.paramNames || this.store.paramNames;
32071 beforeLoad : function(){
32072 if(this.rendered && this.refresh){
32073 this.refresh.disable();
32078 doLoad : function(start){
32079 var o = {}, pn = this.getParams();
32080 o[pn.start] = start;
32081 o[pn.limit] = this.pageSize;
32082 if(this.fireEvent('beforechange', this, o) !== false){
32083 this.store.load({params:o});
32088 moveFirst : function(){
32093 movePrevious : function(){
32094 this.doLoad(Math.max(0, this.cursor-this.pageSize));
32098 moveNext : function(){
32099 this.doLoad(this.cursor+this.pageSize);
32103 moveLast : function(){
32104 var total = this.store.getTotalCount(),
32105 extra = total % this.pageSize;
32107 this.doLoad(extra ? (total - extra) : total - this.pageSize);
32111 doRefresh : function(){
32112 this.doLoad(this.cursor);
32116 bindStore : function(store, initial){
32118 if(!initial && this.store){
32119 if(store !== this.store && this.store.autoDestroy){
32120 this.store.destroy();
32122 this.store.un('beforeload', this.beforeLoad, this);
32123 this.store.un('load', this.onLoad, this);
32124 this.store.un('exception', this.onLoadError, this);
32131 store = Ext.StoreMgr.lookup(store);
32134 beforeload: this.beforeLoad,
32136 exception: this.onLoadError
32140 this.store = store;
32142 this.onLoad(store, null, {});
32147 unbind : function(store){
32148 this.bindStore(null);
32152 bind : function(store){
32153 this.bindStore(store);
32157 onDestroy : function(){
32158 this.bindStore(null);
32159 Ext.PagingToolbar.superclass.onDestroy.call(this);
32164 Ext.reg('paging', Ext.PagingToolbar);
32165 Ext.History = (function () {
32166 var iframe, hiddenField;
32170 function getHash() {
32171 var href = location.href, i = href.indexOf("#");
32172 return i >= 0 ? href.substr(i + 1) : null;
32175 function doSave() {
32176 hiddenField.value = currentToken;
32179 function handleStateChange(token) {
32180 currentToken = token;
32181 Ext.History.fireEvent('change', token);
32184 function updateIFrame (token) {
32185 var html = ['<html><body><div id="state">',Ext.util.Format.htmlEncode(token),'</div></body></html>'].join('');
32187 var doc = iframe.contentWindow.document;
32197 function checkIFrame() {
32198 if (!iframe.contentWindow || !iframe.contentWindow.document) {
32199 setTimeout(checkIFrame, 10);
32203 var doc = iframe.contentWindow.document;
32204 var elem = doc.getElementById("state");
32205 var token = elem ? elem.innerText : null;
32207 var hash = getHash();
32209 setInterval(function () {
32211 doc = iframe.contentWindow.document;
32212 elem = doc.getElementById("state");
32214 var newtoken = elem ? elem.innerText : null;
32216 var newHash = getHash();
32218 if (newtoken !== token) {
32220 handleStateChange(token);
32221 top.location.hash = token;
32224 } else if (newHash !== hash) {
32226 updateIFrame(newHash);
32233 Ext.History.fireEvent('ready', Ext.History);
32236 function startUp() {
32237 currentToken = hiddenField.value ? hiddenField.value : getHash();
32242 var hash = getHash();
32243 setInterval(function () {
32244 var newHash = getHash();
32245 if (newHash !== hash) {
32247 handleStateChange(hash);
32252 Ext.History.fireEvent('ready', Ext.History);
32258 fieldId: 'x-history-field',
32260 iframeId: 'x-history-frame',
32265 init: function (onReady, scope) {
32267 Ext.callback(onReady, scope, [this]);
32271 Ext.onReady(function(){
32272 Ext.History.init(onReady, scope);
32276 hiddenField = Ext.getDom(Ext.History.fieldId);
32278 iframe = Ext.getDom(Ext.History.iframeId);
32287 this.on('ready', onReady, scope, {single:true});
32293 add: function (token, preventDup) {
32294 if(preventDup !== false){
32295 if(this.getToken() == token){
32300 return updateIFrame(token);
32302 top.location.hash = token;
32313 forward: function(){
32318 getToken: function() {
32319 return ready ? currentToken : getHash();
32323 Ext.apply(Ext.History, new Ext.util.Observable());
32324 Ext.Tip = Ext.extend(Ext.Panel, {
32334 defaultAlign : "tl-bl?",
32336 quickShowInterval : 250,
32342 floating:{shadow:true,shim:true,useDisplay:true,constrain:false},
32345 closeAction: 'hide',
32348 initComponent : function(){
32349 Ext.Tip.superclass.initComponent.call(this);
32350 if(this.closable && !this.title){
32351 this.elements += ',header';
32356 afterRender : function(){
32357 Ext.Tip.superclass.afterRender.call(this);
32361 handler: this[this.closeAction],
32368 showAt : function(xy){
32369 Ext.Tip.superclass.show.call(this);
32370 if(this.measureWidth !== false && (!this.initialConfig || typeof this.initialConfig.width != 'number')){
32371 this.doAutoWidth();
32373 if(this.constrainPosition){
32374 xy = this.el.adjustForConstraints(xy);
32376 this.setPagePosition(xy[0], xy[1]);
32380 doAutoWidth : function(adjust){
32381 adjust = adjust || 0;
32382 var bw = this.body.getTextWidth();
32384 bw = Math.max(bw, this.header.child('span').getTextWidth(this.title));
32386 bw += this.getFrameWidth() + (this.closable ? 20 : 0) + this.body.getPadding("lr") + adjust;
32387 this.setWidth(bw.constrain(this.minWidth, this.maxWidth));
32390 if(Ext.isIE7 && !this.repainted){
32392 this.repainted = true;
32397 showBy : function(el, pos){
32398 if(!this.rendered){
32399 this.render(Ext.getBody());
32401 this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign));
32404 initDraggable : function(){
32405 this.dd = new Ext.Tip.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);
32406 this.header.addClass('x-tip-draggable');
32410 Ext.reg('tip', Ext.Tip);
32413 Ext.Tip.DD = function(tip, config){
32414 Ext.apply(this, config);
32416 Ext.Tip.DD.superclass.constructor.call(this, tip.el.id, 'WindowDD-'+tip.id);
32417 this.setHandleElId(tip.header.id);
32418 this.scroll = false;
32421 Ext.extend(Ext.Tip.DD, Ext.dd.DD, {
32424 headerOffsets:[100, 25],
32425 startDrag : function(){
32426 this.tip.el.disableShadow();
32428 endDrag : function(e){
32429 this.tip.el.enableShadow(true);
32432 Ext.ToolTip = Ext.extend(Ext.Tip, {
32441 dismissDelay : 5000,
32444 trackMouse : false,
32446 anchorToTarget : true,
32454 constrainPosition : false,
32457 initComponent : function(){
32458 Ext.ToolTip.superclass.initComponent.call(this);
32459 this.lastActive = new Date();
32460 this.initTarget(this.target);
32461 this.origAnchor = this.anchor;
32465 onRender : function(ct, position){
32466 Ext.ToolTip.superclass.onRender.call(this, ct, position);
32467 this.anchorCls = 'x-tip-anchor-' + this.getAnchorPosition();
32468 this.anchorEl = this.el.createChild({
32469 cls: 'x-tip-anchor ' + this.anchorCls
32474 afterRender : function(){
32475 Ext.ToolTip.superclass.afterRender.call(this);
32476 this.anchorEl.setStyle('z-index', this.el.getZIndex() + 1).setVisibilityMode(Ext.Element.DISPLAY);
32480 initTarget : function(target){
32482 if((t = Ext.get(target))){
32484 var tg = Ext.get(this.target);
32485 this.mun(tg, 'mouseover', this.onTargetOver, this);
32486 this.mun(tg, 'mouseout', this.onTargetOut, this);
32487 this.mun(tg, 'mousemove', this.onMouseMove, this);
32490 mouseover: this.onTargetOver,
32491 mouseout: this.onTargetOut,
32492 mousemove: this.onMouseMove,
32498 this.anchorTarget = this.target;
32503 onMouseMove : function(e){
32504 var t = this.delegate ? e.getTarget(this.delegate) : this.triggerElement = true;
32506 this.targetXY = e.getXY();
32507 if (t === this.triggerElement) {
32508 if(!this.hidden && this.trackMouse){
32509 this.setPagePosition(this.getTargetXY());
32513 this.lastActive = new Date(0);
32514 this.onTargetOver(e);
32516 } else if (!this.closable && this.isVisible()) {
32522 getTargetXY : function(){
32524 this.anchorTarget = this.triggerElement;
32527 this.targetCounter++;
32528 var offsets = this.getOffsets(),
32529 xy = (this.anchorToTarget && !this.trackMouse) ? this.el.getAlignToXY(this.anchorTarget, this.getAnchorAlign()) : this.targetXY,
32530 dw = Ext.lib.Dom.getViewWidth() - 5,
32531 dh = Ext.lib.Dom.getViewHeight() - 5,
32532 de = document.documentElement,
32533 bd = document.body,
32534 scrollX = (de.scrollLeft || bd.scrollLeft || 0) + 5,
32535 scrollY = (de.scrollTop || bd.scrollTop || 0) + 5,
32536 axy = [xy[0] + offsets[0], xy[1] + offsets[1]],
32537 sz = this.getSize();
32539 this.anchorEl.removeClass(this.anchorCls);
32541 if(this.targetCounter < 2){
32542 if(axy[0] < scrollX){
32543 if(this.anchorToTarget){
32544 this.defaultAlign = 'l-r';
32545 if(this.mouseOffset){this.mouseOffset[0] *= -1;}
32547 this.anchor = 'left';
32548 return this.getTargetXY();
32550 if(axy[0]+sz.width > dw){
32551 if(this.anchorToTarget){
32552 this.defaultAlign = 'r-l';
32553 if(this.mouseOffset){this.mouseOffset[0] *= -1;}
32555 this.anchor = 'right';
32556 return this.getTargetXY();
32558 if(axy[1] < scrollY){
32559 if(this.anchorToTarget){
32560 this.defaultAlign = 't-b';
32561 if(this.mouseOffset){this.mouseOffset[1] *= -1;}
32563 this.anchor = 'top';
32564 return this.getTargetXY();
32566 if(axy[1]+sz.height > dh){
32567 if(this.anchorToTarget){
32568 this.defaultAlign = 'b-t';
32569 if(this.mouseOffset){this.mouseOffset[1] *= -1;}
32571 this.anchor = 'bottom';
32572 return this.getTargetXY();
32576 this.anchorCls = 'x-tip-anchor-'+this.getAnchorPosition();
32577 this.anchorEl.addClass(this.anchorCls);
32578 this.targetCounter = 0;
32581 var mouseOffset = this.getMouseOffset();
32582 return [this.targetXY[0]+mouseOffset[0], this.targetXY[1]+mouseOffset[1]];
32586 getMouseOffset : function(){
32587 var offset = this.anchor ? [0,0] : [15,18];
32588 if(this.mouseOffset){
32589 offset[0] += this.mouseOffset[0];
32590 offset[1] += this.mouseOffset[1];
32596 getAnchorPosition : function(){
32598 this.tipAnchor = this.anchor.charAt(0);
32600 var m = this.defaultAlign.match(/^([a-z]+)-([a-z]+)(\?)?$/);
32602 throw 'AnchorTip.defaultAlign is invalid';
32604 this.tipAnchor = m[1].charAt(0);
32607 switch(this.tipAnchor){
32608 case 't': return 'top';
32609 case 'b': return 'bottom';
32610 case 'r': return 'right';
32616 getAnchorAlign : function(){
32617 switch(this.anchor){
32618 case 'top' : return 'tl-bl';
32619 case 'left' : return 'tl-tr';
32620 case 'right': return 'tr-tl';
32621 default : return 'bl-tl';
32626 getOffsets : function(){
32628 ap = this.getAnchorPosition().charAt(0);
32629 if(this.anchorToTarget && !this.trackMouse){
32635 offsets = [0, -13];
32638 offsets = [-13, 0];
32647 offsets = [-15-this.anchorOffset, 30];
32650 offsets = [-19-this.anchorOffset, -13-this.el.dom.offsetHeight];
32653 offsets = [-15-this.el.dom.offsetWidth, -13-this.anchorOffset];
32656 offsets = [25, -13-this.anchorOffset];
32660 var mouseOffset = this.getMouseOffset();
32661 offsets[0] += mouseOffset[0];
32662 offsets[1] += mouseOffset[1];
32668 onTargetOver : function(e){
32669 if(this.disabled || e.within(this.target.dom, true)){
32672 var t = e.getTarget(this.delegate);
32674 this.triggerElement = t;
32675 this.clearTimer('hide');
32676 this.targetXY = e.getXY();
32682 delayShow : function(){
32683 if(this.hidden && !this.showTimer){
32684 if(this.lastActive.getElapsed() < this.quickShowInterval){
32687 this.showTimer = this.show.defer(this.showDelay, this);
32689 }else if(!this.hidden && this.autoHide !== false){
32695 onTargetOut : function(e){
32696 if(this.disabled || e.within(this.target.dom, true)){
32699 this.clearTimer('show');
32700 if(this.autoHide !== false){
32706 delayHide : function(){
32707 if(!this.hidden && !this.hideTimer){
32708 this.hideTimer = this.hide.defer(this.hideDelay, this);
32714 this.clearTimer('dismiss');
32715 this.lastActive = new Date();
32717 this.anchorEl.hide();
32719 Ext.ToolTip.superclass.hide.call(this);
32720 delete this.triggerElement;
32728 this.showAt([-1000,-1000]);
32729 this.origConstrainPosition = this.constrainPosition;
32730 this.constrainPosition = false;
32731 this.anchor = this.origAnchor;
32733 this.showAt(this.getTargetXY());
32736 this.anchorEl.show();
32738 this.constrainPosition = this.origConstrainPosition;
32740 this.anchorEl.hide();
32745 showAt : function(xy){
32746 this.lastActive = new Date();
32747 this.clearTimers();
32748 Ext.ToolTip.superclass.showAt.call(this, xy);
32749 if(this.dismissDelay && this.autoHide !== false){
32750 this.dismissTimer = this.hide.defer(this.dismissDelay, this);
32752 if(this.anchor && !this.anchorEl.isVisible()){
32754 this.anchorEl.show();
32756 this.anchorEl.hide();
32761 syncAnchor : function(){
32762 var anchorPos, targetPos, offset;
32763 switch(this.tipAnchor.charAt(0)){
32767 offset = [20+this.anchorOffset, 2];
32772 offset = [-2, 11+this.anchorOffset];
32777 offset = [20+this.anchorOffset, -2];
32782 offset = [2, 11+this.anchorOffset];
32785 this.anchorEl.alignTo(this.el, anchorPos+'-'+targetPos, offset);
32789 setPagePosition : function(x, y){
32790 Ext.ToolTip.superclass.setPagePosition.call(this, x, y);
32797 clearTimer : function(name){
32798 name = name + 'Timer';
32799 clearTimeout(this[name]);
32804 clearTimers : function(){
32805 this.clearTimer('show');
32806 this.clearTimer('dismiss');
32807 this.clearTimer('hide');
32811 onShow : function(){
32812 Ext.ToolTip.superclass.onShow.call(this);
32813 Ext.getDoc().on('mousedown', this.onDocMouseDown, this);
32817 onHide : function(){
32818 Ext.ToolTip.superclass.onHide.call(this);
32819 Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
32823 onDocMouseDown : function(e){
32824 if(this.autoHide !== true && !this.closable && !e.within(this.el.dom)){
32826 this.doEnable.defer(100, this);
32831 doEnable : function(){
32832 if(!this.isDestroyed){
32838 onDisable : function(){
32839 this.clearTimers();
32844 adjustPosition : function(x, y){
32845 if(this.contstrainPosition){
32846 var ay = this.targetXY[1], h = this.getSize().height;
32847 if(y <= ay && (y+h) >= ay){
32851 return {x : x, y: y};
32854 beforeDestroy : function(){
32855 this.clearTimers();
32856 Ext.destroy(this.anchorEl);
32857 delete this.anchorEl;
32858 delete this.target;
32859 delete this.anchorTarget;
32860 delete this.triggerElement;
32861 Ext.ToolTip.superclass.beforeDestroy.call(this);
32865 onDestroy : function(){
32866 Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
32867 Ext.ToolTip.superclass.onDestroy.call(this);
32871 Ext.reg('tooltip', Ext.ToolTip);
32872 Ext.QuickTip = Ext.extend(Ext.ToolTip, {
32875 interceptTitles : false,
32880 attribute : "qtip",
32891 initComponent : function(){
32892 this.target = this.target || Ext.getDoc();
32893 this.targets = this.targets || {};
32894 Ext.QuickTip.superclass.initComponent.call(this);
32898 register : function(config){
32899 var cs = Ext.isArray(config) ? config : arguments;
32900 for(var i = 0, len = cs.length; i < len; i++){
32902 var target = c.target;
32904 if(Ext.isArray(target)){
32905 for(var j = 0, jlen = target.length; j < jlen; j++){
32906 this.targets[Ext.id(target[j])] = c;
32909 this.targets[Ext.id(target)] = c;
32916 unregister : function(el){
32917 delete this.targets[Ext.id(el)];
32921 cancelShow: function(el){
32922 var at = this.activeTarget;
32923 el = Ext.get(el).dom;
32924 if(this.isVisible()){
32925 if(at && at.el == el){
32928 }else if(at && at.el == el){
32929 this.clearTimer('show');
32933 getTipCfg: function(e) {
32934 var t = e.getTarget(),
32937 if(this.interceptTitles && t.title && Ext.isString(t.title)){
32940 t.removeAttribute("title");
32941 e.preventDefault();
32943 cfg = this.tagConfig;
32944 ttp = t.qtip || Ext.fly(t).getAttribute(cfg.attribute, cfg.namespace);
32950 onTargetOver : function(e){
32954 this.targetXY = e.getXY();
32955 var t = e.getTarget();
32956 if(!t || t.nodeType !== 1 || t == document || t == document.body){
32959 if(this.activeTarget && ((t == this.activeTarget.el) || Ext.fly(this.activeTarget.el).contains(t))){
32960 this.clearTimer('hide');
32964 if(t && this.targets[t.id]){
32965 this.activeTarget = this.targets[t.id];
32966 this.activeTarget.el = t;
32967 this.anchor = this.activeTarget.anchor;
32969 this.anchorTarget = t;
32974 var ttp, et = Ext.fly(t), cfg = this.tagConfig, ns = cfg.namespace;
32975 if(ttp = this.getTipCfg(e)){
32976 var autoHide = et.getAttribute(cfg.hide, ns);
32977 this.activeTarget = {
32980 width: et.getAttribute(cfg.width, ns),
32981 autoHide: autoHide != "user" && autoHide !== 'false',
32982 title: et.getAttribute(cfg.title, ns),
32983 cls: et.getAttribute(cfg.cls, ns),
32984 align: et.getAttribute(cfg.align, ns)
32987 this.anchor = et.getAttribute(cfg.anchor, ns);
32989 this.anchorTarget = t;
32996 onTargetOut : function(e){
32999 if (this.activeTarget && e.within(this.activeTarget.el) && !this.getTipCfg(e)) {
33003 this.clearTimer('show');
33004 if(this.autoHide !== false){
33010 showAt : function(xy){
33011 var t = this.activeTarget;
33013 if(!this.rendered){
33014 this.render(Ext.getBody());
33015 this.activeTarget = t;
33018 this.setWidth(t.width);
33019 this.body.setWidth(this.adjustBodyWidth(t.width - this.getFrameWidth()));
33020 this.measureWidth = false;
33022 this.measureWidth = true;
33024 this.setTitle(t.title || '');
33025 this.body.update(t.text);
33026 this.autoHide = t.autoHide;
33027 this.dismissDelay = t.dismissDelay || this.dismissDelay;
33029 this.el.removeClass(this.lastCls);
33030 delete this.lastCls;
33033 this.el.addClass(t.cls);
33034 this.lastCls = t.cls;
33037 this.constrainPosition = false;
33039 xy = this.el.getAlignToXY(t.el, t.align);
33040 this.constrainPosition = false;
33042 this.constrainPosition = true;
33045 Ext.QuickTip.superclass.showAt.call(this, xy);
33050 delete this.activeTarget;
33051 Ext.QuickTip.superclass.hide.call(this);
33054 Ext.reg('quicktip', Ext.QuickTip);
33055 Ext.QuickTips = function(){
33061 init : function(autoRender){
33064 Ext.onReady(function(){
33065 Ext.QuickTips.init(autoRender);
33069 tip = new Ext.QuickTip({
33070 elements:'header,body',
33073 if(autoRender !== false){
33074 tip.render(Ext.getBody());
33080 ddDisable : function(){
33082 if(tip && !disabled){
33088 ddEnable : function(){
33090 if(tip && !disabled){
33096 enable : function(){
33104 disable : function(){
33112 isEnabled : function(){
33113 return tip !== undefined && !tip.disabled;
33117 getQuickTip : function(){
33122 register : function(){
33123 tip.register.apply(tip, arguments);
33127 unregister : function(){
33128 tip.unregister.apply(tip, arguments);
33133 tip.register.apply(tip, arguments);
33137 Ext.slider.Tip = Ext.extend(Ext.Tip, {
33139 offsets : [0, -10],
33141 init: function(slider) {
33144 dragstart: this.onSlide,
33145 drag : this.onSlide,
33146 dragend : this.hide,
33147 destroy : this.destroy
33152 onSlide : function(slider, e, thumb) {
33154 this.body.update(this.getText(thumb));
33155 this.doAutoWidth();
33156 this.el.alignTo(thumb.el, 'b-t?', this.offsets);
33160 getText : function(thumb) {
33161 return String(thumb.value);
33166 Ext.ux.SliderTip = Ext.slider.Tip;
33167 Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
33168 rootVisible : true,
33169 animate : Ext.enableFx,
33172 hlDrop : Ext.enableFx,
33173 pathSeparator : '/',
33178 initComponent : function(){
33179 Ext.tree.TreePanel.superclass.initComponent.call(this);
33181 if(!this.eventModel){
33182 this.eventModel = new Ext.tree.TreeEventModel(this);
33186 var l = this.loader;
33188 l = new Ext.tree.TreeLoader({
33189 dataUrl: this.dataUrl,
33190 requestMethod: this.requestMethod
33192 }else if(Ext.isObject(l) && !l.load){
33193 l = new Ext.tree.TreeLoader(l);
33197 this.nodeHash = {};
33203 this.setRootNode(r);
33233 'beforeexpandnode',
33235 'beforecollapsenode',
33255 'containerdblclick',
33259 'containercontextmenu',
33261 'beforechildrenrendered',
33275 if(this.singleExpand){
33276 this.on('beforeexpandnode', this.restrictExpand, this);
33281 proxyNodeEvent : function(ename, a1, a2, a3, a4, a5, a6){
33282 if(ename == 'collapse' || ename == 'expand' || ename == 'beforecollapse' || ename == 'beforeexpand' || ename == 'move' || ename == 'beforemove'){
33283 ename = ename+'node';
33286 return this.fireEvent(ename, a1, a2, a3, a4, a5, a6);
33291 getRootNode : function(){
33296 setRootNode : function(node){
33297 this.destroyRoot();
33299 node = this.loader.createNode(node);
33302 node.ownerTree = this;
33303 node.isRoot = true;
33304 this.registerNode(node);
33305 if(!this.rootVisible){
33306 var uiP = node.attributes.uiProvider;
33307 node.ui = uiP ? new uiP(node) : new Ext.tree.RootTreeNodeUI(node);
33310 this.clearInnerCt();
33316 clearInnerCt : function(){
33317 this.innerCt.update('');
33321 renderRoot : function(){
33322 this.root.render();
33323 if(!this.rootVisible){
33324 this.root.renderChildren();
33329 getNodeById : function(id){
33330 return this.nodeHash[id];
33334 registerNode : function(node){
33335 this.nodeHash[node.id] = node;
33339 unregisterNode : function(node){
33340 delete this.nodeHash[node.id];
33344 toString : function(){
33345 return '[Tree'+(this.id?' '+this.id:'')+']';
33349 restrictExpand : function(node){
33350 var p = node.parentNode;
33352 if(p.expandedChild && p.expandedChild.parentNode == p){
33353 p.expandedChild.collapse();
33355 p.expandedChild = node;
33360 getChecked : function(a, startNode){
33361 startNode = startNode || this.root;
33363 var f = function(){
33364 if(this.attributes.checked){
33365 r.push(!a ? this : (a == 'id' ? this.id : this.attributes[a]));
33368 startNode.cascade(f);
33373 getLoader : function(){
33374 return this.loader;
33378 expandAll : function(){
33379 this.root.expand(true);
33383 collapseAll : function(){
33384 this.root.collapse(true);
33388 getSelectionModel : function(){
33389 if(!this.selModel){
33390 this.selModel = new Ext.tree.DefaultSelectionModel();
33392 return this.selModel;
33396 expandPath : function(path, attr, callback){
33397 if(Ext.isEmpty(path)){
33399 callback(false, undefined);
33403 attr = attr || 'id';
33404 var keys = path.split(this.pathSeparator);
33405 var curNode = this.root;
33406 if(curNode.attributes[attr] != keys[1]){
33408 callback(false, null);
33413 var f = function(){
33414 if(++index == keys.length){
33416 callback(true, curNode);
33420 var c = curNode.findChild(attr, keys[index]);
33423 callback(false, curNode);
33428 c.expand(false, false, f);
33430 curNode.expand(false, false, f);
33434 selectPath : function(path, attr, callback){
33435 if(Ext.isEmpty(path)){
33437 callback(false, undefined);
33441 attr = attr || 'id';
33442 var keys = path.split(this.pathSeparator),
33444 if(keys.length > 1){
33445 var f = function(success, node){
33446 if(success && node){
33447 var n = node.findChild(attr, v);
33453 }else if(callback){
33454 callback(false, n);
33458 callback(false, n);
33462 this.expandPath(keys.join(this.pathSeparator), attr, f);
33464 this.root.select();
33466 callback(true, this.root);
33472 getTreeEl : function(){
33477 onRender : function(ct, position){
33478 Ext.tree.TreePanel.superclass.onRender.call(this, ct, position);
33479 this.el.addClass('x-tree');
33480 this.innerCt = this.body.createChild({tag:'ul',
33481 cls:'x-tree-root-ct ' +
33482 (this.useArrows ? 'x-tree-arrows' : this.lines ? 'x-tree-lines' : 'x-tree-no-lines')});
33486 initEvents : function(){
33487 Ext.tree.TreePanel.superclass.initEvents.call(this);
33489 if(this.containerScroll){
33490 Ext.dd.ScrollManager.register(this.body);
33492 if((this.enableDD || this.enableDrop) && !this.dropZone){
33494 this.dropZone = new Ext.tree.TreeDropZone(this, this.dropConfig || {
33495 ddGroup: this.ddGroup || 'TreeDD', appendOnly: this.ddAppendOnly === true
33498 if((this.enableDD || this.enableDrag) && !this.dragZone){
33500 this.dragZone = new Ext.tree.TreeDragZone(this, this.dragConfig || {
33501 ddGroup: this.ddGroup || 'TreeDD',
33502 scroll: this.ddScroll
33505 this.getSelectionModel().init(this);
33509 afterRender : function(){
33510 Ext.tree.TreePanel.superclass.afterRender.call(this);
33514 beforeDestroy : function(){
33516 Ext.dd.ScrollManager.unregister(this.body);
33517 Ext.destroy(this.dropZone, this.dragZone);
33519 this.destroyRoot();
33520 Ext.destroy(this.loader);
33521 this.nodeHash = this.root = this.loader = null;
33522 Ext.tree.TreePanel.superclass.beforeDestroy.call(this);
33526 destroyRoot : function(){
33527 if(this.root && this.root.destroy){
33528 this.root.destroy(true);
33584 Ext.tree.TreePanel.nodeTypes = {};
33586 Ext.reg('treepanel', Ext.tree.TreePanel);Ext.tree.TreeEventModel = function(tree){
33588 this.tree.on('render', this.initEvents, this);
33591 Ext.tree.TreeEventModel.prototype = {
33592 initEvents : function(){
33595 if(t.trackMouseOver !== false){
33598 mouseover: this.delegateOver,
33599 mouseout: this.delegateOut
33602 t.mon(t.getTreeEl(), {
33604 click: this.delegateClick,
33605 dblclick: this.delegateDblClick,
33606 contextmenu: this.delegateContextMenu
33610 getNode : function(e){
33612 if(t = e.getTarget('.x-tree-node-el', 10)){
33613 var id = Ext.fly(t, '_treeEvents').getAttribute('tree-node-id', 'ext');
33615 return this.tree.getNodeById(id);
33621 getNodeTarget : function(e){
33622 var t = e.getTarget('.x-tree-node-icon', 1);
33624 t = e.getTarget('.x-tree-node-el', 6);
33629 delegateOut : function(e, t){
33630 if(!this.beforeEvent(e)){
33633 if(e.getTarget('.x-tree-ec-icon', 1)){
33634 var n = this.getNode(e);
33635 this.onIconOut(e, n);
33636 if(n == this.lastEcOver){
33637 delete this.lastEcOver;
33640 if((t = this.getNodeTarget(e)) && !e.within(t, true)){
33641 this.onNodeOut(e, this.getNode(e));
33645 delegateOver : function(e, t){
33646 if(!this.beforeEvent(e)){
33649 if(Ext.isGecko && !this.trackingDoc){
33650 Ext.getBody().on('mouseover', this.trackExit, this);
33651 this.trackingDoc = true;
33653 if(this.lastEcOver){
33654 this.onIconOut(e, this.lastEcOver);
33655 delete this.lastEcOver;
33657 if(e.getTarget('.x-tree-ec-icon', 1)){
33658 this.lastEcOver = this.getNode(e);
33659 this.onIconOver(e, this.lastEcOver);
33661 if(t = this.getNodeTarget(e)){
33662 this.onNodeOver(e, this.getNode(e));
33666 trackExit : function(e){
33667 if(this.lastOverNode){
33668 if(this.lastOverNode.ui && !e.within(this.lastOverNode.ui.getEl())){
33669 this.onNodeOut(e, this.lastOverNode);
33671 delete this.lastOverNode;
33672 Ext.getBody().un('mouseover', this.trackExit, this);
33673 this.trackingDoc = false;
33678 delegateClick : function(e, t){
33679 if(this.beforeEvent(e)){
33680 if(e.getTarget('input[type=checkbox]', 1)){
33681 this.onCheckboxClick(e, this.getNode(e));
33682 }else if(e.getTarget('.x-tree-ec-icon', 1)){
33683 this.onIconClick(e, this.getNode(e));
33684 }else if(this.getNodeTarget(e)){
33685 this.onNodeClick(e, this.getNode(e));
33688 this.checkContainerEvent(e, 'click');
33692 delegateDblClick : function(e, t){
33693 if(this.beforeEvent(e)){
33694 if(this.getNodeTarget(e)){
33695 this.onNodeDblClick(e, this.getNode(e));
33698 this.checkContainerEvent(e, 'dblclick');
33702 delegateContextMenu : function(e, t){
33703 if(this.beforeEvent(e)){
33704 if(this.getNodeTarget(e)){
33705 this.onNodeContextMenu(e, this.getNode(e));
33708 this.checkContainerEvent(e, 'contextmenu');
33712 checkContainerEvent: function(e, type){
33717 this.onContainerEvent(e, type);
33720 onContainerEvent: function(e, type){
33721 this.tree.fireEvent('container' + type, this.tree, e);
33724 onNodeClick : function(e, node){
33725 node.ui.onClick(e);
33728 onNodeOver : function(e, node){
33729 this.lastOverNode = node;
33733 onNodeOut : function(e, node){
33737 onIconOver : function(e, node){
33738 node.ui.addClass('x-tree-ec-over');
33741 onIconOut : function(e, node){
33742 node.ui.removeClass('x-tree-ec-over');
33745 onIconClick : function(e, node){
33746 node.ui.ecClick(e);
33749 onCheckboxClick : function(e, node){
33750 node.ui.onCheckChange(e);
33753 onNodeDblClick : function(e, node){
33754 node.ui.onDblClick(e);
33757 onNodeContextMenu : function(e, node){
33758 node.ui.onContextMenu(e);
33761 beforeEvent : function(e){
33762 var node = this.getNode(e);
33763 if(this.disabled || !node || !node.ui){
33770 disable: function(){
33771 this.disabled = true;
33774 enable: function(){
33775 this.disabled = false;
33778 Ext.tree.DefaultSelectionModel = Ext.extend(Ext.util.Observable, {
33780 constructor : function(config){
33781 this.selNode = null;
33791 Ext.apply(this, config);
33792 Ext.tree.DefaultSelectionModel.superclass.constructor.call(this);
33795 init : function(tree){
33797 tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);
33798 tree.on('click', this.onNodeClick, this);
33801 onNodeClick : function(node, e){
33806 select : function(node, selectNextNode){
33808 if (!Ext.fly(node.ui.wrap).isVisible() && selectNextNode) {
33809 return selectNextNode.call(this, node);
33811 var last = this.selNode;
33813 node.ui.onSelectedChange(true);
33814 }else if(this.fireEvent('beforeselect', this, node, last) !== false){
33815 if(last && last.ui){
33816 last.ui.onSelectedChange(false);
33818 this.selNode = node;
33819 node.ui.onSelectedChange(true);
33820 this.fireEvent('selectionchange', this, node, last);
33826 unselect : function(node, silent){
33827 if(this.selNode == node){
33828 this.clearSelections(silent);
33833 clearSelections : function(silent){
33834 var n = this.selNode;
33836 n.ui.onSelectedChange(false);
33837 this.selNode = null;
33838 if(silent !== true){
33839 this.fireEvent('selectionchange', this, null);
33846 getSelectedNode : function(){
33847 return this.selNode;
33851 isSelected : function(node){
33852 return this.selNode == node;
33856 selectPrevious : function( s){
33857 if(!(s = s || this.selNode || this.lastSelNode)){
33861 var ps = s.previousSibling;
33863 if(!ps.isExpanded() || ps.childNodes.length < 1){
33864 return this.select(ps, this.selectPrevious);
33866 var lc = ps.lastChild;
33867 while(lc && lc.isExpanded() && Ext.fly(lc.ui.wrap).isVisible() && lc.childNodes.length > 0){
33870 return this.select(lc, this.selectPrevious);
33872 } else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){
33873 return this.select(s.parentNode, this.selectPrevious);
33879 selectNext : function( s){
33880 if(!(s = s || this.selNode || this.lastSelNode)){
33884 if(s.firstChild && s.isExpanded() && Ext.fly(s.ui.wrap).isVisible()){
33885 return this.select(s.firstChild, this.selectNext);
33886 }else if(s.nextSibling){
33887 return this.select(s.nextSibling, this.selectNext);
33888 }else if(s.parentNode){
33890 s.parentNode.bubble(function(){
33891 if(this.nextSibling){
33892 newS = this.getOwnerTree().selModel.select(this.nextSibling, this.selectNext);
33901 onKeyDown : function(e){
33902 var s = this.selNode || this.lastSelNode;
33908 var k = e.getKey();
33916 this.selectPrevious();
33919 e.preventDefault();
33920 if(s.hasChildNodes()){
33921 if(!s.isExpanded()){
33923 }else if(s.firstChild){
33924 this.select(s.firstChild, e);
33929 e.preventDefault();
33930 if(s.hasChildNodes() && s.isExpanded()){
33932 }else if(s.parentNode && (this.tree.rootVisible || s.parentNode != this.tree.getRootNode())){
33933 this.select(s.parentNode, e);
33941 Ext.tree.MultiSelectionModel = Ext.extend(Ext.util.Observable, {
33943 constructor : function(config){
33944 this.selNodes = [];
33950 Ext.apply(this, config);
33951 Ext.tree.MultiSelectionModel.superclass.constructor.call(this);
33954 init : function(tree){
33956 tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);
33957 tree.on('click', this.onNodeClick, this);
33960 onNodeClick : function(node, e){
33961 if(e.ctrlKey && this.isSelected(node)){
33962 this.unselect(node);
33964 this.select(node, e, e.ctrlKey);
33969 select : function(node, e, keepExisting){
33970 if(keepExisting !== true){
33971 this.clearSelections(true);
33973 if(this.isSelected(node)){
33974 this.lastSelNode = node;
33977 this.selNodes.push(node);
33978 this.selMap[node.id] = node;
33979 this.lastSelNode = node;
33980 node.ui.onSelectedChange(true);
33981 this.fireEvent('selectionchange', this, this.selNodes);
33986 unselect : function(node){
33987 if(this.selMap[node.id]){
33988 node.ui.onSelectedChange(false);
33989 var sn = this.selNodes;
33990 var index = sn.indexOf(node);
33992 this.selNodes.splice(index, 1);
33994 delete this.selMap[node.id];
33995 this.fireEvent('selectionchange', this, this.selNodes);
34000 clearSelections : function(suppressEvent){
34001 var sn = this.selNodes;
34003 for(var i = 0, len = sn.length; i < len; i++){
34004 sn[i].ui.onSelectedChange(false);
34006 this.selNodes = [];
34008 if(suppressEvent !== true){
34009 this.fireEvent('selectionchange', this, this.selNodes);
34015 isSelected : function(node){
34016 return this.selMap[node.id] ? true : false;
34020 getSelectedNodes : function(){
34021 return this.selNodes.concat([]);
34024 onKeyDown : Ext.tree.DefaultSelectionModel.prototype.onKeyDown,
34026 selectNext : Ext.tree.DefaultSelectionModel.prototype.selectNext,
34028 selectPrevious : Ext.tree.DefaultSelectionModel.prototype.selectPrevious
34030 Ext.data.Tree = Ext.extend(Ext.util.Observable, {
34032 constructor: function(root){
34033 this.nodeHash = {};
34037 this.setRootNode(root);
34057 Ext.data.Tree.superclass.constructor.call(this);
34061 pathSeparator: "/",
34064 proxyNodeEvent : function(){
34065 return this.fireEvent.apply(this, arguments);
34069 getRootNode : function(){
34074 setRootNode : function(node){
34076 node.ownerTree = this;
34077 node.isRoot = true;
34078 this.registerNode(node);
34083 getNodeById : function(id){
34084 return this.nodeHash[id];
34088 registerNode : function(node){
34089 this.nodeHash[node.id] = node;
34093 unregisterNode : function(node){
34094 delete this.nodeHash[node.id];
34097 toString : function(){
34098 return "[Tree"+(this.id?" "+this.id:"")+"]";
34103 Ext.data.Node = Ext.extend(Ext.util.Observable, {
34105 constructor: function(attributes){
34107 this.attributes = attributes || {};
34108 this.leaf = this.attributes.leaf;
34110 this.id = this.attributes.id;
34112 this.id = Ext.id(null, "xnode-");
34113 this.attributes.id = this.id;
34116 this.childNodes = [];
34118 this.parentNode = null;
34120 this.firstChild = null;
34122 this.lastChild = null;
34124 this.previousSibling = null;
34126 this.nextSibling = null;
34138 "beforeappend" : true,
34140 "beforeremove" : true,
34142 "beforemove" : true,
34144 "beforeinsert" : true
34146 this.listeners = this.attributes.listeners;
34147 Ext.data.Node.superclass.constructor.call(this);
34151 fireEvent : function(evtName){
34153 if(Ext.data.Node.superclass.fireEvent.apply(this, arguments) === false){
34157 var ot = this.getOwnerTree();
34159 if(ot.proxyNodeEvent.apply(ot, arguments) === false){
34167 isLeaf : function(){
34168 return this.leaf === true;
34172 setFirstChild : function(node){
34173 this.firstChild = node;
34177 setLastChild : function(node){
34178 this.lastChild = node;
34183 isLast : function(){
34184 return (!this.parentNode ? true : this.parentNode.lastChild == this);
34188 isFirst : function(){
34189 return (!this.parentNode ? true : this.parentNode.firstChild == this);
34193 hasChildNodes : function(){
34194 return !this.isLeaf() && this.childNodes.length > 0;
34198 isExpandable : function(){
34199 return this.attributes.expandable || this.hasChildNodes();
34203 appendChild : function(node){
34205 if(Ext.isArray(node)){
34207 }else if(arguments.length > 1){
34212 for(var i = 0, len = multi.length; i < len; i++) {
34213 this.appendChild(multi[i]);
34216 if(this.fireEvent("beforeappend", this.ownerTree, this, node) === false){
34219 var index = this.childNodes.length;
34220 var oldParent = node.parentNode;
34223 if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index) === false){
34226 oldParent.removeChild(node);
34228 index = this.childNodes.length;
34230 this.setFirstChild(node);
34232 this.childNodes.push(node);
34233 node.parentNode = this;
34234 var ps = this.childNodes[index-1];
34236 node.previousSibling = ps;
34237 ps.nextSibling = node;
34239 node.previousSibling = null;
34241 node.nextSibling = null;
34242 this.setLastChild(node);
34243 node.setOwnerTree(this.getOwnerTree());
34244 this.fireEvent("append", this.ownerTree, this, node, index);
34246 node.fireEvent("move", this.ownerTree, node, oldParent, this, index);
34253 removeChild : function(node, destroy){
34254 var index = this.childNodes.indexOf(node);
34258 if(this.fireEvent("beforeremove", this.ownerTree, this, node) === false){
34263 this.childNodes.splice(index, 1);
34266 if(node.previousSibling){
34267 node.previousSibling.nextSibling = node.nextSibling;
34269 if(node.nextSibling){
34270 node.nextSibling.previousSibling = node.previousSibling;
34274 if(this.firstChild == node){
34275 this.setFirstChild(node.nextSibling);
34277 if(this.lastChild == node){
34278 this.setLastChild(node.previousSibling);
34281 this.fireEvent("remove", this.ownerTree, this, node);
34283 node.destroy(true);
34291 clear : function(destroy){
34293 this.setOwnerTree(null, destroy);
34294 this.parentNode = this.previousSibling = this.nextSibling = null;
34296 this.firstChild = this.lastChild = null;
34301 destroy : function( silent){
34303 if(silent === true){
34304 this.purgeListeners();
34306 Ext.each(this.childNodes, function(n){
34309 this.childNodes = null;
34316 insertBefore : function(node, refNode){
34318 return this.appendChild(node);
34321 if(node == refNode){
34325 if(this.fireEvent("beforeinsert", this.ownerTree, this, node, refNode) === false){
34328 var index = this.childNodes.indexOf(refNode);
34329 var oldParent = node.parentNode;
34330 var refIndex = index;
34333 if(oldParent == this && this.childNodes.indexOf(node) < index){
34339 if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index, refNode) === false){
34342 oldParent.removeChild(node);
34344 if(refIndex === 0){
34345 this.setFirstChild(node);
34347 this.childNodes.splice(refIndex, 0, node);
34348 node.parentNode = this;
34349 var ps = this.childNodes[refIndex-1];
34351 node.previousSibling = ps;
34352 ps.nextSibling = node;
34354 node.previousSibling = null;
34356 node.nextSibling = refNode;
34357 refNode.previousSibling = node;
34358 node.setOwnerTree(this.getOwnerTree());
34359 this.fireEvent("insert", this.ownerTree, this, node, refNode);
34361 node.fireEvent("move", this.ownerTree, node, oldParent, this, refIndex, refNode);
34367 remove : function(destroy){
34368 if (this.parentNode) {
34369 this.parentNode.removeChild(this, destroy);
34375 removeAll : function(destroy){
34376 var cn = this.childNodes,
34378 while((n = cn[0])){
34379 this.removeChild(n, destroy);
34385 item : function(index){
34386 return this.childNodes[index];
34390 replaceChild : function(newChild, oldChild){
34391 var s = oldChild ? oldChild.nextSibling : null;
34392 this.removeChild(oldChild);
34393 this.insertBefore(newChild, s);
34398 indexOf : function(child){
34399 return this.childNodes.indexOf(child);
34403 getOwnerTree : function(){
34405 if(!this.ownerTree){
34409 this.ownerTree = p.ownerTree;
34415 return this.ownerTree;
34419 getDepth : function(){
34422 while(p.parentNode){
34430 setOwnerTree : function(tree, destroy){
34432 if(tree != this.ownerTree){
34433 if(this.ownerTree){
34434 this.ownerTree.unregisterNode(this);
34436 this.ownerTree = tree;
34438 if(destroy !== true){
34439 Ext.each(this.childNodes, function(n){
34440 n.setOwnerTree(tree);
34444 tree.registerNode(this);
34450 setId: function(id){
34451 if(id !== this.id){
34452 var t = this.ownerTree;
34454 t.unregisterNode(this);
34456 this.id = this.attributes.id = id;
34458 t.registerNode(this);
34460 this.onIdChange(id);
34465 onIdChange: Ext.emptyFn,
34468 getPath : function(attr){
34469 attr = attr || "id";
34470 var p = this.parentNode;
34471 var b = [this.attributes[attr]];
34473 b.unshift(p.attributes[attr]);
34476 var sep = this.getOwnerTree().pathSeparator;
34477 return sep + b.join(sep);
34481 bubble : function(fn, scope, args){
34484 if(fn.apply(scope || p, args || [p]) === false){
34492 cascade : function(fn, scope, args){
34493 if(fn.apply(scope || this, args || [this]) !== false){
34494 var cs = this.childNodes;
34495 for(var i = 0, len = cs.length; i < len; i++) {
34496 cs[i].cascade(fn, scope, args);
34502 eachChild : function(fn, scope, args){
34503 var cs = this.childNodes;
34504 for(var i = 0, len = cs.length; i < len; i++) {
34505 if(fn.apply(scope || cs[i], args || [cs[i]]) === false){
34512 findChild : function(attribute, value, deep){
34513 return this.findChildBy(function(){
34514 return this.attributes[attribute] == value;
34519 findChildBy : function(fn, scope, deep){
34520 var cs = this.childNodes,
34525 for(; i < len; i++){
34527 if(fn.call(scope || n, n) === true){
34530 res = n.findChildBy(fn, scope, deep);
34541 sort : function(fn, scope){
34542 var cs = this.childNodes;
34543 var len = cs.length;
34545 var sortFn = scope ? function(){fn.apply(scope, arguments);} : fn;
34547 for(var i = 0; i < len; i++){
34549 n.previousSibling = cs[i-1];
34550 n.nextSibling = cs[i+1];
34552 this.setFirstChild(n);
34555 this.setLastChild(n);
34562 contains : function(node){
34563 return node.isAncestor(this);
34567 isAncestor : function(node){
34568 var p = this.parentNode;
34578 toString : function(){
34579 return "[Node"+(this.id?" "+this.id:"")+"]";
34582 Ext.tree.TreeNode = Ext.extend(Ext.data.Node, {
34584 constructor : function(attributes){
34585 attributes = attributes || {};
34586 if(Ext.isString(attributes)){
34587 attributes = {text: attributes};
34589 this.childrenRendered = false;
34590 this.rendered = false;
34591 Ext.tree.TreeNode.superclass.constructor.call(this, attributes);
34592 this.expanded = attributes.expanded === true;
34593 this.isTarget = attributes.isTarget !== false;
34594 this.draggable = attributes.draggable !== false && attributes.allowDrag !== false;
34595 this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false;
34598 this.text = attributes.text;
34600 this.disabled = attributes.disabled === true;
34602 this.hidden = attributes.hidden === true;
34630 'beforechildrenrendered'
34633 var uiClass = this.attributes.uiProvider || this.defaultUI || Ext.tree.TreeNodeUI;
34636 this.ui = new uiClass(this);
34639 preventHScroll : true,
34641 isExpanded : function(){
34642 return this.expanded;
34646 getUI : function(){
34650 getLoader : function(){
34652 return this.loader || ((owner = this.getOwnerTree()) && owner.loader ? owner.loader : (this.loader = new Ext.tree.TreeLoader()));
34656 setFirstChild : function(node){
34657 var of = this.firstChild;
34658 Ext.tree.TreeNode.superclass.setFirstChild.call(this, node);
34659 if(this.childrenRendered && of && node != of){
34660 of.renderIndent(true, true);
34663 this.renderIndent(true, true);
34668 setLastChild : function(node){
34669 var ol = this.lastChild;
34670 Ext.tree.TreeNode.superclass.setLastChild.call(this, node);
34671 if(this.childrenRendered && ol && node != ol){
34672 ol.renderIndent(true, true);
34675 this.renderIndent(true, true);
34681 appendChild : function(n){
34682 if(!n.render && !Ext.isArray(n)){
34683 n = this.getLoader().createNode(n);
34685 var node = Ext.tree.TreeNode.superclass.appendChild.call(this, n);
34686 if(node && this.childrenRendered){
34689 this.ui.updateExpandIcon();
34694 removeChild : function(node, destroy){
34695 this.ownerTree.getSelectionModel().unselect(node);
34696 Ext.tree.TreeNode.superclass.removeChild.apply(this, arguments);
34699 var rendered = node.ui.rendered;
34704 if(rendered && this.childNodes.length < 1){
34705 this.collapse(false, false);
34707 this.ui.updateExpandIcon();
34709 if(!this.firstChild && !this.isHiddenRoot()){
34710 this.childrenRendered = false;
34717 insertBefore : function(node, refNode){
34719 node = this.getLoader().createNode(node);
34721 var newNode = Ext.tree.TreeNode.superclass.insertBefore.call(this, node, refNode);
34722 if(newNode && refNode && this.childrenRendered){
34725 this.ui.updateExpandIcon();
34730 setText : function(text){
34731 var oldText = this.text;
34732 this.text = this.attributes.text = text;
34734 this.ui.onTextChange(this, text, oldText);
34736 this.fireEvent('textchange', this, text, oldText);
34740 setIconCls : function(cls){
34741 var old = this.attributes.iconCls;
34742 this.attributes.iconCls = cls;
34744 this.ui.onIconClsChange(this, cls, old);
34749 setTooltip : function(tip, title){
34750 this.attributes.qtip = tip;
34751 this.attributes.qtipTitle = title;
34753 this.ui.onTipChange(this, tip, title);
34758 setIcon : function(icon){
34759 this.attributes.icon = icon;
34761 this.ui.onIconChange(this, icon);
34766 setHref : function(href, target){
34767 this.attributes.href = href;
34768 this.attributes.hrefTarget = target;
34770 this.ui.onHrefChange(this, href, target);
34775 setCls : function(cls){
34776 var old = this.attributes.cls;
34777 this.attributes.cls = cls;
34779 this.ui.onClsChange(this, cls, old);
34784 select : function(){
34785 var t = this.getOwnerTree();
34787 t.getSelectionModel().select(this);
34792 unselect : function(silent){
34793 var t = this.getOwnerTree();
34795 t.getSelectionModel().unselect(this, silent);
34800 isSelected : function(){
34801 var t = this.getOwnerTree();
34802 return t ? t.getSelectionModel().isSelected(this) : false;
34806 expand : function(deep, anim, callback, scope){
34807 if(!this.expanded){
34808 if(this.fireEvent('beforeexpand', this, deep, anim) === false){
34811 if(!this.childrenRendered){
34812 this.renderChildren();
34814 this.expanded = true;
34815 if(!this.isHiddenRoot() && (this.getOwnerTree().animate && anim !== false) || anim){
34816 this.ui.animExpand(function(){
34817 this.fireEvent('expand', this);
34818 this.runCallback(callback, scope || this, [this]);
34820 this.expandChildNodes(true, true);
34822 }.createDelegate(this));
34826 this.fireEvent('expand', this);
34827 this.runCallback(callback, scope || this, [this]);
34830 this.runCallback(callback, scope || this, [this]);
34833 this.expandChildNodes(true);
34837 runCallback : function(cb, scope, args){
34838 if(Ext.isFunction(cb)){
34839 cb.apply(scope, args);
34843 isHiddenRoot : function(){
34844 return this.isRoot && !this.getOwnerTree().rootVisible;
34848 collapse : function(deep, anim, callback, scope){
34849 if(this.expanded && !this.isHiddenRoot()){
34850 if(this.fireEvent('beforecollapse', this, deep, anim) === false){
34853 this.expanded = false;
34854 if((this.getOwnerTree().animate && anim !== false) || anim){
34855 this.ui.animCollapse(function(){
34856 this.fireEvent('collapse', this);
34857 this.runCallback(callback, scope || this, [this]);
34859 this.collapseChildNodes(true);
34861 }.createDelegate(this));
34864 this.ui.collapse();
34865 this.fireEvent('collapse', this);
34866 this.runCallback(callback, scope || this, [this]);
34868 }else if(!this.expanded){
34869 this.runCallback(callback, scope || this, [this]);
34872 var cs = this.childNodes;
34873 for(var i = 0, len = cs.length; i < len; i++) {
34874 cs[i].collapse(true, false);
34880 delayedExpand : function(delay){
34881 if(!this.expandProcId){
34882 this.expandProcId = this.expand.defer(delay, this);
34887 cancelExpand : function(){
34888 if(this.expandProcId){
34889 clearTimeout(this.expandProcId);
34891 this.expandProcId = false;
34895 toggle : function(){
34904 ensureVisible : function(callback, scope){
34905 var tree = this.getOwnerTree();
34906 tree.expandPath(this.parentNode ? this.parentNode.getPath() : this.getPath(), false, function(){
34907 var node = tree.getNodeById(this.id);
34908 tree.getTreeEl().scrollChildIntoView(node.ui.anchor);
34909 this.runCallback(callback, scope || this, [this]);
34910 }.createDelegate(this));
34914 expandChildNodes : function(deep, anim) {
34915 var cs = this.childNodes,
34918 for (i = 0; i < len; i++) {
34919 cs[i].expand(deep, anim);
34924 collapseChildNodes : function(deep){
34925 var cs = this.childNodes;
34926 for(var i = 0, len = cs.length; i < len; i++) {
34927 cs[i].collapse(deep);
34932 disable : function(){
34933 this.disabled = true;
34935 if(this.rendered && this.ui.onDisableChange){
34936 this.ui.onDisableChange(this, true);
34938 this.fireEvent('disabledchange', this, true);
34942 enable : function(){
34943 this.disabled = false;
34944 if(this.rendered && this.ui.onDisableChange){
34945 this.ui.onDisableChange(this, false);
34947 this.fireEvent('disabledchange', this, false);
34951 renderChildren : function(suppressEvent){
34952 if(suppressEvent !== false){
34953 this.fireEvent('beforechildrenrendered', this);
34955 var cs = this.childNodes;
34956 for(var i = 0, len = cs.length; i < len; i++){
34957 cs[i].render(true);
34959 this.childrenRendered = true;
34963 sort : function(fn, scope){
34964 Ext.tree.TreeNode.superclass.sort.apply(this, arguments);
34965 if(this.childrenRendered){
34966 var cs = this.childNodes;
34967 for(var i = 0, len = cs.length; i < len; i++){
34968 cs[i].render(true);
34974 render : function(bulkRender){
34975 this.ui.render(bulkRender);
34976 if(!this.rendered){
34978 this.getOwnerTree().registerNode(this);
34979 this.rendered = true;
34981 this.expanded = false;
34982 this.expand(false, false);
34988 renderIndent : function(deep, refresh){
34990 this.ui.childIndent = null;
34992 this.ui.renderIndent();
34993 if(deep === true && this.childrenRendered){
34994 var cs = this.childNodes;
34995 for(var i = 0, len = cs.length; i < len; i++){
34996 cs[i].renderIndent(true, refresh);
35001 beginUpdate : function(){
35002 this.childrenRendered = false;
35005 endUpdate : function(){
35006 if(this.expanded && this.rendered){
35007 this.renderChildren();
35012 destroy : function(silent){
35013 if(silent === true){
35014 this.unselect(true);
35016 Ext.tree.TreeNode.superclass.destroy.call(this, silent);
35017 Ext.destroy(this.ui, this.loader);
35018 this.ui = this.loader = null;
35022 onIdChange : function(id){
35023 this.ui.onIdChange(id);
35027 Ext.tree.TreePanel.nodeTypes.node = Ext.tree.TreeNode;
35028 Ext.tree.AsyncTreeNode = function(config){
35029 this.loaded = config && config.loaded === true;
35030 this.loading = false;
35031 Ext.tree.AsyncTreeNode.superclass.constructor.apply(this, arguments);
35033 this.addEvents('beforeload', 'load');
35037 Ext.extend(Ext.tree.AsyncTreeNode, Ext.tree.TreeNode, {
35038 expand : function(deep, anim, callback, scope){
35041 var f = function(){
35043 clearInterval(timer);
35044 this.expand(deep, anim, callback, scope);
35046 }.createDelegate(this);
35047 timer = setInterval(f, 200);
35051 if(this.fireEvent("beforeload", this) === false){
35054 this.loading = true;
35055 this.ui.beforeLoad(this);
35056 var loader = this.loader || this.attributes.loader || this.getOwnerTree().getLoader();
35058 loader.load(this, this.loadComplete.createDelegate(this, [deep, anim, callback, scope]), this);
35062 Ext.tree.AsyncTreeNode.superclass.expand.call(this, deep, anim, callback, scope);
35066 isLoading : function(){
35067 return this.loading;
35070 loadComplete : function(deep, anim, callback, scope){
35071 this.loading = false;
35072 this.loaded = true;
35073 this.ui.afterLoad(this);
35074 this.fireEvent("load", this);
35075 this.expand(deep, anim, callback, scope);
35079 isLoaded : function(){
35080 return this.loaded;
35083 hasChildNodes : function(){
35084 if(!this.isLeaf() && !this.loaded){
35087 return Ext.tree.AsyncTreeNode.superclass.hasChildNodes.call(this);
35092 reload : function(callback, scope){
35093 this.collapse(false, false);
35094 while(this.firstChild){
35095 this.removeChild(this.firstChild).destroy();
35097 this.childrenRendered = false;
35098 this.loaded = false;
35099 if(this.isHiddenRoot()){
35100 this.expanded = false;
35102 this.expand(false, false, callback, scope);
35106 Ext.tree.TreePanel.nodeTypes.async = Ext.tree.AsyncTreeNode;
35107 Ext.tree.TreeNodeUI = Ext.extend(Object, {
35109 constructor : function(node){
35115 ecc: 'x-tree-ec-icon x-tree-elbow',
35116 emptyIcon: Ext.BLANK_IMAGE_URL
35121 removeChild : function(node){
35123 this.ctNode.removeChild(node.ui.getEl());
35128 beforeLoad : function(){
35129 this.addClass("x-tree-node-loading");
35133 afterLoad : function(){
35134 this.removeClass("x-tree-node-loading");
35138 onTextChange : function(node, text, oldText){
35140 this.textNode.innerHTML = text;
35145 onIconClsChange : function(node, cls, oldCls){
35147 Ext.fly(this.iconNode).replaceClass(oldCls, cls);
35152 onIconChange : function(node, icon){
35155 var empty = Ext.isEmpty(icon);
35156 this.iconNode.src = empty ? this.emptyIcon : icon;
35157 Ext.fly(this.iconNode)[empty ? 'removeClass' : 'addClass']('x-tree-node-inline-icon');
35162 onTipChange : function(node, tip, title){
35164 var hasTitle = Ext.isDefined(title);
35165 if(this.textNode.setAttributeNS){
35166 this.textNode.setAttributeNS("ext", "qtip", tip);
35168 this.textNode.setAttributeNS("ext", "qtitle", title);
35171 this.textNode.setAttribute("ext:qtip", tip);
35173 this.textNode.setAttribute("ext:qtitle", title);
35180 onHrefChange : function(node, href, target){
35182 this.anchor.href = this.getHref(href);
35183 if(Ext.isDefined(target)){
35184 this.anchor.target = target;
35190 onClsChange : function(node, cls, oldCls){
35192 Ext.fly(this.elNode).replaceClass(oldCls, cls);
35197 onDisableChange : function(node, state){
35198 this.disabled = state;
35199 if (this.checkbox) {
35200 this.checkbox.disabled = state;
35202 this[state ? 'addClass' : 'removeClass']('x-tree-node-disabled');
35206 onSelectedChange : function(state){
35209 this.addClass("x-tree-selected");
35212 this.removeClass("x-tree-selected");
35217 onMove : function(tree, node, oldParent, newParent, index, refNode){
35218 this.childIndent = null;
35220 var targetNode = newParent.ui.getContainer();
35222 this.holder = document.createElement("div");
35223 this.holder.appendChild(this.wrap);
35226 var insertBefore = refNode ? refNode.ui.getEl() : null;
35228 targetNode.insertBefore(this.wrap, insertBefore);
35230 targetNode.appendChild(this.wrap);
35232 this.node.renderIndent(true, oldParent != newParent);
35237 addClass : function(cls){
35239 Ext.fly(this.elNode).addClass(cls);
35244 removeClass : function(cls){
35246 Ext.fly(this.elNode).removeClass(cls);
35251 remove : function(){
35253 this.holder = document.createElement("div");
35254 this.holder.appendChild(this.wrap);
35259 fireEvent : function(){
35260 return this.node.fireEvent.apply(this.node, arguments);
35264 initEvents : function(){
35265 this.node.on("move", this.onMove, this);
35267 if(this.node.disabled){
35268 this.onDisableChange(this.node, true);
35270 if(this.node.hidden){
35273 var ot = this.node.getOwnerTree();
35274 var dd = ot.enableDD || ot.enableDrag || ot.enableDrop;
35275 if(dd && (!this.node.isRoot || ot.rootVisible)){
35276 Ext.dd.Registry.register(this.elNode, {
35278 handles: this.getDDHandles(),
35285 getDDHandles : function(){
35286 return [this.iconNode, this.textNode, this.elNode];
35291 this.node.hidden = true;
35293 this.wrap.style.display = "none";
35299 this.node.hidden = false;
35301 this.wrap.style.display = "";
35306 onContextMenu : function(e){
35307 if (this.node.hasListener("contextmenu") || this.node.getOwnerTree().hasListener("contextmenu")) {
35308 e.preventDefault();
35310 this.fireEvent("contextmenu", this.node, e);
35315 onClick : function(e){
35320 if(this.fireEvent("beforeclick", this.node, e) !== false){
35321 var a = e.getTarget('a');
35322 if(!this.disabled && this.node.attributes.href && a){
35323 this.fireEvent("click", this.node, e);
35325 }else if(a && e.ctrlKey){
35328 e.preventDefault();
35333 if(this.node.attributes.singleClickExpand && !this.animating && this.node.isExpandable()){
35334 this.node.toggle();
35337 this.fireEvent("click", this.node, e);
35344 onDblClick : function(e){
35345 e.preventDefault();
35349 if(this.fireEvent("beforedblclick", this.node, e) !== false){
35351 this.toggleCheck();
35353 if(!this.animating && this.node.isExpandable()){
35354 this.node.toggle();
35356 this.fireEvent("dblclick", this.node, e);
35360 onOver : function(e){
35361 this.addClass('x-tree-node-over');
35364 onOut : function(e){
35365 this.removeClass('x-tree-node-over');
35369 onCheckChange : function(){
35370 var checked = this.checkbox.checked;
35372 this.checkbox.defaultChecked = checked;
35373 this.node.attributes.checked = checked;
35374 this.fireEvent('checkchange', this.node, checked);
35378 ecClick : function(e){
35379 if(!this.animating && this.node.isExpandable()){
35380 this.node.toggle();
35385 startDrop : function(){
35386 this.dropping = true;
35390 endDrop : function(){
35391 setTimeout(function(){
35392 this.dropping = false;
35393 }.createDelegate(this), 50);
35397 expand : function(){
35398 this.updateExpandIcon();
35399 this.ctNode.style.display = "";
35403 focus : function(){
35404 if(!this.node.preventHScroll){
35405 try{this.anchor.focus();
35409 var noscroll = this.node.getOwnerTree().getTreeEl().dom;
35410 var l = noscroll.scrollLeft;
35411 this.anchor.focus();
35412 noscroll.scrollLeft = l;
35418 toggleCheck : function(value){
35419 var cb = this.checkbox;
35421 cb.checked = (value === undefined ? !cb.checked : value);
35422 this.onCheckChange();
35429 this.anchor.blur();
35434 animExpand : function(callback){
35435 var ct = Ext.get(this.ctNode);
35437 if(!this.node.isExpandable()){
35438 this.updateExpandIcon();
35439 this.ctNode.style.display = "";
35440 Ext.callback(callback);
35443 this.animating = true;
35444 this.updateExpandIcon();
35447 callback : function(){
35448 this.animating = false;
35449 Ext.callback(callback);
35452 duration: this.node.ownerTree.duration || .25
35457 highlight : function(){
35458 var tree = this.node.getOwnerTree();
35459 Ext.fly(this.wrap).highlight(
35460 tree.hlColor || "C3DAF9",
35461 {endColor: tree.hlBaseColor}
35466 collapse : function(){
35467 this.updateExpandIcon();
35468 this.ctNode.style.display = "none";
35472 animCollapse : function(callback){
35473 var ct = Ext.get(this.ctNode);
35474 ct.enableDisplayMode('block');
35477 this.animating = true;
35478 this.updateExpandIcon();
35481 callback : function(){
35482 this.animating = false;
35483 Ext.callback(callback);
35486 duration: this.node.ownerTree.duration || .25
35491 getContainer : function(){
35492 return this.ctNode;
35496 getEl : function(){
35501 appendDDGhost : function(ghostNode){
35502 ghostNode.appendChild(this.elNode.cloneNode(true));
35506 getDDRepairXY : function(){
35507 return Ext.lib.Dom.getXY(this.iconNode);
35511 onRender : function(){
35516 render : function(bulkRender){
35517 var n = this.node, a = n.attributes;
35518 var targetNode = n.parentNode ?
35519 n.parentNode.ui.getContainer() : n.ownerTree.innerCt.dom;
35521 if(!this.rendered){
35522 this.rendered = true;
35524 this.renderElements(n, a, targetNode, bulkRender);
35527 this.onTipChange(n, a.qtip, a.qtipTitle);
35528 }else if(a.qtipCfg){
35529 a.qtipCfg.target = Ext.id(this.textNode);
35530 Ext.QuickTips.register(a.qtipCfg);
35533 if(!this.node.expanded){
35534 this.updateExpandIcon(true);
35537 if(bulkRender === true) {
35538 targetNode.appendChild(this.wrap);
35544 renderElements : function(n, a, targetNode, bulkRender){
35546 this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
35548 var cb = Ext.isBoolean(a.checked),
35550 href = this.getHref(a.href),
35551 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">',
35552 '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
35553 '<img alt="" src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
35554 '<img alt="" src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />',
35555 cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
35556 '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
35557 a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span unselectable="on">',n.text,"</span></a></div>",
35558 '<ul class="x-tree-node-ct" style="display:none;"></ul>',
35561 if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){
35562 this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
35564 this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
35567 this.elNode = this.wrap.childNodes[0];
35568 this.ctNode = this.wrap.childNodes[1];
35569 var cs = this.elNode.childNodes;
35570 this.indentNode = cs[0];
35571 this.ecNode = cs[1];
35572 this.iconNode = cs[2];
35575 this.checkbox = cs[3];
35577 this.checkbox.defaultChecked = this.checkbox.checked;
35580 this.anchor = cs[index];
35581 this.textNode = cs[index].firstChild;
35585 getHref : function(href){
35586 return Ext.isEmpty(href) ? (Ext.isGecko ? '' : '#') : href;
35590 getAnchor : function(){
35591 return this.anchor;
35595 getTextEl : function(){
35596 return this.textNode;
35600 getIconEl : function(){
35601 return this.iconNode;
35605 isChecked : function(){
35606 return this.checkbox ? this.checkbox.checked : false;
35610 updateExpandIcon : function(){
35615 cls = n.isLast() ? "x-tree-elbow-end" : "x-tree-elbow",
35616 hasChild = n.hasChildNodes();
35617 if(hasChild || n.attributes.expandable){
35620 c1 = "x-tree-node-collapsed";
35621 c2 = "x-tree-node-expanded";
35624 c1 = "x-tree-node-expanded";
35625 c2 = "x-tree-node-collapsed";
35628 this.removeClass("x-tree-node-leaf");
35629 this.wasLeaf = false;
35631 if(this.c1 != c1 || this.c2 != c2){
35632 Ext.fly(this.elNode).replaceClass(c1, c2);
35633 this.c1 = c1; this.c2 = c2;
35637 Ext.fly(this.elNode).replaceClass("x-tree-node-expanded", "x-tree-node-collapsed");
35640 this.wasLeaf = true;
35643 var ecc = "x-tree-ec-icon "+cls;
35644 if(this.ecc != ecc){
35645 this.ecNode.className = ecc;
35652 onIdChange: function(id){
35654 this.elNode.setAttribute('ext:tree-node-id', id);
35659 getChildIndent : function(){
35660 if(!this.childIndent){
35664 if(!p.isRoot || (p.isRoot && p.ownerTree.rootVisible)){
35666 buf.unshift('<img alt="" src="'+this.emptyIcon+'" class="x-tree-elbow-line" />');
35668 buf.unshift('<img alt="" src="'+this.emptyIcon+'" class="x-tree-icon" />');
35673 this.childIndent = buf.join("");
35675 return this.childIndent;
35679 renderIndent : function(){
35682 p = this.node.parentNode;
35684 indent = p.ui.getChildIndent();
35686 if(this.indentMarkup != indent){
35687 this.indentNode.innerHTML = indent;
35688 this.indentMarkup = indent;
35690 this.updateExpandIcon();
35694 destroy : function(){
35696 Ext.dd.Registry.unregister(this.elNode.id);
35699 Ext.each(['textnode', 'anchor', 'checkbox', 'indentNode', 'ecNode', 'iconNode', 'elNode', 'ctNode', 'wrap', 'holder'], function(el){
35701 Ext.fly(this[el]).remove();
35710 Ext.tree.RootTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
35712 render : function(){
35713 if(!this.rendered){
35714 var targetNode = this.node.ownerTree.innerCt.dom;
35715 this.node.expanded = true;
35716 targetNode.innerHTML = '<div class="x-tree-root-node"></div>';
35717 this.wrap = this.ctNode = targetNode.firstChild;
35720 collapse : Ext.emptyFn,
35721 expand : Ext.emptyFn
35723 Ext.tree.TreeLoader = function(config){
35724 this.baseParams = {};
35725 Ext.apply(this, config);
35735 Ext.tree.TreeLoader.superclass.constructor.call(this);
35736 if(Ext.isString(this.paramOrder)){
35737 this.paramOrder = this.paramOrder.split(/[\s,|]/);
35741 Ext.extend(Ext.tree.TreeLoader, Ext.util.Observable, {
35752 clearOnLoad : true,
35755 paramOrder: undefined,
35758 paramsAsHash: false,
35761 nodeParameter: 'node',
35764 directFn : undefined,
35767 load : function(node, callback, scope){
35768 if(this.clearOnLoad){
35769 while(node.firstChild){
35770 node.removeChild(node.firstChild);
35773 if(this.doPreload(node)){
35774 this.runCallback(callback, scope || node, [node]);
35775 }else if(this.directFn || this.dataUrl || this.url){
35776 this.requestData(node, callback, scope || node);
35780 doPreload : function(node){
35781 if(node.attributes.children){
35782 if(node.childNodes.length < 1){
35783 var cs = node.attributes.children;
35784 node.beginUpdate();
35785 for(var i = 0, len = cs.length; i < len; i++){
35786 var cn = node.appendChild(this.createNode(cs[i]));
35787 if(this.preloadChildren){
35788 this.doPreload(cn);
35798 getParams: function(node){
35799 var bp = Ext.apply({}, this.baseParams),
35800 np = this.nodeParameter,
35801 po = this.paramOrder;
35803 np && (bp[ np ] = node.id);
35806 var buf = [node.id];
35809 if(np && po.indexOf(np) > -1){
35813 for(var i = 0, len = po.length; i < len; i++){
35814 buf.push(bp[ po[i] ]);
35816 }else if(this.paramsAsHash){
35825 requestData : function(node, callback, scope){
35826 if(this.fireEvent("beforeload", this, node, callback) !== false){
35828 var args = this.getParams(node);
35829 args.push(this.processDirectResponse.createDelegate(this, [{callback: callback, node: node, scope: scope}], true));
35830 this.directFn.apply(window, args);
35832 this.transId = Ext.Ajax.request({
35833 method:this.requestMethod,
35834 url: this.dataUrl||this.url,
35835 success: this.handleResponse,
35836 failure: this.handleFailure,
35838 argument: {callback: callback, node: node, scope: scope},
35839 params: this.getParams(node)
35845 this.runCallback(callback, scope || node, []);
35849 processDirectResponse: function(result, response, args){
35850 if(response.status){
35851 this.handleResponse({
35852 responseData: Ext.isArray(result) ? result : null,
35853 responseText: result,
35857 this.handleFailure({
35864 runCallback: function(cb, scope, args){
35865 if(Ext.isFunction(cb)){
35866 cb.apply(scope, args);
35870 isLoading : function(){
35871 return !!this.transId;
35874 abort : function(){
35875 if(this.isLoading()){
35876 Ext.Ajax.abort(this.transId);
35881 createNode : function(attr){
35883 if(this.baseAttrs){
35884 Ext.applyIf(attr, this.baseAttrs);
35886 if(this.applyLoader !== false && !attr.loader){
35887 attr.loader = this;
35889 if(Ext.isString(attr.uiProvider)){
35890 attr.uiProvider = this.uiProviders[attr.uiProvider] || eval(attr.uiProvider);
35893 return new Ext.tree.TreePanel.nodeTypes[attr.nodeType](attr);
35896 new Ext.tree.TreeNode(attr) :
35897 new Ext.tree.AsyncTreeNode(attr);
35901 processResponse : function(response, node, callback, scope){
35902 var json = response.responseText;
35904 var o = response.responseData || Ext.decode(json);
35905 node.beginUpdate();
35906 for(var i = 0, len = o.length; i < len; i++){
35907 var n = this.createNode(o[i]);
35909 node.appendChild(n);
35913 this.runCallback(callback, scope || node, [node]);
35915 this.handleFailure(response);
35919 handleResponse : function(response){
35920 this.transId = false;
35921 var a = response.argument;
35922 this.processResponse(response, a.node, a.callback, a.scope);
35923 this.fireEvent("load", this, a.node, response);
35926 handleFailure : function(response){
35927 this.transId = false;
35928 var a = response.argument;
35929 this.fireEvent("loadexception", this, a.node, response);
35930 this.runCallback(a.callback, a.scope || a.node, [a.node]);
35933 destroy : function(){
35935 this.purgeListeners();
35938 Ext.tree.TreeFilter = function(tree, config){
35940 this.filtered = {};
35941 Ext.apply(this, config);
35944 Ext.tree.TreeFilter.prototype = {
35951 filter : function(value, attr, startNode){
35952 attr = attr || "text";
35954 if(typeof value == "string"){
35955 var vlen = value.length;
35957 if(vlen == 0 && this.clearBlank){
35961 value = value.toLowerCase();
35963 return n.attributes[attr].substr(0, vlen).toLowerCase() == value;
35965 }else if(value.exec){
35967 return value.test(n.attributes[attr]);
35970 throw 'Illegal filter type, must be string or regex';
35972 this.filterBy(f, null, startNode);
35976 filterBy : function(fn, scope, startNode){
35977 startNode = startNode || this.tree.root;
35978 if(this.autoClear){
35981 var af = this.filtered, rv = this.reverse;
35982 var f = function(n){
35983 if(n == startNode){
35989 var m = fn.call(scope || n, n);
35997 startNode.cascade(f);
36000 if(typeof id != "function"){
36002 if(n && n.parentNode){
36003 n.parentNode.removeChild(n);
36011 clear : function(){
36013 var af = this.filtered;
36015 if(typeof id != "function"){
36022 this.filtered = {};
36026 Ext.tree.TreeSorter = Ext.extend(Object, {
36028 constructor: function(tree, config){
36036 Ext.apply(this, config);
36039 beforechildrenrendered: this.doSort,
36040 append: this.updateSort,
36041 insert: this.updateSort,
36042 textchange: this.updateSortParent
36045 var desc = this.dir && this.dir.toLowerCase() == 'desc',
36046 prop = this.property || 'text';
36047 sortType = this.sortType;
36048 folderSort = this.folderSort;
36049 caseSensitive = this.caseSensitive === true;
36050 leafAttr = this.leafAttr || 'leaf';
36052 if(Ext.isString(sortType)){
36053 sortType = Ext.data.SortTypes[sortType];
36055 this.sortFn = function(n1, n2){
36056 var attr1 = n1.attributes,
36057 attr2 = n2.attributes;
36060 if(attr1[leafAttr] && !attr2[leafAttr]){
36063 if(!attr1[leafAttr] && attr2[leafAttr]){
36067 var prop1 = attr1[prop],
36068 prop2 = attr2[prop],
36069 v1 = sortType ? sortType(prop1) : (caseSensitive ? prop1 : prop1.toUpperCase());
36070 v2 = sortType ? sortType(prop2) : (caseSensitive ? prop2 : prop2.toUpperCase());
36073 return desc ? 1 : -1;
36075 return desc ? -1 : 1;
36081 doSort : function(node){
36082 node.sort(this.sortFn);
36085 updateSort : function(tree, node){
36086 if(node.childrenRendered){
36087 this.doSort.defer(1, this, [node]);
36091 updateSortParent : function(node){
36092 var p = node.parentNode;
36093 if(p && p.childrenRendered){
36094 this.doSort.defer(1, this, [p]);
36098 if(Ext.dd.DropZone){
36100 Ext.tree.TreeDropZone = function(tree, config){
36102 this.allowParentInsert = config.allowParentInsert || false;
36104 this.allowContainerDrop = config.allowContainerDrop || false;
36106 this.appendOnly = config.appendOnly || false;
36108 Ext.tree.TreeDropZone.superclass.constructor.call(this, tree.getTreeEl(), config);
36112 this.dragOverData = {};
36114 this.lastInsertClass = "x-tree-no-status";
36117 Ext.extend(Ext.tree.TreeDropZone, Ext.dd.DropZone, {
36119 ddGroup : "TreeDD",
36122 expandDelay : 1000,
36125 expandNode : function(node){
36126 if(node.hasChildNodes() && !node.isExpanded()){
36127 node.expand(false, null, this.triggerCacheRefresh.createDelegate(this));
36132 queueExpand : function(node){
36133 this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]);
36137 cancelExpand : function(){
36138 if(this.expandProcId){
36139 clearTimeout(this.expandProcId);
36140 this.expandProcId = false;
36145 isValidDropPoint : function(n, pt, dd, e, data){
36146 if(!n || !data){ return false; }
36147 var targetNode = n.node;
36148 var dropNode = data.node;
36150 if(!(targetNode && targetNode.isTarget && pt)){
36153 if(pt == "append" && targetNode.allowChildren === false){
36156 if((pt == "above" || pt == "below") && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){
36159 if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){
36163 var overEvent = this.dragOverData;
36164 overEvent.tree = this.tree;
36165 overEvent.target = targetNode;
36166 overEvent.data = data;
36167 overEvent.point = pt;
36168 overEvent.source = dd;
36169 overEvent.rawEvent = e;
36170 overEvent.dropNode = dropNode;
36171 overEvent.cancel = false;
36172 var result = this.tree.fireEvent("nodedragover", overEvent);
36173 return overEvent.cancel === false && result !== false;
36177 getDropPoint : function(e, n, dd){
36180 return tn.allowChildren !== false ? "append" : false;
36182 var dragEl = n.ddel;
36183 var t = Ext.lib.Dom.getY(dragEl), b = t + dragEl.offsetHeight;
36184 var y = Ext.lib.Event.getPageY(e);
36185 var noAppend = tn.allowChildren === false || tn.isLeaf();
36186 if(this.appendOnly || tn.parentNode.allowChildren === false){
36187 return noAppend ? false : "append";
36189 var noBelow = false;
36190 if(!this.allowParentInsert){
36191 noBelow = tn.hasChildNodes() && tn.isExpanded();
36193 var q = (b - t) / (noAppend ? 2 : 3);
36194 if(y >= t && y < (t + q)){
36196 }else if(!noBelow && (noAppend || y >= b-q && y <= b)){
36204 onNodeEnter : function(n, dd, e, data){
36205 this.cancelExpand();
36208 onContainerOver : function(dd, e, data) {
36209 if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) {
36210 return this.dropAllowed;
36212 return this.dropNotAllowed;
36216 onNodeOver : function(n, dd, e, data){
36217 var pt = this.getDropPoint(e, n, dd);
36221 if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){
36222 this.queueExpand(node);
36223 }else if(pt != "append"){
36224 this.cancelExpand();
36228 var returnCls = this.dropNotAllowed;
36229 if(this.isValidDropPoint(n, pt, dd, e, data)){
36234 returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between";
36235 cls = "x-tree-drag-insert-above";
36236 }else if(pt == "below"){
36237 returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between";
36238 cls = "x-tree-drag-insert-below";
36240 returnCls = "x-tree-drop-ok-append";
36241 cls = "x-tree-drag-append";
36243 if(this.lastInsertClass != cls){
36244 Ext.fly(el).replaceClass(this.lastInsertClass, cls);
36245 this.lastInsertClass = cls;
36253 onNodeOut : function(n, dd, e, data){
36254 this.cancelExpand();
36255 this.removeDropIndicators(n);
36259 onNodeDrop : function(n, dd, e, data){
36260 var point = this.getDropPoint(e, n, dd);
36261 var targetNode = n.node;
36262 targetNode.ui.startDrop();
36263 if(!this.isValidDropPoint(n, point, dd, e, data)){
36264 targetNode.ui.endDrop();
36268 var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
36269 return this.processDrop(targetNode, data, point, dd, e, dropNode);
36272 onContainerDrop : function(dd, e, data){
36273 if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) {
36274 var targetNode = this.tree.getRootNode();
36275 targetNode.ui.startDrop();
36276 var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, 'append', e) : null);
36277 return this.processDrop(targetNode, data, 'append', dd, e, dropNode);
36283 processDrop: function(target, data, point, dd, e, dropNode){
36291 dropNode: dropNode,
36295 var retval = this.tree.fireEvent("beforenodedrop", dropEvent);
36296 if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
36297 target.ui.endDrop();
36298 return dropEvent.dropStatus;
36301 target = dropEvent.target;
36302 if(point == 'append' && !target.isExpanded()){
36303 target.expand(false, null, function(){
36304 this.completeDrop(dropEvent);
36305 }.createDelegate(this));
36307 this.completeDrop(dropEvent);
36313 completeDrop : function(de){
36314 var ns = de.dropNode, p = de.point, t = de.target;
36315 if(!Ext.isArray(ns)){
36319 for(var i = 0, len = ns.length; i < len; i++){
36322 t.parentNode.insertBefore(n, t);
36323 }else if(p == "below"){
36324 t.parentNode.insertBefore(n, t.nextSibling);
36330 if(Ext.enableFx && this.tree.hlDrop){
36334 this.tree.fireEvent("nodedrop", de);
36338 afterNodeMoved : function(dd, data, e, targetNode, dropNode){
36339 if(Ext.enableFx && this.tree.hlDrop){
36340 dropNode.ui.focus();
36341 dropNode.ui.highlight();
36343 this.tree.fireEvent("nodedrop", this.tree, targetNode, data, dd, e);
36347 getTree : function(){
36352 removeDropIndicators : function(n){
36355 Ext.fly(el).removeClass([
36356 "x-tree-drag-insert-above",
36357 "x-tree-drag-insert-below",
36358 "x-tree-drag-append"]);
36359 this.lastInsertClass = "_noclass";
36364 beforeDragDrop : function(target, e, id){
36365 this.cancelExpand();
36370 afterRepair : function(data){
36371 if(data && Ext.enableFx){
36372 data.node.ui.highlight();
36379 if(Ext.dd.DragZone){
36380 Ext.tree.TreeDragZone = function(tree, config){
36381 Ext.tree.TreeDragZone.superclass.constructor.call(this, tree.innerCt, config);
36386 Ext.extend(Ext.tree.TreeDragZone, Ext.dd.DragZone, {
36388 ddGroup : "TreeDD",
36391 onBeforeDrag : function(data, e){
36393 return n && n.draggable && !n.disabled;
36397 onInitDrag : function(e){
36398 var data = this.dragData;
36399 this.tree.getSelectionModel().select(data.node);
36400 this.tree.eventModel.disable();
36401 this.proxy.update("");
36402 data.node.ui.appendDDGhost(this.proxy.ghost.dom);
36403 this.tree.fireEvent("startdrag", this.tree, data.node, e);
36407 getRepairXY : function(e, data){
36408 return data.node.ui.getDDRepairXY();
36412 onEndDrag : function(data, e){
36413 this.tree.eventModel.enable.defer(100, this.tree.eventModel);
36414 this.tree.fireEvent("enddrag", this.tree, data.node, e);
36418 onValidDrop : function(dd, e, id){
36419 this.tree.fireEvent("dragdrop", this.tree, this.dragData.node, dd, e);
36424 beforeInvalidDrop : function(e, id){
36426 var sm = this.tree.getSelectionModel();
36427 sm.clearSelections();
36428 sm.select(this.dragData.node);
36432 afterRepair : function(){
36433 if (Ext.enableFx && this.tree.hlDrop) {
36434 Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9");
36436 this.dragging = false;
36440 Ext.tree.TreeEditor = function(tree, fc, config){
36442 var field = fc.events ? fc : new Ext.form.TextField(fc);
36444 Ext.tree.TreeEditor.superclass.constructor.call(this, field, config);
36448 if(!tree.rendered){
36449 tree.on('render', this.initEditor, this);
36451 this.initEditor(tree);
36455 Ext.extend(Ext.tree.TreeEditor, Ext.Editor, {
36463 cls: "x-small-editor x-tree-editor",
36473 initEditor : function(tree){
36476 beforeclick: this.beforeNodeClick,
36477 dblclick : this.onNodeDblClick
36482 complete : this.updateNode,
36483 beforestartedit: this.fitToTree,
36484 specialkey : this.onSpecialKey
36487 this.on('startedit', this.bindScroll, this, {delay:10});
36491 fitToTree : function(ed, el){
36492 var td = this.tree.getTreeEl().dom, nd = el.dom;
36493 if(td.scrollLeft > nd.offsetLeft){
36494 td.scrollLeft = nd.offsetLeft;
36498 (td.clientWidth > 20 ? td.clientWidth : td.offsetWidth) - Math.max(0, nd.offsetLeft-td.scrollLeft) - 5);
36499 this.setSize(w, '');
36503 triggerEdit : function(node, defer){
36504 this.completeEdit();
36505 if(node.attributes.editable !== false){
36507 this.editNode = node;
36508 if(this.tree.autoScroll){
36509 Ext.fly(node.ui.getEl()).scrollIntoView(this.tree.body);
36511 var value = node.text || '';
36512 if (!Ext.isGecko && Ext.isEmpty(node.text)){
36513 node.setText(' ');
36515 this.autoEditTimer = this.startEdit.defer(this.editDelay, this, [node.ui.textNode, value]);
36521 bindScroll : function(){
36522 this.tree.getTreeEl().on('scroll', this.cancelEdit, this);
36526 beforeNodeClick : function(node, e){
36527 clearTimeout(this.autoEditTimer);
36528 if(this.tree.getSelectionModel().isSelected(node)){
36530 return this.triggerEdit(node);
36534 onNodeDblClick : function(node, e){
36535 clearTimeout(this.autoEditTimer);
36539 updateNode : function(ed, value){
36540 this.tree.getTreeEl().un('scroll', this.cancelEdit, this);
36541 this.editNode.setText(value);
36545 onHide : function(){
36546 Ext.tree.TreeEditor.superclass.onHide.call(this);
36548 this.editNode.ui.focus.defer(50, this.editNode.ui);
36553 onSpecialKey : function(field, e){
36554 var k = e.getKey();
36558 }else if(k == e.ENTER && !e.hasModifier()){
36560 this.completeEdit();
36564 onDestroy : function(){
36565 clearTimeout(this.autoEditTimer);
36566 Ext.tree.TreeEditor.superclass.onDestroy.call(this);
36567 var tree = this.tree;
36568 tree.un('beforeclick', this.beforeNodeClick, this);
36569 tree.un('dblclick', this.onNodeDblClick, this);
36573 var swfobject = function() {
36575 var UNDEF = "undefined",
36577 SHOCKWAVE_FLASH = "Shockwave Flash",
36578 SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash",
36579 FLASH_MIME_TYPE = "application/x-shockwave-flash",
36580 EXPRESS_INSTALL_ID = "SWFObjectExprInst",
36581 ON_READY_STATE_CHANGE = "onreadystatechange",
36588 domLoadFnArr = [main],
36593 storedAltContentId,
36596 isDomLoaded = false,
36597 isExpressInstallActive = false,
36599 dynamicStylesheetMedia,
36600 autoHideShow = true,
36604 var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF,
36605 u = nav.userAgent.toLowerCase(),
36606 p = nav.platform.toLowerCase(),
36607 windows = p ? (/win/).test(p) : /win/.test(u),
36608 mac = p ? (/mac/).test(p) : /mac/.test(u),
36609 webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false,
36611 playerVersion = [0,0,0],
36613 if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) {
36614 d = nav.plugins[SHOCKWAVE_FLASH].description;
36615 if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) {
36618 d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
36619 playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10);
36620 playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10);
36621 playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0;
36624 else if (typeof win.ActiveXObject != UNDEF) {
36626 var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);
36628 d = a.GetVariable("$version");
36631 d = d.split(" ")[1].split(",");
36632 playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
36638 return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac };
36642 onDomLoad = function() {
36643 if (!ua.w3) { return; }
36644 if ((typeof doc.readyState != UNDEF && doc.readyState == "complete") || (typeof doc.readyState == UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) {
36645 callDomLoadFunctions();
36647 if (!isDomLoaded) {
36648 if (typeof doc.addEventListener != UNDEF) {
36649 doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false);
36651 if (ua.ie && ua.win) {
36652 doc.attachEvent(ON_READY_STATE_CHANGE, function() {
36653 if (doc.readyState == "complete") {
36654 doc.detachEvent(ON_READY_STATE_CHANGE, arguments.callee);
36655 callDomLoadFunctions();
36660 if (isDomLoaded) { return; }
36662 doc.documentElement.doScroll("left");
36665 setTimeout(arguments.callee, 0);
36668 callDomLoadFunctions();
36674 if (isDomLoaded) { return; }
36675 if (!(/loaded|complete/).test(doc.readyState)) {
36676 setTimeout(arguments.callee, 0);
36679 callDomLoadFunctions();
36682 addLoadEvent(callDomLoadFunctions);
36686 function callDomLoadFunctions() {
36687 if (isDomLoaded) { return; }
36689 var t = doc.getElementsByTagName("body")[0].appendChild(createElement("span"));
36690 t.parentNode.removeChild(t);
36692 catch (e) { return; }
36693 isDomLoaded = true;
36694 var dl = domLoadFnArr.length;
36695 for (var i = 0; i < dl; i++) {
36700 function addDomLoadEvent(fn) {
36705 domLoadFnArr[domLoadFnArr.length] = fn;
36710 function addLoadEvent(fn) {
36711 if (typeof win.addEventListener != UNDEF) {
36712 win.addEventListener("load", fn, false);
36714 else if (typeof doc.addEventListener != UNDEF) {
36715 doc.addEventListener("load", fn, false);
36717 else if (typeof win.attachEvent != UNDEF) {
36718 addListener(win, "onload", fn);
36720 else if (typeof win.onload == "function") {
36721 var fnOld = win.onload;
36722 win.onload = function() {
36735 testPlayerVersion();
36743 function testPlayerVersion() {
36744 var b = doc.getElementsByTagName("body")[0];
36745 var o = createElement(OBJECT);
36746 o.setAttribute("type", FLASH_MIME_TYPE);
36747 var t = b.appendChild(o);
36751 if (typeof t.GetVariable != UNDEF) {
36752 var d = t.GetVariable("$version");
36754 d = d.split(" ")[1].split(",");
36755 ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
36758 else if (counter < 10) {
36760 setTimeout(arguments.callee, 10);
36774 function matchVersions() {
36775 var rl = regObjArr.length;
36777 for (var i = 0; i < rl; i++) {
36778 var id = regObjArr[i].id;
36779 var cb = regObjArr[i].callbackFn;
36780 var cbObj = {success:false, id:id};
36781 if (ua.pv[0] > 0) {
36782 var obj = getElementById(id);
36784 if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) {
36785 setVisibility(id, true);
36787 cbObj.success = true;
36788 cbObj.ref = getObjectById(id);
36792 else if (regObjArr[i].expressInstall && canExpressInstall()) {
36794 att.data = regObjArr[i].expressInstall;
36795 att.width = obj.getAttribute("width") || "0";
36796 att.height = obj.getAttribute("height") || "0";
36797 if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); }
36798 if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); }
36801 var p = obj.getElementsByTagName("param");
36803 for (var j = 0; j < pl; j++) {
36804 if (p[j].getAttribute("name").toLowerCase() != "movie") {
36805 par[p[j].getAttribute("name")] = p[j].getAttribute("value");
36808 showExpressInstall(att, par, id, cb);
36811 displayAltContent(obj);
36812 if (cb) { cb(cbObj); }
36817 setVisibility(id, true);
36819 var o = getObjectById(id);
36820 if (o && typeof o.SetVariable != UNDEF) {
36821 cbObj.success = true;
36831 function getObjectById(objectIdStr) {
36833 var o = getElementById(objectIdStr);
36834 if (o && o.nodeName == "OBJECT") {
36835 if (typeof o.SetVariable != UNDEF) {
36839 var n = o.getElementsByTagName(OBJECT)[0];
36849 function canExpressInstall() {
36850 return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312);
36854 function showExpressInstall(att, par, replaceElemIdStr, callbackFn) {
36855 isExpressInstallActive = true;
36856 storedCallbackFn = callbackFn || null;
36857 storedCallbackObj = {success:false, id:replaceElemIdStr};
36858 var obj = getElementById(replaceElemIdStr);
36860 if (obj.nodeName == "OBJECT") {
36861 storedAltContent = abstractAltContent(obj);
36862 storedAltContentId = null;
36865 storedAltContent = obj;
36866 storedAltContentId = replaceElemIdStr;
36868 att.id = EXPRESS_INSTALL_ID;
36869 if (typeof att.width == UNDEF || (!(/%$/).test(att.width) && parseInt(att.width, 10) < 310)) {
36873 if (typeof att.height == UNDEF || (!(/%$/).test(att.height) && parseInt(att.height, 10) < 137)) {
36874 att.height = "137";
36876 doc.title = doc.title.slice(0, 47) + " - Flash Player Installation";
36877 var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn",
36878 fv = "MMredirectURL=" + win.location.toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title;
36879 if (typeof par.flashvars != UNDEF) {
36880 par.flashvars += "&" + fv;
36883 par.flashvars = fv;
36887 if (ua.ie && ua.win && obj.readyState != 4) {
36888 var newObj = createElement("div");
36889 replaceElemIdStr += "SWFObjectNew";
36890 newObj.setAttribute("id", replaceElemIdStr);
36891 obj.parentNode.insertBefore(newObj, obj);
36892 obj.style.display = "none";
36894 if (obj.readyState == 4) {
36895 obj.parentNode.removeChild(obj);
36898 setTimeout(arguments.callee, 10);
36902 createSWF(att, par, replaceElemIdStr);
36907 function displayAltContent(obj) {
36908 if (ua.ie && ua.win && obj.readyState != 4) {
36911 var el = createElement("div");
36912 obj.parentNode.insertBefore(el, obj);
36913 el.parentNode.replaceChild(abstractAltContent(obj), el);
36914 obj.style.display = "none";
36916 if (obj.readyState == 4) {
36917 obj.parentNode.removeChild(obj);
36920 setTimeout(arguments.callee, 10);
36925 obj.parentNode.replaceChild(abstractAltContent(obj), obj);
36929 function abstractAltContent(obj) {
36930 var ac = createElement("div");
36931 if (ua.win && ua.ie) {
36932 ac.innerHTML = obj.innerHTML;
36935 var nestedObj = obj.getElementsByTagName(OBJECT)[0];
36937 var c = nestedObj.childNodes;
36940 for (var i = 0; i < cl; i++) {
36941 if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) {
36942 ac.appendChild(c[i].cloneNode(true));
36952 function createSWF(attObj, parObj, id) {
36953 var r, el = getElementById(id);
36954 if (ua.wk && ua.wk < 312) { return r; }
36956 if (typeof attObj.id == UNDEF) {
36959 if (ua.ie && ua.win) {
36961 for (var i in attObj) {
36962 if (attObj[i] != Object.prototype[i]) {
36963 if (i.toLowerCase() == "data") {
36964 parObj.movie = attObj[i];
36966 else if (i.toLowerCase() == "styleclass") {
36967 att += ' class="' + attObj[i] + '"';
36969 else if (i.toLowerCase() != "classid") {
36970 att += ' ' + i + '="' + attObj[i] + '"';
36975 for (var j in parObj) {
36976 if (parObj[j] != Object.prototype[j]) {
36977 par += '<param name="' + j + '" value="' + parObj[j] + '" />';
36980 el.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + '>' + par + '</object>';
36981 objIdArr[objIdArr.length] = attObj.id;
36982 r = getElementById(attObj.id);
36985 var o = createElement(OBJECT);
36986 o.setAttribute("type", FLASH_MIME_TYPE);
36987 for (var m in attObj) {
36988 if (attObj[m] != Object.prototype[m]) {
36989 if (m.toLowerCase() == "styleclass") {
36990 o.setAttribute("class", attObj[m]);
36992 else if (m.toLowerCase() != "classid") {
36993 o.setAttribute(m, attObj[m]);
36997 for (var n in parObj) {
36998 if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") {
36999 createObjParam(o, n, parObj[n]);
37002 el.parentNode.replaceChild(o, el);
37009 function createObjParam(el, pName, pValue) {
37010 var p = createElement("param");
37011 p.setAttribute("name", pName);
37012 p.setAttribute("value", pValue);
37017 function removeSWF(id) {
37018 var obj = getElementById(id);
37019 if (obj && obj.nodeName == "OBJECT") {
37020 if (ua.ie && ua.win) {
37021 obj.style.display = "none";
37023 if (obj.readyState == 4) {
37024 removeObjectInIE(id);
37027 setTimeout(arguments.callee, 10);
37032 obj.parentNode.removeChild(obj);
37037 function removeObjectInIE(id) {
37038 var obj = getElementById(id);
37040 for (var i in obj) {
37041 if (typeof obj[i] == "function") {
37045 obj.parentNode.removeChild(obj);
37050 function getElementById(id) {
37053 el = doc.getElementById(id);
37059 function createElement(el) {
37060 return doc.createElement(el);
37064 function addListener(target, eventType, fn) {
37065 target.attachEvent(eventType, fn);
37066 listenersArr[listenersArr.length] = [target, eventType, fn];
37070 function hasPlayerVersion(rv) {
37071 var pv = ua.pv, v = rv.split(".");
37072 v[0] = parseInt(v[0], 10);
37073 v[1] = parseInt(v[1], 10) || 0;
37074 v[2] = parseInt(v[2], 10) || 0;
37075 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;
37079 function createCSS(sel, decl, media, newStyle) {
37080 if (ua.ie && ua.mac) { return; }
37081 var h = doc.getElementsByTagName("head")[0];
37082 if (!h) { return; }
37083 var m = (media && typeof media == "string") ? media : "screen";
37085 dynamicStylesheet = null;
37086 dynamicStylesheetMedia = null;
37088 if (!dynamicStylesheet || dynamicStylesheetMedia != m) {
37090 var s = createElement("style");
37091 s.setAttribute("type", "text/css");
37092 s.setAttribute("media", m);
37093 dynamicStylesheet = h.appendChild(s);
37094 if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) {
37095 dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];
37097 dynamicStylesheetMedia = m;
37100 if (ua.ie && ua.win) {
37101 if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) {
37102 dynamicStylesheet.addRule(sel, decl);
37106 if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) {
37107 dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}"));
37112 function setVisibility(id, isVisible) {
37113 if (!autoHideShow) { return; }
37114 var v = isVisible ? "visible" : "hidden";
37115 if (isDomLoaded && getElementById(id)) {
37116 getElementById(id).style.visibility = v;
37119 createCSS("#" + id, "visibility:" + v);
37124 function urlEncodeIfNecessary(s) {
37125 var regex = /[\\\"<>\.;]/;
37126 var hasBadChars = regex.exec(s) != null;
37127 return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s;
37131 var cleanup = function() {
37132 if (ua.ie && ua.win) {
37133 window.attachEvent("onunload", function() {
37135 var ll = listenersArr.length;
37136 for (var i = 0; i < ll; i++) {
37137 listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);
37140 var il = objIdArr.length;
37141 for (var j = 0; j < il; j++) {
37142 removeSWF(objIdArr[j]);
37145 for (var k in ua) {
37149 for (var l in swfobject) {
37150 swfobject[l] = null;
37159 registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) {
37160 if (ua.w3 && objectIdStr && swfVersionStr) {
37162 regObj.id = objectIdStr;
37163 regObj.swfVersion = swfVersionStr;
37164 regObj.expressInstall = xiSwfUrlStr;
37165 regObj.callbackFn = callbackFn;
37166 regObjArr[regObjArr.length] = regObj;
37167 setVisibility(objectIdStr, false);
37169 else if (callbackFn) {
37170 callbackFn({success:false, id:objectIdStr});
37174 getObjectById: function(objectIdStr) {
37176 return getObjectById(objectIdStr);
37180 embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {
37181 var callbackObj = {success:false, id:replaceElemIdStr};
37182 if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) {
37183 setVisibility(replaceElemIdStr, false);
37184 addDomLoadEvent(function() {
37188 if (attObj && typeof attObj === OBJECT) {
37189 for (var i in attObj) {
37190 att[i] = attObj[i];
37193 att.data = swfUrlStr;
37194 att.width = widthStr;
37195 att.height = heightStr;
37197 if (parObj && typeof parObj === OBJECT) {
37198 for (var j in parObj) {
37199 par[j] = parObj[j];
37202 if (flashvarsObj && typeof flashvarsObj === OBJECT) {
37203 for (var k in flashvarsObj) {
37204 if (typeof par.flashvars != UNDEF) {
37205 par.flashvars += "&" + k + "=" + flashvarsObj[k];
37208 par.flashvars = k + "=" + flashvarsObj[k];
37212 if (hasPlayerVersion(swfVersionStr)) {
37213 var obj = createSWF(att, par, replaceElemIdStr);
37214 if (att.id == replaceElemIdStr) {
37215 setVisibility(replaceElemIdStr, true);
37217 callbackObj.success = true;
37218 callbackObj.ref = obj;
37220 else if (xiSwfUrlStr && canExpressInstall()) {
37221 att.data = xiSwfUrlStr;
37222 showExpressInstall(att, par, replaceElemIdStr, callbackFn);
37226 setVisibility(replaceElemIdStr, true);
37228 if (callbackFn) { callbackFn(callbackObj); }
37231 else if (callbackFn) { callbackFn(callbackObj); }
37234 switchOffAutoHideShow: function() {
37235 autoHideShow = false;
37240 getFlashPlayerVersion: function() {
37241 return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] };
37244 hasFlashPlayerVersion: hasPlayerVersion,
37246 createSWF: function(attObj, parObj, replaceElemIdStr) {
37248 return createSWF(attObj, parObj, replaceElemIdStr);
37255 showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) {
37256 if (ua.w3 && canExpressInstall()) {
37257 showExpressInstall(att, par, replaceElemIdStr, callbackFn);
37261 removeSWF: function(objElemIdStr) {
37263 removeSWF(objElemIdStr);
37267 createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) {
37269 createCSS(selStr, declStr, mediaStr, newStyleBoolean);
37273 addDomLoadEvent: addDomLoadEvent,
37275 addLoadEvent: addLoadEvent,
37277 getQueryParamValue: function(param) {
37278 var q = doc.location.search || doc.location.hash;
37280 if (/\?/.test(q)) { q = q.split("?")[1]; }
37281 if (param == null) {
37282 return urlEncodeIfNecessary(q);
37284 var pairs = q.split("&");
37285 for (var i = 0; i < pairs.length; i++) {
37286 if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
37287 return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1)));
37295 expressInstallCallback: function() {
37296 if (isExpressInstallActive) {
37297 var obj = getElementById(EXPRESS_INSTALL_ID);
37298 if (obj && storedAltContent) {
37299 obj.parentNode.replaceChild(storedAltContent, obj);
37300 if (storedAltContentId) {
37301 setVisibility(storedAltContentId, true);
37302 if (ua.ie && ua.win) { storedAltContent.style.display = "block"; }
37304 if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); }
37306 isExpressInstallActive = false;
37312 Ext.FlashComponent = Ext.extend(Ext.BoxComponent, {
37314 flashVersion : '9.0.115',
37317 backgroundColor: '#ffffff',
37323 flashVars: undefined,
37326 flashParams: undefined,
37335 expressInstall: false,
37337 initComponent : function(){
37338 Ext.FlashComponent.superclass.initComponent.call(this);
37346 onRender : function(){
37347 Ext.FlashComponent.superclass.onRender.apply(this, arguments);
37349 var params = Ext.apply({
37350 allowScriptAccess: 'always',
37351 bgcolor: this.backgroundColor,
37353 }, this.flashParams), vars = Ext.apply({
37354 allowedDomain: document.location.hostname,
37355 YUISwfId: this.getId(),
37356 YUIBridgeCallback: 'Ext.FlashEventProxy.onEvent'
37357 }, this.flashVars);
37359 new swfobject.embedSWF(this.url, this.id, this.swfWidth, this.swfHeight, this.flashVersion,
37360 this.expressInstall ? Ext.FlashComponent.EXPRESS_INSTALL_URL : undefined, vars, params);
37362 this.swf = Ext.getDom(this.id);
37363 this.el = Ext.get(this.swf);
37366 getSwfId : function(){
37367 return this.swfId || (this.swfId = "extswf" + (++Ext.Component.AUTO_ID));
37370 getId : function(){
37371 return this.id || (this.id = "extflashcmp" + (++Ext.Component.AUTO_ID));
37374 onFlashEvent : function(e){
37382 e.component = this;
37383 this.fireEvent(e.type.toLowerCase().replace(/event$/, ''), e);
37386 initSwf : function(){
37387 this.onSwfReady(!!this.isInitialized);
37388 this.isInitialized = true;
37389 this.fireEvent('initialize', this);
37392 beforeDestroy: function(){
37394 swfobject.removeSWF(this.swf.id);
37396 Ext.FlashComponent.superclass.beforeDestroy.call(this);
37399 onSwfReady : Ext.emptyFn
37403 Ext.FlashComponent.EXPRESS_INSTALL_URL = 'http:/' + '/swfobject.googlecode.com/svn/trunk/swfobject/expressInstall.swf';
37405 Ext.reg('flash', Ext.FlashComponent);
37406 Ext.FlashEventProxy = {
37407 onEvent : function(id, e){
37408 var fp = Ext.getCmp(id);
37410 fp.onFlashEvent(e);
37412 arguments.callee.defer(10, this, [id, e]);
37417 Ext.chart.Chart = Ext.extend(Ext.FlashComponent, {
37418 refreshBuffer: 100,
37425 animationEnabled: true,
37456 seriesStyles: null,
37459 disableCaching: Ext.isIE || Ext.isOpera,
37460 disableCacheParam: '_dc',
37462 initComponent : function(){
37463 Ext.chart.Chart.superclass.initComponent.call(this);
37465 this.url = Ext.chart.Chart.CHART_URL;
37467 if(this.disableCaching){
37468 this.url = Ext.urlAppend(this.url, String.format('{0}={1}', this.disableCacheParam, new Date().getTime()));
37483 this.store = Ext.StoreMgr.lookup(this.store);
37487 setStyle: function(name, value){
37488 this.swf.setStyle(name, Ext.encode(value));
37492 setStyles: function(styles){
37493 this.swf.setStyles(Ext.encode(styles));
37497 setSeriesStyles: function(styles){
37498 this.seriesStyles = styles;
37500 Ext.each(styles, function(style){
37501 s.push(Ext.encode(style));
37503 this.swf.setSeriesStyles(s);
37506 setCategoryNames : function(names){
37507 this.swf.setCategoryNames(names);
37510 setLegendRenderer : function(fn, scope){
37512 scope = scope || chart;
37513 chart.removeFnProxy(chart.legendFnName);
37514 chart.legendFnName = chart.createFnProxy(function(name){
37515 return fn.call(scope, name);
37517 chart.swf.setLegendLabelFunction(chart.legendFnName);
37520 setTipRenderer : function(fn, scope){
37522 scope = scope || chart;
37523 chart.removeFnProxy(chart.tipFnName);
37524 chart.tipFnName = chart.createFnProxy(function(item, index, series){
37525 var record = chart.store.getAt(index);
37526 return fn.call(scope, chart, record, index, series);
37528 chart.swf.setDataTipFunction(chart.tipFnName);
37531 setSeries : function(series){
37532 this.series = series;
37537 bindStore : function(store, initial){
37538 if(!initial && this.store){
37539 if(store !== this.store && this.store.autoDestroy){
37540 this.store.destroy();
37542 this.store.un("datachanged", this.refresh, this);
37543 this.store.un("add", this.delayRefresh, this);
37544 this.store.un("remove", this.delayRefresh, this);
37545 this.store.un("update", this.delayRefresh, this);
37546 this.store.un("clear", this.refresh, this);
37550 store = Ext.StoreMgr.lookup(store);
37553 datachanged: this.refresh,
37554 add: this.delayRefresh,
37555 remove: this.delayRefresh,
37556 update: this.delayRefresh,
37557 clear: this.refresh
37560 this.store = store;
37561 if(store && !initial){
37566 onSwfReady : function(isReset){
37567 Ext.chart.Chart.superclass.onSwfReady.call(this, isReset);
37569 this.swf.setType(this.type);
37571 if(this.chartStyle){
37572 this.setStyles(Ext.apply({}, this.extraStyle, this.chartStyle));
37575 if(this.categoryNames){
37576 this.setCategoryNames(this.categoryNames);
37579 if(this.tipRenderer){
37580 ref = this.getFunctionRef(this.tipRenderer);
37581 this.setTipRenderer(ref.fn, ref.scope);
37583 if(this.legendRenderer){
37584 ref = this.getFunctionRef(this.legendRenderer);
37585 this.setLegendRenderer(ref.fn, ref.scope);
37588 this.bindStore(this.store, true);
37590 this.refresh.defer(10, this);
37593 delayRefresh : function(){
37594 if(!this.refreshTask){
37595 this.refreshTask = new Ext.util.DelayedTask(this.refresh, this);
37597 this.refreshTask.delay(this.refreshBuffer);
37600 refresh : function(){
37601 if(this.fireEvent('beforerefresh', this) !== false){
37602 var styleChanged = false;
37604 var data = [], rs = this.store.data.items;
37605 for(var j = 0, len = rs.length; j < len; j++){
37606 data[j] = rs[j].data;
37610 var dataProvider = [];
37611 var seriesCount = 0;
37612 var currentSeries = null;
37615 seriesCount = this.series.length;
37616 for(i = 0; i < seriesCount; i++){
37617 currentSeries = this.series[i];
37618 var clonedSeries = {};
37619 for(var prop in currentSeries){
37620 if(prop == "style" && currentSeries.style !== null){
37621 clonedSeries.style = Ext.encode(currentSeries.style);
37622 styleChanged = true;
37628 clonedSeries[prop] = currentSeries[prop];
37631 dataProvider.push(clonedSeries);
37635 if(seriesCount > 0){
37636 for(i = 0; i < seriesCount; i++){
37637 currentSeries = dataProvider[i];
37638 if(!currentSeries.type){
37639 currentSeries.type = this.type;
37641 currentSeries.dataProvider = data;
37644 dataProvider.push({type: this.type, dataProvider: data});
37646 this.swf.setDataProvider(dataProvider);
37647 if(this.seriesStyles){
37648 this.setSeriesStyles(this.seriesStyles);
37650 this.fireEvent('refresh', this);
37655 createFnProxy : function(fn){
37656 var fnName = 'extFnProxy' + (++Ext.chart.Chart.PROXY_FN_ID);
37657 Ext.chart.Chart.proxyFunction[fnName] = fn;
37658 return 'Ext.chart.Chart.proxyFunction.' + fnName;
37662 removeFnProxy : function(fn){
37663 if(!Ext.isEmpty(fn)){
37664 fn = fn.replace('Ext.chart.Chart.proxyFunction.', '');
37665 delete Ext.chart.Chart.proxyFunction[fn];
37670 getFunctionRef : function(val){
37671 if(Ext.isFunction(val)){
37679 scope: val.scope || this
37685 onDestroy: function(){
37686 if (this.refreshTask && this.refreshTask.cancel){
37687 this.refreshTask.cancel();
37689 Ext.chart.Chart.superclass.onDestroy.call(this);
37690 this.bindStore(null);
37691 this.removeFnProxy(this.tipFnName);
37692 this.removeFnProxy(this.legendFnName);
37695 Ext.reg('chart', Ext.chart.Chart);
37696 Ext.chart.Chart.PROXY_FN_ID = 0;
37697 Ext.chart.Chart.proxyFunction = {};
37700 Ext.chart.Chart.CHART_URL = 'http:/' + '/yui.yahooapis.com/2.8.2/build/charts/assets/charts.swf';
37703 Ext.chart.PieChart = Ext.extend(Ext.chart.Chart, {
37706 onSwfReady : function(isReset){
37707 Ext.chart.PieChart.superclass.onSwfReady.call(this, isReset);
37709 this.setDataField(this.dataField);
37710 this.setCategoryField(this.categoryField);
37713 setDataField : function(field){
37714 this.dataField = field;
37715 this.swf.setDataField(field);
37718 setCategoryField : function(field){
37719 this.categoryField = field;
37720 this.swf.setCategoryField(field);
37723 Ext.reg('piechart', Ext.chart.PieChart);
37726 Ext.chart.CartesianChart = Ext.extend(Ext.chart.Chart, {
37727 onSwfReady : function(isReset){
37728 Ext.chart.CartesianChart.superclass.onSwfReady.call(this, isReset);
37731 this.setXField(this.xField);
37734 this.setYField(this.yField);
37737 this.setXAxis(this.xAxis);
37740 this.setXAxes(this.xAxes);
37743 this.setYAxis(this.yAxis);
37746 this.setYAxes(this.yAxes);
37748 if(Ext.isDefined(this.constrainViewport)){
37749 this.swf.setConstrainViewport(this.constrainViewport);
37753 setXField : function(value){
37754 this.xField = value;
37755 this.swf.setHorizontalField(value);
37758 setYField : function(value){
37759 this.yField = value;
37760 this.swf.setVerticalField(value);
37763 setXAxis : function(value){
37764 this.xAxis = this.createAxis('xAxis', value);
37765 this.swf.setHorizontalAxis(this.xAxis);
37768 setXAxes : function(value){
37770 for(var i = 0; i < value.length; i++) {
37771 axis = this.createAxis('xAxis' + i, value[i]);
37772 this.swf.setHorizontalAxis(axis);
37776 setYAxis : function(value){
37777 this.yAxis = this.createAxis('yAxis', value);
37778 this.swf.setVerticalAxis(this.yAxis);
37781 setYAxes : function(value){
37783 for(var i = 0; i < value.length; i++) {
37784 axis = this.createAxis('yAxis' + i, value[i]);
37785 this.swf.setVerticalAxis(axis);
37789 createAxis : function(axis, value){
37790 var o = Ext.apply({}, value),
37795 old = this[axis].labelFunction;
37796 this.removeFnProxy(old);
37797 this.labelFn.remove(old);
37799 if(o.labelRenderer){
37800 ref = this.getFunctionRef(o.labelRenderer);
37801 o.labelFunction = this.createFnProxy(function(v){
37802 return ref.fn.call(ref.scope, v);
37804 delete o.labelRenderer;
37805 this.labelFn.push(o.labelFunction);
37807 if(axis.indexOf('xAxis') > -1 && o.position == 'left'){
37808 o.position = 'bottom';
37813 onDestroy : function(){
37814 Ext.chart.CartesianChart.superclass.onDestroy.call(this);
37815 Ext.each(this.labelFn, function(fn){
37816 this.removeFnProxy(fn);
37820 Ext.reg('cartesianchart', Ext.chart.CartesianChart);
37823 Ext.chart.LineChart = Ext.extend(Ext.chart.CartesianChart, {
37826 Ext.reg('linechart', Ext.chart.LineChart);
37829 Ext.chart.ColumnChart = Ext.extend(Ext.chart.CartesianChart, {
37832 Ext.reg('columnchart', Ext.chart.ColumnChart);
37835 Ext.chart.StackedColumnChart = Ext.extend(Ext.chart.CartesianChart, {
37836 type: 'stackcolumn'
37838 Ext.reg('stackedcolumnchart', Ext.chart.StackedColumnChart);
37841 Ext.chart.BarChart = Ext.extend(Ext.chart.CartesianChart, {
37844 Ext.reg('barchart', Ext.chart.BarChart);
37847 Ext.chart.StackedBarChart = Ext.extend(Ext.chart.CartesianChart, {
37850 Ext.reg('stackedbarchart', Ext.chart.StackedBarChart);
37855 Ext.chart.Axis = function(config){
37856 Ext.apply(this, config);
37859 Ext.chart.Axis.prototype =
37865 orientation: "horizontal",
37871 labelFunction: null,
37874 hideOverlappingLabels: true,
37881 Ext.chart.NumericAxis = Ext.extend(Ext.chart.Axis, {
37900 alwaysShowZero: true,
37906 roundMajorUnit: true,
37909 calculateByLabelSize: true,
37915 adjustMaximumByMajorUnit: true,
37918 adjustMinimumByMajorUnit: true
37923 Ext.chart.TimeAxis = Ext.extend(Ext.chart.Axis, {
37936 majorTimeUnit: null,
37942 minorTimeUnit: null,
37948 stackingEnabled: false,
37951 calculateByLabelSize: true
37956 Ext.chart.CategoryAxis = Ext.extend(Ext.chart.Axis, {
37960 categoryNames: null,
37963 calculateCategoryCount: false
37968 Ext.chart.Series = function(config) { Ext.apply(this, config); };
37970 Ext.chart.Series.prototype =
37980 Ext.chart.CartesianSeries = Ext.extend(Ext.chart.Series, {
37988 showInLegend: true,
37995 Ext.chart.ColumnSeries = Ext.extend(Ext.chart.CartesianSeries, {
38000 Ext.chart.LineSeries = Ext.extend(Ext.chart.CartesianSeries, {
38005 Ext.chart.BarSeries = Ext.extend(Ext.chart.CartesianSeries, {
38011 Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, {
38014 categoryField: null
38016 Ext.menu.Menu = Ext.extend(Ext.Container, {
38024 subMenuAlign : 'tl-tr?',
38026 defaultAlign : 'tl-bl?',
38028 allowOtherMenus : false,
38030 ignoreParentClicks : false,
38032 enableScrolling : true,
38036 scrollIncrement : 24,
38038 showSeparator : true,
38040 defaultOffsets : [0, 0],
38057 hideMode : 'offsets',
38058 scrollerHeight : 8,
38060 defaultType : 'menuitem',
38061 bufferResize : false,
38063 initComponent : function(){
38064 if(Ext.isArray(this.initialConfig)){
38065 Ext.apply(this, {items:this.initialConfig});
38077 Ext.menu.MenuMgr.register(this);
38079 Ext.EventManager.onWindowResize(this.hide, this);
38081 if(this.initialConfig.hidden !== false){
38082 this.hidden = false;
38084 this.internalDefaults = {hideOnClick: false};
38086 Ext.menu.Menu.superclass.initComponent.call(this);
38087 if(this.autoLayout){
38088 var fn = this.doLayout.createDelegate(this, []);
38097 getLayoutTarget : function() {
38102 onRender : function(ct, position){
38104 ct = Ext.getBody();
38109 cls: 'x-menu ' + ((this.floating) ? 'x-menu-floating x-layer ' : '') + (this.cls || '') + (this.plain ? ' x-menu-plain' : '') + (this.showSeparator ? '' : ' x-menu-nosep'),
38112 {tag: 'a', cls: 'x-menu-focus', href: '#', onclick: 'return false;', tabIndex: '-1'},
38113 {tag: 'ul', cls: 'x-menu-list'}
38117 this.el = new Ext.Layer({
38118 shadow: this.shadow,
38122 zindex: this.zIndex
38125 this.el = ct.createChild(dh);
38127 Ext.menu.Menu.superclass.onRender.call(this, ct, position);
38130 this.keyNav = new Ext.menu.MenuNav(this);
38133 this.focusEl = this.el.child('a.x-menu-focus');
38134 this.ul = this.el.child('ul.x-menu-list');
38135 this.mon(this.ul, {
38137 click: this.onClick,
38138 mouseover: this.onMouseOver,
38139 mouseout: this.onMouseOut
38141 if(this.enableScrolling){
38142 this.mon(this.el, {
38144 delegate: '.x-menu-scroller',
38145 click: this.onScroll,
38146 mouseover: this.deactivateActive
38152 findTargetItem : function(e){
38153 var t = e.getTarget('.x-menu-list-item', this.ul, true);
38154 if(t && t.menuItemId){
38155 return this.items.get(t.menuItemId);
38160 onClick : function(e){
38161 var t = this.findTargetItem(e);
38164 this.setActiveItem(t);
38165 }else if(t instanceof Ext.menu.BaseItem){
38166 if(t.menu && this.ignoreParentClicks){
38168 e.preventDefault();
38169 }else if(t.onClick){
38171 this.fireEvent('click', this, t, e);
38178 setActiveItem : function(item, autoExpand){
38179 if(item != this.activeItem){
38180 this.deactivateActive();
38181 if((this.activeItem = item).isFormField){
38184 item.activate(autoExpand);
38186 }else if(autoExpand){
38191 deactivateActive : function(){
38192 var a = this.activeItem;
38202 delete this.activeItem;
38207 tryActivate : function(start, step){
38208 var items = this.items;
38209 for(var i = start, len = items.length; i >= 0 && i < len; i+= step){
38210 var item = items.get(i);
38211 if(item.isVisible() && !item.disabled && (item.canActivate || item.isFormField)){
38212 this.setActiveItem(item, false);
38220 onMouseOver : function(e){
38221 var t = this.findTargetItem(e);
38223 if(t.canActivate && !t.disabled){
38224 this.setActiveItem(t, true);
38228 this.fireEvent('mouseover', this, e, t);
38232 onMouseOut : function(e){
38233 var t = this.findTargetItem(e);
38235 if(t == this.activeItem && t.shouldDeactivate && t.shouldDeactivate(e)){
38236 this.activeItem.deactivate();
38237 delete this.activeItem;
38241 this.fireEvent('mouseout', this, e, t);
38245 onScroll : function(e, t){
38249 var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top');
38250 ul.scrollTop += this.scrollIncrement * (top ? -1 : 1);
38251 if(top ? ul.scrollTop <= 0 : ul.scrollTop + this.activeMax >= ul.scrollHeight){
38252 this.onScrollerOut(null, t);
38257 onScrollerIn : function(e, t){
38258 var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top');
38259 if(top ? ul.scrollTop > 0 : ul.scrollTop + this.activeMax < ul.scrollHeight){
38260 Ext.fly(t).addClass(['x-menu-item-active', 'x-menu-scroller-active']);
38265 onScrollerOut : function(e, t){
38266 Ext.fly(t).removeClass(['x-menu-item-active', 'x-menu-scroller-active']);
38270 show : function(el, pos, parentMenu){
38272 this.parentMenu = parentMenu;
38275 this.doLayout(false, true);
38277 this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign, this.defaultOffsets), parentMenu);
38279 Ext.menu.Menu.superclass.show.call(this);
38284 showAt : function(xy, parentMenu){
38285 if(this.fireEvent('beforeshow', this) !== false){
38286 this.parentMenu = parentMenu;
38290 if(this.enableScrolling){
38294 xy[1] = this.constrainScroll(xy[1]);
38295 xy = [this.el.adjustForConstraints(xy)[0], xy[1]];
38298 xy = this.el.adjustForConstraints(xy);
38302 Ext.menu.Menu.superclass.onShow.call(this);
38305 this.fireEvent('autosize', this);
38310 this.hidden = false;
38312 this.fireEvent('show', this);
38316 constrainScroll : function(y){
38317 var max, full = this.ul.setHeight('auto').getHeight(),
38318 returnY = y, normalY, parentEl, scrollTop, viewHeight;
38320 parentEl = Ext.fly(this.el.dom.parentNode);
38321 scrollTop = parentEl.getScroll().top;
38322 viewHeight = parentEl.getViewSize().height;
38325 normalY = y - scrollTop;
38326 max = this.maxHeight ? this.maxHeight : viewHeight - normalY;
38327 if(full > viewHeight) {
38330 returnY = y - normalY;
38331 } else if(max < full) {
38332 returnY = y - (full - max);
38336 max = this.getHeight();
38339 if (this.maxHeight){
38340 max = Math.min(this.maxHeight, max);
38342 if(full > max && max > 0){
38343 this.activeMax = max - this.scrollerHeight * 2 - this.el.getFrameWidth('tb') - Ext.num(this.el.shadowOffset, 0);
38344 this.ul.setHeight(this.activeMax);
38345 this.createScrollers();
38346 this.el.select('.x-menu-scroller').setDisplayed('');
38348 this.ul.setHeight(full);
38349 this.el.select('.x-menu-scroller').setDisplayed('none');
38351 this.ul.dom.scrollTop = 0;
38355 createScrollers : function(){
38356 if(!this.scroller){
38359 top: this.el.insertFirst({
38361 cls: 'x-menu-scroller x-menu-scroller-top',
38364 bottom: this.el.createChild({
38366 cls: 'x-menu-scroller x-menu-scroller-bottom',
38370 this.scroller.top.hover(this.onScrollerIn, this.onScrollerOut, this);
38371 this.scroller.topRepeater = new Ext.util.ClickRepeater(this.scroller.top, {
38373 click: this.onScroll.createDelegate(this, [null, this.scroller.top], false)
38376 this.scroller.bottom.hover(this.onScrollerIn, this.onScrollerOut, this);
38377 this.scroller.bottomRepeater = new Ext.util.ClickRepeater(this.scroller.bottom, {
38379 click: this.onScroll.createDelegate(this, [null, this.scroller.bottom], false)
38385 onLayout : function(){
38386 if(this.isVisible()){
38387 if(this.enableScrolling){
38388 this.constrainScroll(this.el.getTop());
38396 focus : function(){
38398 this.doFocus.defer(50, this);
38402 doFocus : function(){
38404 this.focusEl.focus();
38409 hide : function(deep){
38410 if (!this.isDestroyed) {
38411 this.deepHide = deep;
38412 Ext.menu.Menu.superclass.hide.call(this);
38413 delete this.deepHide;
38418 onHide : function(){
38419 Ext.menu.Menu.superclass.onHide.call(this);
38420 this.deactivateActive();
38421 if(this.el && this.floating){
38424 var pm = this.parentMenu;
38425 if(this.deepHide === true && pm){
38429 pm.deactivateActive();
38435 lookupComponent : function(c){
38436 if(Ext.isString(c)){
38437 c = (c == 'separator' || c == '-') ? new Ext.menu.Separator() : new Ext.menu.TextItem(c);
38438 this.applyDefaults(c);
38440 if(Ext.isObject(c)){
38441 c = this.getMenuItem(c);
38442 }else if(c.tagName || c.el){
38443 c = new Ext.BoxComponent({
38451 applyDefaults : function(c) {
38452 if (!Ext.isString(c)) {
38453 c = Ext.menu.Menu.superclass.applyDefaults.call(this, c);
38454 var d = this.internalDefaults;
38457 Ext.applyIf(c.initialConfig, d);
38468 getMenuItem : function(config) {
38469 if (!config.isXType) {
38470 if (!config.xtype && Ext.isBoolean(config.checked)) {
38471 return new Ext.menu.CheckItem(config);
38473 return Ext.create(config, this.defaultType);
38479 addSeparator : function() {
38480 return this.add(new Ext.menu.Separator());
38484 addElement : function(el) {
38485 return this.add(new Ext.menu.BaseItem({
38491 addItem : function(item) {
38492 return this.add(item);
38496 addMenuItem : function(config) {
38497 return this.add(this.getMenuItem(config));
38501 addText : function(text){
38502 return this.add(new Ext.menu.TextItem(text));
38506 onDestroy : function(){
38507 Ext.EventManager.removeResizeListener(this.hide, this);
38508 var pm = this.parentMenu;
38509 if(pm && pm.activeChild == this){
38510 delete pm.activeChild;
38512 delete this.parentMenu;
38513 Ext.menu.Menu.superclass.onDestroy.call(this);
38514 Ext.menu.MenuMgr.unregister(this);
38516 this.keyNav.disable();
38518 var s = this.scroller;
38520 Ext.destroy(s.topRepeater, s.bottomRepeater, s.top, s.bottom);
38530 Ext.reg('menu', Ext.menu.Menu);
38533 Ext.menu.MenuNav = Ext.extend(Ext.KeyNav, function(){
38535 if(!m.tryActivate(m.items.indexOf(m.activeItem)-1, -1)){
38536 m.tryActivate(m.items.length-1, -1);
38539 function down(e, m){
38540 if(!m.tryActivate(m.items.indexOf(m.activeItem)+1, 1)){
38541 m.tryActivate(0, 1);
38545 constructor : function(menu){
38546 Ext.menu.MenuNav.superclass.constructor.call(this, menu.el);
38547 this.scope = this.menu = menu;
38550 doRelay : function(e, h){
38551 var k = e.getKey();
38553 if (this.menu.activeItem && this.menu.activeItem.isFormField && k != e.TAB) {
38556 if(!this.menu.activeItem && e.isNavKeyPress() && k != e.SPACE && k != e.RETURN){
38557 this.menu.tryActivate(0, 1);
38560 return h.call(this.scope || this, e, this.menu);
38563 tab: function(e, m) {
38576 right : function(e, m){
38578 m.activeItem.expandMenu(true);
38582 left : function(e, m){
38584 if(m.parentMenu && m.parentMenu.activeItem){
38585 m.parentMenu.activeItem.activate();
38589 enter : function(e, m){
38591 e.stopPropagation();
38592 m.activeItem.onClick(e);
38593 m.fireEvent('click', this, m.activeItem);
38600 Ext.menu.MenuMgr = function(){
38601 var menus, active, groups = {}, attached = false, lastShow = new Date();
38606 active = new Ext.util.MixedCollection();
38607 Ext.getDoc().addKeyListener(27, function(){
38608 if(active.length > 0){
38615 function hideAll(){
38616 if(active && active.length > 0){
38617 var c = active.clone();
38618 c.each(function(m){
38627 function onHide(m){
38629 if(active.length < 1){
38630 Ext.getDoc().un("mousedown", onMouseDown);
38636 function onShow(m){
38637 var last = active.last();
38638 lastShow = new Date();
38641 Ext.getDoc().on("mousedown", onMouseDown);
38645 m.getEl().setZIndex(parseInt(m.parentMenu.getEl().getStyle("z-index"), 10) + 3);
38646 m.parentMenu.activeChild = m;
38647 }else if(last && !last.isDestroyed && last.isVisible()){
38648 m.getEl().setZIndex(parseInt(last.getEl().getStyle("z-index"), 10) + 3);
38653 function onBeforeHide(m){
38655 m.activeChild.hide();
38657 if(m.autoHideTimer){
38658 clearTimeout(m.autoHideTimer);
38659 delete m.autoHideTimer;
38664 function onBeforeShow(m){
38665 var pm = m.parentMenu;
38666 if(!pm && !m.allowOtherMenus){
38668 }else if(pm && pm.activeChild){
38669 pm.activeChild.hide();
38674 function onMouseDown(e){
38675 if(lastShow.getElapsed() > 50 && active.length > 0 && !e.getTarget(".x-menu")){
38683 hideAll : function(){
38688 register : function(menu){
38692 menus[menu.id] = menu;
38694 beforehide: onBeforeHide,
38696 beforeshow: onBeforeShow,
38702 get : function(menu){
38703 if(typeof menu == "string"){
38707 return menus[menu];
38708 }else if(menu.events){
38710 }else if(typeof menu.length == 'number'){
38711 return new Ext.menu.Menu({items:menu});
38713 return Ext.create(menu, 'menu');
38718 unregister : function(menu){
38719 delete menus[menu.id];
38720 menu.un("beforehide", onBeforeHide);
38721 menu.un("hide", onHide);
38722 menu.un("beforeshow", onBeforeShow);
38723 menu.un("show", onShow);
38727 registerCheckable : function(menuItem){
38728 var g = menuItem.group;
38733 groups[g].push(menuItem);
38738 unregisterCheckable : function(menuItem){
38739 var g = menuItem.group;
38741 groups[g].remove(menuItem);
38746 onCheckChange: function(item, state){
38747 if(item.group && state){
38748 var group = groups[item.group],
38750 len = group.length,
38753 for(; i < len; i++){
38754 current = group[i];
38755 if(current != item){
38756 current.setChecked(false);
38762 getCheckedItem : function(groupId){
38763 var g = groups[groupId];
38765 for(var i = 0, l = g.length; i < l; i++){
38774 setCheckedItem : function(groupId, itemId){
38775 var g = groups[groupId];
38777 for(var i = 0, l = g.length; i < l; i++){
38778 if(g[i].id == itemId){
38779 g[i].setChecked(true);
38788 Ext.menu.BaseItem = Ext.extend(Ext.Component, {
38793 canActivate : false,
38795 activeClass : "x-menu-item-active",
38797 hideOnClick : true,
38799 clickHideDelay : 1,
38802 ctype : "Ext.menu.BaseItem",
38805 actionMode : "container",
38807 initComponent : function(){
38808 Ext.menu.BaseItem.superclass.initComponent.call(this);
38818 this.on("click", this.handler, this.scope);
38823 onRender : function(container, position){
38824 Ext.menu.BaseItem.superclass.onRender.apply(this, arguments);
38825 if(this.ownerCt && this.ownerCt instanceof Ext.menu.Menu){
38826 this.parentMenu = this.ownerCt;
38828 this.container.addClass('x-menu-list-item');
38829 this.mon(this.el, {
38831 click: this.onClick,
38832 mouseenter: this.activate,
38833 mouseleave: this.deactivate
38839 setHandler : function(handler, scope){
38841 this.un("click", this.handler, this.scope);
38843 this.on("click", this.handler = handler, this.scope = scope);
38847 onClick : function(e){
38848 if(!this.disabled && this.fireEvent("click", this, e) !== false
38849 && (this.parentMenu && this.parentMenu.fireEvent("itemclick", this, e) !== false)){
38850 this.handleClick(e);
38857 activate : function(){
38861 var li = this.container;
38862 li.addClass(this.activeClass);
38863 this.region = li.getRegion().adjust(2, 2, -2, -2);
38864 this.fireEvent("activate", this);
38869 deactivate : function(){
38870 this.container.removeClass(this.activeClass);
38871 this.fireEvent("deactivate", this);
38875 shouldDeactivate : function(e){
38876 return !this.region || !this.region.contains(e.getPoint());
38880 handleClick : function(e){
38881 var pm = this.parentMenu;
38882 if(this.hideOnClick){
38884 pm.hide.defer(this.clickHideDelay, pm, [true]);
38886 pm.deactivateActive();
38892 expandMenu : Ext.emptyFn,
38895 hideMenu : Ext.emptyFn
38897 Ext.reg('menubaseitem', Ext.menu.BaseItem);
38898 Ext.menu.TextItem = Ext.extend(Ext.menu.BaseItem, {
38901 hideOnClick : false,
38903 itemCls : "x-menu-text",
38905 constructor : function(config) {
38906 if (typeof config == 'string') {
38911 Ext.menu.TextItem.superclass.constructor.call(this, config);
38915 onRender : function() {
38916 var s = document.createElement("span");
38917 s.className = this.itemCls;
38918 s.innerHTML = this.text;
38920 Ext.menu.TextItem.superclass.onRender.apply(this, arguments);
38923 Ext.reg('menutextitem', Ext.menu.TextItem);
38924 Ext.menu.Separator = Ext.extend(Ext.menu.BaseItem, {
38926 itemCls : "x-menu-sep",
38928 hideOnClick : false,
38934 onRender : function(li){
38935 var s = document.createElement("span");
38936 s.className = this.itemCls;
38937 s.innerHTML = " ";
38939 li.addClass("x-menu-sep-li");
38940 Ext.menu.Separator.superclass.onRender.apply(this, arguments);
38943 Ext.reg('menuseparator', Ext.menu.Separator);
38944 Ext.menu.Item = Ext.extend(Ext.menu.BaseItem, {
38953 itemCls : 'x-menu-item',
38955 canActivate : true,
38966 ctype: 'Ext.menu.Item',
38968 initComponent : function(){
38969 Ext.menu.Item.superclass.initComponent.call(this);
38971 this.menu = Ext.menu.MenuMgr.get(this.menu);
38972 this.menu.ownerCt = this;
38977 onRender : function(container, position){
38978 if (!this.itemTpl) {
38979 this.itemTpl = Ext.menu.Item.prototype.itemTpl = new Ext.XTemplate(
38980 '<a id="{id}" class="{cls}" hidefocus="true" unselectable="on" href="{href}"',
38981 '<tpl if="hrefTarget">',
38982 ' target="{hrefTarget}"',
38985 '<img alt="{altText}" src="{icon}" class="x-menu-item-icon {iconCls}"/>',
38986 '<span class="x-menu-item-text">{text}</span>',
38990 var a = this.getTemplateArgs();
38991 this.el = position ? this.itemTpl.insertBefore(position, a, true) : this.itemTpl.append(container, a, true);
38992 this.iconEl = this.el.child('img.x-menu-item-icon');
38993 this.textEl = this.el.child('.x-menu-item-text');
38995 this.mon(this.el, 'click', Ext.emptyFn, null, { preventDefault: true });
38997 Ext.menu.Item.superclass.onRender.call(this, container, position);
39000 getTemplateArgs: function() {
39003 cls: this.itemCls + (this.menu ? ' x-menu-item-arrow' : '') + (this.cls ? ' ' + this.cls : ''),
39004 href: this.href || '#',
39005 hrefTarget: this.hrefTarget,
39006 icon: this.icon || Ext.BLANK_IMAGE_URL,
39007 iconCls: this.iconCls || '',
39008 text: this.itemText||this.text||' ',
39009 altText: this.altText || ''
39014 setText : function(text){
39015 this.text = text||' ';
39017 this.textEl.update(this.text);
39018 this.parentMenu.layout.doAutoSize();
39023 setIconClass : function(cls){
39024 var oldCls = this.iconCls;
39025 this.iconCls = cls;
39027 this.iconEl.replaceClass(oldCls, this.iconCls);
39032 beforeDestroy: function(){
39034 delete this.menu.ownerCt;
39035 this.menu.destroy();
39037 Ext.menu.Item.superclass.beforeDestroy.call(this);
39041 handleClick : function(e){
39045 Ext.menu.Item.superclass.handleClick.apply(this, arguments);
39049 activate : function(autoExpand){
39050 if(Ext.menu.Item.superclass.activate.apply(this, arguments)){
39060 shouldDeactivate : function(e){
39061 if(Ext.menu.Item.superclass.shouldDeactivate.call(this, e)){
39062 if(this.menu && this.menu.isVisible()){
39063 return !this.menu.getEl().getRegion().contains(e.getPoint());
39071 deactivate : function(){
39072 Ext.menu.Item.superclass.deactivate.apply(this, arguments);
39077 expandMenu : function(autoActivate){
39078 if(!this.disabled && this.menu){
39079 clearTimeout(this.hideTimer);
39080 delete this.hideTimer;
39081 if(!this.menu.isVisible() && !this.showTimer){
39082 this.showTimer = this.deferExpand.defer(this.showDelay, this, [autoActivate]);
39083 }else if (this.menu.isVisible() && autoActivate){
39084 this.menu.tryActivate(0, 1);
39090 deferExpand : function(autoActivate){
39091 delete this.showTimer;
39092 this.menu.show(this.container, this.parentMenu.subMenuAlign || 'tl-tr?', this.parentMenu);
39094 this.menu.tryActivate(0, 1);
39099 hideMenu : function(){
39100 clearTimeout(this.showTimer);
39101 delete this.showTimer;
39102 if(!this.hideTimer && this.menu && this.menu.isVisible()){
39103 this.hideTimer = this.deferHide.defer(this.hideDelay, this);
39108 deferHide : function(){
39109 delete this.hideTimer;
39110 if(this.menu.over){
39111 this.parentMenu.setActiveItem(this, false);
39117 Ext.reg('menuitem', Ext.menu.Item);
39118 Ext.menu.CheckItem = Ext.extend(Ext.menu.Item, {
39121 itemCls : "x-menu-item x-menu-check-item",
39123 groupClass : "x-menu-group-item",
39129 ctype: "Ext.menu.CheckItem",
39131 initComponent : function(){
39132 Ext.menu.CheckItem.superclass.initComponent.call(this);
39135 "beforecheckchange" ,
39140 if(this.checkHandler){
39141 this.on('checkchange', this.checkHandler, this.scope);
39143 Ext.menu.MenuMgr.registerCheckable(this);
39147 onRender : function(c){
39148 Ext.menu.CheckItem.superclass.onRender.apply(this, arguments);
39150 this.el.addClass(this.groupClass);
39153 this.checked = false;
39154 this.setChecked(true, true);
39159 destroy : function(){
39160 Ext.menu.MenuMgr.unregisterCheckable(this);
39161 Ext.menu.CheckItem.superclass.destroy.apply(this, arguments);
39165 setChecked : function(state, suppressEvent){
39166 var suppress = suppressEvent === true;
39167 if(this.checked != state && (suppress || this.fireEvent("beforecheckchange", this, state) !== false)){
39168 Ext.menu.MenuMgr.onCheckChange(this, state);
39169 if(this.container){
39170 this.container[state ? "addClass" : "removeClass"]("x-menu-item-checked");
39172 this.checked = state;
39174 this.fireEvent("checkchange", this, state);
39180 handleClick : function(e){
39181 if(!this.disabled && !(this.checked && this.group)){
39182 this.setChecked(!this.checked);
39184 Ext.menu.CheckItem.superclass.handleClick.apply(this, arguments);
39187 Ext.reg('menucheckitem', Ext.menu.CheckItem);
39188 Ext.menu.DateMenu = Ext.extend(Ext.menu.Menu, {
39190 enableScrolling : false,
39194 hideOnClick : true,
39202 cls : 'x-date-menu',
39208 initComponent : function(){
39209 this.on('beforeshow', this.onBeforeShow, this);
39210 if(this.strict = (Ext.isIE7 && Ext.isStrict)){
39211 this.on('show', this.onShow, this, {single: true, delay: 20});
39215 showSeparator: false,
39216 items: this.picker = new Ext.DatePicker(Ext.applyIf({
39217 internalRender: this.strict || !Ext.isIE,
39218 ctCls: 'x-menu-date-item',
39220 }, this.initialConfig))
39222 this.picker.purgeListeners();
39223 Ext.menu.DateMenu.superclass.initComponent.call(this);
39225 this.relayEvents(this.picker, ['select']);
39226 this.on('show', this.picker.focus, this.picker);
39227 this.on('select', this.menuHide, this);
39229 this.on('select', this.handler, this.scope || this);
39233 menuHide : function() {
39234 if(this.hideOnClick){
39239 onBeforeShow : function(){
39241 this.picker.hideMonthPicker(true);
39245 onShow : function(){
39246 var el = this.picker.getEl();
39247 el.setWidth(el.getWidth());
39250 Ext.reg('datemenu', Ext.menu.DateMenu);
39252 Ext.menu.ColorMenu = Ext.extend(Ext.menu.Menu, {
39254 enableScrolling : false,
39259 hideOnClick : true,
39261 cls : 'x-color-menu',
39275 initComponent : function(){
39278 showSeparator: false,
39279 items: this.palette = new Ext.ColorPalette(Ext.applyIf({
39281 }, this.initialConfig))
39283 this.palette.purgeListeners();
39284 Ext.menu.ColorMenu.superclass.initComponent.call(this);
39286 this.relayEvents(this.palette, ['select']);
39287 this.on('select', this.menuHide, this);
39289 this.on('select', this.handler, this.scope || this);
39293 menuHide : function(){
39294 if(this.hideOnClick){
39299 Ext.reg('colormenu', Ext.menu.ColorMenu);
39301 Ext.form.Field = Ext.extend(Ext.BoxComponent, {
39310 invalidClass : 'x-form-invalid',
39312 invalidText : 'The value in this field is invalid',
39314 focusClass : 'x-form-focus',
39317 validationEvent : 'keyup',
39319 validateOnBlur : true,
39321 validationDelay : 250,
39323 defaultAutoCreate : {tag: 'input', type: 'text', size: '20', autocomplete: 'off'},
39325 fieldClass : 'x-form-field',
39327 msgTarget : 'qtip',
39338 isFormField : true,
39347 initComponent : function(){
39348 Ext.form.Field.superclass.initComponent.call(this);
39366 getName : function(){
39367 return this.rendered && this.el.dom.name ? this.el.dom.name : this.name || this.id || '';
39371 onRender : function(ct, position){
39373 var cfg = this.getAutoCreate();
39376 cfg.name = this.name || this.id;
39378 if(this.inputType){
39379 cfg.type = this.inputType;
39383 Ext.form.Field.superclass.onRender.call(this, ct, position);
39384 if(this.submitValue === false){
39385 this.el.dom.removeAttribute('name');
39387 var type = this.el.dom.type;
39389 if(type == 'password'){
39392 this.el.addClass('x-form-'+type);
39395 this.setReadOnly(true);
39397 if(this.tabIndex !== undefined){
39398 this.el.dom.setAttribute('tabIndex', this.tabIndex);
39401 this.el.addClass([this.fieldClass, this.cls]);
39405 getItemCt : function(){
39406 return this.itemCt;
39410 initValue : function(){
39411 if(this.value !== undefined){
39412 this.setValue(this.value);
39413 }else if(!Ext.isEmpty(this.el.dom.value) && this.el.dom.value != this.emptyText){
39414 this.setValue(this.el.dom.value);
39417 this.originalValue = this.getValue();
39421 isDirty : function() {
39422 if(this.disabled || !this.rendered) {
39425 return String(this.getValue()) !== String(this.originalValue);
39429 setReadOnly : function(readOnly){
39431 this.el.dom.readOnly = readOnly;
39433 this.readOnly = readOnly;
39437 afterRender : function(){
39438 Ext.form.Field.superclass.afterRender.call(this);
39444 fireKey : function(e){
39445 if(e.isSpecialKey()){
39446 this.fireEvent('specialkey', this, e);
39451 reset : function(){
39452 this.setValue(this.originalValue);
39453 this.clearInvalid();
39457 initEvents : function(){
39458 this.mon(this.el, Ext.EventManager.getKeyEvent(), this.fireKey, this);
39459 this.mon(this.el, 'focus', this.onFocus, this);
39463 this.mon(this.el, 'blur', this.onBlur, this, this.inEditor ? {buffer:10} : null);
39467 preFocus: Ext.emptyFn,
39470 onFocus : function(){
39472 if(this.focusClass){
39473 this.el.addClass(this.focusClass);
39475 if(!this.hasFocus){
39476 this.hasFocus = true;
39478 this.startValue = this.getValue();
39479 this.fireEvent('focus', this);
39484 beforeBlur : Ext.emptyFn,
39487 onBlur : function(){
39489 if(this.focusClass){
39490 this.el.removeClass(this.focusClass);
39492 this.hasFocus = false;
39493 if(this.validationEvent !== false && (this.validateOnBlur || this.validationEvent == 'blur')){
39496 var v = this.getValue();
39497 if(String(v) !== String(this.startValue)){
39498 this.fireEvent('change', this, v, this.startValue);
39500 this.fireEvent('blur', this);
39505 postBlur : Ext.emptyFn,
39508 isValid : function(preventMark){
39512 var restore = this.preventMark;
39513 this.preventMark = preventMark === true;
39514 var v = this.validateValue(this.processValue(this.getRawValue()));
39515 this.preventMark = restore;
39520 validate : function(){
39521 if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
39522 this.clearInvalid();
39529 processValue : function(value){
39534 validateValue : function(value) {
39536 var error = this.getErrors(value)[0];
39538 if (error == undefined) {
39541 this.markInvalid(error);
39547 getErrors: function() {
39552 getActiveError : function(){
39553 return this.activeError || '';
39557 markInvalid : function(msg){
39559 if (this.rendered && !this.preventMark) {
39560 msg = msg || this.invalidText;
39562 var mt = this.getMessageHandler();
39564 mt.mark(this, msg);
39565 }else if(this.msgTarget){
39566 this.el.addClass(this.invalidClass);
39567 var t = Ext.getDom(this.msgTarget);
39570 t.style.display = this.msgDisplay;
39575 this.setActiveError(msg);
39579 clearInvalid : function(){
39581 if (this.rendered && !this.preventMark) {
39582 this.el.removeClass(this.invalidClass);
39583 var mt = this.getMessageHandler();
39586 }else if(this.msgTarget){
39587 this.el.removeClass(this.invalidClass);
39588 var t = Ext.getDom(this.msgTarget);
39591 t.style.display = 'none';
39596 this.unsetActiveError();
39600 setActiveError: function(msg, suppressEvent) {
39601 this.activeError = msg;
39602 if (suppressEvent !== true) this.fireEvent('invalid', this, msg);
39606 unsetActiveError: function(suppressEvent) {
39607 delete this.activeError;
39608 if (suppressEvent !== true) this.fireEvent('valid', this);
39612 getMessageHandler : function(){
39613 return Ext.form.MessageTargets[this.msgTarget];
39617 getErrorCt : function(){
39618 return this.el.findParent('.x-form-element', 5, true) ||
39619 this.el.findParent('.x-form-field-wrap', 5, true);
39623 alignErrorEl : function(){
39624 this.errorEl.setWidth(this.getErrorCt().getWidth(true) - 20);
39628 alignErrorIcon : function(){
39629 this.errorIcon.alignTo(this.el, 'tl-tr', [2, 0]);
39633 getRawValue : function(){
39634 var v = this.rendered ? this.el.getValue() : Ext.value(this.value, '');
39635 if(v === this.emptyText){
39642 getValue : function(){
39643 if(!this.rendered) {
39646 var v = this.el.getValue();
39647 if(v === this.emptyText || v === undefined){
39654 setRawValue : function(v){
39655 return this.rendered ? (this.el.dom.value = (Ext.isEmpty(v) ? '' : v)) : '';
39659 setValue : function(v){
39662 this.el.dom.value = (Ext.isEmpty(v) ? '' : v);
39669 append : function(v){
39670 this.setValue([this.getValue(), v].join(''));
39680 Ext.form.MessageTargets = {
39682 mark: function(field, msg){
39683 field.el.addClass(field.invalidClass);
39684 field.el.dom.qtip = msg;
39685 field.el.dom.qclass = 'x-form-invalid-tip';
39687 Ext.QuickTips.enable();
39690 clear: function(field){
39691 field.el.removeClass(field.invalidClass);
39692 field.el.dom.qtip = '';
39696 mark: function(field, msg){
39697 field.el.addClass(field.invalidClass);
39698 field.el.dom.title = msg;
39700 clear: function(field){
39701 field.el.dom.title = '';
39705 mark: function(field, msg){
39706 field.el.addClass(field.invalidClass);
39707 if(!field.errorEl){
39708 var elp = field.getErrorCt();
39710 field.el.dom.title = msg;
39713 field.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
39714 field.on('resize', field.alignErrorEl, field);
39715 field.on('destroy', function(){
39716 Ext.destroy(this.errorEl);
39719 field.alignErrorEl();
39720 field.errorEl.update(msg);
39721 Ext.form.Field.msgFx[field.msgFx].show(field.errorEl, field);
39723 clear: function(field){
39724 field.el.removeClass(field.invalidClass);
39726 Ext.form.Field.msgFx[field.msgFx].hide(field.errorEl, field);
39728 field.el.dom.title = '';
39733 mark: function(field, msg){
39734 field.el.addClass(field.invalidClass);
39735 if(!field.errorIcon){
39736 var elp = field.getErrorCt();
39739 field.el.dom.title = msg;
39742 field.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
39743 if (field.ownerCt) {
39744 field.ownerCt.on('afterlayout', field.alignErrorIcon, field);
39745 field.ownerCt.on('expand', field.alignErrorIcon, field);
39747 field.on('resize', field.alignErrorIcon, field);
39748 field.on('destroy', function(){
39749 Ext.destroy(this.errorIcon);
39752 field.alignErrorIcon();
39753 field.errorIcon.dom.qtip = msg;
39754 field.errorIcon.dom.qclass = 'x-form-invalid-tip';
39755 field.errorIcon.show();
39757 clear: function(field){
39758 field.el.removeClass(field.invalidClass);
39759 if(field.errorIcon){
39760 field.errorIcon.dom.qtip = '';
39761 field.errorIcon.hide();
39763 field.el.dom.title = '';
39770 Ext.form.Field.msgFx = {
39772 show: function(msgEl, f){
39773 msgEl.setDisplayed('block');
39776 hide : function(msgEl, f){
39777 msgEl.setDisplayed(false).update('');
39782 show: function(msgEl, f){
39783 msgEl.slideIn('t', {stopFx:true});
39786 hide : function(msgEl, f){
39787 msgEl.slideOut('t', {stopFx:true,useDisplay:true});
39792 show: function(msgEl, f){
39793 msgEl.fixDisplay();
39794 msgEl.alignTo(f.el, 'tl-tr');
39795 msgEl.slideIn('l', {stopFx:true});
39798 hide : function(msgEl, f){
39799 msgEl.slideOut('l', {stopFx:true,useDisplay:true});
39803 Ext.reg('field', Ext.form.Field);
39805 Ext.form.TextField = Ext.extend(Ext.form.Field, {
39819 disableKeyFilter : false,
39825 maxLength : Number.MAX_VALUE,
39827 minLengthText : 'The minimum length for this field is {0}',
39829 maxLengthText : 'The maximum length for this field is {0}',
39831 selectOnFocus : false,
39833 blankText : 'This field is required',
39843 emptyClass : 'x-form-empty-field',
39847 initComponent : function(){
39848 Ext.form.TextField.superclass.initComponent.call(this);
39863 initEvents : function(){
39864 Ext.form.TextField.superclass.initEvents.call(this);
39865 if(this.validationEvent == 'keyup'){
39866 this.validationTask = new Ext.util.DelayedTask(this.validate, this);
39867 this.mon(this.el, 'keyup', this.filterValidation, this);
39869 else if(this.validationEvent !== false && this.validationEvent != 'blur'){
39870 this.mon(this.el, this.validationEvent, this.validate, this, {buffer: this.validationDelay});
39872 if(this.selectOnFocus || this.emptyText){
39873 this.mon(this.el, 'mousedown', this.onMouseDown, this);
39875 if(this.emptyText){
39876 this.applyEmptyText();
39879 if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Ext.form.VTypes[this.vtype+'Mask']))){
39880 this.mon(this.el, 'keypress', this.filterKeys, this);
39883 this.mon(this.el, 'keyup', this.onKeyUpBuffered, this, {buffer: 50});
39884 this.mon(this.el, 'click', this.autoSize, this);
39886 if(this.enableKeyEvents){
39887 this.mon(this.el, {
39889 keyup: this.onKeyUp,
39890 keydown: this.onKeyDown,
39891 keypress: this.onKeyPress
39896 onMouseDown: function(e){
39897 if(!this.hasFocus){
39898 this.mon(this.el, 'mouseup', Ext.emptyFn, this, { single: true, preventDefault: true });
39902 processValue : function(value){
39903 if(this.stripCharsRe){
39904 var newValue = value.replace(this.stripCharsRe, '');
39905 if(newValue !== value){
39906 this.setRawValue(newValue);
39913 filterValidation : function(e){
39914 if(!e.isNavKeyPress()){
39915 this.validationTask.delay(this.validationDelay);
39920 onDisable: function(){
39921 Ext.form.TextField.superclass.onDisable.call(this);
39923 this.el.dom.unselectable = 'on';
39928 onEnable: function(){
39929 Ext.form.TextField.superclass.onEnable.call(this);
39931 this.el.dom.unselectable = '';
39936 onKeyUpBuffered : function(e){
39937 if(this.doAutoSize(e)){
39943 doAutoSize : function(e){
39944 return !e.isNavKeyPress();
39948 onKeyUp : function(e){
39949 this.fireEvent('keyup', this, e);
39953 onKeyDown : function(e){
39954 this.fireEvent('keydown', this, e);
39958 onKeyPress : function(e){
39959 this.fireEvent('keypress', this, e);
39963 reset : function(){
39964 Ext.form.TextField.superclass.reset.call(this);
39965 this.applyEmptyText();
39968 applyEmptyText : function(){
39969 if(this.rendered && this.emptyText && this.getRawValue().length < 1 && !this.hasFocus){
39970 this.setRawValue(this.emptyText);
39971 this.el.addClass(this.emptyClass);
39976 preFocus : function(){
39979 if(this.emptyText){
39980 if(el.dom.value == this.emptyText){
39981 this.setRawValue('');
39984 el.removeClass(this.emptyClass);
39986 if(this.selectOnFocus || isEmpty){
39992 postBlur : function(){
39993 this.applyEmptyText();
39997 filterKeys : function(e){
40001 var k = e.getKey();
40002 if(Ext.isGecko && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
40005 var cc = String.fromCharCode(e.getCharCode());
40006 if(!Ext.isGecko && e.isSpecialKey() && !cc){
40009 if(!this.maskRe.test(cc)){
40014 setValue : function(v){
40015 if(this.emptyText && this.el && !Ext.isEmpty(v)){
40016 this.el.removeClass(this.emptyClass);
40018 Ext.form.TextField.superclass.setValue.apply(this, arguments);
40019 this.applyEmptyText();
40025 getErrors: function(value) {
40026 var errors = Ext.form.TextField.superclass.getErrors.apply(this, arguments);
40028 value = Ext.isDefined(value) ? value : this.processValue(this.getRawValue());
40030 if (Ext.isFunction(this.validator)) {
40031 var msg = this.validator(value);
40032 if (msg !== true) {
40037 if (value.length < 1 || value === this.emptyText) {
40038 if (this.allowBlank) {
40042 errors.push(this.blankText);
40046 if (!this.allowBlank && (value.length < 1 || value === this.emptyText)) {
40047 errors.push(this.blankText);
40050 if (value.length < this.minLength) {
40051 errors.push(String.format(this.minLengthText, this.minLength));
40054 if (value.length > this.maxLength) {
40055 errors.push(String.format(this.maxLengthText, this.maxLength));
40059 var vt = Ext.form.VTypes;
40060 if(!vt[this.vtype](value, this)){
40061 errors.push(this.vtypeText || vt[this.vtype +'Text']);
40065 if (this.regex && !this.regex.test(value)) {
40066 errors.push(this.regexText);
40073 selectText : function(start, end){
40074 var v = this.getRawValue();
40075 var doFocus = false;
40077 start = start === undefined ? 0 : start;
40078 end = end === undefined ? v.length : end;
40079 var d = this.el.dom;
40080 if(d.setSelectionRange){
40081 d.setSelectionRange(start, end);
40082 }else if(d.createTextRange){
40083 var range = d.createTextRange();
40084 range.moveStart('character', start);
40085 range.moveEnd('character', end-v.length);
40088 doFocus = Ext.isGecko || Ext.isOpera;
40098 autoSize : function(){
40099 if(!this.grow || !this.rendered){
40103 this.metrics = Ext.util.TextMetrics.createInstance(this.el);
40106 var v = el.dom.value;
40107 var d = document.createElement('div');
40108 d.appendChild(document.createTextNode(v));
40113 var w = Math.min(this.growMax, Math.max(this.metrics.getWidth(v) + 10, this.growMin));
40114 this.el.setWidth(w);
40115 this.fireEvent('autosize', this, w);
40118 onDestroy: function(){
40119 if(this.validationTask){
40120 this.validationTask.cancel();
40121 this.validationTask = null;
40123 Ext.form.TextField.superclass.onDestroy.call(this);
40126 Ext.reg('textfield', Ext.form.TextField);
40128 Ext.form.TriggerField = Ext.extend(Ext.form.TextField, {
40132 defaultAutoCreate : {tag: "input", type: "text", size: "16", autocomplete: "off"},
40140 wrapFocusClass: 'x-trigger-wrap-focus',
40142 autoSize: Ext.emptyFn,
40146 deferHeight : true,
40150 actionMode: 'wrap',
40152 defaultTriggerWidth: 17,
40155 onResize : function(w, h){
40156 Ext.form.TriggerField.superclass.onResize.call(this, w, h);
40157 var tw = this.getTriggerWidth();
40158 if(Ext.isNumber(w)){
40159 this.el.setWidth(w - tw);
40161 this.wrap.setWidth(this.el.getWidth() + tw);
40164 getTriggerWidth: function(){
40165 var tw = this.trigger.getWidth();
40166 if(!this.hideTrigger && !this.readOnly && tw === 0){
40167 tw = this.defaultTriggerWidth;
40173 alignErrorIcon : function(){
40175 this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
40180 onRender : function(ct, position){
40181 this.doc = Ext.isIE ? Ext.getBody() : Ext.getDoc();
40182 Ext.form.TriggerField.superclass.onRender.call(this, ct, position);
40184 this.wrap = this.el.wrap({cls: 'x-form-field-wrap x-form-field-trigger-wrap'});
40185 this.trigger = this.wrap.createChild(this.triggerConfig ||
40186 {tag: "img", src: Ext.BLANK_IMAGE_URL, alt: "", cls: "x-form-trigger " + this.triggerClass});
40187 this.initTrigger();
40189 this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
40191 this.resizeEl = this.positionEl = this.wrap;
40194 getWidth: function() {
40195 return(this.el.getWidth() + this.trigger.getWidth());
40198 updateEditState: function(){
40200 if (this.readOnly) {
40201 this.el.dom.readOnly = true;
40202 this.el.addClass('x-trigger-noedit');
40203 this.mun(this.el, 'click', this.onTriggerClick, this);
40204 this.trigger.setDisplayed(false);
40206 if (!this.editable) {
40207 this.el.dom.readOnly = true;
40208 this.el.addClass('x-trigger-noedit');
40209 this.mon(this.el, 'click', this.onTriggerClick, this);
40211 this.el.dom.readOnly = false;
40212 this.el.removeClass('x-trigger-noedit');
40213 this.mun(this.el, 'click', this.onTriggerClick, this);
40215 this.trigger.setDisplayed(!this.hideTrigger);
40217 this.onResize(this.width || this.wrap.getWidth());
40222 setHideTrigger: function(hideTrigger){
40223 if(hideTrigger != this.hideTrigger){
40224 this.hideTrigger = hideTrigger;
40225 this.updateEditState();
40230 setEditable: function(editable){
40231 if(editable != this.editable){
40232 this.editable = editable;
40233 this.updateEditState();
40238 setReadOnly: function(readOnly){
40239 if(readOnly != this.readOnly){
40240 this.readOnly = readOnly;
40241 this.updateEditState();
40245 afterRender : function(){
40246 Ext.form.TriggerField.superclass.afterRender.call(this);
40247 this.updateEditState();
40251 initTrigger : function(){
40252 this.mon(this.trigger, 'click', this.onTriggerClick, this, {preventDefault:true});
40253 this.trigger.addClassOnOver('x-form-trigger-over');
40254 this.trigger.addClassOnClick('x-form-trigger-click');
40258 onDestroy : function(){
40259 Ext.destroy(this.trigger, this.wrap);
40260 if (this.mimicing){
40261 this.doc.un('mousedown', this.mimicBlur, this);
40264 Ext.form.TriggerField.superclass.onDestroy.call(this);
40268 onFocus : function(){
40269 Ext.form.TriggerField.superclass.onFocus.call(this);
40270 if(!this.mimicing){
40271 this.wrap.addClass(this.wrapFocusClass);
40272 this.mimicing = true;
40273 this.doc.on('mousedown', this.mimicBlur, this, {delay: 10});
40274 if(this.monitorTab){
40275 this.on('specialkey', this.checkTab, this);
40281 checkTab : function(me, e){
40282 if(e.getKey() == e.TAB){
40283 this.triggerBlur();
40288 onBlur : Ext.emptyFn,
40291 mimicBlur : function(e){
40292 if(!this.isDestroyed && !this.wrap.contains(e.target) && this.validateBlur(e)){
40293 this.triggerBlur();
40298 triggerBlur : function(){
40299 this.mimicing = false;
40300 this.doc.un('mousedown', this.mimicBlur, this);
40301 if(this.monitorTab && this.el){
40302 this.un('specialkey', this.checkTab, this);
40304 Ext.form.TriggerField.superclass.onBlur.call(this);
40306 this.wrap.removeClass(this.wrapFocusClass);
40310 beforeBlur : Ext.emptyFn,
40314 validateBlur : function(e){
40319 onTriggerClick : Ext.emptyFn
40327 Ext.form.TwinTriggerField = Ext.extend(Ext.form.TriggerField, {
40332 initComponent : function(){
40333 Ext.form.TwinTriggerField.superclass.initComponent.call(this);
40335 this.triggerConfig = {
40336 tag:'span', cls:'x-form-twin-triggers', cn:[
40337 {tag: "img", src: Ext.BLANK_IMAGE_URL, alt: "", cls: "x-form-trigger " + this.trigger1Class},
40338 {tag: "img", src: Ext.BLANK_IMAGE_URL, alt: "", cls: "x-form-trigger " + this.trigger2Class}
40342 getTrigger : function(index){
40343 return this.triggers[index];
40346 afterRender: function(){
40347 Ext.form.TwinTriggerField.superclass.afterRender.call(this);
40348 var triggers = this.triggers,
40350 len = triggers.length;
40352 for(; i < len; ++i){
40353 if(this['hideTrigger' + (i + 1)]){
40354 triggers[i].hide();
40360 initTrigger : function(){
40361 var ts = this.trigger.select('.x-form-trigger', true),
40362 triggerField = this;
40364 ts.each(function(t, all, index){
40365 var triggerIndex = 'Trigger'+(index+1);
40366 t.hide = function(){
40367 var w = triggerField.wrap.getWidth();
40368 this.dom.style.display = 'none';
40369 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
40370 triggerField['hidden' + triggerIndex] = true;
40372 t.show = function(){
40373 var w = triggerField.wrap.getWidth();
40374 this.dom.style.display = '';
40375 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
40376 triggerField['hidden' + triggerIndex] = false;
40378 this.mon(t, 'click', this['on'+triggerIndex+'Click'], this, {preventDefault:true});
40379 t.addClassOnOver('x-form-trigger-over');
40380 t.addClassOnClick('x-form-trigger-click');
40382 this.triggers = ts.elements;
40385 getTriggerWidth: function(){
40387 Ext.each(this.triggers, function(t, index){
40388 var triggerIndex = 'Trigger' + (index + 1),
40390 if(w === 0 && !this['hidden' + triggerIndex]){
40391 tw += this.defaultTriggerWidth;
40400 onDestroy : function() {
40401 Ext.destroy(this.triggers);
40402 Ext.form.TwinTriggerField.superclass.onDestroy.call(this);
40406 onTrigger1Click : Ext.emptyFn,
40408 onTrigger2Click : Ext.emptyFn
40410 Ext.reg('trigger', Ext.form.TriggerField);
40412 Ext.form.TextArea = Ext.extend(Ext.form.TextField, {
40417 growAppend : ' \n ',
40419 enterIsSpecial : false,
40422 preventScrollbars: false,
40426 onRender : function(ct, position){
40428 this.defaultAutoCreate = {
40430 style:"width:100px;height:60px;",
40431 autocomplete: "off"
40434 Ext.form.TextArea.superclass.onRender.call(this, ct, position);
40436 this.textSizeEl = Ext.DomHelper.append(document.body, {
40437 tag: "pre", cls: "x-form-grow-sizer"
40439 if(this.preventScrollbars){
40440 this.el.setStyle("overflow", "hidden");
40442 this.el.setHeight(this.growMin);
40446 onDestroy : function(){
40447 Ext.removeNode(this.textSizeEl);
40448 Ext.form.TextArea.superclass.onDestroy.call(this);
40451 fireKey : function(e){
40452 if(e.isSpecialKey() && (this.enterIsSpecial || (e.getKey() != e.ENTER || e.hasModifier()))){
40453 this.fireEvent("specialkey", this, e);
40458 doAutoSize : function(e){
40459 return !e.isNavKeyPress() || e.getKey() == e.ENTER;
40463 filterValidation: function(e) {
40464 if(!e.isNavKeyPress() || (!this.enterIsSpecial && e.keyCode == e.ENTER)){
40465 this.validationTask.delay(this.validationDelay);
40470 autoSize: function(){
40471 if(!this.grow || !this.textSizeEl){
40475 v = Ext.util.Format.htmlEncode(el.dom.value),
40476 ts = this.textSizeEl,
40479 Ext.fly(ts).setWidth(this.el.getWidth());
40481 v = "  ";
40483 v += this.growAppend;
40485 v = v.replace(/\n/g, ' <br />');
40489 h = Math.min(this.growMax, Math.max(ts.offsetHeight, this.growMin));
40490 if(h != this.lastHeight){
40491 this.lastHeight = h;
40492 this.el.setHeight(h);
40493 this.fireEvent("autosize", this, h);
40497 Ext.reg('textarea', Ext.form.TextArea);
40498 Ext.form.NumberField = Ext.extend(Ext.form.TextField, {
40502 fieldClass: "x-form-field x-form-num-field",
40505 allowDecimals : true,
40508 decimalSeparator : ".",
40511 decimalPrecision : 2,
40514 allowNegative : true,
40517 minValue : Number.NEGATIVE_INFINITY,
40520 maxValue : Number.MAX_VALUE,
40523 minText : "The minimum value for this field is {0}",
40526 maxText : "The maximum value for this field is {0}",
40529 nanText : "{0} is not a valid number",
40532 baseChars : "0123456789",
40535 autoStripChars: false,
40538 initEvents : function() {
40539 var allowed = this.baseChars + '';
40540 if (this.allowDecimals) {
40541 allowed += this.decimalSeparator;
40543 if (this.allowNegative) {
40546 allowed = Ext.escapeRe(allowed);
40547 this.maskRe = new RegExp('[' + allowed + ']');
40548 if (this.autoStripChars) {
40549 this.stripCharsRe = new RegExp('[^' + allowed + ']', 'gi');
40552 Ext.form.NumberField.superclass.initEvents.call(this);
40556 getErrors: function(value) {
40557 var errors = Ext.form.NumberField.superclass.getErrors.apply(this, arguments);
40559 value = Ext.isDefined(value) ? value : this.processValue(this.getRawValue());
40561 if (value.length < 1) {
40565 value = String(value).replace(this.decimalSeparator, ".");
40568 errors.push(String.format(this.nanText, value));
40571 var num = this.parseValue(value);
40573 if (num < this.minValue) {
40574 errors.push(String.format(this.minText, this.minValue));
40577 if (num > this.maxValue) {
40578 errors.push(String.format(this.maxText, this.maxValue));
40584 getValue : function() {
40585 return this.fixPrecision(this.parseValue(Ext.form.NumberField.superclass.getValue.call(this)));
40588 setValue : function(v) {
40589 v = this.fixPrecision(v);
40590 v = Ext.isNumber(v) ? v : parseFloat(String(v).replace(this.decimalSeparator, "."));
40591 v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator);
40592 return Ext.form.NumberField.superclass.setValue.call(this, v);
40596 setMinValue : function(value) {
40597 this.minValue = Ext.num(value, Number.NEGATIVE_INFINITY);
40601 setMaxValue : function(value) {
40602 this.maxValue = Ext.num(value, Number.MAX_VALUE);
40606 parseValue : function(value) {
40607 value = parseFloat(String(value).replace(this.decimalSeparator, "."));
40608 return isNaN(value) ? '' : value;
40612 fixPrecision : function(value) {
40613 var nan = isNaN(value);
40615 if (!this.allowDecimals || this.decimalPrecision == -1 || nan || !value) {
40616 return nan ? '' : value;
40619 return parseFloat(parseFloat(value).toFixed(this.decimalPrecision));
40622 beforeBlur : function() {
40623 var v = this.parseValue(this.getRawValue());
40625 if (!Ext.isEmpty(v)) {
40631 Ext.reg('numberfield', Ext.form.NumberField);
40633 Ext.form.DateField = Ext.extend(Ext.form.TriggerField, {
40637 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|n-j|n/j",
40639 disabledDaysText : "Disabled",
40641 disabledDatesText : "Disabled",
40643 minText : "The date in this field must be equal to or after {0}",
40645 maxText : "The date in this field must be equal to or before {0}",
40647 invalidText : "{0} is not a valid date - it must be in the format {1}",
40649 triggerClass : 'x-form-date-trigger',
40663 defaultAutoCreate : {tag: "input", type: "text", size: "10", autocomplete: "off"},
40669 initTimeFormat: 'H',
40672 safeParse : function(value, format) {
40673 if (/[gGhH]/.test(format.replace(/(\\.)/g, ''))) {
40675 return Date.parseDate(value, format);
40678 var parsedDate = Date.parseDate(value + ' ' + this.initTime, format + ' ' + this.initTimeFormat);
40681 return parsedDate.clearTime();
40686 initComponent : function(){
40687 Ext.form.DateField.superclass.initComponent.call(this);
40694 if(Ext.isString(this.minValue)){
40695 this.minValue = this.parseDate(this.minValue);
40697 if(Ext.isString(this.maxValue)){
40698 this.maxValue = this.parseDate(this.maxValue);
40700 this.disabledDatesRE = null;
40701 this.initDisabledDays();
40704 initEvents: function() {
40705 Ext.form.DateField.superclass.initEvents.call(this);
40706 this.keyNav = new Ext.KeyNav(this.el, {
40707 "down": function(e) {
40708 this.onTriggerClick();
40717 initDisabledDays : function(){
40718 if(this.disabledDates){
40719 var dd = this.disabledDates,
40720 len = dd.length - 1,
40723 Ext.each(dd, function(d, i){
40724 re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i];
40729 this.disabledDatesRE = new RegExp(re + ')');
40734 setDisabledDates : function(dd){
40735 this.disabledDates = dd;
40736 this.initDisabledDays();
40738 this.menu.picker.setDisabledDates(this.disabledDatesRE);
40743 setDisabledDays : function(dd){
40744 this.disabledDays = dd;
40746 this.menu.picker.setDisabledDays(dd);
40751 setMinValue : function(dt){
40752 this.minValue = (Ext.isString(dt) ? this.parseDate(dt) : dt);
40754 this.menu.picker.setMinDate(this.minValue);
40759 setMaxValue : function(dt){
40760 this.maxValue = (Ext.isString(dt) ? this.parseDate(dt) : dt);
40762 this.menu.picker.setMaxDate(this.maxValue);
40767 getErrors: function(value) {
40768 var errors = Ext.form.DateField.superclass.getErrors.apply(this, arguments);
40770 value = this.formatDate(value || this.processValue(this.getRawValue()));
40772 if (value.length < 1) {
40776 var svalue = value;
40777 value = this.parseDate(value);
40779 errors.push(String.format(this.invalidText, svalue, this.format));
40783 var time = value.getTime();
40784 if (this.minValue && time < this.minValue.clearTime().getTime()) {
40785 errors.push(String.format(this.minText, this.formatDate(this.minValue)));
40788 if (this.maxValue && time > this.maxValue.clearTime().getTime()) {
40789 errors.push(String.format(this.maxText, this.formatDate(this.maxValue)));
40792 if (this.disabledDays) {
40793 var day = value.getDay();
40795 for(var i = 0; i < this.disabledDays.length; i++) {
40796 if (day === this.disabledDays[i]) {
40797 errors.push(this.disabledDaysText);
40803 var fvalue = this.formatDate(value);
40804 if (this.disabledDatesRE && this.disabledDatesRE.test(fvalue)) {
40805 errors.push(String.format(this.disabledDatesText, fvalue));
40813 validateBlur : function(){
40814 return !this.menu || !this.menu.isVisible();
40818 getValue : function(){
40819 return this.parseDate(Ext.form.DateField.superclass.getValue.call(this)) || "";
40823 setValue : function(date){
40824 return Ext.form.DateField.superclass.setValue.call(this, this.formatDate(this.parseDate(date)));
40828 parseDate : function(value) {
40829 if(!value || Ext.isDate(value)){
40833 var v = this.safeParse(value, this.format),
40834 af = this.altFormats,
40835 afa = this.altFormatsArray;
40838 afa = afa || af.split("|");
40840 for (var i = 0, len = afa.length; i < len && !v; i++) {
40841 v = this.safeParse(value, afa[i]);
40848 onDestroy : function(){
40849 Ext.destroy(this.menu, this.keyNav);
40850 Ext.form.DateField.superclass.onDestroy.call(this);
40854 formatDate : function(date){
40855 return Ext.isDate(date) ? date.dateFormat(this.format) : date;
40861 onTriggerClick : function(){
40865 if(this.menu == null){
40866 this.menu = new Ext.menu.DateMenu({
40867 hideOnClick: false,
40868 focusOnSelect: false
40872 Ext.apply(this.menu.picker, {
40873 minDate : this.minValue,
40874 maxDate : this.maxValue,
40875 disabledDatesRE : this.disabledDatesRE,
40876 disabledDatesText : this.disabledDatesText,
40877 disabledDays : this.disabledDays,
40878 disabledDaysText : this.disabledDaysText,
40879 format : this.format,
40880 showToday : this.showToday,
40881 startDay: this.startDay,
40882 minText : String.format(this.minText, this.formatDate(this.minValue)),
40883 maxText : String.format(this.maxText, this.formatDate(this.maxValue))
40885 this.menu.picker.setValue(this.getValue() || new Date());
40886 this.menu.show(this.el, "tl-bl?");
40887 this.menuEvents('on');
40891 menuEvents: function(method){
40892 this.menu[method]('select', this.onSelect, this);
40893 this.menu[method]('hide', this.onMenuHide, this);
40894 this.menu[method]('show', this.onFocus, this);
40897 onSelect: function(m, d){
40899 this.fireEvent('select', this, d);
40903 onMenuHide: function(){
40904 this.focus(false, 60);
40905 this.menuEvents('un');
40909 beforeBlur : function(){
40910 var v = this.parseDate(this.getRawValue());
40921 Ext.reg('datefield', Ext.form.DateField);
40923 Ext.form.DisplayField = Ext.extend(Ext.form.Field, {
40924 validationEvent : false,
40925 validateOnBlur : false,
40926 defaultAutoCreate : {tag: "div"},
40928 fieldClass : "x-form-display-field",
40933 initEvents : Ext.emptyFn,
40935 isValid : function(){
40939 validate : function(){
40943 getRawValue : function(){
40944 var v = this.rendered ? this.el.dom.innerHTML : Ext.value(this.value, '');
40945 if(v === this.emptyText){
40948 if(this.htmlEncode){
40949 v = Ext.util.Format.htmlDecode(v);
40954 getValue : function(){
40955 return this.getRawValue();
40958 getName: function() {
40962 setRawValue : function(v){
40963 if(this.htmlEncode){
40964 v = Ext.util.Format.htmlEncode(v);
40966 return this.rendered ? (this.el.dom.innerHTML = (Ext.isEmpty(v) ? '' : v)) : (this.value = v);
40969 setValue : function(v){
40970 this.setRawValue(v);
40981 Ext.reg('displayfield', Ext.form.DisplayField);
40983 Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
40991 defaultAutoCreate : {tag: "input", type: "text", size: "24", autocomplete: "off"},
41001 selectedClass : 'x-combo-selected',
41005 triggerClass : 'x-form-arrow-trigger',
41009 listAlign : 'tl-bl?',
41015 triggerAction : 'query',
41027 selectOnFocus : false,
41029 queryParam : 'query',
41031 loadingText : 'Loading...',
41043 forceSelection : false,
41045 typeAheadDelay : 250,
41052 clearFilterOnReset : true,
41055 submitValue: undefined,
41060 initComponent : function(){
41061 Ext.form.ComboBox.superclass.initComponent.call(this);
41075 if(this.transform){
41076 var s = Ext.getDom(this.transform);
41077 if(!this.hiddenName){
41078 this.hiddenName = s.name;
41081 this.mode = 'local';
41082 var d = [], opts = s.options;
41083 for(var i = 0, len = opts.length;i < len; i++){
41085 value = (o.hasAttribute ? o.hasAttribute('value') : o.getAttributeNode('value').specified) ? o.value : o.text;
41086 if(o.selected && Ext.isEmpty(this.value, true)) {
41087 this.value = value;
41089 d.push([value, o.text]);
41091 this.store = new Ext.data.ArrayStore({
41093 fields: ['value', 'text'],
41097 this.valueField = 'value';
41098 this.displayField = 'text';
41101 if(!this.lazyRender){
41102 this.target = true;
41103 this.el = Ext.DomHelper.insertBefore(s, this.autoCreate || this.defaultAutoCreate);
41104 this.render(this.el.parentNode, s);
41109 else if(this.store){
41110 this.store = Ext.StoreMgr.lookup(this.store);
41111 if(this.store.autoCreated){
41112 this.displayField = this.valueField = 'field1';
41113 if(!this.store.expandData){
41114 this.displayField = 'field2';
41116 this.mode = 'local';
41120 this.selectedIndex = -1;
41121 if(this.mode == 'local'){
41122 if(!Ext.isDefined(this.initialConfig.queryDelay)){
41123 this.queryDelay = 10;
41125 if(!Ext.isDefined(this.initialConfig.minChars)){
41132 onRender : function(ct, position){
41133 if(this.hiddenName && !Ext.isDefined(this.submitValue)){
41134 this.submitValue = false;
41136 Ext.form.ComboBox.superclass.onRender.call(this, ct, position);
41137 if(this.hiddenName){
41138 this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName,
41139 id: (this.hiddenId || Ext.id())}, 'before', true);
41143 this.el.dom.setAttribute('autocomplete', 'off');
41146 if(!this.lazyInit){
41149 this.on('focus', this.initList, this, {single: true});
41154 initValue : function(){
41155 Ext.form.ComboBox.superclass.initValue.call(this);
41156 if(this.hiddenField){
41157 this.hiddenField.value =
41158 Ext.value(Ext.isDefined(this.hiddenValue) ? this.hiddenValue : this.value, '');
41162 getParentZIndex : function(){
41165 this.findParentBy(function(ct){
41166 zindex = parseInt(ct.getPositionEl().getStyle('z-index'), 10);
41173 getZIndex : function(listParent){
41174 listParent = listParent || Ext.getDom(this.getListParent() || Ext.getBody());
41175 var zindex = parseInt(Ext.fly(listParent).getStyle('z-index'), 10);
41177 zindex = this.getParentZIndex();
41179 return (zindex || 12000) + 5;
41183 initList : function(){
41185 var cls = 'x-combo-list',
41186 listParent = Ext.getDom(this.getListParent() || Ext.getBody());
41188 this.list = new Ext.Layer({
41189 parentEl: listParent,
41190 shadow: this.shadow,
41191 cls: [cls, this.listClass].join(' '),
41193 zindex: this.getZIndex(listParent)
41196 var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
41197 this.list.setSize(lw, 0);
41198 this.list.swallowEvent('mousewheel');
41199 this.assetHeight = 0;
41200 if(this.syncFont !== false){
41201 this.list.setStyle('font-size', this.el.getStyle('font-size'));
41204 this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
41205 this.assetHeight += this.header.getHeight();
41208 this.innerList = this.list.createChild({cls:cls+'-inner'});
41209 this.mon(this.innerList, 'mouseover', this.onViewOver, this);
41210 this.mon(this.innerList, 'mousemove', this.onViewMove, this);
41211 this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
41214 this.footer = this.list.createChild({cls:cls+'-ft'});
41215 this.pageTb = new Ext.PagingToolbar({
41217 pageSize: this.pageSize,
41218 renderTo:this.footer
41220 this.assetHeight += this.footer.getHeight();
41225 this.tpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';
41230 this.view = new Ext.DataView({
41231 applyTo: this.innerList,
41233 singleSelect: true,
41234 selectedClass: this.selectedClass,
41235 itemSelector: this.itemSelector || '.' + cls + '-item',
41236 emptyText: this.listEmptyText,
41237 deferEmptyText: false
41240 this.mon(this.view, {
41241 containerclick : this.onViewClick,
41242 click : this.onViewClick,
41246 this.bindStore(this.store, true);
41248 if(this.resizable){
41249 this.resizer = new Ext.Resizable(this.list, {
41250 pinned:true, handles:'se'
41252 this.mon(this.resizer, 'resize', function(r, w, h){
41253 this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
41254 this.listWidth = w;
41255 this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
41256 this.restrictHeight();
41259 this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
41265 getListParent : function() {
41266 return document.body;
41270 getStore : function(){
41275 bindStore : function(store, initial){
41276 if(this.store && !initial){
41277 if(this.store !== store && this.store.autoDestroy){
41278 this.store.destroy();
41280 this.store.un('beforeload', this.onBeforeLoad, this);
41281 this.store.un('load', this.onLoad, this);
41282 this.store.un('exception', this.collapse, this);
41287 this.view.bindStore(null);
41290 this.pageTb.bindStore(null);
41296 this.lastQuery = null;
41298 this.pageTb.bindStore(store);
41302 this.store = Ext.StoreMgr.lookup(store);
41305 beforeload: this.onBeforeLoad,
41307 exception: this.collapse
41311 this.view.bindStore(store);
41316 reset : function(){
41317 if(this.clearFilterOnReset && this.mode == 'local'){
41318 this.store.clearFilter();
41320 Ext.form.ComboBox.superclass.reset.call(this);
41324 initEvents : function(){
41325 Ext.form.ComboBox.superclass.initEvents.call(this);
41328 this.keyNav = new Ext.KeyNav(this.el, {
41329 "up" : function(e){
41330 this.inKeyMode = true;
41334 "down" : function(e){
41335 if(!this.isExpanded()){
41336 this.onTriggerClick();
41338 this.inKeyMode = true;
41343 "enter" : function(e){
41344 this.onViewClick();
41347 "esc" : function(e){
41351 "tab" : function(e){
41352 if (this.forceSelection === true) {
41355 this.onViewClick(false);
41362 doRelay : function(e, h, hname){
41363 if(hname == 'down' || this.scope.isExpanded()){
41365 var relay = Ext.KeyNav.prototype.doRelay.apply(this, arguments);
41366 if(!Ext.isIE && Ext.EventManager.useKeydown){
41368 this.scope.fireKey(e);
41375 forceKeyDown : true,
41376 defaultEventAction: 'stopEvent'
41378 this.queryDelay = Math.max(this.queryDelay || 10,
41379 this.mode == 'local' ? 10 : 250);
41380 this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);
41381 if(this.typeAhead){
41382 this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
41384 if(!this.enableKeyEvents){
41385 this.mon(this.el, 'keyup', this.onKeyUp, this);
41391 onDestroy : function(){
41393 this.dqTask.cancel();
41394 this.dqTask = null;
41396 this.bindStore(null);
41403 Ext.destroyMembers(this, 'hiddenField');
41404 Ext.form.ComboBox.superclass.onDestroy.call(this);
41408 fireKey : function(e){
41409 if (!this.isExpanded()) {
41410 Ext.form.ComboBox.superclass.fireKey.call(this, e);
41415 onResize : function(w, h){
41416 Ext.form.ComboBox.superclass.onResize.apply(this, arguments);
41417 if(!isNaN(w) && this.isVisible() && this.list){
41420 this.bufferSize = w;
41424 doResize: function(w){
41425 if(!Ext.isDefined(this.listWidth)){
41426 var lw = Math.max(w, this.minListWidth);
41427 this.list.setWidth(lw);
41428 this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
41433 onEnable : function(){
41434 Ext.form.ComboBox.superclass.onEnable.apply(this, arguments);
41435 if(this.hiddenField){
41436 this.hiddenField.disabled = false;
41441 onDisable : function(){
41442 Ext.form.ComboBox.superclass.onDisable.apply(this, arguments);
41443 if(this.hiddenField){
41444 this.hiddenField.disabled = true;
41449 onBeforeLoad : function(){
41450 if(!this.hasFocus){
41453 this.innerList.update(this.loadingText ?
41454 '<div class="loading-indicator">'+this.loadingText+'</div>' : '');
41455 this.restrictHeight();
41456 this.selectedIndex = -1;
41460 onLoad : function(){
41461 if(!this.hasFocus){
41464 if(this.store.getCount() > 0 || this.listEmptyText){
41466 this.restrictHeight();
41467 if(this.lastQuery == this.allQuery){
41469 this.el.dom.select();
41472 if(this.autoSelect !== false && !this.selectByValue(this.value, true)){
41473 this.select(0, true);
41476 if(this.autoSelect !== false){
41479 if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){
41480 this.taTask.delay(this.typeAheadDelay);
41490 onTypeAhead : function(){
41491 if(this.store.getCount() > 0){
41492 var r = this.store.getAt(0);
41493 var newValue = r.data[this.displayField];
41494 var len = newValue.length;
41495 var selStart = this.getRawValue().length;
41496 if(selStart != len){
41497 this.setRawValue(newValue);
41498 this.selectText(selStart, newValue.length);
41504 assertValue : function(){
41505 var val = this.getRawValue(),
41508 if(this.valueField && Ext.isDefined(this.value)){
41509 rec = this.findRecord(this.valueField, this.value);
41511 if(!rec || rec.get(this.displayField) != val){
41512 rec = this.findRecord(this.displayField, val);
41514 if(!rec && this.forceSelection){
41515 if(val.length > 0 && val != this.emptyText){
41516 this.el.dom.value = Ext.value(this.lastSelectionText, '');
41517 this.applyEmptyText();
41522 if(rec && this.valueField){
41526 if (this.value == val){
41529 val = rec.get(this.valueField || this.displayField);
41531 this.setValue(val);
41536 onSelect : function(record, index){
41537 if(this.fireEvent('beforeselect', this, record, index) !== false){
41538 this.setValue(record.data[this.valueField || this.displayField]);
41540 this.fireEvent('select', this, record, index);
41545 getName: function(){
41546 var hf = this.hiddenField;
41547 return hf && hf.name ? hf.name : this.hiddenName || Ext.form.ComboBox.superclass.getName.call(this);
41551 getValue : function(){
41552 if(this.valueField){
41553 return Ext.isDefined(this.value) ? this.value : '';
41555 return Ext.form.ComboBox.superclass.getValue.call(this);
41560 clearValue : function(){
41561 if(this.hiddenField){
41562 this.hiddenField.value = '';
41564 this.setRawValue('');
41565 this.lastSelectionText = '';
41566 this.applyEmptyText();
41571 setValue : function(v){
41573 if(this.valueField){
41574 var r = this.findRecord(this.valueField, v);
41576 text = r.data[this.displayField];
41577 }else if(Ext.isDefined(this.valueNotFoundText)){
41578 text = this.valueNotFoundText;
41581 this.lastSelectionText = text;
41582 if(this.hiddenField){
41583 this.hiddenField.value = Ext.value(v, '');
41585 Ext.form.ComboBox.superclass.setValue.call(this, text);
41591 findRecord : function(prop, value){
41593 if(this.store.getCount() > 0){
41594 this.store.each(function(r){
41595 if(r.data[prop] == value){
41605 onViewMove : function(e, t){
41606 this.inKeyMode = false;
41610 onViewOver : function(e, t){
41611 if(this.inKeyMode){
41614 var item = this.view.findItemFromChild(t);
41616 var index = this.view.indexOf(item);
41617 this.select(index, false);
41622 onViewClick : function(doFocus){
41623 var index = this.view.getSelectedIndexes()[0],
41625 r = s.getAt(index);
41627 this.onSelect(r, index);
41631 if(doFocus !== false){
41638 restrictHeight : function(){
41639 this.innerList.dom.style.height = '';
41640 var inner = this.innerList.dom,
41641 pad = this.list.getFrameWidth('tb') + (this.resizable ? this.handleHeight : 0) + this.assetHeight,
41642 h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight),
41643 ha = this.getPosition()[1]-Ext.getBody().getScroll().top,
41644 hb = Ext.lib.Dom.getViewHeight()-ha-this.getSize().height,
41645 space = Math.max(ha, hb, this.minHeight || 0)-this.list.shadowOffset-pad-5;
41647 h = Math.min(h, space, this.maxHeight);
41649 this.innerList.setHeight(h);
41650 this.list.beginUpdate();
41651 this.list.setHeight(h+pad);
41652 this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
41653 this.list.endUpdate();
41657 isExpanded : function(){
41658 return this.list && this.list.isVisible();
41662 selectByValue : function(v, scrollIntoView){
41663 if(!Ext.isEmpty(v, true)){
41664 var r = this.findRecord(this.valueField || this.displayField, v);
41666 this.select(this.store.indexOf(r), scrollIntoView);
41674 select : function(index, scrollIntoView){
41675 this.selectedIndex = index;
41676 this.view.select(index);
41677 if(scrollIntoView !== false){
41678 var el = this.view.getNode(index);
41680 this.innerList.scrollChildIntoView(el, false);
41687 selectNext : function(){
41688 var ct = this.store.getCount();
41690 if(this.selectedIndex == -1){
41692 }else if(this.selectedIndex < ct-1){
41693 this.select(this.selectedIndex+1);
41699 selectPrev : function(){
41700 var ct = this.store.getCount();
41702 if(this.selectedIndex == -1){
41704 }else if(this.selectedIndex !== 0){
41705 this.select(this.selectedIndex-1);
41711 onKeyUp : function(e){
41712 var k = e.getKey();
41713 if(this.editable !== false && this.readOnly !== true && (k == e.BACKSPACE || !e.isSpecialKey())){
41716 this.dqTask.delay(this.queryDelay);
41718 Ext.form.ComboBox.superclass.onKeyUp.call(this, e);
41722 validateBlur : function(){
41723 return !this.list || !this.list.isVisible();
41727 initQuery : function(){
41728 this.doQuery(this.getRawValue());
41732 beforeBlur : function(){
41733 this.assertValue();
41737 postBlur : function(){
41738 Ext.form.ComboBox.superclass.postBlur.call(this);
41740 this.inKeyMode = false;
41744 doQuery : function(q, forceAll){
41745 q = Ext.isEmpty(q) ? '' : q;
41748 forceAll: forceAll,
41752 if(this.fireEvent('beforequery', qe)===false || qe.cancel){
41756 forceAll = qe.forceAll;
41757 if(forceAll === true || (q.length >= this.minChars)){
41758 if(this.lastQuery !== q){
41759 this.lastQuery = q;
41760 if(this.mode == 'local'){
41761 this.selectedIndex = -1;
41763 this.store.clearFilter();
41765 this.store.filter(this.displayField, q);
41769 this.store.baseParams[this.queryParam] = q;
41771 params: this.getParams(q)
41776 this.selectedIndex = -1;
41783 getParams : function(q){
41785 paramNames = this.store.paramNames;
41787 params[paramNames.start] = 0;
41788 params[paramNames.limit] = this.pageSize;
41794 collapse : function(){
41795 if(!this.isExpanded()){
41799 Ext.getDoc().un('mousewheel', this.collapseIf, this);
41800 Ext.getDoc().un('mousedown', this.collapseIf, this);
41801 this.fireEvent('collapse', this);
41805 collapseIf : function(e){
41806 if(!this.isDestroyed && !e.within(this.wrap) && !e.within(this.list)){
41812 expand : function(){
41813 if(this.isExpanded() || !this.hasFocus){
41817 if(this.title || this.pageSize){
41818 this.assetHeight = 0;
41820 this.assetHeight += this.header.getHeight();
41823 this.assetHeight += this.footer.getHeight();
41827 if(this.bufferSize){
41828 this.doResize(this.bufferSize);
41829 delete this.bufferSize;
41831 this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
41834 this.list.setZIndex(this.getZIndex());
41837 this.innerList.setOverflow('auto');
41839 this.mon(Ext.getDoc(), {
41841 mousewheel: this.collapseIf,
41842 mousedown: this.collapseIf
41844 this.fireEvent('expand', this);
41850 onTriggerClick : function(){
41851 if(this.readOnly || this.disabled){
41854 if(this.isExpanded()){
41859 if(this.triggerAction == 'all') {
41860 this.doQuery(this.allQuery, true);
41862 this.doQuery(this.getRawValue());
41874 Ext.reg('combo', Ext.form.ComboBox);
41876 Ext.form.Checkbox = Ext.extend(Ext.form.Field, {
41878 focusClass : undefined,
41880 fieldClass : 'x-form-field',
41884 boxLabel: ' ',
41886 defaultAutoCreate : { tag: 'input', type: 'checkbox', autocomplete: 'off'},
41892 actionMode : 'wrap',
41895 initComponent : function(){
41896 Ext.form.Checkbox.superclass.initComponent.call(this);
41904 onResize : function(){
41905 Ext.form.Checkbox.superclass.onResize.apply(this, arguments);
41906 if(!this.boxLabel && !this.fieldLabel){
41907 this.el.alignTo(this.wrap, 'c-c');
41912 initEvents : function(){
41913 Ext.form.Checkbox.superclass.initEvents.call(this);
41914 this.mon(this.el, {
41916 click: this.onClick,
41917 change: this.onClick
41922 markInvalid : Ext.emptyFn,
41924 clearInvalid : Ext.emptyFn,
41927 onRender : function(ct, position){
41928 Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
41929 if(this.inputValue !== undefined){
41930 this.el.dom.value = this.inputValue;
41932 this.wrap = this.el.wrap({cls: 'x-form-check-wrap'});
41934 this.wrap.createChild({tag: 'label', htmlFor: this.el.id, cls: 'x-form-cb-label', html: this.boxLabel});
41937 this.setValue(true);
41939 this.checked = this.el.dom.checked;
41942 if (Ext.isIE && !Ext.isStrict) {
41943 this.wrap.repaint();
41945 this.resizeEl = this.positionEl = this.wrap;
41949 onDestroy : function(){
41950 Ext.destroy(this.wrap);
41951 Ext.form.Checkbox.superclass.onDestroy.call(this);
41955 initValue : function() {
41956 this.originalValue = this.getValue();
41960 getValue : function(){
41962 return this.el.dom.checked;
41964 return this.checked;
41968 onClick : function(){
41969 if(this.el.dom.checked != this.checked){
41970 this.setValue(this.el.dom.checked);
41975 setValue : function(v){
41976 var checked = this.checked,
41977 inputVal = this.inputValue;
41979 this.checked = (v === true || v === 'true' || v == '1' || (inputVal ? v == inputVal : String(v).toLowerCase() == 'on'));
41981 this.el.dom.checked = this.checked;
41982 this.el.dom.defaultChecked = this.checked;
41984 if(checked != this.checked){
41985 this.fireEvent('check', this, this.checked);
41987 this.handler.call(this.scope || this, this, this.checked);
41993 Ext.reg('checkbox', Ext.form.Checkbox);
41995 Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {
42004 blankText : "You must select at least one item in this group",
42007 defaultType : 'checkbox',
42010 groupCls : 'x-form-check-group',
42013 initComponent: function(){
42018 this.on('change', this.validate, this);
42019 Ext.form.CheckboxGroup.superclass.initComponent.call(this);
42023 onRender : function(ct, position){
42029 cls: this.groupCls,
42032 bufferResize: false
42035 xtype: 'container',
42036 defaultType: this.defaultType,
42044 if(this.items[0].items){
42048 Ext.apply(panelCfg, {
42049 layoutConfig: {columns: this.items.length},
42050 defaults: this.defaults,
42053 for(var i=0, len=this.items.length; i<len; i++){
42054 Ext.applyIf(this.items[i], colCfg);
42062 var numCols, cols = [];
42064 if(typeof this.columns == 'string'){
42065 this.columns = this.items.length;
42067 if(!Ext.isArray(this.columns)){
42069 for(var i=0; i<this.columns; i++){
42070 cs.push((100/this.columns)*.01);
42075 numCols = this.columns.length;
42078 for(var i=0; i<numCols; i++){
42079 var cc = Ext.apply({items:[]}, colCfg);
42080 cc[this.columns[i] <= 1 ? 'columnWidth' : 'width'] = this.columns[i];
42082 cc.defaults = Ext.apply(cc.defaults || {}, this.defaults);
42089 var rows = Math.ceil(this.items.length / numCols), ri = 0;
42090 for(var i=0, len=this.items.length; i<len; i++){
42091 if(i>0 && i%rows==0){
42094 if(this.items[i].fieldLabel){
42095 this.items[i].hideLabel = false;
42097 cols[ri].items.push(this.items[i]);
42100 for(var i=0, len=this.items.length; i<len; i++){
42101 var ci = i % numCols;
42102 if(this.items[i].fieldLabel){
42103 this.items[i].hideLabel = false;
42105 cols[ci].items.push(this.items[i]);
42109 Ext.apply(panelCfg, {
42110 layoutConfig: {columns: numCols},
42115 this.panel = new Ext.Container(panelCfg);
42116 this.panel.ownerCt = this;
42117 this.el = this.panel.getEl();
42119 if(this.forId && this.itemCls){
42120 var l = this.el.up(this.itemCls).child('label', true);
42122 l.setAttribute('htmlFor', this.forId);
42126 var fields = this.panel.findBy(function(c){
42127 return c.isFormField;
42130 this.items = new Ext.util.MixedCollection();
42131 this.items.addAll(fields);
42133 Ext.form.CheckboxGroup.superclass.onRender.call(this, ct, position);
42136 initValue : function(){
42138 this.setValue.apply(this, this.buffered ? this.value : [this.value]);
42139 delete this.buffered;
42144 afterRender : function(){
42145 Ext.form.CheckboxGroup.superclass.afterRender.call(this);
42146 this.eachItem(function(item){
42147 item.on('check', this.fireChecked, this);
42148 item.inGroup = true;
42153 doLayout: function(){
42156 this.panel.forceLayout = this.ownerCt.forceLayout;
42157 this.panel.doLayout();
42162 fireChecked: function(){
42164 this.eachItem(function(item){
42169 this.fireEvent('change', this, arr);
42173 getErrors: function() {
42174 var errors = Ext.form.CheckboxGroup.superclass.getErrors.apply(this, arguments);
42176 if (!this.allowBlank) {
42179 this.eachItem(function(f){
42181 return (blank = false);
42185 if (blank) errors.push(this.blankText);
42192 isDirty: function(){
42194 if (this.disabled || !this.rendered) {
42200 this.eachItem(function(item){
42201 if(item.isDirty()){
42211 setReadOnly : function(readOnly){
42213 this.eachItem(function(item){
42214 item.setReadOnly(readOnly);
42217 this.readOnly = readOnly;
42221 onDisable : function(){
42222 this.eachItem(function(item){
42228 onEnable : function(){
42229 this.eachItem(function(item){
42235 onResize : function(w, h){
42236 this.panel.setSize(w, h);
42237 this.panel.doLayout();
42241 reset : function(){
42242 if (this.originalValue) {
42244 this.eachItem(function(c){
42247 c.originalValue = c.getValue();
42252 this.resetOriginal = true;
42253 this.setValue(this.originalValue);
42254 delete this.resetOriginal;
42256 this.eachItem(function(c){
42265 this.clearInvalid();
42266 }).defer(50, this);
42270 setValue: function(){
42272 this.onSetValue.apply(this, arguments);
42274 this.buffered = true;
42275 this.value = arguments;
42281 onSetValue: function(id, value){
42282 if(arguments.length == 1){
42283 if(Ext.isArray(id)){
42284 Ext.each(id, function(val, idx){
42285 if (Ext.isObject(val) && val.setValue){
42286 val.setValue(true);
42287 if (this.resetOriginal === true) {
42288 val.originalValue = val.getValue();
42291 var item = this.items.itemAt(idx);
42293 item.setValue(val);
42297 }else if(Ext.isObject(id)){
42300 var f = this.getBox(i);
42306 this.setValueForItem(id);
42309 var f = this.getBox(id);
42317 beforeDestroy: function(){
42318 Ext.destroy(this.panel);
42319 if (!this.rendered) {
42320 Ext.destroy(this.items);
42322 Ext.form.CheckboxGroup.superclass.beforeDestroy.call(this);
42326 setValueForItem : function(val){
42327 val = String(val).split(',');
42328 this.eachItem(function(item){
42329 if(val.indexOf(item.inputValue)> -1){
42330 item.setValue(true);
42336 getBox : function(id){
42338 this.eachItem(function(f){
42339 if(id == f || f.dataIndex == id || f.id == id || f.getName() == id){
42348 getValue : function(){
42350 this.eachItem(function(item){
42359 eachItem: function(fn, scope) {
42360 if(this.items && this.items.each){
42361 this.items.each(fn, scope || this);
42368 getRawValue : Ext.emptyFn,
42371 setRawValue : Ext.emptyFn
42375 Ext.reg('checkboxgroup', Ext.form.CheckboxGroup);
42377 Ext.form.CompositeField = Ext.extend(Ext.form.Field, {
42380 defaultMargins: '0 5 0 0',
42383 skipLastItemMargin: true,
42389 combineErrors: true,
42392 labelConnector: ', ',
42398 initComponent: function() {
42400 items = this.items,
42403 for (var i=0, j = items.length; i < j; i++) {
42406 if (!Ext.isEmpty(item.ref)){
42407 item.ref = '../' + item.ref;
42410 labels.push(item.fieldLabel);
42413 Ext.applyIf(item, this.defaults);
42416 if (!(i == j - 1 && this.skipLastItemMargin)) {
42417 Ext.applyIf(item, {margins: this.defaultMargins});
42421 this.fieldLabel = this.fieldLabel || this.buildLabel(labels);
42424 this.fieldErrors = new Ext.util.MixedCollection(true, function(item) {
42428 this.fieldErrors.on({
42430 add : this.updateInvalidMark,
42431 remove : this.updateInvalidMark,
42432 replace: this.updateInvalidMark
42435 Ext.form.CompositeField.superclass.initComponent.apply(this, arguments);
42437 this.innerCt = new Ext.Container({
42439 items : this.items,
42440 cls : 'x-form-composite',
42441 defaultMargins: '0 3 0 0',
42444 this.innerCt.ownerCt = undefined;
42446 var fields = this.innerCt.findBy(function(c) {
42447 return c.isFormField;
42451 this.items = new Ext.util.MixedCollection();
42452 this.items.addAll(fields);
42457 onRender: function(ct, position) {
42460 var innerCt = this.innerCt;
42461 innerCt.render(ct);
42463 this.el = innerCt.getEl();
42467 if (this.combineErrors) {
42468 this.eachItem(function(field) {
42470 markInvalid : this.onFieldMarkInvalid.createDelegate(this, [field], 0),
42471 clearInvalid: this.onFieldClearInvalid.createDelegate(this, [field], 0)
42477 var l = this.el.parent().parent().child('label', true);
42479 l.setAttribute('for', this.items.items[0].id);
42483 Ext.form.CompositeField.superclass.onRender.apply(this, arguments);
42487 onFieldMarkInvalid: function(field, message) {
42488 var name = field.getName(),
42491 errorName: field.fieldLabel || name,
42495 this.fieldErrors.replace(name, error);
42497 field.el.addClass(field.invalidClass);
42501 onFieldClearInvalid: function(field) {
42502 this.fieldErrors.removeKey(field.getName());
42504 field.el.removeClass(field.invalidClass);
42508 updateInvalidMark: function() {
42509 var ieStrict = Ext.isIE6 && Ext.isStrict;
42511 if (this.fieldErrors.length == 0) {
42512 this.clearInvalid();
42516 this.clearInvalid.defer(50, this);
42519 var message = this.buildCombinedErrorMessage(this.fieldErrors.items);
42522 this.markInvalid(message);
42526 this.markInvalid(message);
42532 validateValue: function() {
42535 this.eachItem(function(field) {
42536 if (!field.isValid()) valid = false;
42543 buildCombinedErrorMessage: function(errors) {
42547 for (var i = 0, j = errors.length; i < j; i++) {
42550 combined.push(String.format("{0}: {1}", error.errorName, error.error));
42553 return combined.join("<br />");
42557 sortErrors: function() {
42558 var fields = this.items;
42560 this.fieldErrors.sort("ASC", function(a, b) {
42561 var findByName = function(key) {
42562 return function(field) {
42563 return field.getName() == key;
42567 var aIndex = fields.findIndexBy(findByName(a.field)),
42568 bIndex = fields.findIndexBy(findByName(b.field));
42570 return aIndex < bIndex ? -1 : 1;
42575 reset: function() {
42576 this.eachItem(function(item) {
42583 this.clearInvalid();
42584 }).defer(50, this);
42588 clearInvalidChildren: function() {
42589 this.eachItem(function(item) {
42590 item.clearInvalid();
42595 buildLabel: function(segments) {
42596 return Ext.clean(segments).join(this.labelConnector);
42600 isDirty: function(){
42602 if (this.disabled || !this.rendered) {
42607 this.eachItem(function(item){
42608 if(item.isDirty()){
42617 eachItem: function(fn, scope) {
42618 if(this.items && this.items.each){
42619 this.items.each(fn, scope || this);
42624 onResize: function(adjWidth, adjHeight, rawWidth, rawHeight) {
42625 var innerCt = this.innerCt;
42627 if (this.rendered && innerCt.rendered) {
42628 innerCt.setSize(adjWidth, adjHeight);
42631 Ext.form.CompositeField.superclass.onResize.apply(this, arguments);
42635 doLayout: function(shallow, force) {
42636 if (this.rendered) {
42637 var innerCt = this.innerCt;
42639 innerCt.forceLayout = this.ownerCt.forceLayout;
42640 innerCt.doLayout(shallow, force);
42645 beforeDestroy: function(){
42646 Ext.destroy(this.innerCt);
42648 Ext.form.CompositeField.superclass.beforeDestroy.call(this);
42652 setReadOnly : function(readOnly) {
42653 if (readOnly == undefined) {
42656 readOnly = !!readOnly;
42659 this.eachItem(function(item){
42660 item.setReadOnly(readOnly);
42663 this.readOnly = readOnly;
42666 onShow : function() {
42667 Ext.form.CompositeField.superclass.onShow.call(this);
42672 onDisable : function(){
42673 this.eachItem(function(item){
42679 onEnable : function(){
42680 this.eachItem(function(item){
42686 Ext.reg('compositefield', Ext.form.CompositeField);
42687 Ext.form.Radio = Ext.extend(Ext.form.Checkbox, {
42688 inputType: 'radio',
42691 markInvalid : Ext.emptyFn,
42693 clearInvalid : Ext.emptyFn,
42696 getGroupValue : function(){
42697 var p = this.el.up('form') || Ext.getBody();
42698 var c = p.child('input[name='+this.el.dom.name+']:checked', true);
42699 return c ? c.value : null;
42703 setValue : function(v){
42707 if (typeof v == 'boolean') {
42708 Ext.form.Radio.superclass.setValue.call(this, v);
42709 } else if (this.rendered) {
42710 checkEl = this.getCheckEl();
42711 radio = checkEl.child('input[name=' + this.el.dom.name + '][value=' + v + ']', true);
42713 Ext.getCmp(radio.id).setValue(true);
42716 if(this.rendered && this.checked){
42717 checkEl = checkEl || this.getCheckEl();
42718 els = this.getCheckEl().select('input[name=' + this.el.dom.name + ']');
42719 els.each(function(el){
42720 if(el.dom.id != this.id){
42721 Ext.getCmp(el.dom.id).setValue(false);
42729 getCheckEl: function(){
42731 return this.el.up('.x-form-radio-group');
42733 return this.el.up('form') || Ext.getBody();
42736 Ext.reg('radio', Ext.form.Radio);
42738 Ext.form.RadioGroup = Ext.extend(Ext.form.CheckboxGroup, {
42743 blankText : 'You must select one item in this group',
42746 defaultType : 'radio',
42749 groupCls : 'x-form-radio-group',
42754 getValue : function(){
42756 this.eachItem(function(item){
42766 onSetValue : function(id, value){
42767 if(arguments.length > 1){
42768 var f = this.getBox(id);
42772 this.eachItem(function(item){
42774 item.setValue(false);
42780 this.setValueForItem(id);
42784 setValueForItem : function(val){
42785 val = String(val).split(',')[0];
42786 this.eachItem(function(item){
42787 item.setValue(val == item.inputValue);
42792 fireChecked : function(){
42793 if(!this.checkTask){
42794 this.checkTask = new Ext.util.DelayedTask(this.bufferChecked, this);
42796 this.checkTask.delay(10);
42800 bufferChecked : function(){
42802 this.eachItem(function(item){
42808 this.fireEvent('change', this, out);
42811 onDestroy : function(){
42812 if(this.checkTask){
42813 this.checkTask.cancel();
42814 this.checkTask = null;
42816 Ext.form.RadioGroup.superclass.onDestroy.call(this);
42821 Ext.reg('radiogroup', Ext.form.RadioGroup);
42823 Ext.form.Hidden = Ext.extend(Ext.form.Field, {
42825 inputType : 'hidden',
42827 shouldLayout: false,
42830 onRender : function(){
42831 Ext.form.Hidden.superclass.onRender.apply(this, arguments);
42835 initEvents : function(){
42836 this.originalValue = this.getValue();
42840 setSize : Ext.emptyFn,
42841 setWidth : Ext.emptyFn,
42842 setHeight : Ext.emptyFn,
42843 setPosition : Ext.emptyFn,
42844 setPagePosition : Ext.emptyFn,
42845 markInvalid : Ext.emptyFn,
42846 clearInvalid : Ext.emptyFn
42848 Ext.reg('hidden', Ext.form.Hidden);
42849 Ext.form.BasicForm = Ext.extend(Ext.util.Observable, {
42851 constructor: function(el, config){
42852 Ext.apply(this, config);
42853 if(Ext.isString(this.paramOrder)){
42854 this.paramOrder = this.paramOrder.split(/[\s,|]/);
42857 this.items = new Ext.util.MixedCollection(false, function(o){
42858 return o.getItemId();
42872 Ext.form.BasicForm.superclass.constructor.call(this);
42887 paramOrder: undefined,
42890 paramsAsHash: false,
42893 waitTitle: 'Please Wait...',
42896 activeAction : null,
42899 trackResetOnLoad : false,
42905 initEl : function(el){
42906 this.el = Ext.get(el);
42907 this.id = this.el.id || Ext.id();
42908 if(!this.standardSubmit){
42909 this.el.on('submit', this.onSubmit, this);
42911 this.el.addClass('x-form');
42920 onSubmit : function(e){
42925 destroy: function(bound){
42926 if(bound !== true){
42927 this.items.each(function(f){
42930 Ext.destroy(this.el);
42932 this.items.clear();
42933 this.purgeListeners();
42937 isValid : function(){
42939 this.items.each(function(f){
42948 isDirty : function(){
42950 this.items.each(function(f){
42960 doAction : function(action, options){
42961 if(Ext.isString(action)){
42962 action = new Ext.form.Action.ACTION_TYPES[action](this, options);
42964 if(this.fireEvent('beforeaction', this, action) !== false){
42965 this.beforeAction(action);
42966 action.run.defer(100, action);
42972 submit : function(options){
42973 options = options || {};
42974 if(this.standardSubmit){
42975 var v = options.clientValidation === false || this.isValid();
42977 var el = this.el.dom;
42978 if(this.url && Ext.isEmpty(el.action)){
42979 el.action = this.url;
42985 var submitAction = String.format('{0}submit', this.api ? 'direct' : '');
42986 this.doAction(submitAction, options);
42991 load : function(options){
42992 var loadAction = String.format('{0}load', this.api ? 'direct' : '');
42993 this.doAction(loadAction, options);
42998 updateRecord : function(record){
42999 record.beginEdit();
43000 var fs = record.fields,
43003 fs.each(function(f){
43004 field = this.findField(f.name);
43006 value = field.getValue();
43007 if (typeof value != undefined && value.getGroupValue) {
43008 value = value.getGroupValue();
43009 } else if ( field.eachItem ) {
43011 field.eachItem(function(item){
43012 value.push(item.getValue());
43015 record.set(f.name, value);
43023 loadRecord : function(record){
43024 this.setValues(record.data);
43029 beforeAction : function(action){
43031 this.items.each(function(f){
43032 if(f.isFormField && f.syncValue){
43036 var o = action.options;
43038 if(this.waitMsgTarget === true){
43039 this.el.mask(o.waitMsg, 'x-mask-loading');
43040 }else if(this.waitMsgTarget){
43041 this.waitMsgTarget = Ext.get(this.waitMsgTarget);
43042 this.waitMsgTarget.mask(o.waitMsg, 'x-mask-loading');
43044 Ext.MessageBox.wait(o.waitMsg, o.waitTitle || this.waitTitle);
43050 afterAction : function(action, success){
43051 this.activeAction = null;
43052 var o = action.options;
43054 if(this.waitMsgTarget === true){
43056 }else if(this.waitMsgTarget){
43057 this.waitMsgTarget.unmask();
43059 Ext.MessageBox.updateProgress(1);
43060 Ext.MessageBox.hide();
43067 Ext.callback(o.success, o.scope, [this, action]);
43068 this.fireEvent('actioncomplete', this, action);
43070 Ext.callback(o.failure, o.scope, [this, action]);
43071 this.fireEvent('actionfailed', this, action);
43076 findField : function(id) {
43077 var field = this.items.get(id);
43079 if (!Ext.isObject(field)) {
43081 var findMatchingField = function(f) {
43082 if (f.isFormField) {
43083 if (f.dataIndex == id || f.id == id || f.getName() == id) {
43086 } else if (f.isComposite) {
43087 return f.items.each(findMatchingField);
43088 } else if (f instanceof Ext.form.CheckboxGroup && f.rendered) {
43089 return f.eachItem(findMatchingField);
43094 this.items.each(findMatchingField);
43096 return field || null;
43101 markInvalid : function(errors){
43102 if (Ext.isArray(errors)) {
43103 for(var i = 0, len = errors.length; i < len; i++){
43104 var fieldError = errors[i];
43105 var f = this.findField(fieldError.id);
43107 f.markInvalid(fieldError.msg);
43113 if(!Ext.isFunction(errors[id]) && (field = this.findField(id))){
43114 field.markInvalid(errors[id]);
43123 setValues : function(values){
43124 if(Ext.isArray(values)){
43125 for(var i = 0, len = values.length; i < len; i++){
43127 var f = this.findField(v.id);
43129 f.setValue(v.value);
43130 if(this.trackResetOnLoad){
43131 f.originalValue = f.getValue();
43138 if(!Ext.isFunction(values[id]) && (field = this.findField(id))){
43139 field.setValue(values[id]);
43140 if(this.trackResetOnLoad){
43141 field.originalValue = field.getValue();
43150 getValues : function(asString){
43151 var fs = Ext.lib.Ajax.serializeForm(this.el.dom);
43152 if(asString === true){
43155 return Ext.urlDecode(fs);
43159 getFieldValues : function(dirtyOnly){
43164 this.items.each(function(f) {
43165 if (!f.disabled && (dirtyOnly !== true || f.isDirty())) {
43168 val = f.getValue();
43170 if(Ext.isDefined(key)){
43171 if(Ext.isArray(key)){
43185 clearInvalid : function(){
43186 this.items.each(function(f){
43193 reset : function(){
43194 this.items.each(function(f){
43202 this.items.addAll(Array.prototype.slice.call(arguments, 0));
43207 remove : function(field){
43208 this.items.remove(field);
43213 cleanDestroyed : function() {
43214 this.items.filterBy(function(o) { return !!o.isDestroyed; }).each(this.remove, this);
43218 render : function(){
43219 this.items.each(function(f){
43220 if(f.isFormField && !f.rendered && document.getElementById(f.id)){
43221 f.applyToMarkup(f.id);
43228 applyToFields : function(o){
43229 this.items.each(function(f){
43236 applyIfToFields : function(o){
43237 this.items.each(function(f){
43243 callFieldMethod : function(fnName, args){
43245 this.items.each(function(f){
43246 if(Ext.isFunction(f[fnName])){
43247 f[fnName].apply(f, args);
43255 Ext.BasicForm = Ext.form.BasicForm;
43257 Ext.FormPanel = Ext.extend(Ext.Panel, {
43268 minButtonWidth : 75,
43271 labelAlign : 'left',
43274 monitorValid : false,
43283 initComponent : function(){
43284 this.form = this.createForm();
43285 Ext.FormPanel.superclass.initComponent.call(this);
43289 cls: this.baseCls + '-body',
43290 method : this.method || 'POST',
43291 id : this.formId || Ext.id()
43293 if(this.fileUpload) {
43294 this.bodyCfg.enctype = 'multipart/form-data';
43303 this.relayEvents(this.form, ['beforeaction', 'actionfailed', 'actioncomplete']);
43307 createForm : function(){
43308 var config = Ext.applyIf({listeners: {}}, this.initialConfig);
43309 return new Ext.form.BasicForm(null, config);
43313 initFields : function(){
43315 var formPanel = this;
43316 var fn = function(c){
43317 if(formPanel.isField(c)){
43319 }else if(c.findBy && c != formPanel){
43320 formPanel.applySettings(c);
43322 if(c.items && c.items.each){
43323 c.items.each(fn, this);
43327 this.items.each(fn, this);
43331 applySettings: function(c){
43332 var ct = c.ownerCt;
43334 labelAlign: ct.labelAlign,
43335 labelWidth: ct.labelWidth,
43336 itemCls: ct.itemCls
43341 getLayoutTarget : function(){
43342 return this.form.el;
43346 getForm : function(){
43351 onRender : function(ct, position){
43353 Ext.FormPanel.superclass.onRender.call(this, ct, position);
43354 this.form.initEl(this.body);
43358 beforeDestroy : function(){
43359 this.stopMonitoring();
43360 this.form.destroy(true);
43361 Ext.FormPanel.superclass.beforeDestroy.call(this);
43365 isField : function(c) {
43366 return !!c.setValue && !!c.getValue && !!c.markInvalid && !!c.clearInvalid;
43370 initEvents : function(){
43371 Ext.FormPanel.superclass.initEvents.call(this);
43375 add: this.onAddEvent,
43376 remove: this.onRemoveEvent
43378 if(this.monitorValid){
43379 this.startMonitoring();
43384 onAdd: function(c){
43385 Ext.FormPanel.superclass.onAdd.call(this, c);
43386 this.processAdd(c);
43390 onAddEvent: function(ct, c){
43392 this.processAdd(c);
43397 processAdd : function(c){
43399 if(this.isField(c)){
43402 }else if(c.findBy){
43403 this.applySettings(c);
43404 this.form.add.apply(this.form, c.findBy(this.isField));
43409 onRemove: function(c){
43410 Ext.FormPanel.superclass.onRemove.call(this, c);
43411 this.processRemove(c);
43414 onRemoveEvent: function(ct, c){
43416 this.processRemove(c);
43421 processRemove: function(c){
43422 if(!this.destroying){
43424 if(this.isField(c)){
43425 this.form.remove(c);
43427 }else if (c.findBy){
43428 Ext.each(c.findBy(this.isField), this.form.remove, this.form);
43430 this.form.cleanDestroyed();
43436 startMonitoring : function(){
43437 if(!this.validTask){
43438 this.validTask = new Ext.util.TaskRunner();
43439 this.validTask.start({
43440 run : this.bindHandler,
43441 interval : this.monitorPoll || 200,
43448 stopMonitoring : function(){
43449 if(this.validTask){
43450 this.validTask.stopAll();
43451 this.validTask = null;
43457 this.form.load.apply(this.form, arguments);
43461 onDisable : function(){
43462 Ext.FormPanel.superclass.onDisable.call(this);
43464 this.form.items.each(function(){
43471 onEnable : function(){
43472 Ext.FormPanel.superclass.onEnable.call(this);
43474 this.form.items.each(function(){
43481 bindHandler : function(){
43483 this.form.items.each(function(f){
43484 if(!f.isValid(true)){
43490 var fitems = this.fbar.items.items;
43491 for(var i = 0, len = fitems.length; i < len; i++){
43492 var btn = fitems[i];
43493 if(btn.formBind === true && btn.disabled === valid){
43494 btn.setDisabled(!valid);
43498 this.fireEvent('clientvalidation', this, valid);
43501 Ext.reg('form', Ext.FormPanel);
43503 Ext.form.FormPanel = Ext.FormPanel;
43505 Ext.form.FieldSet = Ext.extend(Ext.Panel, {
43512 baseCls : 'x-fieldset',
43516 animCollapse : false,
43519 onRender : function(ct, position){
43521 this.el = document.createElement('fieldset');
43522 this.el.id = this.id;
43523 if (this.title || this.header || this.checkboxToggle) {
43524 this.el.appendChild(document.createElement('legend')).className = this.baseCls + '-header';
43528 Ext.form.FieldSet.superclass.onRender.call(this, ct, position);
43530 if(this.checkboxToggle){
43531 var o = typeof this.checkboxToggle == 'object' ?
43532 this.checkboxToggle :
43533 {tag: 'input', type: 'checkbox', name: this.checkboxName || this.id+'-checkbox'};
43534 this.checkbox = this.header.insertFirst(o);
43535 this.checkbox.dom.checked = !this.collapsed;
43536 this.mon(this.checkbox, 'click', this.onCheckClick, this);
43541 onCollapse : function(doAnim, animArg){
43543 this.checkbox.dom.checked = false;
43545 Ext.form.FieldSet.superclass.onCollapse.call(this, doAnim, animArg);
43550 onExpand : function(doAnim, animArg){
43552 this.checkbox.dom.checked = true;
43554 Ext.form.FieldSet.superclass.onExpand.call(this, doAnim, animArg);
43558 onCheckClick : function(){
43559 this[this.checkbox.dom.checked ? 'expand' : 'collapse']();
43597 Ext.reg('fieldset', Ext.form.FieldSet);
43599 Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
43601 enableFormat : true,
43603 enableFontSize : true,
43605 enableColors : true,
43607 enableAlignments : true,
43609 enableLists : true,
43611 enableSourceEdit : true,
43613 enableLinks : true,
43617 createLinkText : 'Please enter the URL for the link:',
43619 defaultLinkValue : 'http:/'+'/',
43628 defaultFont: 'tahoma',
43630 defaultValue: (Ext.isOpera || Ext.isIE6) ? ' ' : '​',
43633 actionMode: 'wrap',
43634 validationEvent : false,
43636 initialized : false,
43638 sourceEditMode : false,
43639 onFocus : Ext.emptyFn,
43641 hideMode:'offsets',
43642 defaultAutoCreate : {
43644 style:"width:500px;height:300px;",
43645 autocomplete: "off"
43649 initComponent : function(){
43666 Ext.form.HtmlEditor.superclass.initComponent.call(this);
43670 createFontOptions : function(){
43671 var buf = [], fs = this.fontFamilies, ff, lc;
43672 for(var i = 0, len = fs.length; i< len; i++){
43674 lc = ff.toLowerCase();
43676 '<option value="',lc,'" style="font-family:',ff,';"',
43677 (this.defaultFont == lc ? ' selected="true">' : '>'),
43682 return buf.join('');
43686 createToolbar : function(editor){
43688 var tipsEnabled = Ext.QuickTips && Ext.QuickTips.isEnabled();
43691 function btn(id, toggle, handler){
43694 cls : 'x-btn-icon',
43695 iconCls: 'x-edit-'+id,
43696 enableToggle:toggle !== false,
43698 handler:handler||editor.relayBtnCmd,
43699 clickEvent:'mousedown',
43700 tooltip: tipsEnabled ? editor.buttonTips[id] || undefined : undefined,
43701 overflowText: editor.buttonTips[id].title || undefined,
43707 if(this.enableFont && !Ext.isSafari2){
43708 var fontSelectItem = new Ext.Toolbar.Item({
43711 cls:'x-font-select',
43712 html: this.createFontOptions()
43722 if(this.enableFormat){
43730 if(this.enableFontSize){
43733 btn('increasefontsize', false, this.adjustFont),
43734 btn('decreasefontsize', false, this.adjustFont)
43738 if(this.enableColors){
43741 itemId:'forecolor',
43743 iconCls: 'x-edit-forecolor',
43744 clickEvent:'mousedown',
43745 tooltip: tipsEnabled ? editor.buttonTips.forecolor || undefined : undefined,
43747 menu : new Ext.menu.ColorMenu({
43748 allowReselect: true,
43749 focus: Ext.emptyFn,
43754 select: function(cp, color){
43755 this.execCmd('forecolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
43759 clickEvent:'mousedown'
43762 itemId:'backcolor',
43764 iconCls: 'x-edit-backcolor',
43765 clickEvent:'mousedown',
43766 tooltip: tipsEnabled ? editor.buttonTips.backcolor || undefined : undefined,
43768 menu : new Ext.menu.ColorMenu({
43769 focus: Ext.emptyFn,
43772 allowReselect: true,
43775 select: function(cp, color){
43777 this.execCmd('useCSS', false);
43778 this.execCmd('hilitecolor', color);
43779 this.execCmd('useCSS', true);
43782 this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
43787 clickEvent:'mousedown'
43793 if(this.enableAlignments){
43796 btn('justifyleft'),
43797 btn('justifycenter'),
43798 btn('justifyright')
43802 if(!Ext.isSafari2){
43803 if(this.enableLinks){
43806 btn('createlink', false, this.createLink)
43810 if(this.enableLists){
43813 btn('insertorderedlist'),
43814 btn('insertunorderedlist')
43817 if(this.enableSourceEdit){
43820 btn('sourceedit', true, function(btn){
43821 this.toggleSourceEdit(!this.sourceEditMode);
43828 var tb = new Ext.Toolbar({
43829 renderTo: this.wrap.dom.firstChild,
43833 if (fontSelectItem) {
43834 this.fontSelect = fontSelectItem.el;
43836 this.mon(this.fontSelect, 'change', function(){
43837 var font = this.fontSelect.dom.value;
43838 this.relayCmd('fontname', font);
43844 this.mon(tb.el, 'click', function(e){
43845 e.preventDefault();
43849 this.tb.doLayout();
43852 onDisable: function(){
43854 Ext.form.HtmlEditor.superclass.onDisable.call(this);
43857 onEnable: function(){
43858 this.wrap.unmask();
43859 Ext.form.HtmlEditor.superclass.onEnable.call(this);
43862 setReadOnly: function(readOnly){
43864 Ext.form.HtmlEditor.superclass.setReadOnly.call(this, readOnly);
43865 if(this.initialized){
43867 this.getEditorBody().contentEditable = !readOnly;
43869 this.setDesignMode(!readOnly);
43871 var bd = this.getEditorBody();
43873 bd.style.cursor = this.readOnly ? 'default' : 'text';
43875 this.disableItems(readOnly);
43880 getDocMarkup : function(){
43881 var h = Ext.fly(this.iframe).getHeight() - this.iframePad * 2;
43882 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);
43886 getEditorBody : function(){
43887 var doc = this.getDoc();
43888 return doc.body || doc.documentElement;
43892 getDoc : function(){
43893 return Ext.isIE ? this.getWin().document : (this.iframe.contentDocument || this.getWin().document);
43897 getWin : function(){
43898 return Ext.isIE ? this.iframe.contentWindow : window.frames[this.iframe.name];
43902 onRender : function(ct, position){
43903 Ext.form.HtmlEditor.superclass.onRender.call(this, ct, position);
43904 this.el.dom.style.border = '0 none';
43905 this.el.dom.setAttribute('tabIndex', -1);
43906 this.el.addClass('x-hidden');
43908 this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;');
43910 this.wrap = this.el.wrap({
43911 cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
43914 this.createToolbar(this);
43916 this.disableItems(true);
43918 this.tb.doLayout();
43920 this.createIFrame();
43923 var sz = this.el.getSize();
43924 this.setSize(sz.width, this.height || sz.height);
43926 this.resizeEl = this.positionEl = this.wrap;
43929 createIFrame: function(){
43930 var iframe = document.createElement('iframe');
43931 iframe.name = Ext.id();
43932 iframe.frameBorder = '0';
43933 iframe.style.overflow = 'auto';
43934 iframe.src = Ext.SSL_SECURE_URL;
43936 this.wrap.dom.appendChild(iframe);
43937 this.iframe = iframe;
43939 this.monitorTask = Ext.TaskMgr.start({
43940 run: this.checkDesignMode,
43946 initFrame : function(){
43947 Ext.TaskMgr.stop(this.monitorTask);
43948 var doc = this.getDoc();
43949 this.win = this.getWin();
43952 doc.write(this.getDocMarkup());
43957 var doc = this.getDoc();
43958 if(doc.body || doc.readyState == 'complete'){
43959 Ext.TaskMgr.stop(task);
43960 this.setDesignMode(true);
43961 this.initEditor.defer(10, this);
43968 Ext.TaskMgr.start(task);
43972 checkDesignMode : function(){
43973 if(this.wrap && this.wrap.dom.offsetWidth){
43974 var doc = this.getDoc();
43978 if(!doc.editorInitialized || this.getDesignMode() != 'on'){
43985 setDesignMode : function(mode){
43986 var doc = this.getDoc();
43991 doc.designMode = (/on|true/i).test(String(mode).toLowerCase()) ?'on':'off';
43997 getDesignMode : function(){
43998 var doc = this.getDoc();
43999 if(!doc){ return ''; }
44000 return String(doc.designMode).toLowerCase();
44004 disableItems: function(disabled){
44005 if(this.fontSelect){
44006 this.fontSelect.dom.disabled = disabled;
44008 this.tb.items.each(function(item){
44009 if(item.getItemId() != 'sourceedit'){
44010 item.setDisabled(disabled);
44016 onResize : function(w, h){
44017 Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments);
44018 if(this.el && this.iframe){
44019 if(Ext.isNumber(w)){
44020 var aw = w - this.wrap.getFrameWidth('lr');
44021 this.el.setWidth(aw);
44022 this.tb.setWidth(aw);
44023 this.iframe.style.width = Math.max(aw, 0) + 'px';
44025 if(Ext.isNumber(h)){
44026 var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight();
44027 this.el.setHeight(ah);
44028 this.iframe.style.height = Math.max(ah, 0) + 'px';
44029 var bd = this.getEditorBody();
44031 bd.style.height = Math.max((ah - (this.iframePad*2)), 0) + 'px';
44038 toggleSourceEdit : function(sourceEditMode){
44042 if (sourceEditMode === undefined) {
44043 sourceEditMode = !this.sourceEditMode;
44045 this.sourceEditMode = sourceEditMode === true;
44046 var btn = this.tb.getComponent('sourceedit');
44048 if (btn.pressed !== this.sourceEditMode) {
44049 btn.toggle(this.sourceEditMode);
44050 if (!btn.xtbHidden) {
44054 if (this.sourceEditMode) {
44056 this.previousSize = this.getSize();
44058 iframeHeight = Ext.get(this.iframe).getHeight();
44060 this.disableItems(true);
44062 this.iframe.className = 'x-hidden';
44063 this.el.removeClass('x-hidden');
44064 this.el.dom.removeAttribute('tabIndex');
44066 this.el.dom.style.height = iframeHeight + 'px';
44069 elHeight = parseInt(this.el.dom.style.height, 10);
44070 if (this.initialized) {
44071 this.disableItems(this.readOnly);
44074 this.iframe.className = '';
44075 this.el.addClass('x-hidden');
44076 this.el.dom.setAttribute('tabIndex', -1);
44079 this.setSize(this.previousSize);
44080 delete this.previousSize;
44081 this.iframe.style.height = elHeight + 'px';
44083 this.fireEvent('editmodechange', this, this.sourceEditMode);
44087 createLink : function() {
44088 var url = prompt(this.createLinkText, this.defaultLinkValue);
44089 if(url && url != 'http:/'+'/'){
44090 this.relayCmd('createlink', url);
44095 initEvents : function(){
44096 this.originalValue = this.getValue();
44100 markInvalid : Ext.emptyFn,
44103 clearInvalid : Ext.emptyFn,
44106 setValue : function(v){
44107 Ext.form.HtmlEditor.superclass.setValue.call(this, v);
44113 cleanHtml: function(html) {
44114 html = String(html);
44116 html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');
44120 if(html.charCodeAt(0) == this.defaultValue.replace(/\D/g, '')){
44121 html = html.substring(1);
44127 syncValue : function(){
44128 if(this.initialized){
44129 var bd = this.getEditorBody();
44130 var html = bd.innerHTML;
44132 var bs = bd.getAttribute('style');
44133 var m = bs.match(/text-align:(.*?);/i);
44135 html = '<div style="'+m[0]+'">' + html + '</div>';
44138 html = this.cleanHtml(html);
44139 if(this.fireEvent('beforesync', this, html) !== false){
44140 this.el.dom.value = html;
44141 this.fireEvent('sync', this, html);
44147 getValue : function() {
44148 this[this.sourceEditMode ? 'pushValue' : 'syncValue']();
44149 return Ext.form.HtmlEditor.superclass.getValue.call(this);
44153 pushValue : function(){
44154 if(this.initialized){
44155 var v = this.el.dom.value;
44156 if(!this.activated && v.length < 1){
44157 v = this.defaultValue;
44159 if(this.fireEvent('beforepush', this, v) !== false){
44160 this.getEditorBody().innerHTML = v;
44163 this.setDesignMode(false);
44164 this.setDesignMode(true);
44166 this.fireEvent('push', this, v);
44173 deferFocus : function(){
44174 this.focus.defer(10, this);
44178 focus : function(){
44179 if(this.win && !this.sourceEditMode){
44187 initEditor : function(){
44190 var dbody = this.getEditorBody(),
44191 ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat', 'background-color', 'color'),
44195 ss['background-attachment'] = 'fixed';
44196 dbody.bgProperties = 'fixed';
44198 Ext.DomHelper.applyStyles(dbody, ss);
44200 doc = this.getDoc();
44204 Ext.EventManager.removeAll(doc);
44209 fn = this.onEditorEvent.createDelegate(this);
44210 Ext.EventManager.on(doc, {
44219 Ext.EventManager.on(doc, 'keypress', this.applyCommand, this);
44221 if(Ext.isIE || Ext.isWebKit || Ext.isOpera){
44222 Ext.EventManager.on(doc, 'keydown', this.fixKeys, this);
44224 doc.editorInitialized = true;
44225 this.initialized = true;
44227 this.setReadOnly(this.readOnly);
44228 this.fireEvent('initialize', this);
44233 beforeDestroy : function(){
44234 if(this.monitorTask){
44235 Ext.TaskMgr.stop(this.monitorTask);
44238 Ext.destroy(this.tb);
44239 var doc = this.getDoc();
44242 Ext.EventManager.removeAll(doc);
44243 for (var prop in doc){
44249 this.wrap.dom.innerHTML = '';
44250 this.wrap.remove();
44253 Ext.form.HtmlEditor.superclass.beforeDestroy.call(this);
44257 onFirstFocus : function(){
44258 this.activated = true;
44259 this.disableItems(this.readOnly);
44262 var s = this.win.getSelection();
44263 if(!s.focusNode || s.focusNode.nodeType != 3){
44264 var r = s.getRangeAt(0);
44265 r.selectNodeContents(this.getEditorBody());
44270 this.execCmd('useCSS', true);
44271 this.execCmd('styleWithCSS', false);
44274 this.fireEvent('activate', this);
44278 adjustFont: function(btn){
44279 var adjust = btn.getItemId() == 'increasefontsize' ? 1 : -1,
44280 doc = this.getDoc(),
44281 v = parseInt(doc.queryCommandValue('FontSize') || 2, 10);
44282 if((Ext.isSafari && !Ext.isSafari2) || Ext.isChrome || Ext.isAir){
44298 v = v.constrain(1, 6);
44303 v = Math.max(1, v+adjust) + (Ext.isSafari ? 'px' : 0);
44305 this.execCmd('FontSize', v);
44309 onEditorEvent : function(e){
44310 this.updateToolbar();
44315 updateToolbar: function(){
44321 if(!this.activated){
44322 this.onFirstFocus();
44326 var btns = this.tb.items.map,
44327 doc = this.getDoc();
44329 if(this.enableFont && !Ext.isSafari2){
44330 var name = (doc.queryCommandValue('FontName')||this.defaultFont).toLowerCase();
44331 if(name != this.fontSelect.dom.value){
44332 this.fontSelect.dom.value = name;
44335 if(this.enableFormat){
44336 btns.bold.toggle(doc.queryCommandState('bold'));
44337 btns.italic.toggle(doc.queryCommandState('italic'));
44338 btns.underline.toggle(doc.queryCommandState('underline'));
44340 if(this.enableAlignments){
44341 btns.justifyleft.toggle(doc.queryCommandState('justifyleft'));
44342 btns.justifycenter.toggle(doc.queryCommandState('justifycenter'));
44343 btns.justifyright.toggle(doc.queryCommandState('justifyright'));
44345 if(!Ext.isSafari2 && this.enableLists){
44346 btns.insertorderedlist.toggle(doc.queryCommandState('insertorderedlist'));
44347 btns.insertunorderedlist.toggle(doc.queryCommandState('insertunorderedlist'));
44350 Ext.menu.MenuMgr.hideAll();
44356 relayBtnCmd : function(btn){
44357 this.relayCmd(btn.getItemId());
44361 relayCmd : function(cmd, value){
44364 this.execCmd(cmd, value);
44365 this.updateToolbar();
44366 }).defer(10, this);
44370 execCmd : function(cmd, value){
44371 var doc = this.getDoc();
44372 doc.execCommand(cmd, false, value === undefined ? null : value);
44377 applyCommand : function(e){
44379 var c = e.getCharCode(), cmd;
44381 c = String.fromCharCode(c);
44397 e.preventDefault();
44404 insertAtCursor : function(text){
44405 if(!this.activated){
44410 var doc = this.getDoc(),
44411 r = doc.selection.createRange();
44419 this.execCmd('InsertHTML', text);
44425 fixKeys : function(){
44427 return function(e){
44428 var k = e.getKey(),
44429 doc = this.getDoc(),
44433 r = doc.selection.createRange();
44436 r.pasteHTML(' ');
44439 }else if(k == e.ENTER){
44440 r = doc.selection.createRange();
44442 var target = r.parentElement();
44443 if(!target || target.tagName.toLowerCase() != 'li'){
44445 r.pasteHTML('<br />');
44452 }else if(Ext.isOpera){
44453 return function(e){
44454 var k = e.getKey();
44458 this.execCmd('InsertHTML',' ');
44462 }else if(Ext.isWebKit){
44463 return function(e){
44464 var k = e.getKey();
44467 this.execCmd('InsertText','\t');
44469 }else if(k == e.ENTER){
44471 this.execCmd('InsertHtml','<br /><br />');
44479 getToolbar : function(){
44486 title: 'Bold (Ctrl+B)',
44487 text: 'Make the selected text bold.',
44488 cls: 'x-html-editor-tip'
44491 title: 'Italic (Ctrl+I)',
44492 text: 'Make the selected text italic.',
44493 cls: 'x-html-editor-tip'
44496 title: 'Underline (Ctrl+U)',
44497 text: 'Underline the selected text.',
44498 cls: 'x-html-editor-tip'
44500 increasefontsize : {
44501 title: 'Grow Text',
44502 text: 'Increase the font size.',
44503 cls: 'x-html-editor-tip'
44505 decreasefontsize : {
44506 title: 'Shrink Text',
44507 text: 'Decrease the font size.',
44508 cls: 'x-html-editor-tip'
44511 title: 'Text Highlight Color',
44512 text: 'Change the background color of the selected text.',
44513 cls: 'x-html-editor-tip'
44516 title: 'Font Color',
44517 text: 'Change the color of the selected text.',
44518 cls: 'x-html-editor-tip'
44521 title: 'Align Text Left',
44522 text: 'Align text to the left.',
44523 cls: 'x-html-editor-tip'
44526 title: 'Center Text',
44527 text: 'Center text in the editor.',
44528 cls: 'x-html-editor-tip'
44531 title: 'Align Text Right',
44532 text: 'Align text to the right.',
44533 cls: 'x-html-editor-tip'
44535 insertunorderedlist : {
44536 title: 'Bullet List',
44537 text: 'Start a bulleted list.',
44538 cls: 'x-html-editor-tip'
44540 insertorderedlist : {
44541 title: 'Numbered List',
44542 text: 'Start a numbered list.',
44543 cls: 'x-html-editor-tip'
44546 title: 'Hyperlink',
44547 text: 'Make the selected text a hyperlink.',
44548 cls: 'x-html-editor-tip'
44551 title: 'Source Edit',
44552 text: 'Switch to source editing mode.',
44553 cls: 'x-html-editor-tip'
44592 Ext.reg('htmleditor', Ext.form.HtmlEditor);
44594 Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {
44596 minValue : undefined,
44598 maxValue : undefined,
44600 minText : "The time in this field must be equal to or after {0}",
44602 maxText : "The time in this field must be equal to or before {0}",
44604 invalidText : "{0} is not a valid time",
44608 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",
44615 triggerAction: 'all',
44622 initDate: '1/1/2008',
44624 initDateFormat: 'j/n/Y',
44627 initComponent : function(){
44628 if(Ext.isDefined(this.minValue)){
44629 this.setMinValue(this.minValue, true);
44631 if(Ext.isDefined(this.maxValue)){
44632 this.setMaxValue(this.maxValue, true);
44635 this.generateStore(true);
44637 Ext.form.TimeField.superclass.initComponent.call(this);
44641 setMinValue: function(value, initial){
44642 this.setLimit(value, true, initial);
44647 setMaxValue: function(value, initial){
44648 this.setLimit(value, false, initial);
44653 generateStore: function(initial){
44654 var min = this.minValue || new Date(this.initDate).clearTime(),
44655 max = this.maxValue || new Date(this.initDate).clearTime().add('mi', (24 * 60) - 1),
44659 times.push(min.dateFormat(this.format));
44660 min = min.add('mi', this.increment);
44662 this.bindStore(times, initial);
44666 setLimit: function(value, isMin, initial){
44668 if(Ext.isString(value)){
44669 d = this.parseDate(value);
44670 }else if(Ext.isDate(value)){
44674 var val = new Date(this.initDate).clearTime();
44675 val.setHours(d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
44676 this[isMin ? 'minValue' : 'maxValue'] = val;
44678 this.generateStore();
44684 getValue : function(){
44685 var v = Ext.form.TimeField.superclass.getValue.call(this);
44686 return this.formatDate(this.parseDate(v)) || '';
44690 setValue : function(value){
44691 return Ext.form.TimeField.superclass.setValue.call(this, this.formatDate(this.parseDate(value)));
44695 validateValue : Ext.form.DateField.prototype.validateValue,
44697 formatDate : Ext.form.DateField.prototype.formatDate,
44699 parseDate: function(value) {
44700 if (!value || Ext.isDate(value)) {
44704 var id = this.initDate + ' ',
44705 idf = this.initDateFormat + ' ',
44706 v = Date.parseDate(id + value, idf + this.format),
44707 af = this.altFormats;
44710 if (!this.altFormatsArray) {
44711 this.altFormatsArray = af.split("|");
44713 for (var i = 0, afa = this.altFormatsArray, len = afa.length; i < len && !v; i++) {
44714 v = Date.parseDate(id + value, idf + afa[i]);
44721 Ext.reg('timefield', Ext.form.TimeField);
44722 Ext.form.SliderField = Ext.extend(Ext.form.Field, {
44731 actionMode: 'wrap',
44734 initComponent : function() {
44735 var cfg = Ext.copyTo({
44736 id: this.id + '-slider'
44737 }, this.initialConfig, ['vertical', 'minValue', 'maxValue', 'decimalPrecision', 'keyIncrement', 'increment', 'clickToChange', 'animate']);
44740 if (this.useTips) {
44741 var plug = this.tipText ? {getText: this.tipText} : {};
44742 cfg.plugins = [new Ext.slider.Tip(plug)];
44744 this.slider = new Ext.Slider(cfg);
44745 Ext.form.SliderField.superclass.initComponent.call(this);
44749 onRender : function(ct, position){
44750 this.autoCreate = {
44756 Ext.form.SliderField.superclass.onRender.call(this, ct, position);
44757 this.wrap = this.el.wrap({cls: 'x-form-field-wrap'});
44758 this.resizeEl = this.positionEl = this.wrap;
44759 this.slider.render(this.wrap);
44763 onResize : function(w, h, aw, ah){
44764 Ext.form.SliderField.superclass.onResize.call(this, w, h, aw, ah);
44765 this.slider.setSize(w, h);
44769 initEvents : function(){
44770 Ext.form.SliderField.superclass.initEvents.call(this);
44771 this.slider.on('change', this.onChange, this);
44775 onChange : function(slider, v){
44776 this.setValue(v, undefined, true);
44780 onEnable : function(){
44781 Ext.form.SliderField.superclass.onEnable.call(this);
44782 this.slider.enable();
44786 onDisable : function(){
44787 Ext.form.SliderField.superclass.onDisable.call(this);
44788 this.slider.disable();
44792 beforeDestroy : function(){
44793 Ext.destroy(this.slider);
44794 Ext.form.SliderField.superclass.beforeDestroy.call(this);
44798 alignErrorIcon : function(){
44799 this.errorIcon.alignTo(this.slider.el, 'tl-tr', [2, 0]);
44803 setMinValue : function(v){
44804 this.slider.setMinValue(v);
44809 setMaxValue : function(v){
44810 this.slider.setMaxValue(v);
44815 setValue : function(v, animate, silent){
44819 this.slider.setValue(v, animate);
44821 return Ext.form.SliderField.superclass.setValue.call(this, this.slider.getValue());
44825 getValue : function(){
44826 return this.slider.getValue();
44830 Ext.reg('sliderfield', Ext.form.SliderField);
44831 Ext.form.Label = Ext.extend(Ext.BoxComponent, {
44837 onRender : function(ct, position){
44839 this.el = document.createElement('label');
44840 this.el.id = this.getId();
44841 this.el.innerHTML = this.text ? Ext.util.Format.htmlEncode(this.text) : (this.html || '');
44843 this.el.setAttribute('for', this.forId);
44846 Ext.form.Label.superclass.onRender.call(this, ct, position);
44850 setText : function(t, encode){
44851 var e = encode === false;
44852 this[!e ? 'text' : 'html'] = t;
44853 delete this[e ? 'text' : 'html'];
44855 this.el.dom.innerHTML = encode !== false ? Ext.util.Format.htmlEncode(t) : t;
44861 Ext.reg('label', Ext.form.Label);
44862 Ext.form.Action = function(form, options){
44864 this.options = options || {};
44868 Ext.form.Action.CLIENT_INVALID = 'client';
44870 Ext.form.Action.SERVER_INVALID = 'server';
44872 Ext.form.Action.CONNECT_FAILURE = 'connect';
44874 Ext.form.Action.LOAD_FAILURE = 'load';
44876 Ext.form.Action.prototype = {
44897 run : function(options){
44902 success : function(response){
44907 handleResponse : function(response){
44912 failure : function(response){
44913 this.response = response;
44914 this.failureType = Ext.form.Action.CONNECT_FAILURE;
44915 this.form.afterAction(this, false);
44921 processResponse : function(response){
44922 this.response = response;
44923 if(!response.responseText && !response.responseXML){
44926 this.result = this.handleResponse(response);
44927 return this.result;
44931 getUrl : function(appendParams){
44932 var url = this.options.url || this.form.url || this.form.el.dom.action;
44934 var p = this.getParams();
44936 url = Ext.urlAppend(url, p);
44943 getMethod : function(){
44944 return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();
44948 getParams : function(){
44949 var bp = this.form.baseParams;
44950 var p = this.options.params;
44952 if(typeof p == "object"){
44953 p = Ext.urlEncode(Ext.applyIf(p, bp));
44954 }else if(typeof p == 'string' && bp){
44955 p += '&' + Ext.urlEncode(bp);
44958 p = Ext.urlEncode(bp);
44964 createCallback : function(opts){
44965 var opts = opts || {};
44967 success: this.success,
44968 failure: this.failure,
44970 timeout: (opts.timeout*1000) || (this.form.timeout*1000),
44971 upload: this.form.fileUpload ? this.success : undefined
44977 Ext.form.Action.Submit = function(form, options){
44978 Ext.form.Action.Submit.superclass.constructor.call(this, form, options);
44981 Ext.extend(Ext.form.Action.Submit, Ext.form.Action, {
44988 var o = this.options,
44989 method = this.getMethod(),
44990 isGet = method == 'GET';
44991 if(o.clientValidation === false || this.form.isValid()){
44992 if (o.submitEmptyText === false) {
44993 var fields = this.form.items,
44995 setupEmptyFields = function(f){
44996 if (f.el.getValue() == f.emptyText) {
44997 emptyFields.push(f);
44998 f.el.dom.value = "";
45000 if(f.isComposite && f.rendered){
45001 f.items.each(setupEmptyFields);
45005 fields.each(setupEmptyFields);
45007 Ext.Ajax.request(Ext.apply(this.createCallback(o), {
45008 form:this.form.el.dom,
45009 url:this.getUrl(isGet),
45011 headers: o.headers,
45012 params:!isGet ? this.getParams() : null,
45013 isUpload: this.form.fileUpload
45015 if (o.submitEmptyText === false) {
45016 Ext.each(emptyFields, function(f) {
45017 if (f.applyEmptyText) {
45018 f.applyEmptyText();
45022 }else if (o.clientValidation !== false){
45023 this.failureType = Ext.form.Action.CLIENT_INVALID;
45024 this.form.afterAction(this, false);
45029 success : function(response){
45030 var result = this.processResponse(response);
45031 if(result === true || result.success){
45032 this.form.afterAction(this, true);
45036 this.form.markInvalid(result.errors);
45038 this.failureType = Ext.form.Action.SERVER_INVALID;
45039 this.form.afterAction(this, false);
45043 handleResponse : function(response){
45044 if(this.form.errorReader){
45045 var rs = this.form.errorReader.read(response);
45048 for(var i = 0, len = rs.records.length; i < len; i++) {
45049 var r = rs.records[i];
45050 errors[i] = r.data;
45053 if(errors.length < 1){
45057 success : rs.success,
45061 return Ext.decode(response.responseText);
45067 Ext.form.Action.Load = function(form, options){
45068 Ext.form.Action.Load.superclass.constructor.call(this, form, options);
45069 this.reader = this.form.reader;
45072 Ext.extend(Ext.form.Action.Load, Ext.form.Action, {
45078 Ext.Ajax.request(Ext.apply(
45079 this.createCallback(this.options), {
45080 method:this.getMethod(),
45081 url:this.getUrl(false),
45082 headers: this.options.headers,
45083 params:this.getParams()
45088 success : function(response){
45089 var result = this.processResponse(response);
45090 if(result === true || !result.success || !result.data){
45091 this.failureType = Ext.form.Action.LOAD_FAILURE;
45092 this.form.afterAction(this, false);
45095 this.form.clearInvalid();
45096 this.form.setValues(result.data);
45097 this.form.afterAction(this, true);
45101 handleResponse : function(response){
45102 if(this.form.reader){
45103 var rs = this.form.reader.read(response);
45104 var data = rs.records && rs.records[0] ? rs.records[0].data : null;
45106 success : rs.success,
45110 return Ext.decode(response.responseText);
45117 Ext.form.Action.DirectLoad = Ext.extend(Ext.form.Action.Load, {
45118 constructor: function(form, opts) {
45119 Ext.form.Action.DirectLoad.superclass.constructor.call(this, form, opts);
45121 type : 'directload',
45124 var args = this.getParams();
45125 args.push(this.success, this);
45126 this.form.api.load.apply(window, args);
45129 getParams : function() {
45130 var buf = [], o = {};
45131 var bp = this.form.baseParams;
45132 var p = this.options.params;
45133 Ext.apply(o, p, bp);
45134 var paramOrder = this.form.paramOrder;
45136 for(var i = 0, len = paramOrder.length; i < len; i++){
45137 buf.push(o[paramOrder[i]]);
45139 }else if(this.form.paramsAsHash){
45147 processResponse : function(result) {
45148 this.result = result;
45152 success : function(response, trans){
45153 if(trans.type == Ext.Direct.exceptions.SERVER){
45156 Ext.form.Action.DirectLoad.superclass.success.call(this, response);
45161 Ext.form.Action.DirectSubmit = Ext.extend(Ext.form.Action.Submit, {
45162 constructor : function(form, opts) {
45163 Ext.form.Action.DirectSubmit.superclass.constructor.call(this, form, opts);
45165 type : 'directsubmit',
45168 var o = this.options;
45169 if(o.clientValidation === false || this.form.isValid()){
45172 this.success.params = this.getParams();
45173 this.form.api.submit(this.form.el.dom, this.success, this);
45174 }else if (o.clientValidation !== false){
45175 this.failureType = Ext.form.Action.CLIENT_INVALID;
45176 this.form.afterAction(this, false);
45180 getParams : function() {
45182 var bp = this.form.baseParams;
45183 var p = this.options.params;
45184 Ext.apply(o, p, bp);
45190 processResponse : function(result) {
45191 this.result = result;
45195 success : function(response, trans){
45196 if(trans.type == Ext.Direct.exceptions.SERVER){
45199 Ext.form.Action.DirectSubmit.superclass.success.call(this, response);
45203 Ext.form.Action.ACTION_TYPES = {
45204 'load' : Ext.form.Action.Load,
45205 'submit' : Ext.form.Action.Submit,
45206 'directload' : Ext.form.Action.DirectLoad,
45207 'directsubmit' : Ext.form.Action.DirectSubmit
45210 Ext.form.VTypes = function(){
45212 var alpha = /^[a-zA-Z_]+$/,
45213 alphanum = /^[a-zA-Z0-9_]+$/,
45214 email = /^(\w+)([\-+.][\w]+)*@(\w[\-\w]*\.){1,5}([A-Za-z]){2,6}$/,
45215 url = /(((^https?)|(^ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
45220 'email' : function(v){
45221 return email.test(v);
45224 'emailText' : 'This field should be an e-mail address in the format "user@example.com"',
45226 'emailMask' : /[a-z0-9_\.\-@\+]/i,
45229 'url' : function(v){
45230 return url.test(v);
45233 'urlText' : 'This field should be a URL in the format "http:/'+'/www.example.com"',
45236 'alpha' : function(v){
45237 return alpha.test(v);
45240 'alphaText' : 'This field should only contain letters and _',
45242 'alphaMask' : /[a-z_]/i,
45245 'alphanum' : function(v){
45246 return alphanum.test(v);
45249 'alphanumText' : 'This field should only contain letters, numbers and _',
45251 'alphanumMask' : /[a-z0-9_]/i
45255 Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
45257 autoExpandColumn : false,
45260 autoExpandMax : 1000,
45263 autoExpandMin : 50,
45266 columnLines : false,
45273 ddText : '{0} selected row{1}',
45276 deferRowRender : true,
45281 enableColumnHide : true,
45284 enableColumnMove : true,
45287 enableDragDrop : false,
45290 enableHdMenu : true,
45298 minColumnWidth : 25,
45304 stripeRows : false,
45307 trackMouseOver : true,
45310 stateEvents : ['columnmove', 'columnresize', 'sortchange', 'groupchange'],
45327 initComponent : function() {
45328 Ext.grid.GridPanel.superclass.initComponent.call(this);
45330 if (this.columnLines) {
45331 this.cls = (this.cls || '') + ' x-grid-with-col-lines';
45335 this.autoScroll = false;
45336 this.autoWidth = false;
45338 if(Ext.isArray(this.columns)){
45339 this.colModel = new Ext.grid.ColumnModel(this.columns);
45340 delete this.columns;
45345 this.store = this.ds;
45349 this.colModel = this.cm;
45353 this.selModel = this.sm;
45356 this.store = Ext.StoreMgr.lookup(this.store);
45391 'rowbodymousedown',
45394 'containermousedown',
45415 'containerdblclick',
45427 'headercontextmenu',
45429 'groupcontextmenu',
45431 'containercontextmenu',
45433 'rowbodycontextmenu',
45452 onRender : function(ct, position){
45453 Ext.grid.GridPanel.superclass.onRender.apply(this, arguments);
45455 var c = this.getGridEl();
45457 this.el.addClass('x-grid-panel');
45461 mousedown: this.onMouseDown,
45462 click: this.onClick,
45463 dblclick: this.onDblClick,
45464 contextmenu: this.onContextMenu
45467 this.relayEvents(c, ['mousedown','mouseup','mouseover','mouseout','keypress', 'keydown']);
45469 var view = this.getView();
45472 this.getSelectionModel().init(this);
45476 initEvents : function(){
45477 Ext.grid.GridPanel.superclass.initEvents.call(this);
45480 this.loadMask = new Ext.LoadMask(this.bwrap,
45481 Ext.apply({store:this.store}, this.loadMask));
45485 initStateEvents : function(){
45486 Ext.grid.GridPanel.superclass.initStateEvents.call(this);
45487 this.mon(this.colModel, 'hiddenchange', this.saveState, this, {delay: 100});
45490 applyState : function(state){
45491 var cm = this.colModel,
45492 cs = state.columns,
45493 store = this.store,
45499 for(var i = 0, len = cs.length; i < len; i++){
45501 c = cm.getColumnById(s.id);
45503 colIndex = cm.getIndexById(s.id);
45504 cm.setState(colIndex, {
45507 sortable: s.sortable
45510 cm.moveColumn(colIndex, i);
45518 store[store.remoteSort ? 'setDefaultSort' : 'sort'](s.field, s.direction);
45525 store.clearGrouping();
45530 var o = Ext.apply({}, state);
45533 Ext.grid.GridPanel.superclass.applyState.call(this, o);
45536 getState : function(){
45537 var o = {columns: []},
45538 store = this.store,
45542 for(var i = 0, c; (c = this.colModel.config[i]); i++){
45548 o.columns[i].hidden = true;
45551 o.columns[i].sortable = true;
45555 ss = store.getSortState();
45559 if(store.getGroupState){
45560 gs = store.getGroupState();
45570 afterRender : function(){
45571 Ext.grid.GridPanel.superclass.afterRender.call(this);
45573 this.on('bodyresize', v.layout, v);
45575 if(this.deferRowRender){
45576 if (!this.deferRowRenderTask){
45577 this.deferRowRenderTask = new Ext.util.DelayedTask(v.afterRender, this.view);
45579 this.deferRowRenderTask.delay(10);
45583 this.viewReady = true;
45587 reconfigure : function(store, colModel){
45588 var rendered = this.rendered;
45591 this.loadMask.destroy();
45592 this.loadMask = new Ext.LoadMask(this.bwrap,
45593 Ext.apply({}, {store:store}, this.initialConfig.loadMask));
45597 this.view.initData(store, colModel);
45599 this.store = store;
45600 this.colModel = colModel;
45602 this.view.refresh(true);
45604 this.fireEvent('reconfigure', this, store, colModel);
45608 onDestroy : function(){
45609 if (this.deferRowRenderTask && this.deferRowRenderTask.cancel){
45610 this.deferRowRenderTask.cancel();
45613 Ext.destroy(this.view, this.loadMask);
45614 }else if(this.store && this.store.autoDestroy){
45615 this.store.destroy();
45617 Ext.destroy(this.colModel, this.selModel);
45618 this.store = this.selModel = this.colModel = this.view = this.loadMask = null;
45619 Ext.grid.GridPanel.superclass.onDestroy.call(this);
45623 processEvent : function(name, e){
45624 this.view.processEvent(name, e);
45628 onClick : function(e){
45629 this.processEvent('click', e);
45633 onMouseDown : function(e){
45634 this.processEvent('mousedown', e);
45638 onContextMenu : function(e, t){
45639 this.processEvent('contextmenu', e);
45643 onDblClick : function(e){
45644 this.processEvent('dblclick', e);
45648 walkCells : function(row, col, step, fn, scope){
45649 var cm = this.colModel,
45650 clen = cm.getColumnCount(),
45652 rlen = ds.getCount(),
45666 if(fn.call(scope || this, row, col, cm) === true){
45684 if(fn.call(scope || this, row, col, cm) === true){
45696 getGridEl : function(){
45701 stopEditing : Ext.emptyFn,
45704 getSelectionModel : function(){
45705 if(!this.selModel){
45706 this.selModel = new Ext.grid.RowSelectionModel(
45707 this.disableSelection ? {selectRow: Ext.emptyFn} : null);
45709 return this.selModel;
45713 getStore : function(){
45718 getColumnModel : function(){
45719 return this.colModel;
45723 getView : function() {
45725 this.view = new Ext.grid.GridView(this.viewConfig);
45731 getDragDropText : function(){
45732 var count = this.selModel.getCount();
45733 return String.format(this.ddText, count, count == 1 ? '' : 's');
45787 Ext.reg('grid', Ext.grid.GridPanel);
45788 Ext.grid.PivotGrid = Ext.extend(Ext.grid.GridPanel, {
45794 renderer: undefined,
45803 initComponent: function() {
45804 Ext.grid.PivotGrid.superclass.initComponent.apply(this, arguments);
45809 this.enableColumnResize = false;
45811 this.viewConfig = Ext.apply(this.viewConfig || {}, {
45817 this.colModel = new Ext.grid.ColumnModel({});
45821 getAggregator: function() {
45822 if (typeof this.aggregator == 'string') {
45823 return Ext.grid.PivotAggregatorMgr.types[this.aggregator];
45825 return this.aggregator;
45830 setAggregator: function(aggregator) {
45831 this.aggregator = aggregator;
45835 setMeasure: function(measure) {
45836 this.measure = measure;
45840 setLeftAxis: function(axis, refresh) {
45842 this.leftAxis = axis;
45845 this.view.refresh();
45850 setTopAxis: function(axis, refresh) {
45852 this.topAxis = axis;
45855 this.view.refresh();
45860 initAxes: function() {
45861 var PivotAxis = Ext.grid.PivotAxis;
45863 if (!(this.leftAxis instanceof PivotAxis)) {
45864 this.setLeftAxis(new PivotAxis({
45865 orientation: 'vertical',
45866 dimensions : this.leftAxis || [],
45871 if (!(this.topAxis instanceof PivotAxis)) {
45872 this.setTopAxis(new PivotAxis({
45873 orientation: 'horizontal',
45874 dimensions : this.topAxis || [],
45881 extractData: function() {
45882 var records = this.store.data.items,
45883 recCount = records.length,
45887 if (recCount == 0) {
45891 var leftTuples = this.leftAxis.getTuples(),
45892 leftCount = leftTuples.length,
45893 topTuples = this.topAxis.getTuples(),
45894 topCount = topTuples.length,
45895 aggregator = this.getAggregator();
45897 for (i = 0; i < recCount; i++) {
45898 record = records[i];
45900 for (j = 0; j < leftCount; j++) {
45901 cells[j] = cells[j] || [];
45903 if (leftTuples[j].matcher(record) === true) {
45904 for (k = 0; k < topCount; k++) {
45905 cells[j][k] = cells[j][k] || [];
45907 if (topTuples[k].matcher(record)) {
45908 cells[j][k].push(record);
45915 var rowCount = cells.length,
45918 for (i = 0; i < rowCount; i++) {
45920 colCount = row.length;
45922 for (j = 0; j < colCount; j++) {
45923 cells[i][j] = aggregator(cells[i][j], this.measure);
45931 getView: function() {
45933 this.view = new Ext.grid.PivotGridView(this.viewConfig);
45940 Ext.reg('pivotgrid', Ext.grid.PivotGrid);
45943 Ext.grid.PivotAggregatorMgr = new Ext.AbstractManager();
45945 Ext.grid.PivotAggregatorMgr.registerType('sum', function(records, measure) {
45946 var length = records.length,
45950 for (i = 0; i < length; i++) {
45951 total += records[i].get(measure);
45957 Ext.grid.PivotAggregatorMgr.registerType('avg', function(records, measure) {
45958 var length = records.length,
45962 for (i = 0; i < length; i++) {
45963 total += records[i].get(measure);
45966 return (total / length) || 'n/a';
45969 Ext.grid.PivotAggregatorMgr.registerType('min', function(records, measure) {
45971 length = records.length,
45974 for (i = 0; i < length; i++) {
45975 data.push(records[i].get(measure));
45978 return Math.min.apply(this, data) || 'n/a';
45981 Ext.grid.PivotAggregatorMgr.registerType('max', function(records, measure) {
45983 length = records.length,
45986 for (i = 0; i < length; i++) {
45987 data.push(records[i].get(measure));
45990 return Math.max.apply(this, data) || 'n/a';
45993 Ext.grid.PivotAggregatorMgr.registerType('count', function(records, measure) {
45994 return records.length;
45996 Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
46008 deferEmptyText : true,
46011 scrollOffset : undefined,
46020 sortClasses : ['sort-asc', 'sort-desc'],
46023 sortAscText : 'Sort Ascending',
46026 sortDescText : 'Sort Descending',
46029 columnsText : 'Columns',
46032 selectedRowClass : 'x-grid3-row-selected',
46036 tdClass : 'x-grid3-cell',
46037 hdCls : 'x-grid3-hd',
46044 cellSelectorDepth : 4,
46047 rowSelectorDepth : 10,
46050 rowBodySelectorDepth : 10,
46053 cellSelector : 'td.x-grid3-cell',
46056 rowSelector : 'div.x-grid3-row',
46059 rowBodySelector : 'div.x-grid3-row-body',
46062 firstRowCls: 'x-grid3-row-first',
46063 lastRowCls: 'x-grid3-row-last',
46064 rowClsRe: /(?:^|\s+)x-grid3-row-(first|last|alt)(?:\s+|$)/g,
46067 headerMenuOpenCls: 'x-grid3-hd-menu-open',
46070 rowOverCls: 'x-grid3-row-over',
46072 constructor : function(config) {
46073 Ext.apply(this, config);
46078 'beforerowremoved',
46081 'beforerowsinserted',
46099 Ext.grid.GridView.superclass.constructor.call(this);
46105 masterTpl: new Ext.Template(
46106 '<div class="x-grid3" hidefocus="true">',
46107 '<div class="x-grid3-viewport">',
46108 '<div class="x-grid3-header">',
46109 '<div class="x-grid3-header-inner">',
46110 '<div class="x-grid3-header-offset" style="{ostyle}">{header}</div>',
46112 '<div class="x-clear"></div>',
46114 '<div class="x-grid3-scroller">',
46115 '<div class="x-grid3-body" style="{bstyle}">{body}</div>',
46116 '<a href="#" class="x-grid3-focus" tabIndex="-1"></a>',
46119 '<div class="x-grid3-resize-marker"> </div>',
46120 '<div class="x-grid3-resize-proxy"> </div>',
46125 headerTpl: new Ext.Template(
46126 '<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
46128 '<tr class="x-grid3-hd-row">{cells}</tr>',
46134 bodyTpl: new Ext.Template('{rows}'),
46137 cellTpl: new Ext.Template(
46138 '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}" tabIndex="0" {cellAttr}>',
46139 '<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr}>{value}</div>',
46144 initTemplates : function() {
46145 var templates = this.templates || {},
46148 headerCellTpl = new Ext.Template(
46149 '<td class="x-grid3-hd x-grid3-cell x-grid3-td-{id} {css}" style="{style}">',
46150 '<div {tooltip} {attr} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">',
46151 this.grid.enableHdMenu ? '<a class="x-grid3-hd-btn" href="#"></a>' : '',
46153 '<img alt="" class="x-grid3-sort-icon" src="', Ext.BLANK_IMAGE_URL, '" />',
46159 '<tr class="x-grid3-row-body-tr" style="{bodyStyle}">',
46160 '<td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on">',
46161 '<div class="x-grid3-row-body">{body}</div>',
46167 '<table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
46169 '<tr>{cells}</tr>',
46170 this.enableRowBody ? rowBodyText : '',
46175 Ext.applyIf(templates, {
46176 hcell : headerCellTpl,
46177 cell : this.cellTpl,
46178 body : this.bodyTpl,
46179 header : this.headerTpl,
46180 master : this.masterTpl,
46181 row : new Ext.Template('<div class="x-grid3-row {alt}" style="{tstyle}">' + innerText + '</div>'),
46182 rowInner: new Ext.Template(innerText)
46185 for (name in templates) {
46186 template = templates[name];
46188 if (template && Ext.isFunction(template.compile) && !template.compiled) {
46189 template.disableFormats = true;
46190 template.compile();
46194 this.templates = templates;
46195 this.colRe = new RegExp('x-grid3-td-([^\\s]+)', '');
46199 fly : function(el) {
46200 if (!this._flyweight) {
46201 this._flyweight = new Ext.Element.Flyweight(document.body);
46203 this._flyweight.dom = el;
46204 return this._flyweight;
46208 getEditorParent : function() {
46209 return this.scroller.dom;
46213 initElements : function() {
46214 var Element = Ext.Element,
46215 el = Ext.get(this.grid.getGridEl().dom.firstChild),
46216 mainWrap = new Element(el.child('div.x-grid3-viewport')),
46217 mainHd = new Element(mainWrap.child('div.x-grid3-header')),
46218 scroller = new Element(mainWrap.child('div.x-grid3-scroller'));
46220 if (this.grid.hideHeaders) {
46221 mainHd.setDisplayed(false);
46224 if (this.forceFit) {
46225 scroller.setStyle('overflow-x', 'hidden');
46232 mainWrap: mainWrap,
46233 scroller: scroller,
46235 innerHd : mainHd.child('div.x-grid3-header-inner').dom,
46236 mainBody: new Element(Element.fly(scroller).child('div.x-grid3-body')),
46237 focusEl : new Element(Element.fly(scroller).child('a')),
46239 resizeMarker: new Element(el.child('div.x-grid3-resize-marker')),
46240 resizeProxy : new Element(el.child('div.x-grid3-resize-proxy'))
46243 this.focusEl.swallowEvent('click', true);
46247 getRows : function() {
46248 return this.hasRows() ? this.mainBody.dom.childNodes : [];
46254 findCell : function(el) {
46258 return this.fly(el).findParent(this.cellSelector, this.cellSelectorDepth);
46262 findCellIndex : function(el, requiredCls) {
46263 var cell = this.findCell(el),
46267 hasCls = this.fly(cell).hasClass(requiredCls);
46268 if (!requiredCls || hasCls) {
46269 return this.getCellIndex(cell);
46276 getCellIndex : function(el) {
46278 var match = el.className.match(this.colRe);
46280 if (match && match[1]) {
46281 return this.cm.getIndexById(match[1]);
46288 findHeaderCell : function(el) {
46289 var cell = this.findCell(el);
46290 return cell && this.fly(cell).hasClass(this.hdCls) ? cell : null;
46294 findHeaderIndex : function(el){
46295 return this.findCellIndex(el, this.hdCls);
46299 findRow : function(el) {
46303 return this.fly(el).findParent(this.rowSelector, this.rowSelectorDepth);
46307 findRowIndex : function(el) {
46308 var row = this.findRow(el);
46309 return row ? row.rowIndex : false;
46313 findRowBody : function(el) {
46318 return this.fly(el).findParent(this.rowBodySelector, this.rowBodySelectorDepth);
46324 getRow : function(row) {
46325 return this.getRows()[row];
46329 getCell : function(row, col) {
46330 return Ext.fly(this.getRow(row)).query(this.cellSelector)[col];
46334 getHeaderCell : function(index) {
46335 return this.mainHd.dom.getElementsByTagName('td')[index];
46341 addRowClass : function(rowId, cls) {
46342 var row = this.getRow(rowId);
46344 this.fly(row).addClass(cls);
46349 removeRowClass : function(row, cls) {
46350 var r = this.getRow(row);
46352 this.fly(r).removeClass(cls);
46357 removeRow : function(row) {
46358 Ext.removeNode(this.getRow(row));
46359 this.syncFocusEl(row);
46363 removeRows : function(firstRow, lastRow) {
46364 var bd = this.mainBody.dom,
46367 for (rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
46368 Ext.removeNode(bd.childNodes[firstRow]);
46371 this.syncFocusEl(firstRow);
46377 getScrollState : function() {
46378 var sb = this.scroller.dom;
46381 left: sb.scrollLeft,
46387 restoreScroll : function(state) {
46388 var sb = this.scroller.dom;
46389 sb.scrollLeft = state.left;
46390 sb.scrollTop = state.top;
46394 scrollToTop : function() {
46395 var dom = this.scroller.dom;
46398 dom.scrollLeft = 0;
46402 syncScroll : function() {
46403 this.syncHeaderScroll();
46404 var mb = this.scroller.dom;
46405 this.grid.fireEvent('bodyscroll', mb.scrollLeft, mb.scrollTop);
46409 syncHeaderScroll : function() {
46410 var innerHd = this.innerHd,
46411 scrollLeft = this.scroller.dom.scrollLeft;
46413 innerHd.scrollLeft = scrollLeft;
46414 innerHd.scrollLeft = scrollLeft;
46418 updateSortIcon : function(col, dir) {
46419 var sortClasses = this.sortClasses,
46420 sortClass = sortClasses[dir == "DESC" ? 1 : 0],
46421 headers = this.mainHd.select('td').removeClass(sortClasses);
46423 headers.item(col).addClass(sortClass);
46427 updateAllColumnWidths : function() {
46428 var totalWidth = this.getTotalWidth(),
46429 colCount = this.cm.getColumnCount(),
46430 rows = this.getRows(),
46431 rowCount = rows.length,
46433 row, rowFirstChild, trow, i, j;
46435 for (i = 0; i < colCount; i++) {
46436 widths[i] = this.getColumnWidth(i);
46437 this.getHeaderCell(i).style.width = widths[i];
46440 this.updateHeaderWidth();
46442 for (i = 0; i < rowCount; i++) {
46444 row.style.width = totalWidth;
46445 rowFirstChild = row.firstChild;
46447 if (rowFirstChild) {
46448 rowFirstChild.style.width = totalWidth;
46449 trow = rowFirstChild.rows[0];
46451 for (j = 0; j < colCount; j++) {
46452 trow.childNodes[j].style.width = widths[j];
46457 this.onAllColumnWidthsUpdated(widths, totalWidth);
46461 updateColumnWidth : function(column, width) {
46462 var columnWidth = this.getColumnWidth(column),
46463 totalWidth = this.getTotalWidth(),
46464 headerCell = this.getHeaderCell(column),
46465 nodes = this.getRows(),
46466 nodeCount = nodes.length,
46467 row, i, firstChild;
46469 this.updateHeaderWidth();
46470 headerCell.style.width = columnWidth;
46472 for (i = 0; i < nodeCount; i++) {
46474 firstChild = row.firstChild;
46476 row.style.width = totalWidth;
46478 firstChild.style.width = totalWidth;
46479 firstChild.rows[0].childNodes[column].style.width = columnWidth;
46483 this.onColumnWidthUpdated(column, columnWidth, totalWidth);
46487 updateColumnHidden : function(col, hidden) {
46488 var totalWidth = this.getTotalWidth(),
46489 display = hidden ? 'none' : '',
46490 headerCell = this.getHeaderCell(col),
46491 nodes = this.getRows(),
46492 nodeCount = nodes.length,
46493 row, rowFirstChild, i;
46495 this.updateHeaderWidth();
46496 headerCell.style.display = display;
46498 for (i = 0; i < nodeCount; i++) {
46500 row.style.width = totalWidth;
46501 rowFirstChild = row.firstChild;
46503 if (rowFirstChild) {
46504 rowFirstChild.style.width = totalWidth;
46505 rowFirstChild.rows[0].childNodes[col].style.display = display;
46509 this.onColumnHiddenUpdated(col, hidden, totalWidth);
46510 delete this.lastViewWidth;
46515 doRender : function(columns, records, store, startRow, colCount, stripe) {
46516 var templates = this.templates,
46517 cellTemplate = templates.cell,
46518 rowTemplate = templates.row,
46519 last = colCount - 1,
46520 tstyle = 'width:' + this.getTotalWidth() + ';',
46524 rowParams = {tstyle: tstyle},
46526 len = records.length,
46529 record, i, j, rowIndex;
46532 for (j = 0; j < len; j++) {
46533 record = records[j];
46536 rowIndex = j + startRow;
46539 for (i = 0; i < colCount; i++) {
46540 column = columns[i];
46542 meta.id = column.id;
46543 meta.css = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
46544 meta.attr = meta.cellAttr = '';
46545 meta.style = column.style;
46546 meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store);
46548 if (Ext.isEmpty(meta.value)) {
46549 meta.value = ' ';
46552 if (this.markDirty && record.dirty && typeof record.modified[column.name] != 'undefined') {
46553 meta.css += ' x-grid3-dirty-cell';
46556 colBuffer[colBuffer.length] = cellTemplate.apply(meta);
46561 if (stripe && ((rowIndex + 1) % 2 === 0)) {
46562 alt[0] = 'x-grid3-row-alt';
46565 if (record.dirty) {
46566 alt[1] = ' x-grid3-dirty-row';
46569 rowParams.cols = colCount;
46571 if (this.getRowClass) {
46572 alt[2] = this.getRowClass(record, rowIndex, rowParams, store);
46575 rowParams.alt = alt.join(' ');
46576 rowParams.cells = colBuffer.join('');
46578 rowBuffer[rowBuffer.length] = rowTemplate.apply(rowParams);
46581 return rowBuffer.join('');
46585 processRows : function(startRow, skipStripe) {
46586 if (!this.ds || this.ds.getCount() < 1) {
46590 var rows = this.getRows(),
46591 length = rows.length,
46594 skipStripe = skipStripe || !this.grid.stripeRows;
46595 startRow = startRow || 0;
46597 for (i = 0; i < length; i++) {
46602 row.className = row.className.replace(this.rowClsRe, ' ');
46603 if ((i + 1) % 2 === 0){
46604 row.className += ' x-grid3-row-alt';
46611 if (startRow === 0) {
46612 Ext.fly(rows[0]).addClass(this.firstRowCls);
46615 Ext.fly(rows[length - 1]).addClass(this.lastRowCls);
46619 afterRender : function() {
46620 if (!this.ds || !this.cm) {
46624 this.mainBody.dom.innerHTML = this.renderBody() || ' ';
46625 this.processRows(0, true);
46627 if (this.deferEmptyText !== true) {
46628 this.applyEmptyText();
46631 this.grid.fireEvent('viewready', this.grid);
46635 afterRenderUI: function() {
46636 var grid = this.grid;
46638 this.initElements();
46641 Ext.fly(this.innerHd).on('click', this.handleHdDown, this);
46645 mouseover: this.handleHdOver,
46646 mouseout : this.handleHdOut,
46647 mousemove: this.handleHdMove
46650 this.scroller.on('scroll', this.syncScroll, this);
46652 if (grid.enableColumnResize !== false) {
46653 this.splitZone = new Ext.grid.GridView.SplitDragZone(grid, this.mainHd.dom);
46656 if (grid.enableColumnMove) {
46657 this.columnDrag = new Ext.grid.GridView.ColumnDragZone(grid, this.innerHd);
46658 this.columnDrop = new Ext.grid.HeaderDropZone(grid, this.mainHd.dom);
46661 if (grid.enableHdMenu !== false) {
46662 this.hmenu = new Ext.menu.Menu({id: grid.id + '-hctx'});
46664 {itemId:'asc', text: this.sortAscText, cls: 'xg-hmenu-sort-asc'},
46665 {itemId:'desc', text: this.sortDescText, cls: 'xg-hmenu-sort-desc'}
46668 if (grid.enableColumnHide !== false) {
46669 this.colMenu = new Ext.menu.Menu({id:grid.id + '-hcols-menu'});
46672 beforeshow: this.beforeColMenuShow,
46673 itemclick : this.handleHdMenuClick
46675 this.hmenu.add('-', {
46677 hideOnClick: false,
46678 text: this.columnsText,
46679 menu: this.colMenu,
46680 iconCls: 'x-cols-icon'
46684 this.hmenu.on('itemclick', this.handleHdMenuClick, this);
46687 if (grid.trackMouseOver) {
46690 mouseover: this.onRowOver,
46691 mouseout : this.onRowOut
46695 if (grid.enableDragDrop || grid.enableDrag) {
46696 this.dragZone = new Ext.grid.GridDragZone(grid, {
46697 ddGroup : grid.ddGroup || 'GridDD'
46701 this.updateHeaderSortState();
46705 renderUI : function() {
46706 var templates = this.templates;
46708 return templates.master.apply({
46709 body : templates.body.apply({rows:' '}),
46710 header: this.renderHeaders(),
46711 ostyle: 'width:' + this.getOffsetWidth() + ';',
46712 bstyle: 'width:' + this.getTotalWidth() + ';'
46717 processEvent : function(name, e) {
46718 var target = e.getTarget(),
46720 header = this.findHeaderIndex(target),
46721 row, cell, col, body;
46723 grid.fireEvent(name, e);
46725 if (header !== false) {
46726 grid.fireEvent('header' + name, grid, header, e);
46728 row = this.findRowIndex(target);
46733 if (row !== false) {
46734 cell = this.findCellIndex(target);
46735 if (cell !== false) {
46736 col = grid.colModel.getColumnAt(cell);
46737 if (grid.fireEvent('cell' + name, grid, row, cell, e) !== false) {
46738 if (!col || (col.processEvent && (col.processEvent(name, e, grid, row, cell) !== false))) {
46739 grid.fireEvent('row' + name, grid, row, e);
46743 if (grid.fireEvent('row' + name, grid, row, e) !== false) {
46744 (body = this.findRowBody(target)) && grid.fireEvent('rowbody' + name, grid, row, e);
46748 grid.fireEvent('container' + name, grid, e);
46754 layout : function(initial) {
46755 if (!this.mainBody) {
46759 var grid = this.grid,
46760 gridEl = grid.getGridEl(),
46761 gridSize = gridEl.getSize(true),
46762 gridWidth = gridSize.width,
46763 gridHeight = gridSize.height,
46764 scroller = this.scroller,
46765 scrollStyle, headerHeight, scrollHeight;
46767 if (gridWidth < 20 || gridHeight < 20) {
46771 if (grid.autoHeight) {
46772 scrollStyle = scroller.dom.style;
46773 scrollStyle.overflow = 'visible';
46775 if (Ext.isWebKit) {
46776 scrollStyle.position = 'static';
46779 this.el.setSize(gridWidth, gridHeight);
46781 headerHeight = this.mainHd.getHeight();
46782 scrollHeight = gridHeight - headerHeight;
46784 scroller.setSize(gridWidth, scrollHeight);
46786 if (this.innerHd) {
46787 this.innerHd.style.width = (gridWidth) + "px";
46791 if (this.forceFit || (initial === true && this.autoFill)) {
46792 if (this.lastViewWidth != gridWidth) {
46793 this.fitColumns(false, false);
46794 this.lastViewWidth = gridWidth;
46798 this.syncHeaderScroll();
46801 this.onLayout(gridWidth, scrollHeight);
46806 onLayout : function(vw, vh) {
46810 onColumnWidthUpdated : function(col, w, tw) {
46814 onAllColumnWidthsUpdated : function(ws, tw) {
46818 onColumnHiddenUpdated : function(col, hidden, tw) {
46822 updateColumnText : function(col, text) {
46826 afterMove : function(colIndex) {
46832 init : function(grid) {
46835 this.initTemplates();
46836 this.initData(grid.store, grid.colModel);
46841 getColumnId : function(index){
46842 return this.cm.getColumnId(index);
46846 getOffsetWidth : function() {
46847 return (this.cm.getTotalWidth() + this.getScrollOffset()) + 'px';
46851 getScrollOffset: function() {
46852 return Ext.num(this.scrollOffset, Ext.getScrollBarWidth());
46856 renderHeaders : function() {
46857 var colModel = this.cm,
46858 templates = this.templates,
46859 headerTpl = templates.hcell,
46861 colCount = colModel.getColumnCount(),
46862 last = colCount - 1,
46866 for (i = 0; i < colCount; i++) {
46868 cssCls = 'x-grid3-cell-first ';
46870 cssCls = i == last ? 'x-grid3-cell-last ' : '';
46874 id : colModel.getColumnId(i),
46875 value : colModel.getColumnHeader(i) || '',
46876 style : this.getColumnStyle(i, true),
46878 tooltip: this.getColumnTooltip(i)
46881 if (colModel.config[i].align == 'right') {
46882 properties.istyle = 'padding-right: 16px;';
46884 delete properties.istyle;
46887 cells[i] = headerTpl.apply(properties);
46890 return templates.header.apply({
46891 cells : cells.join(""),
46892 tstyle: String.format("width: {0};", this.getTotalWidth())
46897 getColumnTooltip : function(i) {
46898 var tooltip = this.cm.getColumnTooltip(i);
46900 if (Ext.QuickTips.isEnabled()) {
46901 return 'ext:qtip="' + tooltip + '"';
46903 return 'title="' + tooltip + '"';
46911 beforeUpdate : function() {
46912 this.grid.stopEditing(true);
46916 updateHeaders : function() {
46917 this.innerHd.firstChild.innerHTML = this.renderHeaders();
46919 this.updateHeaderWidth(false);
46923 updateHeaderWidth: function(updateMain) {
46924 var innerHdChild = this.innerHd.firstChild,
46925 totalWidth = this.getTotalWidth();
46927 innerHdChild.style.width = this.getOffsetWidth();
46928 innerHdChild.firstChild.style.width = totalWidth;
46930 if (updateMain !== false) {
46931 this.mainBody.dom.style.width = totalWidth;
46936 focusRow : function(row) {
46937 this.focusCell(row, 0, false);
46941 focusCell : function(row, col, hscroll) {
46942 this.syncFocusEl(this.ensureVisible(row, col, hscroll));
46944 var focusEl = this.focusEl;
46949 focusEl.focus.defer(1, focusEl);
46954 resolveCell : function(row, col, hscroll) {
46955 if (!Ext.isNumber(row)) {
46956 row = row.rowIndex;
46963 if (row < 0 || row >= this.ds.getCount()) {
46966 col = (col !== undefined ? col : 0);
46968 var rowEl = this.getRow(row),
46969 colModel = this.cm,
46970 colCount = colModel.getColumnCount(),
46973 if (!(hscroll === false && col === 0)) {
46974 while (col < colCount && colModel.isHidden(col)) {
46978 cellEl = this.getCell(row, col);
46981 return {row: rowEl, cell: cellEl};
46985 getResolvedXY : function(resolved) {
46990 var cell = resolved.cell,
46991 row = resolved.row;
46994 return Ext.fly(cell).getXY();
46996 return [this.el.getX(), Ext.fly(row).getY()];
47001 syncFocusEl : function(row, col, hscroll) {
47004 if (!Ext.isArray(xy)) {
47005 row = Math.min(row, Math.max(0, this.getRows().length-1));
47011 xy = this.getResolvedXY(this.resolveCell(row, col, hscroll));
47014 this.focusEl.setXY(xy || this.scroller.getXY());
47018 ensureVisible : function(row, col, hscroll) {
47019 var resolved = this.resolveCell(row, col, hscroll);
47021 if (!resolved || !resolved.row) {
47025 var rowEl = resolved.row,
47026 cellEl = resolved.cell,
47027 c = this.scroller.dom,
47030 stop = this.el.dom;
47032 while (p && p != stop) {
47033 ctop += p.offsetTop;
47034 p = p.offsetParent;
47037 ctop -= this.mainHd.dom.offsetHeight;
47038 stop = parseInt(c.scrollTop, 10);
47040 var cbot = ctop + rowEl.offsetHeight,
47041 ch = c.clientHeight,
47046 c.scrollTop = ctop;
47047 } else if(cbot > sbot) {
47048 c.scrollTop = cbot-ch;
47051 if (hscroll !== false) {
47052 var cleft = parseInt(cellEl.offsetLeft, 10),
47053 cright = cleft + cellEl.offsetWidth,
47054 sleft = parseInt(c.scrollLeft, 10),
47055 sright = sleft + c.clientWidth;
47057 if (cleft < sleft) {
47058 c.scrollLeft = cleft;
47059 } else if(cright > sright) {
47060 c.scrollLeft = cright-c.clientWidth;
47064 return this.getResolvedXY(resolved);
47068 insertRows : function(dm, firstRow, lastRow, isUpdate) {
47069 var last = dm.getCount() - 1;
47070 if( !isUpdate && firstRow === 0 && lastRow >= last) {
47071 this.fireEvent('beforerowsinserted', this, firstRow, lastRow);
47073 this.fireEvent('rowsinserted', this, firstRow, lastRow);
47076 this.fireEvent('beforerowsinserted', this, firstRow, lastRow);
47078 var html = this.renderRows(firstRow, lastRow),
47079 before = this.getRow(firstRow);
47081 if(firstRow === 0){
47082 Ext.fly(this.getRow(0)).removeClass(this.firstRowCls);
47084 Ext.DomHelper.insertHtml('beforeBegin', before, html);
47086 var r = this.getRow(last - 1);
47088 Ext.fly(r).removeClass(this.lastRowCls);
47090 Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html);
47093 this.processRows(firstRow);
47094 this.fireEvent('rowsinserted', this, firstRow, lastRow);
47095 } else if (firstRow === 0 || firstRow >= last) {
47097 Ext.fly(this.getRow(firstRow)).addClass(firstRow === 0 ? this.firstRowCls : this.lastRowCls);
47100 this.syncFocusEl(firstRow);
47104 deleteRows : function(dm, firstRow, lastRow) {
47105 if (dm.getRowCount() < 1) {
47108 this.fireEvent('beforerowsdeleted', this, firstRow, lastRow);
47110 this.removeRows(firstRow, lastRow);
47112 this.processRows(firstRow);
47113 this.fireEvent('rowsdeleted', this, firstRow, lastRow);
47118 getColumnStyle : function(colIndex, isHeader) {
47119 var colModel = this.cm,
47120 colConfig = colModel.config,
47121 style = isHeader ? '' : colConfig[colIndex].css || '',
47122 align = colConfig[colIndex].align;
47124 style += String.format("width: {0};", this.getColumnWidth(colIndex));
47126 if (colModel.isHidden(colIndex)) {
47127 style += 'display: none; ';
47131 style += String.format("text-align: {0};", align);
47138 getColumnWidth : function(column) {
47139 var columnWidth = this.cm.getColumnWidth(column),
47140 borderWidth = this.borderWidth;
47142 if (Ext.isNumber(columnWidth)) {
47143 if (Ext.isBorderBox || (Ext.isWebKit && !Ext.isSafari2)) {
47144 return columnWidth + "px";
47146 return Math.max(columnWidth - borderWidth, 0) + "px";
47149 return columnWidth;
47154 getTotalWidth : function() {
47155 return this.cm.getTotalWidth() + 'px';
47159 fitColumns : function(preventRefresh, onlyExpand, omitColumn) {
47160 var grid = this.grid,
47161 colModel = this.cm,
47162 totalColWidth = colModel.getTotalWidth(false),
47163 gridWidth = this.getGridInnerWidth(),
47164 extraWidth = gridWidth - totalColWidth,
47168 colWidth, fraction, i;
47171 if (gridWidth < 20 || extraWidth === 0) {
47175 var visibleColCount = colModel.getColumnCount(true),
47176 totalColCount = colModel.getColumnCount(false),
47177 adjCount = visibleColCount - (Ext.isNumber(omitColumn) ? 1 : 0);
47179 if (adjCount === 0) {
47181 omitColumn = undefined;
47185 for (i = 0; i < totalColCount; i++) {
47186 if (!colModel.isFixed(i) && i !== omitColumn) {
47187 colWidth = colModel.getColumnWidth(i);
47188 columns.push(i, colWidth);
47190 if (!colModel.isHidden(i)) {
47197 fraction = (gridWidth - colModel.getTotalWidth()) / width;
47199 while (columns.length) {
47200 colWidth = columns.pop();
47203 colModel.setColumnWidth(i, Math.max(grid.minColumnWidth, Math.floor(colWidth + colWidth * fraction)), true);
47207 totalColWidth = colModel.getTotalWidth(false);
47209 if (totalColWidth > gridWidth) {
47210 var adjustCol = (adjCount == visibleColCount) ? extraCol : omitColumn,
47211 newWidth = Math.max(1, colModel.getColumnWidth(adjustCol) - (totalColWidth - gridWidth));
47213 colModel.setColumnWidth(adjustCol, newWidth, true);
47216 if (preventRefresh !== true) {
47217 this.updateAllColumnWidths();
47224 autoExpand : function(preventUpdate) {
47225 var grid = this.grid,
47226 colModel = this.cm,
47227 gridWidth = this.getGridInnerWidth(),
47228 totalColumnWidth = colModel.getTotalWidth(false),
47229 autoExpandColumn = grid.autoExpandColumn;
47231 if (!this.userResized && autoExpandColumn) {
47232 if (gridWidth != totalColumnWidth) {
47234 var colIndex = colModel.getIndexById(autoExpandColumn),
47235 currentWidth = colModel.getColumnWidth(colIndex),
47236 desiredWidth = gridWidth - totalColumnWidth + currentWidth,
47237 newWidth = Math.min(Math.max(desiredWidth, grid.autoExpandMin), grid.autoExpandMax);
47239 if (currentWidth != newWidth) {
47240 colModel.setColumnWidth(colIndex, newWidth, true);
47242 if (preventUpdate !== true) {
47243 this.updateColumnWidth(colIndex, newWidth);
47251 getGridInnerWidth: function() {
47252 return this.grid.getGridEl().getWidth(true) - this.getScrollOffset();
47256 getColumnData : function() {
47258 colModel = this.cm,
47259 colCount = colModel.getColumnCount(),
47260 fields = this.ds.fields,
47263 for (i = 0; i < colCount; i++) {
47264 name = colModel.getDataIndex(i);
47267 name : Ext.isDefined(name) ? name : (fields.get(i) ? fields.get(i).name : undefined),
47268 renderer: colModel.getRenderer(i),
47269 scope : colModel.getRendererScope(i),
47270 id : colModel.getColumnId(i),
47271 style : this.getColumnStyle(i)
47279 renderRows : function(startRow, endRow) {
47280 var grid = this.grid,
47281 store = grid.store,
47282 stripe = grid.stripeRows,
47283 colModel = grid.colModel,
47284 colCount = colModel.getColumnCount(),
47285 rowCount = store.getCount(),
47288 if (rowCount < 1) {
47292 startRow = startRow || 0;
47293 endRow = Ext.isDefined(endRow) ? endRow : rowCount - 1;
47294 records = store.getRange(startRow, endRow);
47296 return this.doRender(this.getColumnData(), records, store, startRow, colCount, stripe);
47300 renderBody : function(){
47301 var markup = this.renderRows() || ' ';
47302 return this.templates.body.apply({rows: markup});
47306 refreshRow: function(record) {
47307 var store = this.ds,
47308 colCount = this.cm.getColumnCount(),
47309 columns = this.getColumnData(),
47310 last = colCount - 1,
47311 cls = ['x-grid3-row'],
47313 tstyle: String.format("width: {0};", this.getTotalWidth())
47316 cellTpl = this.templates.cell,
47317 rowIndex, row, column, meta, css, i;
47319 if (Ext.isNumber(record)) {
47321 record = store.getAt(rowIndex);
47323 rowIndex = store.indexOf(record);
47327 if (!record || rowIndex < 0) {
47332 for (i = 0; i < colCount; i++) {
47333 column = columns[i];
47336 css = 'x-grid3-cell-first';
47338 css = (i == last) ? 'x-grid3-cell-last ' : '';
47343 style : column.style,
47349 meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store);
47351 if (Ext.isEmpty(meta.value)) {
47352 meta.value = ' ';
47355 if (this.markDirty && record.dirty && typeof record.modified[column.name] != 'undefined') {
47356 meta.css += ' x-grid3-dirty-cell';
47359 colBuffer[i] = cellTpl.apply(meta);
47362 row = this.getRow(rowIndex);
47363 row.className = '';
47365 if (this.grid.stripeRows && ((rowIndex + 1) % 2 === 0)) {
47366 cls.push('x-grid3-row-alt');
47369 if (this.getRowClass) {
47370 rowParams.cols = colCount;
47371 cls.push(this.getRowClass(record, rowIndex, rowParams, store));
47374 this.fly(row).addClass(cls).setStyle(rowParams.tstyle);
47375 rowParams.cells = colBuffer.join("");
47376 row.innerHTML = this.templates.rowInner.apply(rowParams);
47378 this.fireEvent('rowupdated', this, rowIndex, record);
47382 refresh : function(headersToo) {
47383 this.fireEvent('beforerefresh', this);
47384 this.grid.stopEditing(true);
47386 var result = this.renderBody();
47387 this.mainBody.update(result).setWidth(this.getTotalWidth());
47388 if (headersToo === true) {
47389 this.updateHeaders();
47390 this.updateHeaderSortState();
47392 this.processRows(0, true);
47394 this.applyEmptyText();
47395 this.fireEvent('refresh', this);
47399 applyEmptyText : function() {
47400 if (this.emptyText && !this.hasRows()) {
47401 this.mainBody.update('<div class="x-grid-empty">' + this.emptyText + '</div>');
47406 updateHeaderSortState : function() {
47407 var state = this.ds.getSortState();
47412 if (!this.sortState || (this.sortState.field != state.field || this.sortState.direction != state.direction)) {
47413 this.grid.fireEvent('sortchange', this.grid, state);
47416 this.sortState = state;
47418 var sortColumn = this.cm.findColumnIndex(state.field);
47419 if (sortColumn != -1) {
47420 var sortDir = state.direction;
47421 this.updateSortIcon(sortColumn, sortDir);
47426 clearHeaderSortState : function() {
47427 if (!this.sortState) {
47430 this.grid.fireEvent('sortchange', this.grid, null);
47431 this.mainHd.select('td').removeClass(this.sortClasses);
47432 delete this.sortState;
47436 destroy : function() {
47439 gridEl = grid.getGridEl(),
47440 dragZone = me.dragZone,
47441 splitZone = me.splitZone,
47442 columnDrag = me.columnDrag,
47443 columnDrop = me.columnDrop,
47444 scrollToTopTask = me.scrollToTopTask,
47448 if (scrollToTopTask && scrollToTopTask.cancel) {
47449 scrollToTopTask.cancel();
47452 Ext.destroyMembers(me, 'colMenu', 'hmenu');
47454 me.initData(null, null);
47455 me.purgeListeners();
47457 Ext.fly(me.innerHd).un("click", me.handleHdDown, me);
47459 if (grid.enableColumnMove) {
47460 columnDragData = columnDrag.dragData;
47461 columnDragProxy = columnDrag.proxy;
47464 columnDragProxy.ghost,
47465 columnDragProxy.el,
47467 columnDrop.proxyTop,
47468 columnDrop.proxyBottom,
47469 columnDragData.ddel,
47470 columnDragData.header
47473 if (columnDragProxy.anim) {
47474 Ext.destroy(columnDragProxy.anim);
47477 delete columnDragProxy.ghost;
47478 delete columnDragData.ddel;
47479 delete columnDragData.header;
47480 columnDrag.destroy();
47482 delete Ext.dd.DDM.locationCache[columnDrag.id];
47483 delete columnDrag._domRef;
47485 delete columnDrop.proxyTop;
47486 delete columnDrop.proxyBottom;
47487 columnDrop.destroy();
47488 delete Ext.dd.DDM.locationCache["gridHeader" + gridEl.id];
47489 delete columnDrop._domRef;
47490 delete Ext.dd.DDM.ids[columnDrop.ddGroup];
47494 splitZone.destroy();
47495 delete splitZone._domRef;
47496 delete Ext.dd.DDM.ids["gridSplitters" + gridEl.id];
47499 Ext.fly(me.innerHd).removeAllListeners();
47500 Ext.removeNode(me.innerHd);
47518 delete grid.container;
47521 dragZone.destroy();
47524 Ext.dd.DDM.currentTarget = null;
47525 delete Ext.dd.DDM.locationCache[gridEl.id];
47527 Ext.EventManager.removeResizeListener(me.onWindowResize, me);
47531 onDenyColumnHide : function() {
47536 render : function() {
47537 if (this.autoFill) {
47538 var ct = this.grid.ownerCt;
47540 if (ct && ct.getLayout()) {
47541 ct.on('afterlayout', function() {
47542 this.fitColumns(true, true);
47543 this.updateHeaders();
47544 this.updateHeaderSortState();
47545 }, this, {single: true});
47547 } else if (this.forceFit) {
47548 this.fitColumns(true, false);
47549 } else if (this.grid.autoExpandColumn) {
47550 this.autoExpand(true);
47553 this.grid.getGridEl().dom.innerHTML = this.renderUI();
47555 this.afterRenderUI();
47561 initData : function(newStore, newColModel) {
47565 var oldStore = me.ds;
47567 oldStore.un('add', me.onAdd, me);
47568 oldStore.un('load', me.onLoad, me);
47569 oldStore.un('clear', me.onClear, me);
47570 oldStore.un('remove', me.onRemove, me);
47571 oldStore.un('update', me.onUpdate, me);
47572 oldStore.un('datachanged', me.onDataChange, me);
47574 if (oldStore !== newStore && oldStore.autoDestroy) {
47575 oldStore.destroy();
47584 remove : me.onRemove,
47585 update : me.onUpdate,
47586 clear : me.onClear,
47587 datachanged: me.onDataChange
47592 var oldColModel = me.cm;
47594 oldColModel.un('configchange', me.onColConfigChange, me);
47595 oldColModel.un('widthchange', me.onColWidthChange, me);
47596 oldColModel.un('headerchange', me.onHeaderChange, me);
47597 oldColModel.un('hiddenchange', me.onHiddenChange, me);
47598 oldColModel.un('columnmoved', me.onColumnMove, me);
47602 delete me.lastViewWidth;
47606 configchange: me.onColConfigChange,
47607 widthchange : me.onColWidthChange,
47608 headerchange: me.onHeaderChange,
47609 hiddenchange: me.onHiddenChange,
47610 columnmoved : me.onColumnMove
47615 me.cm = newColModel;
47619 onDataChange : function(){
47620 this.refresh(true);
47621 this.updateHeaderSortState();
47622 this.syncFocusEl(0);
47626 onClear : function() {
47628 this.syncFocusEl(0);
47632 onUpdate : function(store, record) {
47633 this.refreshRow(record);
47637 onAdd : function(store, records, index) {
47638 this.insertRows(store, index, index + (records.length-1));
47642 onRemove : function(store, record, index, isUpdate) {
47643 if (isUpdate !== true) {
47644 this.fireEvent('beforerowremoved', this, index, record);
47647 this.removeRow(index);
47649 if (isUpdate !== true) {
47650 this.processRows(index);
47651 this.applyEmptyText();
47652 this.fireEvent('rowremoved', this, index, record);
47657 onLoad : function() {
47659 if (!this.scrollToTopTask) {
47660 this.scrollToTopTask = new Ext.util.DelayedTask(this.scrollToTop, this);
47662 this.scrollToTopTask.delay(1);
47664 this.scrollToTop();
47669 onColWidthChange : function(cm, col, width) {
47670 this.updateColumnWidth(col, width);
47674 onHeaderChange : function(cm, col, text) {
47675 this.updateHeaders();
47679 onHiddenChange : function(cm, col, hidden) {
47680 this.updateColumnHidden(col, hidden);
47684 onColumnMove : function(cm, oldIndex, newIndex) {
47685 this.indexMap = null;
47686 this.refresh(true);
47687 this.restoreScroll(this.getScrollState());
47689 this.afterMove(newIndex);
47690 this.grid.fireEvent('columnmove', oldIndex, newIndex);
47694 onColConfigChange : function() {
47695 delete this.lastViewWidth;
47696 this.indexMap = null;
47697 this.refresh(true);
47702 initUI : function(grid) {
47703 grid.on('headerclick', this.onHeaderClick, this);
47707 initEvents : Ext.emptyFn,
47710 onHeaderClick : function(g, index) {
47711 if (this.headersDisabled || !this.cm.isSortable(index)) {
47714 g.stopEditing(true);
47715 g.store.sort(this.cm.getDataIndex(index));
47719 onRowOver : function(e, target) {
47720 var row = this.findRowIndex(target);
47722 if (row !== false) {
47723 this.addRowClass(row, this.rowOverCls);
47728 onRowOut : function(e, target) {
47729 var row = this.findRowIndex(target);
47731 if (row !== false && !e.within(this.getRow(row), true)) {
47732 this.removeRowClass(row, this.rowOverCls);
47737 onRowSelect : function(row) {
47738 this.addRowClass(row, this.selectedRowClass);
47742 onRowDeselect : function(row) {
47743 this.removeRowClass(row, this.selectedRowClass);
47747 onCellSelect : function(row, col) {
47748 var cell = this.getCell(row, col);
47750 this.fly(cell).addClass('x-grid3-cell-selected');
47755 onCellDeselect : function(row, col) {
47756 var cell = this.getCell(row, col);
47758 this.fly(cell).removeClass('x-grid3-cell-selected');
47763 handleWheel : function(e) {
47764 e.stopPropagation();
47768 onColumnSplitterMoved : function(cellIndex, width) {
47769 this.userResized = true;
47770 this.grid.colModel.setColumnWidth(cellIndex, width, true);
47772 if (this.forceFit) {
47773 this.fitColumns(true, false, cellIndex);
47774 this.updateAllColumnWidths();
47776 this.updateColumnWidth(cellIndex, width);
47777 this.syncHeaderScroll();
47780 this.grid.fireEvent('columnresize', cellIndex, width);
47784 beforeColMenuShow : function() {
47785 var colModel = this.cm,
47786 colCount = colModel.getColumnCount(),
47787 colMenu = this.colMenu,
47790 colMenu.removeAll();
47792 for (i = 0; i < colCount; i++) {
47793 if (colModel.config[i].hideable !== false) {
47794 colMenu.add(new Ext.menu.CheckItem({
47795 text : colModel.getColumnHeader(i),
47796 itemId : 'col-' + colModel.getColumnId(i),
47797 checked : !colModel.isHidden(i),
47798 disabled : colModel.config[i].hideable === false,
47806 handleHdMenuClick : function(item) {
47807 var store = this.ds,
47808 dataIndex = this.cm.getDataIndex(this.hdCtxIndex);
47810 switch (item.getItemId()) {
47812 store.sort(dataIndex, 'ASC');
47815 store.sort(dataIndex, 'DESC');
47818 this.handleHdMenuClickDefault(item);
47824 handleHdMenuClickDefault: function(item) {
47825 var colModel = this.cm,
47826 itemId = item.getItemId(),
47827 index = colModel.getIndexById(itemId.substr(4));
47830 if (item.checked && colModel.getColumnsBy(this.isHideableColumn, this).length <= 1) {
47831 this.onDenyColumnHide();
47834 colModel.setHidden(index, item.checked);
47839 handleHdDown : function(e, target) {
47840 if (Ext.fly(target).hasClass('x-grid3-hd-btn')) {
47843 var colModel = this.cm,
47844 header = this.findHeaderCell(target),
47845 index = this.getCellIndex(header),
47846 sortable = colModel.isSortable(index),
47848 menuItems = menu.items,
47849 menuCls = this.headerMenuOpenCls;
47851 this.hdCtxIndex = index;
47853 Ext.fly(header).addClass(menuCls);
47854 menuItems.get('asc').setDisabled(!sortable);
47855 menuItems.get('desc').setDisabled(!sortable);
47857 menu.on('hide', function() {
47858 Ext.fly(header).removeClass(menuCls);
47859 }, this, {single:true});
47861 menu.show(target, 'tl-bl?');
47866 handleHdMove : function(e) {
47867 var header = this.findHeaderCell(this.activeHdRef);
47869 if (header && !this.headersDisabled) {
47870 var handleWidth = this.splitHandleWidth || 5,
47871 activeRegion = this.activeHdRegion,
47872 headerStyle = header.style,
47873 colModel = this.cm,
47875 pageX = e.getPageX();
47877 if (this.grid.enableColumnResize !== false) {
47878 var activeHeaderIndex = this.activeHdIndex,
47879 previousVisible = this.getPreviousVisible(activeHeaderIndex),
47880 currentResizable = colModel.isResizable(activeHeaderIndex),
47881 previousResizable = previousVisible && colModel.isResizable(previousVisible),
47882 inLeftResizer = pageX - activeRegion.left <= handleWidth,
47883 inRightResizer = activeRegion.right - pageX <= (!this.activeHdBtn ? handleWidth : 2);
47885 if (inLeftResizer && previousResizable) {
47886 cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'e-resize' : 'col-resize';
47887 } else if (inRightResizer && currentResizable) {
47888 cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'w-resize' : 'col-resize';
47892 headerStyle.cursor = cursor;
47897 getPreviousVisible: function(index) {
47898 while (index > 0) {
47899 if (!this.cm.isHidden(index - 1)) {
47908 handleHdOver : function(e, target) {
47909 var header = this.findHeaderCell(target);
47911 if (header && !this.headersDisabled) {
47912 var fly = this.fly(header);
47914 this.activeHdRef = target;
47915 this.activeHdIndex = this.getCellIndex(header);
47916 this.activeHdRegion = fly.getRegion();
47918 if (!this.isMenuDisabled(this.activeHdIndex, fly)) {
47919 fly.addClass('x-grid3-hd-over');
47920 this.activeHdBtn = fly.child('.x-grid3-hd-btn');
47922 if (this.activeHdBtn) {
47923 this.activeHdBtn.dom.style.height = (header.firstChild.offsetHeight - 1) + 'px';
47930 handleHdOut : function(e, target) {
47931 var header = this.findHeaderCell(target);
47933 if (header && (!Ext.isIE || !e.within(header, true))) {
47934 this.activeHdRef = null;
47935 this.fly(header).removeClass('x-grid3-hd-over');
47936 header.style.cursor = '';
47941 isMenuDisabled: function(cellIndex, el) {
47942 return this.cm.isMenuDisabled(cellIndex);
47946 hasRows : function() {
47947 var fc = this.mainBody.dom.firstChild;
47948 return fc && fc.nodeType == 1 && fc.className != 'x-grid-empty';
47952 isHideableColumn : function(c) {
47957 bind : function(d, c) {
47958 this.initData(d, c);
47965 Ext.grid.GridView.SplitDragZone = Ext.extend(Ext.dd.DDProxy, {
47967 constructor: function(grid, hd){
47969 this.view = grid.getView();
47970 this.marker = this.view.resizeMarker;
47971 this.proxy = this.view.resizeProxy;
47972 Ext.grid.GridView.SplitDragZone.superclass.constructor.call(this, hd,
47973 'gridSplitters' + this.grid.getGridEl().id, {
47974 dragElId : Ext.id(this.proxy.dom), resizeFrame:false
47976 this.scroll = false;
47977 this.hw = this.view.splitHandleWidth || 5;
47980 b4StartDrag : function(x, y){
47981 this.dragHeadersDisabled = this.view.headersDisabled;
47982 this.view.headersDisabled = true;
47983 var h = this.view.mainWrap.getHeight();
47984 this.marker.setHeight(h);
47985 this.marker.show();
47986 this.marker.alignTo(this.view.getHeaderCell(this.cellIndex), 'tl-tl', [-2, 0]);
47987 this.proxy.setHeight(h);
47988 var w = this.cm.getColumnWidth(this.cellIndex),
47989 minw = Math.max(w-this.grid.minColumnWidth, 0);
47990 this.resetConstraints();
47991 this.setXConstraint(minw, 1000);
47992 this.setYConstraint(0, 0);
47993 this.minX = x - minw;
47994 this.maxX = x + 1000;
47996 Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
47999 allowHeaderDrag : function(e){
48003 handleMouseDown : function(e){
48004 var t = this.view.findHeaderCell(e.getTarget());
48005 if(t && this.allowHeaderDrag(e)){
48006 var xy = this.view.fly(t).getXY(),
48013 if((ex - x) <= this.hw){
48015 }else if((x+w) - ex <= this.hw){
48018 if(adjust !== false){
48019 this.cm = this.grid.colModel;
48020 var ci = this.view.getCellIndex(t);
48022 if (ci + adjust < 0) {
48025 while(this.cm.isHidden(ci+adjust)){
48032 this.cellIndex = ci+adjust;
48033 this.split = t.dom;
48034 if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
48035 Ext.grid.GridView.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
48037 }else if(this.view.columnDrag){
48038 this.view.columnDrag.callHandleMouseDown(e);
48043 endDrag : function(e){
48044 this.marker.hide();
48046 endX = Math.max(this.minX, e.getPageX()),
48047 diff = endX - this.startPos,
48048 disabled = this.dragHeadersDisabled;
48050 v.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
48051 setTimeout(function(){
48052 v.headersDisabled = disabled;
48056 autoOffset : function(){
48057 this.setDelta(0,0);
48061 Ext.grid.PivotGridView = Ext.extend(Ext.grid.GridView, {
48064 colHeaderCellCls: 'grid-hd-group-cell',
48072 getColumnHeaders: function() {
48073 return this.grid.topAxis.buildHeaders();;
48077 getRowHeaders: function() {
48078 return this.grid.leftAxis.buildHeaders();
48082 renderRows : function(startRow, endRow) {
48083 var grid = this.grid,
48084 rows = grid.extractData(),
48085 rowCount = rows.length,
48086 templates = this.templates,
48087 renderer = grid.renderer,
48088 hasRenderer = typeof renderer == 'function',
48089 getCellCls = this.getCellCls,
48090 hasGetCellCls = typeof getCellCls == 'function',
48091 cellTemplate = templates.cell,
48092 rowTemplate = templates.row,
48095 tstyle = 'width:' + this.getGridInnerWidth() + 'px;',
48096 colBuffer, column, i;
48098 startRow = startRow || 0;
48099 endRow = Ext.isDefined(endRow) ? endRow : rowCount - 1;
48101 for (i = 0; i < rowCount; i++) {
48103 colCount = row.length;
48106 rowIndex = startRow + i;
48109 for (j = 0; j < colCount; j++) {
48112 meta.css = j === 0 ? 'x-grid3-cell-first ' : (j == (colCount - 1) ? 'x-grid3-cell-last ' : '');
48113 meta.attr = meta.cellAttr = '';
48116 if (Ext.isEmpty(meta.value)) {
48117 meta.value = ' ';
48121 meta.value = renderer(meta.value);
48124 if (hasGetCellCls) {
48125 meta.css += getCellCls(meta.value) + ' ';
48128 colBuffer[colBuffer.length] = cellTemplate.apply(meta);
48131 rowBuffer[rowBuffer.length] = rowTemplate.apply({
48134 cells : colBuffer.join(""),
48139 return rowBuffer.join("");
48143 masterTpl: new Ext.Template(
48144 '<div class="x-grid3 x-pivotgrid" hidefocus="true">',
48145 '<div class="x-grid3-viewport">',
48146 '<div class="x-grid3-header">',
48147 '<div class="x-grid3-header-title"><span>{title}</span></div>',
48148 '<div class="x-grid3-header-inner">',
48149 '<div class="x-grid3-header-offset" style="{ostyle}"></div>',
48151 '<div class="x-clear"></div>',
48153 '<div class="x-grid3-scroller">',
48154 '<div class="x-grid3-row-headers"></div>',
48155 '<div class="x-grid3-body" style="{bstyle}">{body}</div>',
48156 '<a href="#" class="x-grid3-focus" tabIndex="-1"></a>',
48159 '<div class="x-grid3-resize-marker"> </div>',
48160 '<div class="x-grid3-resize-proxy"> </div>',
48165 initTemplates: function() {
48166 Ext.grid.PivotGridView.superclass.initTemplates.apply(this, arguments);
48168 var templates = this.templates || {};
48169 if (!templates.gcell) {
48170 templates.gcell = new Ext.XTemplate(
48171 '<td class="x-grid3-hd x-grid3-gcell x-grid3-td-{id} ux-grid-hd-group-row-{row} ' + this.colHeaderCellCls + '" style="{style}">',
48172 '<div {tooltip} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">',
48173 this.grid.enableHdMenu ? '<a class="x-grid3-hd-btn" href="#"></a>' : '', '{value}',
48179 this.templates = templates;
48180 this.hrowRe = new RegExp("ux-grid-hd-group-row-(\\d+)", "");
48184 initElements: function() {
48185 Ext.grid.PivotGridView.superclass.initElements.apply(this, arguments);
48188 this.rowHeadersEl = new Ext.Element(this.scroller.child('div.x-grid3-row-headers'));
48191 this.headerTitleEl = new Ext.Element(this.mainHd.child('div.x-grid3-header-title'));
48195 getGridInnerWidth: function() {
48196 var previousWidth = Ext.grid.PivotGridView.superclass.getGridInnerWidth.apply(this, arguments);
48198 return previousWidth - this.getTotalRowHeaderWidth();
48202 getTotalRowHeaderWidth: function() {
48203 var headers = this.getRowHeaders(),
48204 length = headers.length,
48208 for (i = 0; i< length; i++) {
48209 total += headers[i].width;
48216 getTotalColumnHeaderHeight: function() {
48217 return this.getColumnHeaders().length * 21;
48221 renderUI : function() {
48222 var templates = this.templates,
48223 innerWidth = this.getGridInnerWidth();
48225 return templates.master.apply({
48226 body : templates.body.apply({rows:' '}),
48227 ostyle: 'width:' + innerWidth + 'px',
48228 bstyle: 'width:' + innerWidth + 'px'
48233 onLayout: function(width, height) {
48234 Ext.grid.PivotGridView.superclass.onLayout.apply(this, arguments);
48236 var width = this.getGridInnerWidth();
48238 this.resizeColumnHeaders(width);
48239 this.resizeAllRows(width);
48243 refresh : function(headersToo) {
48244 this.fireEvent('beforerefresh', this);
48245 this.grid.stopEditing(true);
48247 var result = this.renderBody();
48248 this.mainBody.update(result).setWidth(this.getGridInnerWidth());
48249 if (headersToo === true) {
48250 this.updateHeaders();
48251 this.updateHeaderSortState();
48253 this.processRows(0, true);
48255 this.applyEmptyText();
48256 this.fireEvent('refresh', this);
48260 renderHeaders: Ext.emptyFn,
48263 fitColumns: Ext.emptyFn,
48266 resizeColumnHeaders: function(width) {
48267 var topAxis = this.grid.topAxis;
48269 if (topAxis.rendered) {
48270 topAxis.el.setWidth(width);
48275 resizeRowHeaders: function() {
48276 var rowHeaderWidth = this.getTotalRowHeaderWidth(),
48277 marginStyle = String.format("margin-left: {0}px;", rowHeaderWidth);
48279 this.rowHeadersEl.setWidth(rowHeaderWidth);
48280 this.mainBody.applyStyles(marginStyle);
48281 Ext.fly(this.innerHd).applyStyles(marginStyle);
48283 this.headerTitleEl.setWidth(rowHeaderWidth);
48284 this.headerTitleEl.setHeight(this.getTotalColumnHeaderHeight());
48288 resizeAllRows: function(width) {
48289 var rows = this.getRows(),
48290 length = rows.length,
48293 for (i = 0; i < length; i++) {
48294 Ext.fly(rows[i]).setWidth(width);
48295 Ext.fly(rows[i]).child('table').setWidth(width);
48300 updateHeaders: function() {
48301 this.renderGroupRowHeaders();
48302 this.renderGroupColumnHeaders();
48306 renderGroupRowHeaders: function() {
48307 var leftAxis = this.grid.leftAxis;
48309 this.resizeRowHeaders();
48310 leftAxis.rendered = false;
48311 leftAxis.render(this.rowHeadersEl);
48313 this.setTitle(this.title);
48317 setTitle: function(title) {
48318 this.headerTitleEl.child('span').dom.innerHTML = title;
48322 renderGroupColumnHeaders: function() {
48323 var topAxis = this.grid.topAxis;
48325 topAxis.rendered = false;
48326 topAxis.render(this.innerHd.firstChild);
48330 isMenuDisabled: function(cellIndex, el) {
48334 Ext.grid.PivotAxis = Ext.extend(Ext.Component, {
48336 orientation: 'horizontal',
48339 defaultHeaderWidth: 80,
48345 setDimensions: function(dimensions) {
48346 this.dimensions = dimensions;
48350 onRender: function(ct, position) {
48351 var rows = this.orientation == 'horizontal'
48352 ? this.renderHorizontalRows()
48353 : this.renderVerticalRows();
48355 this.el = Ext.DomHelper.overwrite(ct.dom, {tag: 'table', cn: rows}, true);
48359 renderHorizontalRows: function() {
48360 var headers = this.buildHeaders(),
48361 rowCount = headers.length,
48363 cells, cols, colCount, i, j;
48365 for (i = 0; i < rowCount; i++) {
48367 cols = headers[i].items;
48368 colCount = cols.length;
48370 for (j = 0; j < colCount; j++) {
48373 html: cols[j].header,
48374 colspan: cols[j].span
48388 renderVerticalRows: function() {
48389 var headers = this.buildHeaders(),
48390 colCount = headers.length,
48393 rowCount, col, row, colWidth, i, j;
48395 for (i = 0; i < colCount; i++) {
48397 colWidth = col.width || 80;
48398 rowCount = col.items.length;
48400 for (j = 0; j < rowCount; j++) {
48401 row = col.items[j];
48403 rowCells[row.start] = rowCells[row.start] || [];
48404 rowCells[row.start].push({
48408 width : Ext.isBorderBox ? colWidth : colWidth - this.paddingWidth
48413 rowCount = rowCells.length;
48414 for (i = 0; i < rowCount; i++) {
48425 getTuples: function() {
48426 var newStore = new Ext.data.Store({});
48428 newStore.data = this.store.data.clone();
48429 newStore.fields = this.store.fields;
48432 dimensions = this.dimensions,
48433 length = dimensions.length,
48436 for (i = 0; i < length; i++) {
48438 field : dimensions[i].dataIndex,
48439 direction: dimensions[i].direction || 'ASC'
48443 newStore.sort(sorters);
48445 var records = newStore.data.items,
48448 recData, hash, info, data, key;
48450 length = records.length;
48452 for (i = 0; i < length; i++) {
48453 info = this.getRecordInfo(records[i]);
48457 for (key in data) {
48458 hash += data[key] + '---';
48461 if (hashes.indexOf(hash) == -1) {
48467 newStore.destroy();
48473 getRecordInfo: function(record) {
48474 var dimensions = this.dimensions,
48475 length = dimensions.length,
48477 dimension, dataIndex, i;
48480 for (i = 0; i < length; i++) {
48481 dimension = dimensions[i];
48482 dataIndex = dimension.dataIndex;
48484 data[dataIndex] = record.get(dataIndex);
48489 var createMatcherFunction = function(data) {
48490 return function(record) {
48491 for (var dataIndex in data) {
48492 if (record.get(dataIndex) != data[dataIndex]) {
48503 matcher: createMatcherFunction(data)
48508 buildHeaders: function() {
48509 var tuples = this.getTuples(),
48510 rowCount = tuples.length,
48511 dimensions = this.dimensions,
48512 colCount = dimensions.length,
48514 tuple, rows, currentHeader, previousHeader, span, start, isLast, changed, i, j;
48516 for (i = 0; i < colCount; i++) {
48517 dimension = dimensions[i];
48522 for (j = 0; j < rowCount; j++) {
48524 isLast = j == (rowCount - 1);
48525 currentHeader = tuple.data[dimension.dataIndex];
48528 changed = previousHeader != undefined && previousHeader != currentHeader;
48529 if (i > 0 && j > 0) {
48530 changed = changed || tuple.data[dimensions[i-1].dataIndex] != tuples[j-1].data[dimensions[i-1].dataIndex];
48535 header: previousHeader,
48546 header: currentHeader,
48555 previousHeader = currentHeader;
48561 width: dimension.width || this.defaultHeaderWidth
48564 previousHeader = undefined;
48572 Ext.grid.HeaderDragZone = Ext.extend(Ext.dd.DragZone, {
48575 constructor : function(grid, hd, hd2){
48577 this.view = grid.getView();
48578 this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
48579 Ext.grid.HeaderDragZone.superclass.constructor.call(this, hd);
48581 this.setHandleElId(Ext.id(hd));
48582 this.setOuterHandleElId(Ext.id(hd2));
48584 this.scroll = false;
48587 getDragData : function(e){
48588 var t = Ext.lib.Event.getTarget(e),
48589 h = this.view.findHeaderCell(t);
48591 return {ddel: h.firstChild, header:h};
48596 onInitDrag : function(e){
48598 this.dragHeadersDisabled = this.view.headersDisabled;
48599 this.view.headersDisabled = true;
48600 var clone = this.dragData.ddel.cloneNode(true);
48601 clone.id = Ext.id();
48602 clone.style.width = Math.min(this.dragData.header.offsetWidth,this.maxDragWidth) + "px";
48603 this.proxy.update(clone);
48607 afterValidDrop : function(){
48608 this.completeDrop();
48611 afterInvalidDrop : function(){
48612 this.completeDrop();
48615 completeDrop: function(){
48617 disabled = this.dragHeadersDisabled;
48618 setTimeout(function(){
48619 v.headersDisabled = disabled;
48626 Ext.grid.HeaderDropZone = Ext.extend(Ext.dd.DropZone, {
48627 proxyOffsets : [-4, -9],
48628 fly: Ext.Element.fly,
48630 constructor : function(grid, hd, hd2){
48632 this.view = grid.getView();
48634 this.proxyTop = Ext.DomHelper.append(document.body, {
48635 cls:"col-move-top", html:" "
48637 this.proxyBottom = Ext.DomHelper.append(document.body, {
48638 cls:"col-move-bottom", html:" "
48640 this.proxyTop.hide = this.proxyBottom.hide = function(){
48641 this.setLeftTop(-100,-100);
48642 this.setStyle("visibility", "hidden");
48644 this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
48647 Ext.grid.HeaderDropZone.superclass.constructor.call(this, grid.getGridEl().dom);
48650 getTargetFromEvent : function(e){
48651 var t = Ext.lib.Event.getTarget(e),
48652 cindex = this.view.findCellIndex(t);
48653 if(cindex !== false){
48654 return this.view.getHeaderCell(cindex);
48658 nextVisible : function(h){
48659 var v = this.view, cm = this.grid.colModel;
48662 if(!cm.isHidden(v.getCellIndex(h))){
48670 prevVisible : function(h){
48671 var v = this.view, cm = this.grid.colModel;
48674 if(!cm.isHidden(v.getCellIndex(h))){
48682 positionIndicator : function(h, n, e){
48683 var x = Ext.lib.Event.getPageX(e),
48684 r = Ext.lib.Dom.getRegion(n.firstChild),
48687 py = r.top + this.proxyOffsets[1];
48688 if((r.right - x) <= (r.right-r.left)/2){
48689 px = r.right+this.view.borderWidth;
48696 if(this.grid.colModel.isFixed(this.view.getCellIndex(n))){
48700 px += this.proxyOffsets[0];
48701 this.proxyTop.setLeftTop(px, py);
48702 this.proxyTop.show();
48703 if(!this.bottomOffset){
48704 this.bottomOffset = this.view.mainHd.getHeight();
48706 this.proxyBottom.setLeftTop(px, py+this.proxyTop.dom.offsetHeight+this.bottomOffset);
48707 this.proxyBottom.show();
48711 onNodeEnter : function(n, dd, e, data){
48712 if(data.header != n){
48713 this.positionIndicator(data.header, n, e);
48717 onNodeOver : function(n, dd, e, data){
48718 var result = false;
48719 if(data.header != n){
48720 result = this.positionIndicator(data.header, n, e);
48723 this.proxyTop.hide();
48724 this.proxyBottom.hide();
48726 return result ? this.dropAllowed : this.dropNotAllowed;
48729 onNodeOut : function(n, dd, e, data){
48730 this.proxyTop.hide();
48731 this.proxyBottom.hide();
48734 onNodeDrop : function(n, dd, e, data){
48735 var h = data.header;
48737 var cm = this.grid.colModel,
48738 x = Ext.lib.Event.getPageX(e),
48739 r = Ext.lib.Dom.getRegion(n.firstChild),
48740 pt = (r.right - x) <= ((r.right-r.left)/2) ? "after" : "before",
48741 oldIndex = this.view.getCellIndex(h),
48742 newIndex = this.view.getCellIndex(n);
48746 if(oldIndex < newIndex){
48749 cm.moveColumn(oldIndex, newIndex);
48756 Ext.grid.GridView.ColumnDragZone = Ext.extend(Ext.grid.HeaderDragZone, {
48758 constructor : function(grid, hd){
48759 Ext.grid.GridView.ColumnDragZone.superclass.constructor.call(this, grid, hd, null);
48760 this.proxy.el.addClass('x-grid3-col-dd');
48763 handleMouseDown : function(e){
48766 callHandleMouseDown : function(e){
48767 Ext.grid.GridView.ColumnDragZone.superclass.handleMouseDown.call(this, e);
48771 Ext.grid.SplitDragZone = Ext.extend(Ext.dd.DDProxy, {
48772 fly: Ext.Element.fly,
48774 constructor : function(grid, hd, hd2){
48776 this.view = grid.getView();
48777 this.proxy = this.view.resizeProxy;
48778 Ext.grid.SplitDragZone.superclass.constructor.call(this, hd,
48779 "gridSplitters" + this.grid.getGridEl().id, {
48780 dragElId : Ext.id(this.proxy.dom), resizeFrame:false
48782 this.setHandleElId(Ext.id(hd));
48783 this.setOuterHandleElId(Ext.id(hd2));
48784 this.scroll = false;
48787 b4StartDrag : function(x, y){
48788 this.view.headersDisabled = true;
48789 this.proxy.setHeight(this.view.mainWrap.getHeight());
48790 var w = this.cm.getColumnWidth(this.cellIndex);
48791 var minw = Math.max(w-this.grid.minColumnWidth, 0);
48792 this.resetConstraints();
48793 this.setXConstraint(minw, 1000);
48794 this.setYConstraint(0, 0);
48795 this.minX = x - minw;
48796 this.maxX = x + 1000;
48798 Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
48802 handleMouseDown : function(e){
48803 var ev = Ext.EventObject.setEvent(e);
48804 var t = this.fly(ev.getTarget());
48805 if(t.hasClass("x-grid-split")){
48806 this.cellIndex = this.view.getCellIndex(t.dom);
48807 this.split = t.dom;
48808 this.cm = this.grid.colModel;
48809 if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
48810 Ext.grid.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
48815 endDrag : function(e){
48816 this.view.headersDisabled = false;
48817 var endX = Math.max(this.minX, Ext.lib.Event.getPageX(e));
48818 var diff = endX - this.startPos;
48819 this.view.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
48822 autoOffset : function(){
48823 this.setDelta(0,0);
48826 Ext.grid.GridDragZone = function(grid, config){
48827 this.view = grid.getView();
48828 Ext.grid.GridDragZone.superclass.constructor.call(this, this.view.mainBody.dom, config);
48829 this.scroll = false;
48831 this.ddel = document.createElement('div');
48832 this.ddel.className = 'x-grid-dd-wrap';
48835 Ext.extend(Ext.grid.GridDragZone, Ext.dd.DragZone, {
48836 ddGroup : "GridDD",
48839 getDragData : function(e){
48840 var t = Ext.lib.Event.getTarget(e);
48841 var rowIndex = this.view.findRowIndex(t);
48842 if(rowIndex !== false){
48843 var sm = this.grid.selModel;
48844 if(!sm.isSelected(rowIndex) || e.hasModifier()){
48845 sm.handleMouseDown(this.grid, rowIndex, e);
48847 return {grid: this.grid, ddel: this.ddel, rowIndex: rowIndex, selections:sm.getSelections()};
48853 onInitDrag : function(e){
48854 var data = this.dragData;
48855 this.ddel.innerHTML = this.grid.getDragDropText();
48856 this.proxy.update(this.ddel);
48861 afterRepair : function(){
48862 this.dragging = false;
48866 getRepairXY : function(e, data){
48870 onEndDrag : function(data, e){
48874 onValidDrop : function(dd, e, id){
48879 beforeInvalidDrop : function(e, id){
48884 Ext.grid.ColumnModel = Ext.extend(Ext.util.Observable, {
48889 defaultSortable: false,
48895 constructor : function(config) {
48897 if (config.columns) {
48898 Ext.apply(this, config);
48899 this.setConfig(config.columns, true);
48901 this.setConfig(config, true);
48921 Ext.grid.ColumnModel.superclass.constructor.call(this);
48925 getColumnId : function(index) {
48926 return this.config[index].id;
48929 getColumnAt : function(index) {
48930 return this.config[index];
48934 setConfig : function(config, initial) {
48938 delete this.totalWidth;
48940 for (i = 0, len = this.config.length; i < len; i++) {
48941 c = this.config[i];
48951 this.defaults = Ext.apply({
48952 width: this.defaultWidth,
48953 sortable: this.defaultSortable
48956 this.config = config;
48959 for (i = 0, len = config.length; i < len; i++) {
48960 c = Ext.applyIf(config[i], this.defaults);
48963 if (Ext.isEmpty(c.id)) {
48968 var Cls = Ext.grid.Column.types[c.xtype || 'gridcolumn'];
48973 this.lookup[c.id] = c;
48977 this.fireEvent('configchange', this);
48982 getColumnById : function(id) {
48983 return this.lookup[id];
48987 getIndexById : function(id) {
48988 for (var i = 0, len = this.config.length; i < len; i++) {
48989 if (this.config[i].id == id) {
48997 moveColumn : function(oldIndex, newIndex) {
48998 var config = this.config,
48999 c = config[oldIndex];
49001 config.splice(oldIndex, 1);
49002 config.splice(newIndex, 0, c);
49003 this.dataMap = null;
49004 this.fireEvent("columnmoved", this, oldIndex, newIndex);
49008 getColumnCount : function(visibleOnly) {
49009 var length = this.config.length,
49013 if (visibleOnly === true) {
49014 for (i = 0; i < length; i++) {
49015 if (!this.isHidden(i)) {
49027 getColumnsBy : function(fn, scope) {
49028 var config = this.config,
49029 length = config.length,
49033 for (i = 0; i < length; i++){
49036 if (fn.call(scope || this, c, i) === true) {
49037 result[result.length] = c;
49045 isSortable : function(col) {
49046 return !!this.config[col].sortable;
49050 isMenuDisabled : function(col) {
49051 return !!this.config[col].menuDisabled;
49055 getRenderer : function(col) {
49056 return this.config[col].renderer || Ext.grid.ColumnModel.defaultRenderer;
49059 getRendererScope : function(col) {
49060 return this.config[col].scope;
49064 setRenderer : function(col, fn) {
49065 this.config[col].renderer = fn;
49069 getColumnWidth : function(col) {
49070 var width = this.config[col].width;
49071 if(typeof width != 'number'){
49072 width = this.defaultWidth;
49078 setColumnWidth : function(col, width, suppressEvent) {
49079 this.config[col].width = width;
49080 this.totalWidth = null;
49082 if (!suppressEvent) {
49083 this.fireEvent("widthchange", this, col, width);
49088 getTotalWidth : function(includeHidden) {
49089 if (!this.totalWidth) {
49090 this.totalWidth = 0;
49091 for (var i = 0, len = this.config.length; i < len; i++) {
49092 if (includeHidden || !this.isHidden(i)) {
49093 this.totalWidth += this.getColumnWidth(i);
49097 return this.totalWidth;
49101 getColumnHeader : function(col) {
49102 return this.config[col].header;
49106 setColumnHeader : function(col, header) {
49107 this.config[col].header = header;
49108 this.fireEvent("headerchange", this, col, header);
49112 getColumnTooltip : function(col) {
49113 return this.config[col].tooltip;
49116 setColumnTooltip : function(col, tooltip) {
49117 this.config[col].tooltip = tooltip;
49121 getDataIndex : function(col) {
49122 return this.config[col].dataIndex;
49126 setDataIndex : function(col, dataIndex) {
49127 this.config[col].dataIndex = dataIndex;
49131 findColumnIndex : function(dataIndex) {
49132 var c = this.config;
49133 for(var i = 0, len = c.length; i < len; i++){
49134 if(c[i].dataIndex == dataIndex){
49142 isCellEditable : function(colIndex, rowIndex) {
49143 var c = this.config[colIndex],
49147 return !!(ed || (!Ext.isDefined(ed) && c.editor));
49151 getCellEditor : function(colIndex, rowIndex) {
49152 return this.config[colIndex].getCellEditor(rowIndex);
49156 setEditable : function(col, editable) {
49157 this.config[col].editable = editable;
49161 isHidden : function(colIndex) {
49162 return !!this.config[colIndex].hidden;
49166 isFixed : function(colIndex) {
49167 return !!this.config[colIndex].fixed;
49171 isResizable : function(colIndex) {
49172 return colIndex >= 0 && this.config[colIndex].resizable !== false && this.config[colIndex].fixed !== true;
49176 setHidden : function(colIndex, hidden) {
49177 var c = this.config[colIndex];
49178 if(c.hidden !== hidden){
49180 this.totalWidth = null;
49181 this.fireEvent("hiddenchange", this, colIndex, hidden);
49186 setEditor : function(col, editor) {
49187 this.config[col].setEditor(editor);
49191 destroy : function() {
49192 var length = this.config.length,
49195 for (; i < length; i++){
49196 this.config[i].destroy();
49198 delete this.config;
49199 delete this.lookup;
49200 this.purgeListeners();
49204 setState : function(col, state) {
49205 state = Ext.applyIf(state, this.defaults);
49206 Ext.apply(this.config[col], state);
49211 Ext.grid.ColumnModel.defaultRenderer = function(value) {
49212 if (typeof value == "string" && value.length < 1) {
49217 Ext.grid.AbstractSelectionModel = Ext.extend(Ext.util.Observable, {
49220 constructor : function(){
49221 this.locked = false;
49222 Ext.grid.AbstractSelectionModel.superclass.constructor.call(this);
49226 init : function(grid){
49228 if(this.lockOnInit){
49229 delete this.lockOnInit;
49230 this.locked = false;
49239 this.locked = true;
49245 beforerefresh: this.sortUnLock,
49246 refresh: this.sortLock
49249 this.lockOnInit = true;
49255 sortLock : function() {
49256 this.locked = true;
49260 sortUnLock : function() {
49261 this.locked = false;
49265 unlock : function(){
49267 this.locked = false;
49274 gv.un('beforerefresh', this.sortUnLock, this);
49275 gv.un('refresh', this.sortLock, this);
49277 delete this.lockOnInit;
49283 isLocked : function(){
49284 return this.locked;
49287 destroy: function(){
49289 this.purgeListeners();
49292 Ext.grid.RowSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel, {
49294 singleSelect : false,
49296 constructor : function(config){
49297 Ext.apply(this, config);
49298 this.selections = new Ext.util.MixedCollection(false, function(o){
49303 this.lastActive = false;
49315 Ext.grid.RowSelectionModel.superclass.constructor.call(this);
49320 initEvents : function(){
49322 if(!this.grid.enableDragDrop && !this.grid.enableDrag){
49323 this.grid.on('rowmousedown', this.handleMouseDown, this);
49326 this.rowNav = new Ext.KeyNav(this.grid.getGridEl(), {
49327 up: this.onKeyPress,
49328 down: this.onKeyPress,
49332 this.grid.getView().on({
49334 refresh: this.onRefresh,
49335 rowupdated: this.onRowUpdated,
49336 rowremoved: this.onRemove
49340 onKeyPress : function(e, name){
49341 var up = name == 'up',
49342 method = up ? 'selectPrevious' : 'selectNext',
49345 if(!e.shiftKey || this.singleSelect){
49346 this[method](false);
49347 }else if(this.last !== false && this.lastActive !== false){
49349 this.selectRange(this.last, this.lastActive + add);
49350 this.grid.getView().focusRow(this.lastActive);
49351 if(last !== false){
49355 this.selectFirstRow();
49360 onRefresh : function(){
49361 var ds = this.grid.store,
49362 s = this.getSelections(),
49367 this.silent = true;
49368 this.clearSelections(true);
49369 for(; i < len; i++){
49371 if((index = ds.indexOfId(r.id)) != -1){
49372 this.selectRow(index, true);
49375 if(s.length != this.selections.getCount()){
49376 this.fireEvent('selectionchange', this);
49378 this.silent = false;
49382 onRemove : function(v, index, r){
49383 if(this.selections.remove(r) !== false){
49384 this.fireEvent('selectionchange', this);
49389 onRowUpdated : function(v, index, r){
49390 if(this.isSelected(r)){
49391 v.onRowSelect(index);
49396 selectRecords : function(records, keepExisting){
49398 this.clearSelections();
49400 var ds = this.grid.store,
49402 len = records.length;
49403 for(; i < len; i++){
49404 this.selectRow(ds.indexOf(records[i]), true);
49409 getCount : function(){
49410 return this.selections.length;
49414 selectFirstRow : function(){
49419 selectLastRow : function(keepExisting){
49420 this.selectRow(this.grid.store.getCount() - 1, keepExisting);
49424 selectNext : function(keepExisting){
49425 if(this.hasNext()){
49426 this.selectRow(this.last+1, keepExisting);
49427 this.grid.getView().focusRow(this.last);
49434 selectPrevious : function(keepExisting){
49435 if(this.hasPrevious()){
49436 this.selectRow(this.last-1, keepExisting);
49437 this.grid.getView().focusRow(this.last);
49444 hasNext : function(){
49445 return this.last !== false && (this.last+1) < this.grid.store.getCount();
49449 hasPrevious : function(){
49450 return !!this.last;
49455 getSelections : function(){
49456 return [].concat(this.selections.items);
49460 getSelected : function(){
49461 return this.selections.itemAt(0);
49465 each : function(fn, scope){
49466 var s = this.getSelections(),
49470 for(; i < len; i++){
49471 if(fn.call(scope || this, s[i], i) === false){
49479 clearSelections : function(fast){
49480 if(this.isLocked()){
49484 var ds = this.grid.store,
49485 s = this.selections;
49486 s.each(function(r){
49487 this.deselectRow(ds.indexOfId(r.id));
49491 this.selections.clear();
49498 selectAll : function(){
49499 if(this.isLocked()){
49502 this.selections.clear();
49503 for(var i = 0, len = this.grid.store.getCount(); i < len; i++){
49504 this.selectRow(i, true);
49509 hasSelection : function(){
49510 return this.selections.length > 0;
49514 isSelected : function(index){
49515 var r = Ext.isNumber(index) ? this.grid.store.getAt(index) : index;
49516 return (r && this.selections.key(r.id) ? true : false);
49520 isIdSelected : function(id){
49521 return (this.selections.key(id) ? true : false);
49525 handleMouseDown : function(g, rowIndex, e){
49526 if(e.button !== 0 || this.isLocked()){
49529 var view = this.grid.getView();
49530 if(e.shiftKey && !this.singleSelect && this.last !== false){
49531 var last = this.last;
49532 this.selectRange(last, rowIndex, e.ctrlKey);
49534 view.focusRow(rowIndex);
49536 var isSelected = this.isSelected(rowIndex);
49537 if(e.ctrlKey && isSelected){
49538 this.deselectRow(rowIndex);
49539 }else if(!isSelected || this.getCount() > 1){
49540 this.selectRow(rowIndex, e.ctrlKey || e.shiftKey);
49541 view.focusRow(rowIndex);
49547 selectRows : function(rows, keepExisting){
49549 this.clearSelections();
49551 for(var i = 0, len = rows.length; i < len; i++){
49552 this.selectRow(rows[i], true);
49557 selectRange : function(startRow, endRow, keepExisting){
49559 if(this.isLocked()){
49563 this.clearSelections();
49565 if(startRow <= endRow){
49566 for(i = startRow; i <= endRow; i++){
49567 this.selectRow(i, true);
49570 for(i = startRow; i >= endRow; i--){
49571 this.selectRow(i, true);
49577 deselectRange : function(startRow, endRow, preventViewNotify){
49578 if(this.isLocked()){
49581 for(var i = startRow; i <= endRow; i++){
49582 this.deselectRow(i, preventViewNotify);
49587 selectRow : function(index, keepExisting, preventViewNotify){
49588 if(this.isLocked() || (index < 0 || index >= this.grid.store.getCount()) || (keepExisting && this.isSelected(index))){
49591 var r = this.grid.store.getAt(index);
49592 if(r && this.fireEvent('beforerowselect', this, index, keepExisting, r) !== false){
49593 if(!keepExisting || this.singleSelect){
49594 this.clearSelections();
49596 this.selections.add(r);
49597 this.last = this.lastActive = index;
49598 if(!preventViewNotify){
49599 this.grid.getView().onRowSelect(index);
49602 this.fireEvent('rowselect', this, index, r);
49603 this.fireEvent('selectionchange', this);
49609 deselectRow : function(index, preventViewNotify){
49610 if(this.isLocked()){
49613 if(this.last == index){
49616 if(this.lastActive == index){
49617 this.lastActive = false;
49619 var r = this.grid.store.getAt(index);
49621 this.selections.remove(r);
49622 if(!preventViewNotify){
49623 this.grid.getView().onRowDeselect(index);
49625 this.fireEvent('rowdeselect', this, index, r);
49626 this.fireEvent('selectionchange', this);
49631 acceptsNav : function(row, col, cm){
49632 return !cm.isHidden(col) && cm.isCellEditable(col, row);
49636 onEditorKey : function(field, e){
49637 var k = e.getKey(),
49641 ed = g.activeEditor,
49642 shift = e.shiftKey,
49649 newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
49651 newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
49653 }else if(k == e.ENTER){
49654 if(this.moveEditorOnEnter !== false){
49656 newCell = g.walkCells(last.row - 1, last.col, -1, this.acceptsNav, this);
49658 newCell = g.walkCells(last.row + 1, last.col, 1, this.acceptsNav, this);
49666 this.onEditorSelect(r, last.row);
49668 if(g.isEditor && g.editing){
49669 ae = g.activeEditor;
49670 if(ae && ae.field.triggerBlur){
49672 ae.field.triggerBlur();
49675 g.startEditing(r, c);
49679 onEditorSelect: function(row, lastRow){
49680 if(lastRow != row){
49681 this.selectRow(row);
49685 destroy : function(){
49686 Ext.destroy(this.rowNav);
49687 this.rowNav = null;
49688 Ext.grid.RowSelectionModel.superclass.destroy.call(this);
49692 Ext.grid.Column = Ext.extend(Ext.util.Observable, {
49719 constructor : function(config){
49720 Ext.apply(this, config);
49722 if(Ext.isString(this.renderer)){
49723 this.renderer = Ext.util.Format[this.renderer];
49724 }else if(Ext.isObject(this.renderer)){
49725 this.scope = this.renderer.scope;
49726 this.renderer = this.renderer.fn;
49732 var ed = this.editor;
49733 delete this.editor;
49734 this.setEditor(ed);
49745 Ext.grid.Column.superclass.constructor.call(this);
49749 processEvent : function(name, e, grid, rowIndex, colIndex){
49750 return this.fireEvent(name, this, grid, rowIndex, e);
49754 destroy: function() {
49755 if(this.setEditor){
49756 this.setEditor(null);
49758 this.purgeListeners();
49762 renderer : function(value){
49767 getEditor: function(rowIndex){
49768 return this.editable !== false ? this.editor : null;
49772 setEditor : function(editor){
49773 var ed = this.editor;
49776 ed.gridEditor.destroy();
49777 delete ed.gridEditor;
49782 this.editor = null;
49785 if(!editor.isXType){
49786 editor = Ext.create(editor, 'textfield');
49788 this.editor = editor;
49793 getCellEditor: function(rowIndex){
49794 var ed = this.getEditor(rowIndex);
49797 if(!ed.gridEditor){
49798 ed.gridEditor = new Ext.grid.GridEditor(ed);
49800 ed = ed.gridEditor;
49808 Ext.grid.BooleanColumn = Ext.extend(Ext.grid.Column, {
49812 falseText: 'false',
49814 undefinedText: ' ',
49816 constructor: function(cfg){
49817 Ext.grid.BooleanColumn.superclass.constructor.call(this, cfg);
49818 var t = this.trueText, f = this.falseText, u = this.undefinedText;
49819 this.renderer = function(v){
49820 if(v === undefined){
49823 if(!v || v === 'false'){
49832 Ext.grid.NumberColumn = Ext.extend(Ext.grid.Column, {
49834 format : '0,000.00',
49835 constructor: function(cfg){
49836 Ext.grid.NumberColumn.superclass.constructor.call(this, cfg);
49837 this.renderer = Ext.util.Format.numberRenderer(this.format);
49842 Ext.grid.DateColumn = Ext.extend(Ext.grid.Column, {
49845 constructor: function(cfg){
49846 Ext.grid.DateColumn.superclass.constructor.call(this, cfg);
49847 this.renderer = Ext.util.Format.dateRenderer(this.format);
49852 Ext.grid.TemplateColumn = Ext.extend(Ext.grid.Column, {
49854 constructor: function(cfg){
49855 Ext.grid.TemplateColumn.superclass.constructor.call(this, cfg);
49856 var tpl = (!Ext.isPrimitive(this.tpl) && this.tpl.compile) ? this.tpl : new Ext.XTemplate(this.tpl);
49857 this.renderer = function(value, p, r){
49858 return tpl.apply(r.data);
49865 Ext.grid.ActionColumn = Ext.extend(Ext.grid.Column, {
49876 actionIdRe: /x-action-col-(\d+)/,
49881 constructor: function(cfg) {
49883 items = cfg.items || (me.items = [me]),
49888 Ext.grid.ActionColumn.superclass.constructor.call(me, cfg);
49892 me.renderer = function(v, meta) {
49894 v = Ext.isFunction(cfg.renderer) ? cfg.renderer.apply(this, arguments)||'' : '';
49896 meta.css += ' x-action-col-cell';
49897 for (i = 0; i < l; i++) {
49899 v += '<img alt="' + me.altText + '" src="' + (item.icon || Ext.BLANK_IMAGE_URL) +
49900 '" class="x-action-col-icon x-action-col-' + String(i) + ' ' + (item.iconCls || '') +
49901 ' ' + (Ext.isFunction(item.getClass) ? item.getClass.apply(item.scope||this.scope||this, arguments) : '') + '"' +
49902 ((item.tooltip) ? ' ext:qtip="' + item.tooltip + '"' : '') + ' />';
49908 destroy: function() {
49910 delete this.renderer;
49911 return Ext.grid.ActionColumn.superclass.destroy.apply(this, arguments);
49915 processEvent : function(name, e, grid, rowIndex, colIndex){
49916 var m = e.getTarget().className.match(this.actionIdRe),
49918 if (m && (item = this.items[parseInt(m[1], 10)])) {
49919 if (name == 'click') {
49920 (fn = item.handler || this.handler) && fn.call(item.scope||this.scope||this, grid, rowIndex, colIndex, item, e);
49921 } else if ((name == 'mousedown') && (item.stopSelection !== false)) {
49925 return Ext.grid.ActionColumn.superclass.processEvent.apply(this, arguments);
49930 Ext.grid.Column.types = {
49931 gridcolumn : Ext.grid.Column,
49932 booleancolumn: Ext.grid.BooleanColumn,
49933 numbercolumn: Ext.grid.NumberColumn,
49934 datecolumn: Ext.grid.DateColumn,
49935 templatecolumn: Ext.grid.TemplateColumn,
49936 actioncolumn: Ext.grid.ActionColumn
49938 Ext.grid.RowNumberer = Ext.extend(Object, {
49946 constructor : function(config){
49947 Ext.apply(this, config);
49949 this.renderer = this.renderer.createDelegate(this);
49959 rowspan: undefined,
49962 renderer : function(v, p, record, rowIndex){
49964 p.cellAttr = 'rowspan="'+this.rowspan+'"';
49969 Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, {
49973 header : '<div class="x-grid3-hd-checker"> </div>',
49980 menuDisabled : true,
49987 constructor : function(){
49988 Ext.grid.CheckboxSelectionModel.superclass.constructor.apply(this, arguments);
49989 if(this.checkOnly){
49990 this.handleMouseDown = Ext.emptyFn;
49995 initEvents : function(){
49996 Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this);
49997 this.grid.on('render', function(){
49998 Ext.fly(this.grid.getView().innerHd).on('mousedown', this.onHdMouseDown, this);
50003 processEvent : function(name, e, grid, rowIndex, colIndex){
50004 if (name == 'mousedown') {
50005 this.onMouseDown(e, e.getTarget());
50008 return Ext.grid.Column.prototype.processEvent.apply(this, arguments);
50013 onMouseDown : function(e, t){
50014 if(e.button === 0 && t.className == 'x-grid3-row-checker'){
50016 var row = e.getTarget('.x-grid3-row');
50018 var index = row.rowIndex;
50019 if(this.isSelected(index)){
50020 this.deselectRow(index);
50022 this.selectRow(index, true);
50023 this.grid.getView().focusRow(index);
50030 onHdMouseDown : function(e, t) {
50031 if(t.className == 'x-grid3-hd-checker'){
50033 var hd = Ext.fly(t.parentNode);
50034 var isChecked = hd.hasClass('x-grid3-hd-checker-on');
50036 hd.removeClass('x-grid3-hd-checker-on');
50037 this.clearSelections();
50039 hd.addClass('x-grid3-hd-checker-on');
50046 renderer : function(v, p, record){
50047 return '<div class="x-grid3-row-checker"> </div>';
50050 onEditorSelect: function(row, lastRow){
50051 if(lastRow != row && !this.checkOnly){
50052 this.selectRow(row);
50056 Ext.grid.CellSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel, {
50058 constructor : function(config){
50059 Ext.apply(this, config);
50061 this.selection = null;
50065 "beforecellselect",
50072 Ext.grid.CellSelectionModel.superclass.constructor.call(this);
50076 initEvents : function(){
50077 this.grid.on('cellmousedown', this.handleMouseDown, this);
50078 this.grid.on(Ext.EventManager.getKeyEvent(), this.handleKeyDown, this);
50079 this.grid.getView().on({
50081 refresh: this.onViewChange,
50082 rowupdated: this.onRowUpdated,
50083 beforerowremoved: this.clearSelections,
50084 beforerowsinserted: this.clearSelections
50086 if(this.grid.isEditor){
50087 this.grid.on('beforeedit', this.beforeEdit, this);
50092 beforeEdit : function(e){
50093 this.select(e.row, e.column, false, true, e.record);
50097 onRowUpdated : function(v, index, r){
50098 if(this.selection && this.selection.record == r){
50099 v.onCellSelect(index, this.selection.cell[1]);
50104 onViewChange : function(){
50105 this.clearSelections(true);
50109 getSelectedCell : function(){
50110 return this.selection ? this.selection.cell : null;
50114 clearSelections : function(preventNotify){
50115 var s = this.selection;
50117 if(preventNotify !== true){
50118 this.grid.view.onCellDeselect(s.cell[0], s.cell[1]);
50120 this.selection = null;
50121 this.fireEvent("selectionchange", this, null);
50126 hasSelection : function(){
50127 return this.selection ? true : false;
50131 handleMouseDown : function(g, row, cell, e){
50132 if(e.button !== 0 || this.isLocked()){
50135 this.select(row, cell);
50139 select : function(rowIndex, colIndex, preventViewNotify, preventFocus, r){
50140 if(this.fireEvent("beforecellselect", this, rowIndex, colIndex) !== false){
50141 this.clearSelections();
50142 r = r || this.grid.store.getAt(rowIndex);
50145 cell : [rowIndex, colIndex]
50147 if(!preventViewNotify){
50148 var v = this.grid.getView();
50149 v.onCellSelect(rowIndex, colIndex);
50150 if(preventFocus !== true){
50151 v.focusCell(rowIndex, colIndex);
50154 this.fireEvent("cellselect", this, rowIndex, colIndex);
50155 this.fireEvent("selectionchange", this, this.selection);
50160 isSelectable : function(rowIndex, colIndex, cm){
50161 return !cm.isHidden(colIndex);
50165 onEditorKey: function(field, e){
50166 if(e.getKey() == e.TAB){
50167 this.handleKeyDown(e);
50172 handleKeyDown : function(e){
50173 if(!e.isNavKeyPress()){
50177 var k = e.getKey(),
50179 s = this.selection,
50181 walk = function(row, col, step){
50182 return g.walkCells(
50186 g.isEditor && g.editing ? sm.acceptsNav : sm.isSelectable,
50190 cell, newCell, r, c, ae;
50205 cell = walk(0, 0, 1);
50207 this.select(cell[0], cell[1]);
50219 newCell = walk(r, c - 1, -1);
50221 newCell = walk(r, c + 1, 1);
50225 newCell = walk(r + 1, c, 1);
50228 newCell = walk(r - 1, c, -1);
50231 newCell = walk(r, c + 1, 1);
50234 newCell = walk(r, c - 1, -1);
50237 if (g.isEditor && !g.editing) {
50238 g.startEditing(r, c);
50251 if(g.isEditor && g.editing){
50252 ae = g.activeEditor;
50253 if(ae && ae.field.triggerBlur){
50255 ae.field.triggerBlur();
50257 g.startEditing(r, c);
50262 acceptsNav : function(row, col, cm){
50263 return !cm.isHidden(col) && cm.isCellEditable(col, row);
50266 Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, {
50271 forceValidation: false,
50279 autoEncode : false,
50283 trackMouseOver: false,
50286 initComponent : function(){
50287 Ext.grid.EditorGridPanel.superclass.initComponent.call(this);
50289 if(!this.selModel){
50291 this.selModel = new Ext.grid.CellSelectionModel();
50294 this.activeEditor = null;
50307 initEvents : function(){
50308 Ext.grid.EditorGridPanel.superclass.initEvents.call(this);
50310 this.getGridEl().on('mousewheel', this.stopEditing.createDelegate(this, [true]), this);
50311 this.on('columnresize', this.stopEditing, this, [true]);
50313 if(this.clicksToEdit == 1){
50314 this.on("cellclick", this.onCellDblClick, this);
50316 var view = this.getView();
50317 if(this.clicksToEdit == 'auto' && view.mainBody){
50318 view.mainBody.on('mousedown', this.onAutoEditClick, this);
50320 this.on('celldblclick', this.onCellDblClick, this);
50324 onResize : function(){
50325 Ext.grid.EditorGridPanel.superclass.onResize.apply(this, arguments);
50326 var ae = this.activeEditor;
50327 if(this.editing && ae){
50333 onCellDblClick : function(g, row, col){
50334 this.startEditing(row, col);
50338 onAutoEditClick : function(e, t){
50339 if(e.button !== 0){
50342 var row = this.view.findRowIndex(t),
50343 col = this.view.findCellIndex(t);
50344 if(row !== false && col !== false){
50345 this.stopEditing();
50346 if(this.selModel.getSelectedCell){
50347 var sc = this.selModel.getSelectedCell();
50348 if(sc && sc[0] === row && sc[1] === col){
50349 this.startEditing(row, col);
50352 if(this.selModel.isSelected(row)){
50353 this.startEditing(row, col);
50360 onEditComplete : function(ed, value, startValue){
50361 this.editing = false;
50362 this.lastActiveEditor = this.activeEditor;
50363 this.activeEditor = null;
50366 field = this.colModel.getDataIndex(ed.col);
50367 value = this.postEditValue(value, startValue, r, field);
50368 if(this.forceValidation === true || String(value) !== String(startValue)){
50373 originalValue: startValue,
50379 if(this.fireEvent("validateedit", e) !== false && !e.cancel && String(value) !== String(startValue)){
50380 r.set(field, e.value);
50382 this.fireEvent("afteredit", e);
50385 this.view.focusCell(ed.row, ed.col);
50389 startEditing : function(row, col){
50390 this.stopEditing();
50391 if(this.colModel.isCellEditable(col, row)){
50392 this.view.ensureVisible(row, col, true);
50393 var r = this.store.getAt(row),
50394 field = this.colModel.getDataIndex(col),
50399 value: r.data[field],
50404 if(this.fireEvent("beforeedit", e) !== false && !e.cancel){
50405 this.editing = true;
50406 var ed = this.colModel.getCellEditor(col, row);
50411 ed.parentEl = this.view.getEditorParent(ed);
50416 c.field.focus(false, true);
50421 specialkey: function(field, e){
50422 this.getSelectionModel().onEditorKey(field, e);
50424 complete: this.onEditComplete,
50425 canceledit: this.stopEditing.createDelegate(this, [true])
50437 this.activeEditor = ed;
50440 ed.selectSameEditor = (this.activeEditor == this.lastActiveEditor);
50441 var v = this.preEditValue(r, field);
50442 ed.startEdit(this.view.getCell(row, col).firstChild, Ext.isDefined(v) ? v : '');
50446 delete ed.selectSameEditor;
50453 preEditValue : function(r, field){
50454 var value = r.data[field];
50455 return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlDecode(value) : value;
50459 postEditValue : function(value, originalValue, r, field){
50460 return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlEncode(value) : value;
50464 stopEditing : function(cancel){
50467 var ae = this.lastActiveEditor = this.activeEditor;
50469 ae[cancel === true ? 'cancelEdit' : 'completeEdit']();
50470 this.view.focusCell(ae.row, ae.col);
50472 this.activeEditor = null;
50474 this.editing = false;
50477 Ext.reg('editorgrid', Ext.grid.EditorGridPanel);
50479 Ext.grid.GridEditor = function(field, config){
50480 Ext.grid.GridEditor.superclass.constructor.call(this, field, config);
50481 field.monitorTab = false;
50484 Ext.extend(Ext.grid.GridEditor, Ext.Editor, {
50485 alignment: "tl-tl",
50488 cls: "x-small-editor x-grid-editor",
50492 Ext.grid.PropertyRecord = Ext.data.Record.create([
50493 {name:'name',type:'string'}, 'value'
50497 Ext.grid.PropertyStore = Ext.extend(Ext.util.Observable, {
50499 constructor : function(grid, source){
50501 this.store = new Ext.data.Store({
50502 recordType : Ext.grid.PropertyRecord
50504 this.store.on('update', this.onUpdate, this);
50506 this.setSource(source);
50508 Ext.grid.PropertyStore.superclass.constructor.call(this);
50512 setSource : function(o){
50514 this.store.removeAll();
50517 if(this.isEditableValue(o[k])){
50518 data.push(new Ext.grid.PropertyRecord({name: k, value: o[k]}, k));
50521 this.store.loadRecords({records: data}, {}, true);
50525 onUpdate : function(ds, record, type){
50526 if(type == Ext.data.Record.EDIT){
50527 var v = record.data.value;
50528 var oldValue = record.modified.value;
50529 if(this.grid.fireEvent('beforepropertychange', this.source, record.id, v, oldValue) !== false){
50530 this.source[record.id] = v;
50532 this.grid.fireEvent('propertychange', this.source, record.id, v, oldValue);
50540 getProperty : function(row){
50541 return this.store.getAt(row);
50545 isEditableValue: function(val){
50546 return Ext.isPrimitive(val) || Ext.isDate(val);
50550 setValue : function(prop, value, create){
50551 var r = this.getRec(prop);
50553 r.set('value', value);
50554 this.source[prop] = value;
50557 this.source[prop] = value;
50558 r = new Ext.grid.PropertyRecord({name: prop, value: value}, prop);
50565 remove : function(prop){
50566 var r = this.getRec(prop);
50568 this.store.remove(r);
50569 delete this.source[prop];
50574 getRec : function(prop){
50575 return this.store.getById(prop);
50579 getSource : function(){
50580 return this.source;
50585 Ext.grid.PropertyColumnModel = Ext.extend(Ext.grid.ColumnModel, {
50588 valueText : 'Value',
50589 dateFormat : 'm/j/Y',
50591 falseText: 'false',
50593 constructor : function(grid, store){
50598 g.PropertyColumnModel.superclass.constructor.call(this, [
50599 {header: this.nameText, width:50, sortable: true, dataIndex:'name', id: 'name', menuDisabled:true},
50600 {header: this.valueText, width:50, resizable:false, dataIndex: 'value', id: 'value', menuDisabled:true}
50602 this.store = store;
50604 var bfield = new f.Field({
50605 autoCreate: {tag: 'select', children: [
50606 {tag: 'option', value: 'true', html: this.trueText},
50607 {tag: 'option', value: 'false', html: this.falseText}
50609 getValue : function(){
50610 return this.el.dom.value == 'true';
50614 'date' : new g.GridEditor(new f.DateField({selectOnFocus:true})),
50615 'string' : new g.GridEditor(new f.TextField({selectOnFocus:true})),
50616 'number' : new g.GridEditor(new f.NumberField({selectOnFocus:true, style:'text-align:left;'})),
50617 'boolean' : new g.GridEditor(bfield, {
50621 this.renderCellDelegate = this.renderCell.createDelegate(this);
50622 this.renderPropDelegate = this.renderProp.createDelegate(this);
50626 renderDate : function(dateVal){
50627 return dateVal.dateFormat(this.dateFormat);
50631 renderBool : function(bVal){
50632 return this[bVal ? 'trueText' : 'falseText'];
50636 isCellEditable : function(colIndex, rowIndex){
50637 return colIndex == 1;
50641 getRenderer : function(col){
50643 this.renderCellDelegate : this.renderPropDelegate;
50647 renderProp : function(v){
50648 return this.getPropertyName(v);
50652 renderCell : function(val, meta, rec){
50653 var renderer = this.grid.customRenderers[rec.get('name')];
50655 return renderer.apply(this, arguments);
50658 if(Ext.isDate(val)){
50659 rv = this.renderDate(val);
50660 }else if(typeof val == 'boolean'){
50661 rv = this.renderBool(val);
50663 return Ext.util.Format.htmlEncode(rv);
50667 getPropertyName : function(name){
50668 var pn = this.grid.propertyNames;
50669 return pn && pn[name] ? pn[name] : name;
50673 getCellEditor : function(colIndex, rowIndex){
50674 var p = this.store.getProperty(rowIndex),
50676 val = p.data.value;
50677 if(this.grid.customEditors[n]){
50678 return this.grid.customEditors[n];
50680 if(Ext.isDate(val)){
50681 return this.editors.date;
50682 }else if(typeof val == 'number'){
50683 return this.editors.number;
50684 }else if(typeof val == 'boolean'){
50685 return this.editors['boolean'];
50687 return this.editors.string;
50692 destroy : function(){
50693 Ext.grid.PropertyColumnModel.superclass.destroy.call(this);
50694 this.destroyEditors(this.editors);
50695 this.destroyEditors(this.grid.customEditors);
50698 destroyEditors: function(editors){
50699 for(var ed in editors){
50700 Ext.destroy(editors[ed]);
50706 Ext.grid.PropertyGrid = Ext.extend(Ext.grid.EditorGridPanel, {
50714 enableColumnMove:false,
50716 trackMouseOver: false,
50718 enableHdMenu : false,
50724 initComponent : function(){
50725 this.customRenderers = this.customRenderers || {};
50726 this.customEditors = this.customEditors || {};
50727 this.lastEditRow = null;
50728 var store = new Ext.grid.PropertyStore(this);
50729 this.propStore = store;
50730 var cm = new Ext.grid.PropertyColumnModel(this, store);
50731 store.store.sort('name', 'ASC');
50734 'beforepropertychange',
50739 this.ds = store.store;
50740 Ext.grid.PropertyGrid.superclass.initComponent.call(this);
50742 this.mon(this.selModel, 'beforecellselect', function(sm, rowIndex, colIndex){
50743 if(colIndex === 0){
50744 this.startEditing.defer(200, this, [rowIndex, 1]);
50751 onRender : function(){
50752 Ext.grid.PropertyGrid.superclass.onRender.apply(this, arguments);
50754 this.getGridEl().addClass('x-props-grid');
50758 afterRender: function(){
50759 Ext.grid.PropertyGrid.superclass.afterRender.apply(this, arguments);
50761 this.setSource(this.source);
50766 setSource : function(source){
50767 this.propStore.setSource(source);
50771 getSource : function(){
50772 return this.propStore.getSource();
50776 setProperty : function(prop, value, create){
50777 this.propStore.setValue(prop, value, create);
50781 removeProperty : function(prop){
50782 this.propStore.remove(prop);
50790 Ext.reg("propertygrid", Ext.grid.PropertyGrid);
50792 Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
50795 groupByText : 'Group By This Field',
50797 showGroupsText : 'Show in Groups',
50799 hideGroupedColumn : false,
50801 showGroupName : true,
50803 startCollapsed : false,
50805 enableGrouping : true,
50807 enableGroupingMenu : true,
50809 enableNoGroups : true,
50811 emptyGroupText : '(None)',
50815 groupTextTpl : '{text}',
50818 groupMode: 'value',
50823 cancelEditOnToggle: true,
50826 initTemplates : function(){
50827 Ext.grid.GroupingView.superclass.initTemplates.call(this);
50830 var sm = this.grid.getSelectionModel();
50831 sm.on(sm.selectRow ? 'beforerowselect' : 'beforecellselect',
50832 this.onBeforeRowSelect, this);
50834 if(!this.startGroup){
50835 this.startGroup = new Ext.XTemplate(
50836 '<div id="{groupId}" class="x-grid-group {cls}">',
50837 '<div id="{groupId}-hd" class="x-grid-group-hd" style="{style}"><div class="x-grid-group-title">', this.groupTextTpl ,'</div></div>',
50838 '<div id="{groupId}-bd" class="x-grid-group-body">'
50841 this.startGroup.compile();
50843 if (!this.endGroup) {
50844 this.endGroup = '</div></div>';
50849 findGroup : function(el){
50850 return Ext.fly(el).up('.x-grid-group', this.mainBody.dom);
50854 getGroups : function(){
50855 return this.hasRows() ? this.mainBody.dom.childNodes : [];
50859 onAdd : function(ds, records, index) {
50860 if (this.canGroup() && !this.ignoreAdd) {
50861 var ss = this.getScrollState();
50862 this.fireEvent('beforerowsinserted', ds, index, index + (records.length-1));
50864 this.restoreScroll(ss);
50865 this.fireEvent('rowsinserted', ds, index, index + (records.length-1));
50866 } else if (!this.canGroup()) {
50867 Ext.grid.GroupingView.superclass.onAdd.apply(this, arguments);
50872 onRemove : function(ds, record, index, isUpdate){
50873 Ext.grid.GroupingView.superclass.onRemove.apply(this, arguments);
50874 var g = document.getElementById(record._groupId);
50875 if(g && g.childNodes[1].childNodes.length < 1){
50878 this.applyEmptyText();
50882 refreshRow : function(record){
50883 if(this.ds.getCount()==1){
50886 this.isUpdating = true;
50887 Ext.grid.GroupingView.superclass.refreshRow.apply(this, arguments);
50888 this.isUpdating = false;
50893 beforeMenuShow : function(){
50894 var item, items = this.hmenu.items, disabled = this.cm.config[this.hdCtxIndex].groupable === false;
50895 if((item = items.get('groupBy'))){
50896 item.setDisabled(disabled);
50898 if((item = items.get('showGroups'))){
50899 item.setDisabled(disabled);
50900 item.setChecked(this.canGroup(), true);
50905 renderUI : function(){
50906 var markup = Ext.grid.GroupingView.superclass.renderUI.call(this);
50908 if(this.enableGroupingMenu && this.hmenu){
50909 this.hmenu.add('-',{
50911 text: this.groupByText,
50912 handler: this.onGroupByClick,
50914 iconCls:'x-group-by-icon'
50916 if(this.enableNoGroups){
50918 itemId:'showGroups',
50919 text: this.showGroupsText,
50921 checkHandler: this.onShowGroupsClick,
50925 this.hmenu.on('beforeshow', this.beforeMenuShow, this);
50930 processEvent: function(name, e){
50931 Ext.grid.GroupingView.superclass.processEvent.call(this, name, e);
50932 var hd = e.getTarget('.x-grid-group-hd', this.mainBody);
50935 var field = this.getGroupField(),
50936 prefix = this.getPrefix(field),
50937 groupValue = hd.id.substring(prefix.length),
50938 emptyRe = new RegExp('gp-' + Ext.escapeRe(field) + '--hd');
50941 groupValue = groupValue.substr(0, groupValue.length - 3);
50944 if(groupValue || emptyRe.test(hd.id)){
50945 this.grid.fireEvent('group' + name, this.grid, field, groupValue, e);
50947 if(name == 'mousedown' && e.button == 0){
50948 this.toggleGroup(hd.parentNode);
50955 onGroupByClick : function(){
50956 var grid = this.grid;
50957 this.enableGrouping = true;
50958 grid.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex));
50959 grid.fireEvent('groupchange', grid, grid.store.getGroupState());
50960 this.beforeMenuShow();
50965 onShowGroupsClick : function(mi, checked){
50966 this.enableGrouping = checked;
50968 this.onGroupByClick();
50970 this.grid.store.clearGrouping();
50971 this.grid.fireEvent('groupchange', this, null);
50976 toggleRowIndex : function(rowIndex, expanded){
50977 if(!this.canGroup()){
50980 var row = this.getRow(rowIndex);
50982 this.toggleGroup(this.findGroup(row), expanded);
50987 toggleGroup : function(group, expanded){
50988 var gel = Ext.get(group);
50989 expanded = Ext.isDefined(expanded) ? expanded : gel.hasClass('x-grid-group-collapsed');
50990 if(this.state[gel.id] !== expanded){
50991 if (this.cancelEditOnToggle !== false) {
50992 this.grid.stopEditing(true);
50994 this.state[gel.id] = expanded;
50995 gel[expanded ? 'removeClass' : 'addClass']('x-grid-group-collapsed');
51000 toggleAllGroups : function(expanded){
51001 var groups = this.getGroups();
51002 for(var i = 0, len = groups.length; i < len; i++){
51003 this.toggleGroup(groups[i], expanded);
51008 expandAllGroups : function(){
51009 this.toggleAllGroups(true);
51013 collapseAllGroups : function(){
51014 this.toggleAllGroups(false);
51018 getGroup : function(v, r, groupRenderer, rowIndex, colIndex, ds){
51019 var column = this.cm.config[colIndex],
51020 g = groupRenderer ? groupRenderer.call(column.scope, v, {}, r, rowIndex, colIndex, ds) : String(v);
51021 if(g === '' || g === ' '){
51022 g = column.emptyGroupText || this.emptyGroupText;
51028 getGroupField : function(){
51029 return this.grid.store.getGroupState();
51033 afterRender : function(){
51034 if(!this.ds || !this.cm){
51037 Ext.grid.GroupingView.superclass.afterRender.call(this);
51038 if(this.grid.deferRowRender){
51039 this.updateGroupWidths();
51043 afterRenderUI: function () {
51044 Ext.grid.GroupingView.superclass.afterRenderUI.call(this);
51046 if (this.enableGroupingMenu && this.hmenu) {
51047 this.hmenu.add('-',{
51049 text: this.groupByText,
51050 handler: this.onGroupByClick,
51052 iconCls:'x-group-by-icon'
51055 if (this.enableNoGroups) {
51057 itemId:'showGroups',
51058 text: this.showGroupsText,
51060 checkHandler: this.onShowGroupsClick,
51065 this.hmenu.on('beforeshow', this.beforeMenuShow, this);
51070 renderRows : function(){
51071 var groupField = this.getGroupField();
51072 var eg = !!groupField;
51074 if(this.hideGroupedColumn) {
51075 var colIndex = this.cm.findColumnIndex(groupField),
51076 hasLastGroupField = Ext.isDefined(this.lastGroupField);
51077 if(!eg && hasLastGroupField){
51078 this.mainBody.update('');
51079 this.cm.setHidden(this.cm.findColumnIndex(this.lastGroupField), false);
51080 delete this.lastGroupField;
51081 }else if (eg && !hasLastGroupField){
51082 this.lastGroupField = groupField;
51083 this.cm.setHidden(colIndex, true);
51084 }else if (eg && hasLastGroupField && groupField !== this.lastGroupField) {
51085 this.mainBody.update('');
51086 var oldIndex = this.cm.findColumnIndex(this.lastGroupField);
51087 this.cm.setHidden(oldIndex, false);
51088 this.lastGroupField = groupField;
51089 this.cm.setHidden(colIndex, true);
51092 return Ext.grid.GroupingView.superclass.renderRows.apply(
51097 doRender : function(cs, rs, ds, startRow, colCount, stripe){
51102 if(!this.canGroup() || this.isUpdating){
51103 return Ext.grid.GroupingView.superclass.doRender.apply(this, arguments);
51106 var groupField = this.getGroupField(),
51107 colIndex = this.cm.findColumnIndex(groupField),
51109 gstyle = 'width:' + this.getTotalWidth() + ';',
51110 cfg = this.cm.config[colIndex],
51111 groupRenderer = cfg.groupRenderer || cfg.renderer,
51112 prefix = this.showGroupName ? (cfg.groupName || cfg.header)+': ' : '',
51114 curGroup, i, len, gid;
51116 for(i = 0, len = rs.length; i < len; i++){
51117 var rowIndex = startRow + i,
51119 gvalue = r.data[groupField];
51121 g = this.getGroup(gvalue, r, groupRenderer, rowIndex, colIndex, ds);
51122 if(!curGroup || curGroup.group != g){
51123 gid = this.constructId(gvalue, groupField, colIndex);
51126 this.state[gid] = !(Ext.isDefined(this.state[gid]) ? !this.state[gid] : this.startCollapsed);
51132 startRow: rowIndex,
51134 cls: this.state[gid] ? '' : 'x-grid-group-collapsed',
51137 groups.push(curGroup);
51139 curGroup.rs.push(r);
51145 for(i = 0, len = groups.length; i < len; i++){
51147 this.doGroupStart(buf, g, cs, ds, colCount);
51148 buf[buf.length] = Ext.grid.GroupingView.superclass.doRender.call(
51149 this, cs, g.rs, ds, g.startRow, colCount, stripe);
51151 this.doGroupEnd(buf, g, cs, ds, colCount);
51153 return buf.join('');
51157 getGroupId : function(value){
51158 var field = this.getGroupField();
51159 return this.constructId(value, field, this.cm.findColumnIndex(field));
51163 constructId : function(value, field, idx){
51164 var cfg = this.cm.config[idx],
51165 groupRenderer = cfg.groupRenderer || cfg.renderer,
51166 val = (this.groupMode == 'value') ? value : this.getGroup(value, {data:{}}, groupRenderer, 0, idx, this.ds);
51168 return this.getPrefix(field) + Ext.util.Format.htmlEncode(val);
51172 canGroup : function(){
51173 return this.enableGrouping && !!this.getGroupField();
51177 getPrefix: function(field){
51178 return this.grid.getGridEl().id + '-gp-' + field + '-';
51182 doGroupStart : function(buf, g, cs, ds, colCount){
51183 buf[buf.length] = this.startGroup.apply(g);
51187 doGroupEnd : function(buf, g, cs, ds, colCount){
51188 buf[buf.length] = this.endGroup;
51192 getRows : function(){
51193 if(!this.canGroup()){
51194 return Ext.grid.GroupingView.superclass.getRows.call(this);
51197 gs = this.getGroups(),
51203 for(; i < len; ++i){
51204 g = gs[i].childNodes[1];
51207 for(j = 0, jlen = g.length; j < jlen; ++j){
51208 r[r.length] = g[j];
51216 updateGroupWidths : function(){
51217 if(!this.canGroup() || !this.hasRows()){
51220 var tw = Math.max(this.cm.getTotalWidth(), this.el.dom.offsetWidth-this.getScrollOffset()) +'px';
51221 var gs = this.getGroups();
51222 for(var i = 0, len = gs.length; i < len; i++){
51223 gs[i].firstChild.style.width = tw;
51228 onColumnWidthUpdated : function(col, w, tw){
51229 Ext.grid.GroupingView.superclass.onColumnWidthUpdated.call(this, col, w, tw);
51230 this.updateGroupWidths();
51234 onAllColumnWidthsUpdated : function(ws, tw){
51235 Ext.grid.GroupingView.superclass.onAllColumnWidthsUpdated.call(this, ws, tw);
51236 this.updateGroupWidths();
51240 onColumnHiddenUpdated : function(col, hidden, tw){
51241 Ext.grid.GroupingView.superclass.onColumnHiddenUpdated.call(this, col, hidden, tw);
51242 this.updateGroupWidths();
51246 onLayout : function(){
51247 this.updateGroupWidths();
51251 onBeforeRowSelect : function(sm, rowIndex){
51252 this.toggleRowIndex(rowIndex, true);
51256 Ext.grid.GroupingView.GROUP_ID = 1000;